通过 AJAX 获取 CSRF 令牌 [英] Getting CSRF token via AJAX

查看:91
本文介绍了通过 AJAX 获取 CSRF 令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我计划构建一个前端和后端分离的应用程序(仅使用 ajax 请求).我不允许跨站点 ajax 请求.我可以通过 ajax 调用生成 csrf 令牌,通过添加像/csrf 这样的 API 返回如下内容:{csrf: 'token'} 以下站点说我绝对不能这样做:https://github.com/pillarjs/understanding-csrf

I am planning on building an application with a decoupled front-end and back-end (using only ajax requests). I do not allow cross-site ajax requests. Can I generate a csrf token with an ajax call, by adding an API like /csrf which returns something like: {csrf: 'token'} The following site says I absolutely cannot do this: https://github.com/pillarjs/understanding-csrf

确保无法通过 AJAX 访问 CSRF 令牌!不要为了获取令牌而创建/csrf 路由,尤其不要在该路由上支持 CORS!

Make sure CSRF tokens can not be accessed with AJAX! Don't create a /csrf route just to grab a token, and especially don't support CORS on that route!

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

Is there a specific reason why? I understand the reasoning behind CORS - that is disabled, but is there any inherent security risk in providing the csrf token via ajax?

推荐答案

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

It's not a security risk, here's why:

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

从可用性的角度来看,如果您不提供通过 AJAX 获取 CSRF 令牌的方法,并且不使用像 Double Submit Cookie 方法(完全解决此问题)之类的方法,那么您的网站可能会使用起来很糟糕,因为任何打开多个选项卡的人都会遇到关于 CSRF 令牌不匹配的错误.

From a usability perspective, if you don’t provide a way to get CSRF tokens via AJAX and are not using an approach like the Double Submit Cookie method (which side steps this issue entirely) then your website is probably going to be hellish to use because anyone who has multiple tabs open is going to run into errors about mismatching CSRF tokens.

在使用 CSRF 令牌的网站上,如果您在提交 POST 请求之前在表单上设置挂钩以获取最新的 CSRF 令牌,那么用户体验会更好.

On a website that uses CSRF tokens it’s a much nicer experience for users if you have a hook on forms to fetch the latest CSRF token before submitting a POST request.

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

A way to easily fetch CSRF tokens is also required for modern Single Page Application websites (e.g. universal sites built using React or Angular), which benefit from projection given by CSRF tokens just like traditional server-rendered only based sites.

CSRF 令牌与会话相关联

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

CSRF tokens are tied to sessions — even if you are not explicitly logged in, it still needs to be tied to a session tracked between the client and server. If you have an HTTP Only cookie for your session token (which is best practice and prevents XSS attacks from stealing it as well as helping protect you from CSRF attacks) no one can read your CSRF token from a request via remote domain (even if the browser doesn’t enforce CORS!).

跨域资源共享

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

CORS bit come ups a lot in discussions like this but it’s actually a bit of a red herring.

安全实际上归结为对您的会话 cookie 使用 HTTP Only cookie,并为带有会话令牌的 cookie 使用相同的域策略 — 从一开始就支持所有浏览器(带有 MSIE 的边缘情况警告)将 cookie 暴露给其他浏览器不会的子域).

The security really comes down to using an HTTP Only cookie for your sesison cookie and having a same domain policy for the cookie with your session token — which all browsers have supported since the dawn of time (with the edge case caveat of MSIE exposing cookies to subdomains where other browsers don’t).

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

If some JavaScript on a remote site can’t read your session token — which it can’t if it’s in an HTTP Only cookie on your domain — then it can’t read your CSRF token!

如果使用仅 HTTP cookie 和 CSRF 令牌,我是否可以抵御 CSRF 和 XSS 攻击?

您应该可以免受 CSRF 攻击,并且您对某些类型的 XSS 攻击的保护有限,但 XSS 仍然存在风险.

You should be safe from CSRF attacks and you will have limited protection from some types of XSS attacks, but XSS is still a risk.

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

If someone finds a way to use XSS to execute arbitrary JavaScript on your website and create requests that come from your domain then neither CSRF, HTTP Only cookies or session fingerprinting will protect you at that point — any action performed could be made to look just like it was triggered by a user.

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

A CAPTCHA on requests would provide some additional protection, although for irreversibly destructive or potentially expensive operations, external confirmation of an action (e.g. via email, SMS, etc) is a good idea.

但是安全不是比抱歉更好吗?

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

上的 值获取 CSRF 令牌.

If you are still worried an AJAX endpoint for CSRF might, somehow be a vector in a way you don’t understand, consider that a remote script that is able to execute a request from your domain and parse the response could equally just trigger a request to a page with a form on it and get the CSRF token from an <input> value on a <form>.

同样,如果有人能够在您的站点上执行任意 JavaScript 并以他们所针对的当前用户身份发出和读取请求,那么从您的 DOM 中读取 CSRF 令牌并从表单已经在页面上,而不是使用 AJAX.

Equally, if someone is able to execute arbitrary JavaScript on your site and make and read requests back as the current user they are targeting, it would be a lot easier to just read the CSRF token from your DOM and extract it from a form already on the page than mess about with AJAX.

总结

使用仅 HTTP cookie 和 CSRF 令牌来帮助抵御 CSRF 和 XSS 攻击.

Use HTTP Only cookies and CSRF tokens to help protect against CSRF and XSS attacks.

  • 当使用 HTTP Only cookie 时,提供通过 AJAX 获取 CSRF 令牌的方法是不可利用的.

  • When using HTTP Only cookies providing a method to fetch a CSRF token via AJAX is not exploitable.

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

Providing a way to fetch your CSRF token via AJAX is a good thing, that leads to better user experiences without compromising security.

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

Consider adding a CAPTCHA and/or external validation to confirm actions as appropriate, as protection against XSS.

双重提交 Cookie 方法实际上消除了遇到陈旧 CSRF 令牌的机会,并避免了通过 Ajax 获取令牌的任何需要担心,但是 注意陷阱(例如,向 cookie 添加签名,在提交时检查签名是否对哈希有效,使用 cookie 前缀).

The Double Submit Cookie Method virtually eliminates the chance of running into stale CSRF tokens and avoids any need to worry about fetching tokens via Ajax, but be aware of the pitfalls (e.g. add signature to cookie, check signature valid for hash on submit, use cookie prefixes).

或者,您无法在给定会话中轮换用户 CSRF 令牌(某些中间件实际上这样做是为了避免完全处理问题),但值得注意的是,这不是大多数 CSRF 令牌库的典型默认行为.

Alternatively, you could not rotate a users CSRF token in a given session (some middleware actually does this to avoid dealing with the issue entirely) but it’s worth noting that is not typical default behaviour for most CSRF token libraries.

来自 Open Web Application Security Project 的 OWASP CSRF 备忘单是一个很好的资源,并有更详细的介绍.

The OWASP CSRF Cheat Sheet from the Open Web Application Security Project is a great resource and goes into more detail.

这篇关于通过 AJAX 获取 CSRF 令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆