如何防止 PHP、csrf、xsrf 中的表单重放/中间人攻击

发布于 2024-08-07 01:37:43 字数 400 浏览 7 评论 0原文

我有一个网络表单,并且正在使用 PHP。我知道表单可以被操纵(我相信这称为重放攻击或中间人攻击)。所以我想使用一些真实性令牌作为隐藏字段。

我知道的威胁可能性是:

  • 攻击者劫持合法用户的表单(我认为这是中间人攻击)
  • 合法用户本身就是攻击者:他获取表单,读取令牌,但使用它发送危险数据(我认为这是重放攻击)

在我回答问题之前,如果我到目前为止所说的任何内容不正确,请纠正我,因为也许我的理解有缺陷。

现在的问题是:

  • 生成此令牌的最佳实践是什么,以便没有它的表单被拒绝(例如,加盐?)。
  • 人们如何确保令牌不被重放。

基于评论的新小问题:

  • 会话劫持与中间人攻击相同吗?

I have a web form and I'm using PHP. I'm aware that forms can be manipulated (I believe it's called replay attack or a man-in-the-middle attack). So I'd like to use some authenticity token as a hidden field.

The threat possibilities that I'm aware of are:

  • Attacker hijacks the legitimate user's form (this I believe is the man-in-the-middle attack)
  • the legitimate user is himself the attacker: he gets the form, reads the token but uses it to send dangerous data (this I believe is the replay attack)

Before I get to the questions, please correct me if anything I said so far is incorrect, because maybe my understanding is flawed.

Now to the questions:

  • What is the best practice to generate this token so that the form without it gets rejected (for example, salting?).
  • What do people do to make sure that the token isn't being replayed.

New small questions based on comments:

  • Is session hijacking the same as man-in-the-middle attack?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

笑咖 2024-08-14 01:37:43

您在标题中提到了 CSRF,但在您的问题中并未真正涵盖它。

您可以在线阅读详细信息,但 CSRF 基本上是一种攻击,允许合法的用户在不知情的情况下提交到网站。例如,如果 SO 不能防止此类攻击,我可以制作一个表单,当您单击我的这个不良表单时,会导致您的 SO 配置文件信息发生更改,并期望发生其他情况(“赢得一百万美元!点击这里!!”)。此表单将使用您的浏览器 cookie 对您进行身份验证,并让您认为您正在合法提交个人资料更新。

为了防止这种情况,您确实需要做几件事:

  • 确保 GET 不会导致更新(例如,不要使用 GET 上的查询参数将新的状态更新发布到用户的个人资料)
  • 确保所有 POST附有一个隐藏字段,可让您验证该表单是由您的服务而不是其他人生成的,并且是针对目标用户的。因此,这个隐藏字段必须由服务器每次发送表单的 html 时生成,并且对于该会话的该用户来说应该是唯一的。

第二项的替代方法是检查引荐来源网址是否始终是您的网站或您期望发布 POST 的网站。我不鼓励非 HTTPS 站点这样做,因为某些浏览器/网络硬件会删除引荐来源网址,并且引荐来源网址的存在并不总是可靠的。

You mentioned CSRF in the title but didn't really cover it in your question.

You can read about it in detail online, but CSRF is basically an attack that lets a legitimate user submit to a site unknowingly. For instance, if SO wasn't protecting against such attacks, I could craft a form that causes your SO profile information to be changed when you click on this bad form of mine, expecting something else to happen ("Win a Million bucks!! Click here!!"). This form would use your browser cookies to auth you with SO and make it appear to SO that you were legitimately submitting updates to your profile.

To protect against this, you really want to do a couple of things:

  • ensure that GETs don't cause updates (for instance, don't post a new status update to a user's profile using query params on a GET)
  • ensure that all POSTs are accompanied by a hidden field that lets you validate that the form was generated by your service and not by someone else, and that it was for the intended user. So this hidden field must be generated by the server each time it sends down the html for the form, and should be unique for that user for that session.

An alternative to that second item is to check that the referrer is always your site or a site you expect the POST from. I don't encourage this for non-HTTPS sites because some browsers/networking hardware strip out referrers, and it's not always reliable that a referrer exists.

梦毁影碎の 2024-08-14 01:37:43

用于生成令牌的方法并不是非常重要。 重要的是令牌只能使用一次。在用户会话中保留为用户生成的令牌列表。如果用户提交表单并且提交的令牌不在会话中,您可以拒绝该表单。

防范中间人有点困难。我见过的一种常见技术是将所有隐藏表单字段包含在哈希函数中以生成令牌,然后根据已知的隐藏字段重新生成令牌。然而,这只能防止隐藏的领域操纵,这可能不是中间人的最终目标。

当用户成功提交带有令牌的表单时,从会话中删除令牌,因此该提交的任何重播都会失败。然而,所需要的只是用户再次请求表单来生成另一个令牌。然后可以在后续的自动攻击中使用该新令牌。 换句话说,表单令牌对于对抗 CSRF 很有用,但对于对抗自动重放和中间人攻击却不是非常有效。

同样,您将希望调整您的应用程序以不需要用户在表单上使用后退按钮。如果他们的提交存在问题,您将需要将填写了数据的表单返回给用户。如果用户点击后退按钮来更正错误,她的提交将因现在无效而失败令牌。

另外,坦率地说,当您需要担心请求重放和中间人攻击时,您的用户连接已经受到损害,并且您可能无能为力来减轻任何损害。仅 SSL 就足以针对 MITM 和重放提供足够的保护级别,如果您担心这一点,那么您将在 SSL 下运行......

The method used to generate the token is not highly important. The important thing is that the token gets to be used only once. Keep a list of tokens generated for the user in the user's session. If the user submits a form and the token submitted isn't in the session, you can reject the form.

Protecting against man-in-the-middle is a little difficult. A common technique I've seen is including all of the hidden form fields in the hash function to generate the token, and then regenerating the token based on known hidden fields. However, that would only protect against hidden field manipulation, which may not be the ultimate target of the man in the middle.

When the user successfully submits a form with the token, delete the token from the session, so any replay of that submission will fail. However, all it takes is the user requesting the form again to generate another token. That new token can then be used in subsequent automated attacks. In other words, form tokens are useful against CSRF, but not highly effective against automated replay and man-in-the-middle attacks.

Likewise, you're going to want to adapt your application to not require the use of the user's back button on forms. If there's an issue with their submission, you're going to need to return the form back to the user with their data filled in. If the user hits her back button to correct the error, her submission will then fail due to the now invalid token.

Also, to be frank, by the time you need to worry about request replays and man-in-the-middle attacks, your user's connection has already been compromised, and there's probably not much you can do to mitigate any damage. SSL alone is an adequate protection level against MITM and replay, and if you're that worried about it, you'll be running under SSL...

苏大泽ㄣ 2024-08-14 01:37:43

为了生成该令牌,我使用了一种似乎效果很好的策略。

  • 将 cookie 设置为随机值(使用通常的技巧在服务器上生成)并根据您的需要将其设置为过期。
  • 当提供带有表单的页面时,嵌入一个隐藏字段,其值等于此 cookie 的值。
  • 处理帖子时,验证该字段是否存在,并且该值与用户的 cookie 匹配

To generate that token, here's a strategy I use that seems to work well.

  • Set a cookie to a random value (generated on the server using the usual tricks) and set it to expire according to your needs.
  • When serving up a page with a form, embed a hidden field whose value equals the value of this cookie.
  • When handling the post, validate that this field exists, and that the value matches the user's cookie
累赘 2024-08-14 01:37:43

csrf-magic 是 CSRF 令牌的一个很棒的类,它会自动将它们放入您的页面

http://csrf.htmlpurifier.org/

“csrf-magic 使用 PHP 的输出缓冲功能动态重写文档中的表单和脚本。它还将拦截 POST 请求并检查其令牌(使用各种算法;一些生成随机数,一些生成用户特定的令牌)这意味着,对于带有表单的传统网站,您可以将 csrf-magic 放入您的应用程序中,然后就不用管它了!”

csrf-magic is a great class for CSRF tokens, it puts them into your page automatically

http://csrf.htmlpurifier.org/

"csrf-magic uses PHP's output buffering capabilities to dynamically rewrite forms and scripts in your document. It will also intercept POST requests and check their token (various algorithms are used; some generate nonces, some generate user-specific tokens). This means, for a traditional website with forms, you can drop csrf-magic into your application and forget about it!"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文