我正在寻找一种(希望是直截了当的)方法来将CSRF保护添加到基于 Spring WebFlow 2 构建的应用程序中。
一种可以很好地迁移到 Spring WebFlow 3(发布时)的方法是首选。
我正在寻找一种(希望是直截了当的)方法来将CSRF保护添加到基于 Spring WebFlow 2 构建的应用程序中。
一种可以很好地迁移到 Spring WebFlow 3(发布时)的方法是首选。
阻止 CSRF 的最简单方法是检查引用者request.getHeader("referer");
以确保请求来自同一个域。CSRF 预防备忘单涵盖了此方法。
在内存需求有限的嵌入式网络硬件上经常看到这种 CSRF 保护系统,摩托罗拉在他们的大部分硬件上都使用这种方法。这不是最安全的 CSRF 保护,基于令牌的保护更好,但仍然可以使用 xss 绕过这两个系统。基于令牌的 CSRF 保护的最大问题是需要花费大量时间来返回并修复每个请求,并且您可能会错过一些请求。
实现此功能的一种安全方法是检查所有传入 POST 请求的引用者,并将 POST 用于更改密码、添加用户帐户、执行代码、进行配置更改等敏感功能。GET 应该只用于导航或搜索,基本上 GET 对任何不会导致状态更改的东西都是安全的。
确保您使用xss 扫描仪测试您的网站。
OWASP 有一个很好的指南来防止 CSRF 攻击:
检查Referer 标头当然是最简单的,并且至少记录Referer 是第3 方或空的实例是一个好主意。然而,有几个缺点使得单独使用引用者不可靠:
幸运的是,WebFlow 可以很容易地实现自定义唯一的 token-per-flow-invocation CSRF 过滤器(您可能不必修改任何视图/表单)!
首先,每当流启动时,使用 FlowExectionListener 创建一个新的随机令牌并将其存储在 flowScope 中。然后,每当发出事件信号时,验证提交的令牌(作为请求中的参数提交)是否等于 flowScope 中存储的值。
然后,配置一个自定义 FlowUrlHandler,它将“_token”参数附加到生成的 URL,因此,如果您一直使用 ${flowExecutionUrl} 来引用您的流,那么每当您 POST/GET 自动返回到您的流时,该令牌就会附加。要从 FlowUrlHandler 内部从 flowScope 获取令牌,我不得不求助于使用 RequestContextHolder
private String retrieveToken() {
RequestContext requestContext = RequestContextHolder.getRequestContext();
if (requestContext == null) {
return null;
}
return (String) requestContext.getFlowScope().get(CsrfTokenFlowListener.TOKEN_NAME);
}
...
每当您输出 ${flowExecutionUrl} 时,此方法将包含 CSRF 令牌 - 对于 GET 和 POST,如果您使用的是 post-redirect-get,则可以确保 CSRF 令牌不会出现在 URL 栏中。
我会告诫不要只检查 POST 的 CSRF 令牌:
WebFlow 和许多其他 Web 框架不区分 GET 和 POST - 默认情况下,您通常可以使用 GET 来执行您对 POST 所做的任何事情,除非您自己验证请求方法(无论如何这都是个好主意)。因此,想要绕过您的 CSRF 过滤器的攻击者只会执行 GET 而不是 POST。
编辑:在 ${flowExecutionUrl} 中包含 CSRF 令牌需要注意的一个缺点是 CSRF 令牌很可能总是作为请求 URL 的一部分发送(因为它是 HTML 表单的“动作”属性的一部分),并且永远不会在 POST 正文中。在请求 URL 中包含敏感信息并不是很好,因为它更有可能被记录在服务器/ISP 日志中。另一种方法是在每个包含 CSRF 令牌的表单中添加一个隐藏的输入,并且只对 POST 请求强制其存在。