出现了关于客户端的会话数据是否会被泄露或更改的问题。
假设我将用户数据保存在会话中
HttpContext.Session.SetString(ROLE, "User")
当从会话接收这些数据时,我不想获得不是User 的角色,但假设是Admin
因为在我的例子中,会话中的数据用于创建 jwt。
因此,据我了解,用户不会接收数据本身,他只接收会话标识符,并且假设数据不会被泄露或更改是合乎逻辑的,因为数据本身存储在服务器上,并且用户只有标识符,并不直接与该数据交互。
但我对此不确定,也许有一些值得担心的漏洞,如果有的话,请告诉我们。
如果有任何信息,我将非常感激。
我的情况,为什么我认为我需要会议:
主要端点验证数据并通常执行一些逻辑:
[HttpPost("login")]
public async Task<IActionResult> Login(UserModel userModel)
{
try
{
if (userModel.email is null || userModel.password is null)
return StatusCode(422, new { message = AccountErrorMessage.InvalidUserData });
var email = userModel.email.ToLowerInvariant();
var user = await _dbContext.Users.FirstOrDefaultAsync(u => u.email == email);
if (user is null)
return StatusCode(404, new { message = AccountErrorMessage.UserNotFound });
bool IsCorrect = _passwordManager.CheckPassword(userModel.password, user.password!);
if (!IsCorrect)
return StatusCode(401, new { message = AccountErrorMessage.PasswordIncorrect });
var clientInfo = Parser.GetDefault().Parse(HttpContext.Request.Headers["User-Agent"].ToString());
if ((bool)!user.is_2fa_enabled)
return await FactLogin(clientInfo, user);
int code = _generateCode.GenerateSixDigitCode();
var emailDto = new EmailDto
{
username = user.username,
email = user.email,
subject = EmailMessage.Verify2FaHeader,
message = EmailMessage.Verify2FaBody + code
};
await _emailSender.SendMessage(emailDto);
HttpContext.Session.SetString(ID, user.id.ToString());
HttpContext.Session.SetString(EMAIL, email);
HttpContext.Session.SetString(USERNAME, user.username!);
HttpContext.Session.SetString(ROLE, user.role!);
HttpContext.Session.SetString(CODE, code.ToString());
return StatusCode(200, new { message = AccountSuccessMessage.EmailSended });
}
catch (UserException)
{
_logger.LogCritical("When trying to update the data, the user was deleted");
_tokenService.DeleteTokens();
_logger.LogDebug("Tokens was deleted");
return StatusCode(404);
}
catch (Exception)
{
return StatusCode(500);
}
}
验证端点:
[HttpPost("verify/2fa")]
public async Task<IActionResult> VerifyTwoFA([FromQuery] int code)
{
int correctCode = int.Parse(HttpContext.Session.GetString(CODE));
int userId = int.Parse(HttpContext.Session.GetString(ID));
string? email = HttpContext.Session.GetString(EMAIL);
string? username = HttpContext.Session.GetString(USERNAME);
string? role = HttpContext.Session.GetString(ROLE);
if (email is null || username is null || role is null)
return StatusCode(422, new { message = AccountErrorMessage.NullUserData });
if (!code.Equals(correctCode))
return StatusCode(422, new { message = AccountErrorMessage.CodeIncorrect });
var clientInfo = Parser.GetDefault().Parse(HttpContext.Request.Headers["User-Agent"].ToString());
var userModel = new UserModel
{
id = userId,
username = username,
email = email,
role = role
};
HttpContext.Session.Clear();
return await FactLogin(clientInfo, userModel);
}
是的,当然,你可以再次向数据库请求数据,但我不想再次加载数据库
会话状态(“会话”)存储在服务器内存(默认情况下)、DBMS 或某种 Redis 中。客户不能以任何方式改变它。
然而,对此状态(会话标识符)的引用存储在cookie中,并且可以被攻击者利用XSRF(跨站点请求伪造)攻击。因此,请使用反 XSRF 令牌保护任何变异操作,并且在任何情况下都不要将 CORS 策略设置为“允许一切和所有人”。