【问题标题】:Anti-forgery token on each request from angular app来自角度应用程序的每个请求的防伪令牌
【发布时间】:2017-10-04 09:21:48
【问题描述】:

我有一个应该非常安全的网站,因为大多数活动都是金融交易。这个网站有很多安全机制,我怀疑其中一个还不够。

此 Web 应用程序基于 AngularJS 1.4 和 ASP.NET MVC 4。使用 Angular 登录系统后,我正在调用控制器操作来设置防伪令牌。所有后续请求都具有相同的令牌,服务器对每个请求都进行相同的验证。

现在问题来了。

由于我们不会更改每个请求的令牌,因此登录用户只需查看 Fiddler 或 Chrome 网络选项卡并尝试请求修改请求的资源即可使用请求中的令牌。

是否需要在每次请求时重置令牌?是否有助于防止此类攻击?

【问题讨论】:

    标签: asp.net angularjs asp.net-mvc csrf csrf-protection


    【解决方案1】:

    令牌并不是为了阻止授权用户手动制作请求。该令牌确保用户以外的其他人不能使用 csrf 请求来伪造来自用户的请求。

    您可以重复使用相同的令牌,因为如果实施得当,潜在的 CSRF 攻击者应该无法读取该值。这依赖于浏览器的同源策略,以确保第三方站点无法读取或提交相同的值。

    如果您有任何漏洞,例如返回令牌的 json GET(最佳做法是返回的 JSON 数据仍应与帖子一起提交),那么令牌可能会被泄露。

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks

    授权 关于来自经过身份验证的用户的潜在欺诈请求

    您需要进行服务器端检查,以确保他仅将编辑发布到他有权编辑的帐户。例如,如果我拥有账户 A,并且我想向账户 B 汇款,那么服务器端检查将确保我拥有账户 A,因此有权将其资金发送到其他地方。如果我手工制作了从 B 向 A 发送资金的请求,服务器端检查应该通过查看帐户和所有者的数据库关系来确定我不是 B 的所有者。这称为授权。授权确保用户有权执行某项操作。这通常由定义表之间关系的业务规则规定,这些关系说明谁可以访问什么。

    身份验证 唯一的另一个问题是确保我是我所说的我,因为如果我只是在请求中发布了一个用户 ID,我可以很容易地在浏览器中更改它。

    当用户证明他是他所说的人时,通常通过提供用户 ID/密码,然后我们生成一个身份验证令牌。在 ASP.NET 中,此令牌是加密安全的,因此只有服务器具有生成和验证令牌所需的密钥信息。通常此令牌作为 cookie 保存。

    身份验证和授权的结合确保我们知道用户是谁,并且在每个请求上使用我们定义授权的业务规则来检查操作是否有效。他可以手工制作无效请求并不重要,因为这些请求将无法通过服务器端授权。

    想象一下这个简化的服务器端代码:

    public void TransferFunds(TransferFundsRequest request)
    {
      var account = Database.GetAccount(request.SourceAccountId);
      if(account.OwnerUserId != session.UserId)
      {
         throw UnauthorizedException("This user is not the owner of the source account in the transfer funds request.");
      }
    
      // continue with logic to transfer funds
    } 
    

    CSRF 跨站点请求伪造是一个完全不同的问题。这是当授权用户的浏览器中加载的另一个站点尝试从用户的浏览器发送请求时。我访问的恶意第三方网站使用 javascript 或其他方法使我的浏览器从账户 A 向账户 C 发出 TransferFunds 请求。现在,如果我是账户 A 的所有者,从服务器的角度来看这是一个有效的请求. CSRF 令牌确保我们可以检测到用户不是从我们的服务器生成的表单发送请求,而是从某个第三方站点的表单或 URL 发送请求。

    例如,如果请求的所有参数都可以编码在查询字符串中,我可以为 TransferFunds 请求制作一个 URL,并将其通过电子邮件发送给账户 A 所有者,并尝试诱使他们点击链接。如果用户碰巧登录了站点,那么我们的服务器就会认为是用户发送了请求。但是,如果我们在生成 HTML 输入表单时包含 anti-CSRF 令牌,那么令牌的缺失向我们证明了请求来自第三方制作的表单或 URL。

    【讨论】:

    • 我的疑问是,如果用户本人是黑客怎么办?他已登录并使用他自己的令牌发布到系统中并带有已编辑的请求。假设资金转移是通过将源帐户编辑到银行中存在的另一个帐户来完成的。我们可以采取什么样的标准措施来防止此类活动?
    • @SanishJoseph 我已经详细说明了您作为示例描述的场景。 CSRF 旨在防止第三方导致用户的浏览器发送请求,但不能防止授权用户发出无效请求。这需要将授权实现为服务器端业务规则。
    • 谢谢。这是我的想法。我们必须确保用户帖子是否有效并且他可以访问。诸如帐户之类的东西不在我们的数据库中,而是在核心银行中,但我们仍然可以验证。每个服务器帖子都需要对有效帖子进行一些检查,这就是为什么我想有一个通用的解决方案。我会想办法保护它。
    • @SanishJoseph 用户始终可以手动制作自己的请求,从而发送您的 HTML 表单可能不允许的内容。根据经验,您永远不会信任用户输入,并且始终验证服务器端的任何问题。
    • 是的。永远不要相信任何输入!
    猜你喜欢
    • 2023-04-09
    • 2018-07-03
    • 2019-03-18
    • 2015-08-15
    • 2018-06-19
    • 2011-05-17
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多