首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >所有表单都应该检查ASP .NET Web中相同的防伪令牌吗?

所有表单都应该检查ASP .NET Web中相同的防伪令牌吗?
EN

Stack Overflow用户
提问于 2022-10-28 12:05:38
回答 1查看 49关注 0票数 0

下面是一个场景:

Web使用在Program.cs中添加的防伪造服务:

代码语言:javascript
复制
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

用户希望编辑项目。因此,客户端通过调用以下命令从API请求表单:

代码语言:javascript
复制
[HttpGet("[action]")]
public IActionResult Edit([FromQuery] int id) 
{
    var obj = _objService.GetObjOrDefault(id);
    if (obj == null)
    {
        return NotFound();
    }

    var antiForgery = HttpContext.RequestServices.GetService<IAntiforgery>();
    if (antiForgery != null)
    {
        var tokens = antiForgery.GetAndStoreTokens(HttpContext);
        HttpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!, new CookieOptions { HttpOnly = false });
    }
    
    return new ObjectResult(obj);
}

用户填写表单。客户端将更新后的对象发送回API (头中包含了防伪造令牌)。客户端调用此API方法:

代码语言:javascript
复制
[HttpPut("[action]")]
[ValidateAntiForgeryToken]
public IActionResult Update([FromQuery] int id, [FromBody] SomeClass updated)
{
    _objService.UpdateObj(id, obj);
}

ASP.NET自动检查防伪令牌是否有效。棒极了..。但是等一下。客户端可以在应用[ValidateAntiForgeryToken]属性的所有其他API方法中重用相同的防伪令牌,似乎没有时间限制(?)。

我的问题是,你如何确保防伪令牌是为那个特定的表格发送的,你应该吗?如果客户端可以使用相同的防伪令牌来填写任何表单,那么为什么不在用户登录时将其发送给客户端呢?你一定要清除或超时防伪令牌吗?

我基本上遵循这篇文章来实现防伪造令牌,而且它是有效的,但我仍然觉得我不理解如何实现

编辑:客户机可以在多个控制器上重复使用防伪造令牌,只要HTTP(基本上是用户当前的URL)保持不变。你不会知道是哪种形式或者是哪个管理员给他的防伪令牌。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-09 21:49:41

防伪令牌是有限的。他们只会防止CSRF攻击。通过实现防伪造令牌,您可以证明请求是由查看您的页面的用户发送的,而不是恶意的。

同源策略(SOP)是在web浏览器中实现的一种安全特性.SOP确保不同域上的恶意站点无法从API读取响应。但是,恶意站点可能会向API发送请求。默认情况下,用户的cookie(如会话ID )包含在对API的请求中,无论用户当前位于哪个域。

由于SOP,只有您域中的客户端才能从GET请求中读取响应。这就是为什么当用户使用例如GET api/something/edit请求表单时添加防伪造令牌的原因。恶意网站将无法知道防伪令牌。因此,当用户稍后使用PUT api/something/update时,我们知道更新请求是从能够从GET请求读取响应的人发送的。

正如MS文档中所述,GET请求在理想情况下应该没有副作用.例如,GET请求不应该修改数据,因为它们可以从恶意站点发送。所有的POST、PUT和DELETE请求都应该应用防伪造令牌( 即使在页面上的标牌上 ).

但是,关于我最初的问题:假设用户请求GET api/something/edit?id=1,但稍后发送请求PUT api/something/update?id=2[ValidateAntiForgeryToken]不会检查客户端实际上更新了他最初请求的对象。您需要实现一些自定义逻辑来检查这一点,但通常您不会费心这样做,因为您可以使用基于声明的授权,只需检查用户是否可以更新该对象。使用防伪造令牌,您知道用户在使用站点时执行操作,而不是恶意操作。

答:要回答我最初的问题,“你应该对多种形式使用相同的防伪令牌吗?”这真的不重要。如果用户能够提供防伪造令牌,他已经证明他是在查看您的页面时发送请求,而不是恶意请求。最佳实践是在所有POST、PUT和DELETE请求中包括[ValidateAntiForgeryToken],同时确保GET请求不会产生任何副作用。您仍然需要检查用户是否可以更新他试图修改的项,例如,使用基于声明的授权。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74235160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档