From 68ee6f411ab74dd2d388dcb910586c23b7ed7bd1 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Mon, 7 Dec 2020 18:11:16 +0000 Subject: [PATCH] --- server/AyaNova/Controllers/AuthController.cs | 21 ++++++++++---------- server/AyaNova/biz/UserBiz.cs | 11 ++++++++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/server/AyaNova/Controllers/AuthController.cs b/server/AyaNova/Controllers/AuthController.cs index be2bac0d..8e4131dc 100644 --- a/server/AyaNova/Controllers/AuthController.cs +++ b/server/AyaNova/Controllers/AuthController.cs @@ -266,18 +266,15 @@ namespace AyaNova.Api.Controllers { //Note: need to be authenticated to use this, only called from own user's UI //it still asks for old creds in case someone attempts to do this on another user's logged in session + //Also it checks here that this is in fact the same user account calling this method as the user attempting to be modified if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); - if (!ModelState.IsValid) - { return BadRequest(new ApiErrorResponse(ModelState)); - } int nFailedAuthDelay = 3000;//should be just long enough to make brute force a hassle but short enough to not annoy people who just mistyped their creds to login - if (string.IsNullOrWhiteSpace(changecreds.OldPassword) || string.IsNullOrWhiteSpace(changecreds.LoginName)) { //Make a failed pw wait @@ -286,16 +283,10 @@ namespace AyaNova.Api.Controllers } if (string.IsNullOrWhiteSpace(changecreds.NewPassword)) - { return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, "NewPassword")); - } if (changecreds.NewPassword != changecreds.ConfirmPassword) - { return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_INVALID_VALUE, "ConfirmPassword", "NewPassword does not match ConfirmPassword")); - } - - //Multiple users are allowed the same password and login //Salt will differentiate them so get all users that match login, then try to match pw @@ -310,10 +301,18 @@ namespace AyaNova.Api.Controllers //If the user is inactive they may not login if (!u.Active) { - //respond like bad creds so as not to leak information + //respond like bad creds so as not to leak information + await Task.Delay(nFailedAuthDelay); return StatusCode(401, new ApiErrorResponse(ApiErrorCode.AUTHENTICATION_FAILED)); } + //double check it's the currently logged in User's own User object only + //otherwise it's feasible someone could change someone else's password through their own change password form with a mis-type or intentional hack + if (u.Id != UserIdFromContext.Id(HttpContext.Items)) + { + await Task.Delay(nFailedAuthDelay); + return StatusCode(401, new ApiErrorResponse(ApiErrorCode.AUTHENTICATION_FAILED)); + } //fetch and update user //Instantiate the business object handler diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index d5a42342..ca7b32d1 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -359,6 +359,17 @@ namespace AyaNova.Biz AddError(ApiErrorCode.NOT_FOUND); return 0; } + //Also used for Contacts (customer type user or ho type user) + //by users with no User right but with Customer rights so need to double check here + if ( + (dbObject.IsOutsideUser && !Authorized.HasModifyRole(CurrentUserRoles, AyaType.Customer)) || + (!dbObject.IsOutsideUser && !Authorized.HasModifyRole(CurrentUserRoles, AyaType.User)) + ) + { + AddError(ApiErrorCode.NOT_AUTHORIZED); + return 0; + } + if (string.IsNullOrWhiteSpace(dbObject.UserOptions.EmailAddress)) { AddError(ApiErrorCode.VALIDATION_REQUIRED, "EmailAddress");