翻译|陈军评论|孙淑娟跨站请求伪造(Cross-siterequestforgery,又名:cross-siterequestforgery)是一种针对web应用的攻击形式。黑客通过伪装恶意请求来诱骗用户运行他们不打算执行的任务。尽管CSRF听起来与XSS攻击类似,但它们的执行方式存在根本差异。对此,Web服务器需要一种机制来判断浏览器产生的请求是否源于合法用户的真实意图,而不是被攻击所胁迫。对于此类问题,服务器可以生成一个唯一且不可预测的键值,作为CSRF令牌包含在客户端的HTTP请求中。当后续请求发送时,Web服务器将验证包含令牌的请求参数,拒绝那些不包含令牌的请求参数。由于黑客几乎不可能构造出完整有效的HTTP请求来欺骗Web用户,因此通常可以采用这种方式来防止CSRF攻击。下面,我将与您讨论CSRF令牌的工作原理及其在应用程序安全中的重要性。1.为什么需要有效的CSRF令牌?通常建议将CSRF令牌添加到所有状态更改请求中,以便在后端进行验证。由于只有应用服务器和客户端可以识别令牌,后端必须确保传入请求包含有效的CSRF令牌,以避免成功的XSS或跨站点请求伪造攻击。需要安全地处理作为键值的CSRF令牌,以在基于cookie的会话期间保持有效。为此,令牌应放置在HTML表单的隐藏字段中,传输到客户端,并使用HTTPPOST请求提交。作为一种好的做法,我们建议使用标准标头来验证请求的来源,并使用其他措施来识别和比较源和目标。如果来源匹配,则确定该请求是合法的;如果不匹配,则表示怀疑是跨域请求,应该丢弃。2、CSRF令牌在防止攻击中的意义由于令牌生成过程中使用了伪随机数(pseudo-randomnumber)生成器、静态密钥和种子时间戳,因此CSRF令牌的价值是不可预测的。此外,每个用户的令牌都是唯一的,并且只存储活动用户会话。由此,安全团队可以通过将随机数生成器的输出与用户特定的熵连接并对整个结构进行哈希处理来增加令牌值的唯一性。在这方面,黑客将很难根据早期会话cookie中发布的令牌样本来猜测CSRF令牌。3.如何使用CSRFtoken虽然我们可以在URL查询字符串中放置token,但是查询字符串记录会保存在服务器端和客户端的多条记录中。因此,查询字符串可以在客户端屏幕上的浏览器上访问,甚至可以在HTTP引用标头中传输到第三方应用程序。可见,这种方法并不安全。对此,我们建议将CSRFtoken存储在服务器端应用程序中,并在自定义请求头中传输CSRFtoken。服务器端应用程序按需验证每个请求,以确保每个有效请求都包含一个与存储在用户活动会话中的值相匹配的令牌。同时,CSRFtoken还可以对包括POST、PUT、DELETE在内的所有HTTP方法进行认证。4.如何在Java中实现CSRF令牌因为Java应用程序缺乏针对CSRF攻击的内在保护。因此,我们建议在使用Java实现CSRF令牌时,使用过滤器和一些辅助类来启用令牌创建、资源分析和响应构建。例如,您可以使用通用无状态过滤器来实现双重提交cookie模式以启用CSRF保护。同时,您可以使用以下工作流程:首先,如以下代码片段所示,过滤器将定义在Java应用程序的web.xml文件中:CSRFFiltercom.github.adriancitu.csrf.GenericCSRFStatelessFilterCSRFilter/*过滤器包括两个可选的初始化变量:1.csrfHeadername–包含令牌的标头名称2.csrfCookieName–用于存储CSRF令牌的cookie的ID。对于每个HTTP请求,过滤器提供ExecutionContext类的一个实例。它包含CSRFcookie,以及HTTP请求和响应Java对象。同时该类还包含了ResourceCheckerHook、ResponseBuilderHook、TokenBuilderHook等辅助类的实现。然后,过滤器会根据以下三种情况检查所请求的HTTP资源的保护状态:1.MUST_NOT_BE_PROTECTED2.MUST_BE_PROTECTED_BUT_NO_COOKIE_ATTACHED3.MUST_BE_PROTECTED_AND_COOKIE_ATTACHED对于MUST_NOT_BE_PROTECTED和MUST_BE_PROTECTED_BUT_NO_COOKIE_ATTACHED的状态,过滤器会通过OrderingCookiesRFCOOKIE_ATTACHED生成一个Cookies.对于标签为MUST_BE_PROTECTED_AND_COOKIE_ATTACHED的资源,过滤器使用ResourceCheckerHook检查资源的CSRF保护状态,然后使用类ResponseBuilderHook返回响应给客户端。当然,上面的代码只是一个参考例子。在实践中,开发团队还需要在源码中进一步构建CSRF缓解机制。5.如何在PHP中实现CSRF令牌由于PHP使开发人员能够创建具有交互功能的动态网站,因此在内容管理系统领域非常流行。但是,我们需要在PHP联系人和用户输入表单中实现帖子处理程序,以验证传入请求并保护网站免受CSRF攻击。在PHP联系表单中实现CSRF保护的典型工作流程如下:首先,我们需要在登录页面创建一个表单页脚脚本。该脚本调用SecurityService(一个PHP类),生成一个令牌,然后启动一个PHP会话。SecurityService将写入此令牌以验证请求并将令牌加载到隐藏字段中。下面的代码展示了一个典型的SecurityService.php配置:(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联系表单,供用户输入主题、消息等详细信息、姓名和电子邮件。该表单还应在隐藏字段中包含生成的令牌--csrf-token。用户单击提交按钮后,应用程序将执行JQuery表单验证并将各种参数发送到PHP。此外,在提交联系表单后,该表单会执行一个脚本,将嵌入的令牌与存储在会话中的令牌进行比较。如果令牌匹配,则应用程序会响应用户的请求。如果不匹配,PHP将通过错误消息通知用户。6.如何在Django中实现CSRFtokenDjango提供了一个开箱即用的CSRF中间件标签,您可以轻松启用它来抵御CSRF攻击。以下工作流程将向您展示如何在现有框架内实现CSRF保护:在Django中,默认启用CSRF中间件。如果开发人员想要覆盖此设置,他们应该在任何视图之前预先声明django.middleware.csrf.CsrfViewMiddleware以启用CSRF令牌验证。对于一些特定的视图,开发者可以调用csrf-protect装饰器(decorator)。此类装饰器可用于在其输出中插入CSRF令牌的视图。以下代码片段展示了装饰器的基本配置:.html",c)左右滑动查看完整代码开发者可以通过在左右滑动查看完整代码主配置文件中的“/”路由会渲染index.ejs模板中的csrfToken变量,并在hidden中插入token字段。当用户提交表单时,相应的请求将被添加到“/profile”路由中,用于CSRFtoken验证。如果缺少此CSRFtoken,应用程序将返回一个无效的CSRFtoken错误。八、如何修复日einvalidCSRFtoken如前所述,CSRF攻击将导致对用户会话进行未经身份验证的访问并产生严重后果。为了防止此类攻击并确保用户使用有效令牌发出请求,我们需要通过以下方法及时修复和防止无效令牌令牌:使用自定义请求标头在易受攻击的应用程序中,添加CSRF令牌通常需要复杂的管理任务,例如就像改变用户界面一样。作为替代方案,安全团队可以构建自定义请求标头以使用同源策略来加强CSRF防御。安全策略拒绝各种跨域请求。利用内置和现有的CSRF处理措施许多开发框架在大多数情况下都包括安全套件中内置的同步器令牌防御机制。它们可以有效地保护整个应用技术栈。如果在开发团队现有的技术栈中,使用的框架默认内置了抵御CSRF的选项,那么可以在此基础上尝试根据实际业务用例进行自定义配置实现。部署基于UI的CSRF防御CAPTCHA,重认证(re-authentication)认证机制,以及一次性令牌等机制,可以对请求进行分析,防止通过CSRF进行非授权操作,过滤掉各种非法操作请求。尽管它们提供了强大的身份验证和防御措施,但我们需要通过部署UI来改变用户体验,以更好地处理关键的安全操作。原文链接:https://dzone.com/articles/what-is-a-csrf-token译者介绍陈朱利安(JulianChen),社区编辑,拥有十余年IT项目实施经验,擅长内外部资源实施风险管控,重点传播网络与信息安全知识和经验;持续以博文、专题、翻译等形式分享前沿技术和新知识;经常在线上和线下开展信息安全培训和讲座。