PHP 中的 CSRF 保护


CSRF protection in PHP

我有一些PHP POST脚本需要保护它们免受CSRF攻击,并且有多个问题:

1)如果我在没有HTML表单的情况下使用jquery向PHP提交POST请求,只是直接从HTML元素中获取值并使用jquery提交它们,我仍然有CSRF的风险吗?

2)当用户登录网站时,我将他们的唯一令牌存储在会话变量中。在 PHP POST 脚本中,我检查该会话变量是否已设置并且具有我之前设置的相同值。这还不够吗?为什么还需要将令牌包含在 HTML 表单中?

谢谢

  1. 是的。无论您如何构造请求,攻击者都可以以相同的方式构造请求。(理论上,您可以强制使用复杂请求的功能(这将触发 CORS 预检请求),以便另一个站点无法让用户的浏览器复制整个请求,但我不想依赖它)。

令牌的重点是检查包含负责决定请求内容的代码(即表单或JavaScript)的页面是否是您网站上的页面。

如果表单(或 JavaScript)可以从页面的 HTML 中读取令牌(与会话中的令牌匹配)并将其放入请求中,那么您就知道构造请求的代码来自您的网站。

如果您只是检查

它是否在会话中,那么您正在检查的只是用户是否生成了令牌(这通常只是意味着访问您网站上的任何页面......可能在隐藏框架中)。

  1. 是的,它仍然不安全

  2. CSRF 令牌应该是每次生成表单时新生成的令牌。对于每个请求,它必须是唯一且不可预测的。 从登录设置的会话令牌仅对整个记录的会话是唯一的。

如果您不发布生成的令牌进行检查,则在哪里检查? 您将会话令牌与... ?原因是,如果令牌不是与请求本身一起发送的,但所有检查都由会话/cookie完成,您仍然可以为人们提供伪造请求的可能性。 如果您只检查会话,则它不会违反 csrf。它需要在请求本身中发送,并检查它是否与您的会话匹配。 当您为每个请求生成唯一的令牌时,坏人无法伪造某人的请求。