如何防止跨站请求伪造攻击?

How to Prevent Cross-Site Request Forgery Attack?

我们 运行 Burp Suite 在我们的产品上发现了一些安全漏洞。该工具检测到一些容易受到 跨站点请求伪造 攻击 (CSRF) 的 CGI 文件。

像往常一样,我在 CPAN 上搜索 CSRF 保护模块并找到 CGI::Application::Plugin::ProtectCSRF

我想知道如何以通用方式将此模块集成到我们的应用程序中?我不清楚文档。我如何配置此模块并进行最少的更改以确保整个应用程序免受 CSRF 攻击。

我还遇到了 mod_csrf(一个防止 CSRF 的 Apache 模块)。安装此模块并在 apache 配置文件中进行以下设置是否足以防止 CSRF?

<VirtualHost>

    CSRF_Enable on
    CSRF_Action deny
    CSRF_EnableReferer off

</VirtualHost>

我可以理解您发现 CGI::Application::Plugin::ProtectCSRF 的文档不清楚:它有点坚不可摧

Perl 模块似乎所做的就是向每个 HTML 表单添加一个 hidden 字段,名称为 _csrf_id 和一个从各种来源派生并通过编码的随机值SHA1。当客户端的响应要求必须向服务器返回相同的值时,保护就来了

它的编码非常好,但它使用自定义 子例程属性 ,并且 attributes pragma 的文档说这个

WARNING: the mechanisms described here are still experimental. Do not rely on the current implementation

我无法通过快速审查判断子例程原型是否对模块必不可少,但我建议您改用 Apache mod_csrf 模块,它可能比 Perl 模块经过更彻底的测试, 并有适当的文档

由于我们使用的是内部服务器,而不是 apache,因此 mod_csrf 无法实施。

由于文档不清楚,我放弃了 ProtectCSRF 模块。

我通过以下方式解决了它:

  1. 在所有页面通用的header模板中添加一个元素,该元素包含从服务器
  2. 传递的CSRF令牌
  3. 创建一个 JavaScript 函数并将其绑定到 onload 事件。此 JS 函数执行以下任务:

    a) 在当前页面查找表单

    b) 如果找到表单,则创建一个隐藏的 "input" 元素并将其附加到每个表单

    c) 获取放入 header 的值并将其分配给上面创建的元素

    d) 现在所有表单都有一个隐藏的输入元素,其中包含来自点 1

  4. 的 CSRF 令牌
  5. 现在,每当提交表单时,也会提交此隐藏元素,我们正在服务器端验证其值。如果令牌不匹配,则存在 CSRF,为此我们抛出错误并阻止 request