6

我正在寻找一种(希望是直截了当的)方法来将CSRF保护添加到基于 Spring WebFlow 2 构建的应用程序中。

一种可以很好地迁移到 Spring WebFlow 3(发布时)的方法是首选。

4

2 回答 2

4

阻止 CSRF 的最简单方法是检查引用者request.getHeader("referer");以确保请求来自同一个域。CSRF 预防备忘单涵盖了此方法。

在内存需求有限的嵌入式网络硬件上经常看到这种 CSRF 保护系统,摩托罗拉在他们的大部分硬件上都使用这种方法。这不是最安全的 CSRF 保护,基于令牌的保护更好,但仍然可以使用 xss 绕过这两个系统。基于令牌的 CSRF 保护的最大问题是需要花费大量时间来返回并修复每个请求,并且您可能会错过一些请求。

实现此功能的一种安全方法是检查所有传入 POST 请求的引用者,并将 POST 用于更改密码、添加用户帐户、执行代码、进行配置更改等敏感功能。GET 应该只用于导航或搜索,基本上 GET 对任何不会导致状态更改的东西都是安全的。

确保您使用xss 扫描仪测试您的网站。

于 2010-05-04T19:57:52.527 回答
2

OWASP 有一个很好的指南来防止 CSRF 攻击:

检查Referer 标头当然是最简单的,并且至少记录Referer 是第3 方或空的实例是一个好主意。然而,有几个缺点使得单独使用引用者不可靠:

  • 出于隐私原因,公司防火墙可能会剥离引用标头
  • 从 HTTPS 移动到 HTTP 时不发送引用
  • 在 CFRF 攻击中,通常很难“伪造”引用者,但可以使用元刷新标签来完成。

幸运的是,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 请求强制其存在。

于 2011-11-10T17:13:54.863 回答