【发布时间】:2011-02-15 04:26:23
【问题描述】:
我正在寻找一种(希望是直截了当的)方法来为基于 Spring WebFlow 2 构建的应用程序添加 CSRF 保护。
首选可以很好地迁移到 Spring WebFlow 3(发布时)的方法。
【问题讨论】:
标签: security spring-security csrf spring-webflow
我正在寻找一种(希望是直截了当的)方法来为基于 Spring WebFlow 2 构建的应用程序添加 CSRF 保护。
首选可以很好地迁移到 Spring WebFlow 3(发布时)的方法。
【问题讨论】:
标签: security spring-security csrf spring-webflow
阻止 CSRF 的最简单方法是检查引用者 request.getHeader("referer"); 以确保请求来自同一个域。这个方法被CSRF Prevention Cheat Sheet覆盖了。
这种 CSRF 保护系统在内存要求有限的嵌入式网络硬件上很常见,摩托罗拉在他们的大多数硬件上都使用了这种方法。这不是最安全的 CSRF 保护,基于令牌的保护更好,但仍然可以使用 xss 绕过这两个系统。基于令牌的 CSRF 保护的最大问题是需要花费大量时间来返回并修复每个请求,并且您可能会错过一些请求。
实现此功能的一种安全方法是检查所有传入 POST 请求的引用者,并将 POST 用于更改密码、添加用户帐户、执行代码、进行配置更改等敏感功能。 GET 应该只用于导航或搜索,基本上 GET 对任何不会导致状态更改的东西都是安全的。
确保使用xss scanner 测试您的网站。
【讨论】:
OWASP 有很好的防止 CSRF 攻击的指南here:
检查Referer 标头当然是最简单的,并且至少记录Referer 是第3 方或空的实例是一个好主意。然而,有几个缺点使得单独使用 referer 不可靠:
幸运的是,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 表单的 'action' 属性),并且从不在 POST 正文中。在请求 URL 中包含敏感信息并不是很好,因为它更有可能记录在服务器/ISP 日志中。另一种方法是在每个包含 CSRF 令牌的表单中添加一个隐藏的输入,并且只对 POST 请求强制其存在。
【讨论】: