需要CSRF令牌吗?

use*_*345 1 php csrf contact-form csrf-protection

好吧,仍然试图围绕它们是什么,并且需要......相信我我已经阅读了很多并且认为我理解但我可能不......

我能得到的最接近的是,当您的网站上有任何形式的登录页面时,绝对需要它们......

我的问题是,当您出于任何原因拥有基本的联系表格和/或填写表格时……您是否需要这些页面的 CSRF 令牌?

Mar*_*tin 5

CSRF 令牌不是“绝对需要”的(例如,没有它们,表单也能工作),但是无论何时将任何数据从一个网页提交到另一个网页/脚本,它们都是一个非常好的主意。几乎没有办法相信page 2接收到的任何数据来自page 1(阅读下图)。隔离中的每个页面都不知道用户之前在哪个页面上,即使是旨在暗示这一点的东西,例如$_SERVER['HTTP_REFERER']浏览器用户也可以轻松操作。

CSRF令牌是一个页面到页面的密钥,为接收页面提供了更高级别的信任,即访问者来自预期的发件人页面。部署的属性还可以防止数据重复,这也是一个很大的好处,可以减少不道德的垃圾邮件和浪费的 CPU 周期。


CSRF 令牌可用于的一方面:

假设您在页面上有一个表单,该页面被调用page1.php并且该表单是一个send contact email,其中填写表单然后发送,它发送到的页面(page2.php)可以构建然后发送联系电子邮件给预期的接受者。

下一步是有人可以阅读page1.php表单的源代码。这非常简单,它告诉人们$_POST存在哪些值以及表单发送到的目的地的位置 ( page2.php)。

一个简单的用户将加载您的page1.php,在按下发送按钮并提交表单之前,花十分钟写一封措辞谨慎的电子邮件。离开表单转到page2.php将其详细信息构建到发送到的电子邮件中的receiver@email.com

现在,如果有人从中获取源代码,page1.php他们可以使用简单的 PHP 脚本(或任何其他代码)处理向 发送数百或数千个垃圾邮件表单page2.php,每个表单都带有正确的详细信息以生成和发送电子邮件,这可以被用于各种邪恶的过程,他们可以从许多其他网站、互联网的任何其他部分甚至从整个僵尸网络发送表单,如果他们愿意的话——page2.php一秒钟内会被许多请求淹没,电子邮件的接收者将有一个邮箱塞满了无用的表单生成的消息。

输入 CSRF 令牌

CSRF 令牌是保存在表单中的唯一密钥,在生成时page1.php通常(但不完全)使用(可能随机)生成的$_SESSION值,以便在提交表单并将$_POST数据发送到page2.php此时可靠地检查表单是从同一网站提交。因此,不是让整个僵尸网络向整个僵尸网络提交数据page2.php并导致大量电子邮件,而是不会对数据采取行动,而是仅在page2.php脚本中运行从同一网站提交的页面。

或者,如果发生上述情况,您还可以跟踪错误提交的来源,并使用其他进程/脚本来阻止/禁止各种其他僵尸网络/服务器向您的服务器提交数据。


上图是一种保险和流程控制形式,因此您对通过 CSRF 的数据具有很强的可靠性page2.php

 if ($_SESSION['key'] === $_POST['key']){
     unset($_SESSION['key']);   ///prevent repetition
      ...
      send email
    }
Run Code Online (Sandbox Code Playgroud)

(例如)。

if语句仅使用从可靠来源 ( page1.php)可靠提交的表单数据运行。因此,防止其他服务器捎带在您的脚本上,防止 DOS 攻击的粗鲁尝试使您的page2.php以及其他各种积极因素超载而无法知道page1.php发送了正在使用的数据page2.php

另一方面CSRF令牌用于

在上面的代码中看到我取消了$_SESSIONCSRF 值吗?这意味着,如果您按 F5 或以其他方式刷新page2.php访问(在浏览器中输入或其他内容),它将不会重新提交两次真实数据。这可以帮助防止人们填写一次表单,然后像论坛上的愤怒少年一样不断重新提交(POST 数据总是保存在页面 HTTP 标头中,并在页面调用时重新提交,因此$_POST在 PHP 中取消设置数据毫无意义。) .


CSRF 是一种安全机制 - 当 CSRF 令牌测试通过时 - 意味着您可以可靠地判断发送到服务器上脚本的数据来自有效且预期的来源。