From b28a2d585bc194ba56b6323165a7cec0dcb8a332 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Fri, 18 Jan 2019 00:39:01 +0000 Subject: [PATCH] --- devdocs/todo.txt | 4 +- server/AyaNova/Controllers/AuthController.cs | 75 ++++++++++++++++++-- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 1b769663..270b04bf 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -29,8 +29,8 @@ SERVER - Add tests to ensure security of JWT - https://assets.pentesterlab.com/jwt_security_cheatsheet/jwt_security_cheatsheet.pdf - https://gist.github.com/ejcx/cbf2e1bb75b02c7d77bc1cfcf84a167e - - Test for expired token - - Wrong key / credentials rejected (ISS?) + - DONE Test for expired token + - . Wrong key / credentials rejected (ISS?) - Test truncated signature portion (3rd part) - Test signature transpose bytes - Test with no or wrong algorithm ensure won't accept diff --git a/server/AyaNova/Controllers/AuthController.cs b/server/AyaNova/Controllers/AuthController.cs index 3494b4a2..04a3e556 100644 --- a/server/AyaNova/Controllers/AuthController.cs +++ b/server/AyaNova/Controllers/AuthController.cs @@ -72,6 +72,76 @@ namespace AyaNova.Api.Controllers int nFailedAuthDelay = 10000; #if (DEBUG) nFailedAuthDelay = 1; + + #region TESTING + + //TEST JWT's with various flaws for testing purposes: + if (creds.Password == "INTEGRATION_TEST") + { + + //build the key (JWT set in startup.cs) + byte[] secretKey = System.Text.Encoding.ASCII.GetBytes(ServerBootConfig.AYANOVA_JWT_SECRET); + + //create a new datetime offset of now in utc time + var iat = new DateTimeOffset(DateTime.Now.ToUniversalTime(), TimeSpan.Zero);//timespan zero means zero time off utc / specifying this is a UTC datetime + var exp = new DateTimeOffset(DateTime.Now.AddDays(30).ToUniversalTime(), TimeSpan.Zero); + string Issuer = "ayanova.com"; + var Algorithm = Jose.JwsAlgorithm.HS256; + + //Pre JWT creation test payloads + switch (creds.Login) + { + case "EXPIRED": + exp = new DateTimeOffset(DateTime.Now.AddDays(-30).ToUniversalTime(), TimeSpan.Zero); + break; + case "WRONG_ISSUER": + Issuer = "Bogus"; + break; + case "NO_ALGORITHM": + Algorithm = Jose.JwsAlgorithm.none; + break; + case "WRONG_SECRET": + secretKey = System.Text.Encoding.ASCII.GetBytes("xxxxxxThisIsObviouslyWrongxxxxxx"); + break; + } + + + var payload = new Dictionary() + { + { "iat", iat.ToUnixTimeSeconds().ToString() }, + { "exp", exp.ToUnixTimeSeconds().ToString() },//in payload exp must be in unix epoch time per standard + { "iss", Issuer }, + { "id", "1" }, + { "ayanova/roles", "0" } + }; + string TestToken = Jose.JWT.Encode(payload, secretKey, Algorithm); + + + //"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOiIxNTQ0NTU5NzAwIiwiZXhwIjoiMTU0NzE1MTcwMCIsImlzcyI6ImF5YW5vdmEuY29tIiwiaWQiOiIxIiwiYXlhbm92YS9yb2xlcyI6IjMyNzY3In0.fMq_8Dvia63rzN_U2zjczPvUNM40OEAeI4VOeV6ulGw" + //Post JWT creation test payloads + switch (creds.Login) + { + case "TRUNCATED_SIGNATURE": + TestToken = TestToken.Substring(0, TestToken.Length - 3); + break; + case "TRANSPOSE_SIGNATURE": + int len=TestToken.Length; + var Transposed = TestToken.Substring(0,len-5) + TestToken[len-3] + TestToken[len-4] + TestToken.Substring(len-3,3); + TestToken=Transposed; + //int len = str.Length; + // return str[len-1] + str.Substring(1,len-2) + str[0]; + break; + } + + + return Ok(new ApiOkResponse(new + { + token = TestToken + })); + + } + + #endregion testing #endif if (string.IsNullOrWhiteSpace(creds.Login) || string.IsNullOrWhiteSpace(creds.Password)) @@ -131,11 +201,6 @@ namespace AyaNova.Api.Controllers //issue tokens as well, but it looked cmplex and this works so unless need to remove in future keeping it. string token = Jose.JWT.Encode(payload, secretKey, Jose.JwsAlgorithm.HS256); - //TODO: Before release double check that security of JWT is still ok: - //https://assets.pentesterlab.com/jwt_security_cheatsheet/jwt_security_cheatsheet.pdf - //https://github.com/ticarpi/jwt_tool - - log.LogDebug($"User number \"{u.Id}\" logged in from \"{Util.StringUtil.MaskIPAddress(HttpContext.Connection.RemoteIpAddress.ToString())}\" ok"); metrics.Measure.Meter.Mark(MetricsRegistry.SuccessfulLoginMeter);