【问题标题】:How much of an html form can be altered without triggering CSRF protection?在不触发 CSRF 保护的情况下可以更改多少 html 表单?
【发布时间】:2013-04-24 15:20:38
【问题描述】:

我通过在每个表单的隐藏输入中包含一个带有 PHP 的令牌来实现 CSRF 保护。当然,每个令牌只能使用一次。

但是,有些工具(例如任何 Web 开发人员工具)允许更改输入。例如,我可以更改页面输入表单:我可以启用禁用的复选框,并且我可以将输入框更改为 textarea 框,而无需重新加载页面或类似的东西。 CSRF 不会捕捉到这样的变化。

那么,为了保证安全,我需要验证多少表单?我是否需要验证每个输入以确保它没有被更改,包括选择、复选框、隐藏输入等?假设这些没有被改变肯定是不安全的吗?

【问题讨论】:

  • 不,您不能确定通过$_POST$_GET 进入的任何内容都没有被操纵。
  • 永远不要相信用户提供的内容。如果字段有效很重要,则验证它。例如,一个电子邮件地址可能值得验证,但一个 cmets 框可能只需要检查它是否为空。

标签: php html forms csrf


【解决方案1】:

您需要(在服务器端)验证所有需要验证的内容。究竟需要验证什么取决于许多因素和个人选择。其中一些可能是为了安全,但在许多情况下只需要最低限度。大多数情况下,验证是为了改善或创造用户体验。

例如,您可以检查他们是否输入了有效的电子邮件地址。如果他们没有,你可以给他们留言。如果您不这样做,您的应用程序不会发生任何不良情况,但用户将无法收到您的电子邮件。

验证卫生之间也有一个重要的区别。卫生是为了安全(例如防止注射)。进行验证是为了确保输入满足与您的应用程序一起正常工作的要求,尽管不正确的输入可能是良性的。净化后的恶意输入也可能是有效的。

所有输入必须经过清理。没有输入需要进行验证,所以这完全取决于您。

CSRF 保护与验证无关。它所做的只是阻止用户使用您的表单从外部来源发出请求,因为生成和查看令牌的唯一方法是首先向您的站点发出请求。

【讨论】:

  • 感谢您的解释。让我举一个简单的例子:如果我想允许用户删除他发布的帖子,我可以创建一个表单提交按钮,该按钮的名称为“delete_post”,值为“[#post_id]”。现在,为了让用户看到那个按钮,他必须是帖子的所有者。在这种情况下,一旦他按下按钮,我是否需要重新检查他是否是“delete_post”值的所有者?甚至可以将此值更改为其他人的帖子吗?我觉得我只是一遍又一遍地做同样的重复验证。
  • @user371699 是的,您需要进行身份验证检查,但这应该相当简单。例如,DELETE FROM post WHERE user_id = ? AND id = ?user_id 可能已经在会话中
  • 毫无疑问这是微不足道的,但就我而言,有很多检查要做。非常感谢您的解释。
【解决方案2】:

我们尝试使用 CSRF 来确保请求来自可靠的来源。例如,您需要做的是确保隐藏字段中的值是合理的。只有当它与服务器呈现表单时提供的相同时,它才可能是理智的(前提是您的令牌足够强大)。

现在表单中的字段是否更改,只是您的应用程序逻辑。它与 csrf 没有任何关系。如果令牌是理智的,那么它来自正确的来源。现在,如果是同一个人在表格中输入值,例如不在csrf范围内。

【讨论】:

    【解决方案3】:

    我认为你在这里搞错了。发送时令牌不是表单的哈希。

    这种工作方式是将您的唯一令牌存储在表单上的隐藏字段中,并在您提供原始页面时存储到会话中。

    当您从用户那里获得 POST/GETed 页面时,您检查页面上的令牌是否与之前存储在会话中的令牌相同。

    仍然必须允许更改字段,否则您的用户将无法在表单上输入任何数据。您只是在检查您收到的表单是否与您发送的相同,因为令牌是相同的,而不是来自其他地方的令牌,即它不是跨站点请求伪造。

    在将数据存储到数据库之前,您仍然需要验证所有字段并进行任何数据准备。

    Reading1 Reading2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-06
      • 2014-01-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多