什么是 CSRF 代币?它的重要性是什么?它是如何运作的?
我正在编写一个应用程序(Django,确实如此),我只想了解“CSRF 令牌”实际上是什么以及它如何保护数据。
如果不使用CSRF token,发布的数据会不安全吗?
I am writing an application (Django, it so happens) and I just want an idea of what actually a "CSRF token" is and how it protects the data.
Is the post data not safe if you do not use CSRF tokens?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这一切的根源是确保请求来自网站的实际用户。为表单生成 csrf 令牌,并且必须与用户的会话绑定。它用于向服务器发送请求,其中令牌对请求进行验证。这是防止 csrf 的一种方法,另一种方法是检查引荐来源网址标头。
The root of it all is to make sure that the requests are coming from the actual users of the site. A csrf token is generated for the forms and Must be tied to the user's sessions. It is used to send requests to the server, in which the token validates them. This is one way of protecting against csrf, another would be checking the referrer header.
简单来说,跨站请求伪造 (CSRF)
假设您当前已登录网上银行
www.mybank.com
假设从
mybank.com
进行转账将导致(概念上)表格(该URL不需要您自己的帐号,因为服务器可以通过您的登录来推断它。)
www.cute-cat-pictures.org
,却不知道它是一个恶意网站。如果该网站的所有者知道上述请求的形式(简单!)并正确猜测您已登录
mybank.com
(需要一些运气!),他们可能会包含如下请求在他们的页面上:其中
123456
是他们的开曼群岛帐户号码,10000
是您之前很高兴拥有的金额。您检索了
www.cute-cat-pictures.org
页面,因此您的浏览器将发出该请求。您的银行无法识别此请求的来源:您的网络浏览器将随您的
www.mybank.com
cookie 一起发送该请求,并且它看起来完全合法。你的钱不见了!这是没有 CSRF 代币的世界。
现在,使用 CSRF 令牌来实现更好的效果:
使用第三个参数扩展传输请求:
该令牌是一个巨大的、无法猜测的随机数,
mybank.com
在向您提供该令牌时会将其包含在他们自己的网页上。每次他们向任何人提供任何页面时,情况都是不同的。攻击者无法猜测令牌,无法说服您的网络浏览器放弃它(如果浏览器工作正常......),因此攻击者将无法创建有效的请求,因为带有错误令牌(或没有令牌)的请求将被
www.mybank.com
拒绝。结果:您保留
10000
货币单位。(您的里程可能会有所不同。)
编辑自值得一读的评论,作者:SOFe:
Cross-Site Request Forgery (CSRF) in simple words
Assume you are currently logged into your online banking at
www.mybank.com
Assume a money transfer from
mybank.com
will result in a request of (conceptually) the form(The URL doesn't require your own account number, because the server can deduce it by your login.)
You visit
www.cute-cat-pictures.org
, not knowing that it is a malicious site.If the owner of that site knows the form of the above request (easy!) and correctly guesses you are logged into
mybank.com
(requires some luck!), they could include a request like this on their page:where
123456
is the number of their Cayman Islands account, and10000
is an amount that you previously thought you were glad to possess.You retrieved that
www.cute-cat-pictures.org
page, so your browser will make that request.Your bank cannot recognize the origin of this request: your web browser will send the request along with your
www.mybank.com
cookie and it will look perfectly legitimate. There goes your money!This is the world without CSRF tokens.
Now for the better one with CSRF tokens:
The transfer request is extended with a third argument:
That token is a huge, impossible-to-guess random number that
mybank.com
will include on their own web page when they serve it to you. It is different each time they serve any page to anybody.The attacker is not able to guess the token, is not able to convince your web browser to surrender it (if the browser works correctly...), and so the attacker will not be able to create a valid request, because requests with the wrong token (or no token) will be refused by
www.mybank.com
.Result: You keep your
10000
monetary units.(Your mileage may vary.)
EDIT from comment worth reading by SOFe:
是的,发布数据是安全的。但该数据的来源并非如此。这样,有人可以使用 JS 欺骗用户登录您的网站,同时浏览攻击者的网页。
为了防止这种情况,django 将在 cookie 和表单数据中发送随机密钥。
然后,当用户 POST 时,它会检查两个密钥是否相同。如果用户被欺骗,第 3 方网站无法获取您网站的 cookie,从而导致身份验证错误。
Yes, the post data is safe. But the origin of that data is not. This way somebody can trick user with JS into logging in to your site, while browsing attacker's web page.
In order to prevent that, django will send a random key both in cookie, and form data.
Then, when users POSTs, it will check if two keys are identical. In case where user is tricked, 3rd party website cannot get your site's cookies, thus causing auth error.
Cloud Under 博客对 CSRF 令牌有很好的解释.(已存档)
The Cloud Under blog has a good explanation of CSRF tokens. (archived)
该网站在制作表单页面时会生成一个唯一的令牌。需要此令牌才能将数据发布/获取回服务器。
由于令牌是由您的网站生成的,并且仅在生成包含表单的页面时提供,因此其他一些网站无法模仿您的表单 - 他们不会拥有令牌,因此无法发布到您的网站。
The site generates a unique token when it makes the form page. This token is required to post/get data back to the server.
Since the token is generated by your site and provided only when the page with the form is generated, some other site can't mimic your forms -- they won't have the token and therefore can't post to your site.