!
也想出现在这里? 联系我们
广告区块

什么是CSRF令牌

CSRF 令牌是一个机密值,应安全处理以在基于 cookie 的会话期间保持有效。

跨站点请求伪造(又名跨站点引用伪造)是 Web 应用程序攻击的一种形式。黑客通过恶意请求诱骗用户运行他们不打算执行的任务。因此,Web服务器需要一种机制来确定合法用户是否通过用户的浏览器生成了请求,以避免此类攻击。CSRF 令牌通过服务器端生成一个唯一的、不可预测的和秘密的值来帮助解决这个问题,该值要包含在客户端的 HTTP 请求中。发出后续请求时,Web 服务器会验证包含令牌的请求参数,并拒绝不包含令牌的请求参数。该方法通常用于防止CSRF攻击,因为黑客几乎不可能构建完整,有效的HTTP请求来伏击受害者。

我们之前讨论了跨站点脚本漏洞如何成为涉及在受害者浏览器上执行恶意代码的最常见攻击形式之一。虽然CSRF听起来类似于XSS攻击,但它们的执行方式存在根本差异。

本文讨论 CSRF 代币的工作原理及其在应用程序安全性中的重要性。

为什么需要有效的CSRF令牌?

建议将 CSRF 令牌添加到所有状态更改请求中,并在后端进行验证。由于只有应用程序服务器和客户端识别令牌,因此后端必须确保传入请求包含有效的 CSRF 令牌,以避免成功的 XSS 或跨站点请求伪造攻击。

CSRF 令牌是一个机密值,应安全地处理该值,以便在基于 cookie 的会话期间保持有效。令牌应传输到 HTML 表单中隐藏字段中的客户端,并使用 HTTP POST 请求提交。作为最佳实践,建议使用标准标头验证请求的来源。其他措施还应确定和比较来源和目标来源。如果源匹配,则认为请求是合法的,而如果不匹配,则表示跨域请求并被丢弃。

CSRF 代币在防止攻击中的重要性

CSRF 令牌值包含显著的熵,并且是不可预测的,因为生成的令牌使用伪随机数生成器、静态机密种子时间戳。除此之外,令牌对于每个用户都是不同的,并且仅为活动用户会话存储。安全团队可以通过将随机数生成器的输出与用户特定的熵连接起来并对整个结构进行哈希处理来提高令牌值的唯一性。这使得黑客很难根据早期会话 cookie 中颁发的令牌样本来猜测 CSRF 令牌。

CSRF 代币:如何使用

在某些应用程序中,建议在自定义请求标头中传输 CSRF 令牌。尽管可以将令牌放在 URL 查询字符串中,但此方法被认为是不安全的,因为查询字符串记录在服务器和客户端的多个记录上。但是,可以在客户端浏览器的屏幕上访问查询字符串,也可以传输到 HTTP 引用标头中的第三方应用程序。

除此之外,CSRF 令牌应存储在服务器端应用程序上,该应用程序验证每个需要验证的请求。服务器端应用程序应确保有效请求包含与用户活动会话期间存储的值匹配的令牌。CSRF 令牌验证也应该对所有 HTTP 方法执行,包括 POST、PUT 和 DELETE。

如何在Java中实现CSRF令牌

Java 应用程序缺乏针对 CSRF 攻击的先天保护。因此,在 Java 中提议的 CSRF 令牌实现涉及使用过滤器和辅助类,以支持令牌创建、资源分析和响应的制作。其中一种解决方案是通用无状态过滤器,它实现双重提交 cookie 模式以启用 CSRF 保护,并完成如下所述的工作流:

过滤器首先在 java 应用程序的文件中定义,如下面的代码片段所示:

<filter>
<filter-name>CSRFFilter</filter-name>
<filter-class>com.github.adriancitu.csrf.GenericCSRFStatelessFilter</filter-class>
<filter>
<filter-mapping>
<filter-name>CSRFFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

筛选器包括两个可选的初始化变量:

  1. csrfHeadername– 包含令牌的标头的名称,以及
  2. csrfCookieName– 用于存储 CSRF 令牌的 cookie 的身份。

对于每个 HTTP 请求,筛选器提供类的实例。这是一个遗留的 Java 对象,包含 CSRF cookie、HTTP 请求和响应。该类还包含辅助类 (、 和 ) 的实现。ExecutionContext ResourceCheckerHookResponseBuilderHookTokenBuilderHook

筛选器首先检查请求的 HTTP 资源的保护状态。有三个选项:

  1. MUST_NOT_BE_PROTECTED
  2. MUST_BE_PROTECTED_BUT_NO_COOKIE_ATTACHED 
  3. MUST_BE_PROTECTED_AND_COOKIE_ATTACHED

对于状态为 and 的资源,过滤器首先使用类提供的 CSRF 令牌生成一个 cookie。对于带有标签的资源,过滤器使用 检查资源的 CSRF 保护状态,然后使用该类向客户端返回响应。MUST_NOT_BE_PROTECTEDMUST_BE_PROTECTED_BUT_NO_COOKIE_ATTACHEDTokenBuilderHookMUST_BE_PROTECTED_AND_COOKIE_ATTACHEDResourceCheckerHookResponseBuilderHook

快速说明: 上面的代码是一个参考示例,需要开发团队在源代码中构建进一步的 CSRF 缓解机制。

如何在PHP中实现CSRF令牌

PHP在内容管理系统中很受欢迎,因为它使开发人员能够创建具有交互功能的动态网站。因此,必须在 PHP 联系人/用户输入表单中实现反 CSRF 保护,以便他们的后处理程序可以验证传入的请求免受 CSRF 攻击。在 PHP 联系表单中实现 CSRF 保护的典型工作流程如下:

首先,在调用 PHP 类的登录页面上创建一个表单页脚脚本,生成令牌并启动 PHP 会话。SecurityService 写入用于验证请求的令牌,并将令牌加载到隐藏字段中。典型的配置类似于:

public function getCSRFToken()
{
if (empty($this->session[$this->sessionTokenLabel])) {
$this->session[$this->sessionTokenLabel] = bin2hex(openssl_random_pseudo_bytes(32));
}
if ($this->hmac_ip !== false) {
$token = $this->hMacWithIp($this->session[$this->sessionTokenLabel]);
} else {
$token = $this->session[$this->sessionTokenLabel];
}
return $token;
    }

然后呈现 PHP 联系表单以输入其详细信息,例如主题、消息、姓名和电子邮件。表单还应在隐藏字段中包含生成的令牌。用户单击“提交”按钮后,应用程序将执行 JQuery 表单验证,然后将参数发布到 PHP。csrf-token

提交联系人表单后,表单操作将执行一个脚本,将嵌入的令牌与存储在会话中的令牌进行比较。如果令牌匹配,应用程序将向用户的请求提供服务。如果没有,PHP 将通过错误消息确认用户。

如何在 Django 中实现 CSRF 代币

Django 提供了一个开箱即用的 CSRF 中间件标签,可以轻松实现对 CSRF 攻击的保护。示例工作流描述了如何在框架内实现 CSRF 保护:

在 Django 中,CSRF 中间件默认处于启用状态。如果开发人员覆盖此设置,则应在任何视图之前声明以启用 CSRF 令牌验证。django.middleware.csrf.CsrfViewMiddleware

对于特定视图,开发人员可以调用修饰器。装饰器用于在输出中插入 CSRF 令牌的视图。装饰器的配置类似于:csrf-protect

from django.shortcuts import render
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def my_view(request):
c = {}
# ...
    return render(request, "a_template.html", c)

开发人员可以通过在元素中包含标记来为使用 POST 表单的模板启用保护。这仅适用于具有内部 URL 的表单,不适用于面向外部 URL 的 POST 表单。对于外部 URL,可以使用以下命令调用 CSRF 令牌标记:csrf_token<form>

{% csrf_token %}”>

<form method="post">{% csrf_token %}

除此之外,还建议用于在相应的 Django 视图中呈现响应。RequestContext

如何在 JavaScript 中实现 CSRF Token

所有 JavaScript 框架都带有实现 CSRF 保护的默认选项。例如,Express.js 包含称为 的中间件,它有助于创建和验证令牌。要使用 启用 CSRF 保护,请按照以下工作流操作:csurfcsurf

在文件中,包括以下代码:index.js

app.get('/', csrfProtection, (req, res) => {
  res.render('index', { csrfToken: req.csrfToken() });

在此之后,使用类似于以下内容的配置将文件添加到 views 文件夹:

  <input type='hidden' name='_csrf' value='<%= csrfToken  %>'> 
<label for='name'> Name:</label>
<input type='text' name='name'>
<button type='submit'> Update </button>
</form>

主配置文件中的路由呈现模板中的变量,并在隐藏字段中插入令牌。当用户提交表单时,请求将添加到路由中,该表单提供 CSRF 令牌验证。如果缺少此 CSRF 令牌,应用程序将返回无效的 CSRF 令牌错误。/csrfTokenindex.ejs/profile

如何修复无效的 CSRF 令牌

CSRF 攻击会导致对用户会话的未经身份验证的访问,并造成严重后果。为了防止这种类型的攻击,确保用户使用有效令牌发布请求至关重要。修复和防止无效令牌的一些常见方法包括:

使用自定义请求标头

在易受攻击的应用程序中添加 CSRF 令牌涉及导致用户界面更改的管理任务,并且通常很复杂且有问题。作为替代方案,安全团队可以构建自定义请求标头,以使用同源策略增强 CSRF 防御。安全策略拒绝跨源请求,同时强制实施自定义标头只能在 JavaScript 中构建且只能在其源中使用的限制。

利用内置和现有的 CSRF 缓解实施

大多数开发框架都包含内置于安全套件中的同步器令牌防御,旨在保护整个应用程序堆栈。如果团队技术堆栈中的框架默认提供了实现 CSRF 保护的选项,建议在尝试创建自定义系统之前使用这些选项。在大多数情况下,内置配置提供了不错的防御,可以进一步加强防御以根据组织的用例实施配置。

部署基于 UI 的 CSRF 防御

几种机制分析请求方法,以防止通过 CSRF 执行未经授权的操作,从而将合法请求与打算执行不需要的操作的请求过滤掉。其中包括 CAPTCHA、重新身份验证身份验证机制一次性令牌。虽然这些为输入验证提供了强大的防御,但它们会改变用户体验,并且只应用于关键的安全操作

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
有新私信 私信列表
搜索