CSRF:我可以使用 cookie 吗?
将 CSRF 令牌放入 cookie 中可以吗? (当然,在每种形式中,作为隐藏输入,这样我就可以检查它们是否匹配)我听到有人说这样做超出了令牌的整个目的,尽管我不明白为什么。对我来说这似乎很安全。
如果它是安全的,是否比将令牌放在 URL 中安全性低?
还有其他方法吗?
我在哪里可以阅读有关该主题的更多信息?
更新:到目前为止,没有人能告诉我 cookie 方法如何不安全,如果它仍然必须与表单中的令牌相匹配,而攻击者不应该获得该令牌,除非他使用另一个方法像 XSS 这样的 hack 是另一回事,并且使用 cookie 和 url token 之间仍然没有区别。
更新2:好的,好像一些著名的框架都使用这种方法,所以应该没问题。谢谢
Is it ok to put the CSRF token in a cookie? (and in every form, as a hidden input, so I can check if they match, of course) I heard someone say that doing so, beats the whole purpose of the token, though I don't understand why. It seems secure to me.
And if it is secure, is it any less secure than puting the token in the URL's ?
Is there any other method?
Where can I read more on the subject?
UPDATE: So far no one can tell me how is the cookie method insecure, if it still has to match the token from the form, which the attacker shouldn't be able to get, unless he uses another hack like XSS, which is a different matter, and still doesn't make a difference between using cookie and url token.
UPDATE 2: Okay, seems like some famous frameworks use this method, so it should be fine. Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用 cookies 是有效的,并且是一种常见的做法(例如 Django 使用它 )。由于同源策略,攻击者无法读取或更改cookie的值,从而无法猜测正确的GET/POST参数。
Using cookies works, and is a common practice (e. g. Django uses it). The attacker cannot read or change the value of the cookie due to the same-origin policy, and thus cannot guess the right GET/POST parameter.
查看加密令牌模式,它允许无状态 CSRF 保护无需在服务器上存储令牌。
Check out the Encrypted Token Pattern, which allows stateless CSRF protection without the need to store tokens on the server.
如果您决定将 CSRF 令牌放入 cookie,请记住将该 cookie 标记为
HttpOnly
。如果您的站点存在跨站点脚本漏洞,黑客将无法读取 CSRF 令牌。您可以在任何现代浏览器控制台中使用命令console.log(document.cookie)
检查 JavaScript 可以读取的 cookie。如果您有会话 Cookie 或其他敏感 Cookie,它们也应标记为HttpOnly
。进一步阅读:
https://www.owasp.org/index.php/HttpOnly
If you decide to put the CSRF-token in a cookie then remember to mark that cookie as
HttpOnly
. If your site has a cross-site scripting vulnerability the hacker won't be able to read the CSRF-token. You can check the cookies that can be read by JavaScript using the commandconsole.log(document.cookie)
in any modern browser console. If you have session cookies or other sensitive cookies these should also be marked asHttpOnly
.Further reading:
https://www.owasp.org/index.php/HttpOnly
“CSRF 之所以有效,是因为许多站点使用 GET 请求来执行命令。”,因此,许多站点没有按预期使用 GET 方法,因为这些请求必须是幂等的:查看 rfc2616。
“CSRF 参数已经存在于 cookie 中,并且它会与会话一起发送。”,那么如何呢?
cookie 仅用于具有令牌存储,就像我们在隐藏输入字段中设置令牌时的 DOM 一样。一段 javascript 必须从该 cookie 中获取令牌值,并将其设置为 URL、请求正文或请求标头中的参数。它将在服务器上检查会话中存储的值。这就是 Django 处理 CSRF 令牌的方式。
由于跨域浏览器保护,Javascript 无法从另一个域访问 cookie,所以我不知道恶意用户如何强迫某人在伪造的请求中发送正确的令牌。对于 XSS,是的,但是 XSS 会击败常见的 CSRF 对策。
我更愿意做出这样的澄清,因为我认为这是一个重要的问题,而且不太容易处理。
GET 请求必须用于获取资源和/或显示其数据,它不得用于更改其状态(删除、属性增量或任何更改)。
CSRF验证必须在服务器端完成,这似乎是显而易见的,但我把它作为一个提醒。 如果您遵守此建议,则此方法不会成为攻击媒介。
"CSRF works because many sites use GET requests to execute commands.", so, many sites don't use the GET method as expected, because these request must be idempotent: see the rfc2616.
"The CSRF parameter is already there in the cookie and it gets sent along with the session.", so how?
The cookie is only used has a token storage, as the DOM when we set the token in a hidden input field. A piece of javascript must get the token value from this cookie, and set it as a parameter in the URL, the request body or in the request header. It will be check on the server with the value stored in the session. That's the Django way to handle the CSRF token.
Javascript can't access the cookie from another domain, due to the cross domain browser protection, so I don't know how a malicious user can force someone to send the correct token along a forged request. With an XSS, yes, but XSS defeat the common CSRF countermeasures.
I prefer giving this clarification, because I think it's an important question and not so easy to handle.
GET request must be used to get a resource and/or display its data, it must not be used to change its state (deletion, property incrementation or any changes).
The CSRF validation must be done server-side, it seems to be obvious, but I put it as a reminder. This method can't be a vector of attack if you observe this recommandations.
使用 cookie 违背了 CSRF 的目的。原因如下:
CSRF 之所以有效,是因为许多站点使用 GET 请求来执行命令。假设鲍勃有某种管理网络帐户并且他已登录该帐户。可以发出一些请求,例如:
http://somesite.com/admin/whatever.php?request=delete_record&id=4
所以现在 Bob 被链接到一个攻击站点(有人试图搞乱)和他的数据)。然后,攻击者可能会使用另一个 ID 将上述 URL 加载到图像中,并删除一些其他记录。浏览器加载它是因为 Bob 已经登录到他的管理站点,因此他有一个有效的会话。
CSRF 试图通过向交易添加安全参数来消除这种情况。该参数应该在每个请求上轮换,然后由浏览器重新发送。让 URL 看起来像这样:
http://somesite.com/admin/whatever.php?request=delete_record&id=4&csrf=
现在的想法是攻击者必须猜测“一些长校验和”才能发起攻击。如果该校验和在每个请求上都很好地轮换,那么这几乎是不可能的。
但是,如果您将该校验和存储在 cookie 中,您就回到了第 1 步。攻击者不再需要猜测它。他只是制作了原始 URL。 CSRF 参数已存在于 cookie 中,并且随会话一起发送。它并不能阻止不安全行为的发生。
Using a cookie defeats the purpose of CSRF. Here's why:
CSRF works because many sites use GET requests to execute commands. So say Bob has some kind of administrative web account and he's logged into it. Some request could be made like:
http://somesite.com/admin/whatever.php?request=delete_record&id=4
So now Bob gets linked to an attack site (someone is trying to mess with his data). The attacker then loads the above URL in an image, probably with another ID and deletes some other record. The browser loads it because Bob is already logged into his admin site so he has a valid session.
CSRF seeks to eliminate this by adding a secure parameter to the transaction. That parameter should rotate on every request and then be resent by the browser. Making the URL look something like this:
http://somesite.com/admin/whatever.php?request=delete_record&id=4&csrf=<some long checksum>
The idea is that now the attacker has to guess "some long checksum" to create an attack. And if that checksum rotates on every request well it should be virtually impossible.
BUT if you store that checksum in a cookie you're back at square 1. The attacker no longer has to guess it. He just crafts the original URL. The CSRF parameter is already there in the cookie and it gets sent along with the session. It doesn't stop the insecure behavior from happening.