通过AJAX获取CSRF令牌

时间:2015-11-06 19:34:40

标签: javascript spring security spring-mvc spring-security

我打算使用解耦的前端和后端构建应用程序(仅使用ajax请求)。我不允许跨站点ajax请求。我可以通过添加像/ csrf之类的API来生成带有ajax调用的csrf令牌,它返回类似的内容:{csrf:'token'}以下网站说我绝对不能这样做:https://github.com/pillarjs/understanding-csrf

  

确保无法使用AJAX访问CSRF令牌!不要仅仅为了获取令牌而创建/ csrf路由,特别是不支持该路由上的CORS!

有具体原因吗?我理解CORS背后的原因 - 已被禁用,但是通过ajax提供csrf令牌是否存在任何固有的安全风险?

1 个答案:

答案 0 :(得分:4)

这不是安全风险,原因如下:

为什么你甚至想通过AJAX公开CSRF令牌?

从可用性角度来看,如果您没有提供通过AJAX获取CSRF令牌的方法,那么您的网站可能会使用起来很糟糕,因为任何打开多个标签的人都会遇到有关CSRF令牌不匹配的错误

在使用CSRF令牌的网站上,如果您在提交POST请求之前在表单上挂钩以获取最新的CSRF令牌,那么这对用户来说是一种更好的体验。

现代单页应用程序网站(例如使用React或Angular构建的通用站点)也需要一种轻松获取CSRF令牌的方法,这可以从CSRF令牌提供的投影中受益,就像传统的基于服务器渲染的站点一样。

CSRF令牌与会话相关联

CSRF令牌与会话绑定 - 即使您未明确登录,它仍然需要绑定到客户端和服务器之间跟踪的会话。 如果你的会话令牌有一个HTTP Only cookie(这是最好的做法并防止XSS攻击窃取它以及帮助保护你免受CSRF攻击),没有人可以通过远程域从请求中读取你的CSRF令牌(即使浏览器不强制执行CORS!)。

跨源资源共享

CORS在这样的讨论中出现了很多,但它实际上是一个红色的鲱鱼。

安全性实际上归结为您的sesison cookie使用HTTP Only cookie,并且使用您的会话令牌为cookie提供相同的域策略 - 所有浏览器都支持自上次开始以来(有关MSIE的边缘情况警告)将cookie暴露给其他浏览器没有的子域名。)

如果远程站点上的某些JavaScript无法读取您的会话令牌 - 如果它位于您域中的HTTP Only cookie中则无法读取 - 那么它就无法读取您的CSRF令牌!

如果使用HTTP Only cookie和CSRF令牌,我是否能够抵御CSRF和XSS攻击?

您应该对CSRF攻击安全,并且您对某些类型的XSS攻击的保护有限,但XSS仍然存在风险。

如果有人找到了一种方法来使用XSS在您的网站上执行任意JavaScript并创建来自您的域的请求,那么CSRF,HTTP Only cookie或会话指纹识别都不会在此时保护您 - 可以执行任何操作看起来就像它是由用户触发的。

关于请求的CAPTCHA会提供一些额外的保护,但对于不可逆转的破坏性或可能是昂贵的操作,外部确认某项行动(例如通过电子邮件,短信等)是一个好主意。

但安全比抱歉更好吗?

如果您仍然担心CSRF的AJAX端点可能会以某种您不理解的方式成为矢量,请考虑一个能够从您的域执行请求并解析响应的远程脚本同样可能只是触发对页面上带有表单的请求,并从。

上的值获取CSRF令牌

同样,如果某人能够在您的网站上执行任意JavaScript并以他们所定位的当前用户的形式发回和读取请求,那么从DOM中读取CSRF令牌并从中提取它将会容易得多。已经出现在页面上,而不是与AJAX混淆。

<强>摘要

使用HTTP Only cookie和CSRF令牌来帮助防止CSRF和XSS攻击。

  • 使用HTTP时,只提供通过AJAX获取CSRF令牌的方法的cookie不可利用。

  • 提供一种通过AJAX获取CSRF令牌的方法是一件好事,可以在不影响安全性的情况下提供更好的用户体验。

  • 考虑添加CAPTCHA和/或外部验证以确认适当的操作,以防止XSS。

您也可以不在给定会话中轮换用户CSRF令牌(某些中间件实际上是为了避免完全处理该问题),但值得注意的是,这不是大多数CSRF令牌库的典型行为。