AntiForgeryToken 是如何工作的
我试图防止 CSRF 并有两种情况:
- 从另一个站点内执行 POST,当我启用 AntiForgeryToken 时它会失败
- 我尝试从我的“恶意”Javascript(在另一个站点上运行)首先执行页面的 GET,解析它并提取 RequestVerificationToken,然后执行 POST。这也失败了,但我不清楚为什么?
谁能解释一下为什么吗?
I'm in trying to protect from CSRF and have two scenarious:
- Doing POST from within another site and it fails when I enable AntiForgeryToken
- I have tried from my "malicious" Javascript (running on another site) to first do GET of the page, parse it and extract RequestVerificationToken and then do a POST. This also fails but it is unclear to me why?
Can anyone please explain why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个关于 CSRF 的很好的教程:
http://youtu.be/vrjgD0azkCw
这是一般要点:您已登录到银行的网站。您的银行会在您的计算机上放置一个 cookie,以便对您进行身份验证。每次您向 yourbank.com 发出请求(即加载页面)时,浏览器都会将 cookie 发送到 Web 服务器,并且 Web 服务器上的代码会检查 Cookie 以确保您已通过身份验证。伟大的。
然而,虽然 cookie 尚未过期,但您检查了邮件并打开了一封来自尼日利亚王子的电子邮件,告诉您单击链接。您点击它(谁能抗拒),该链接不会将您带到王子所描述的页面,而是将您带到以下 URL:
http://yourbank.com/transfer.aspx?amt=1000000&from=myAccount&to=princeAccount
因为您已经在银行进行了身份验证(通过 cookie ),它认为您实际上是在要求转账,所以它会这样做。
这显然是一个有点做作的例子,但它说明了要点。更现实的是,该链接可能会提交一个请求,更改您所属的论坛网站上的电子邮件地址或其他内容,以便他们可以访问它。
现在,回答您的具体问题:
解决此问题的一种方法(由 Ruby 和 .NET 等使用)是包含防伪令牌。基本上,当您请求页面时,服务器会包含一个带有加密值的隐藏字段。当您提交表单时,网站会查看 cookie 以确保您已通过身份验证,但它还会查看浏览器发送的加密值并确保其有效。加密的令牌实际上是您的帐户所绑定的会话 ID。因此,服务器会看到 cookie,将您标识为用户 123,然后检查加密的表单字段令牌,解密该值并确保未加密的值与您的会话或用户 ID 或其他内容相匹配。如果是,它就知道要继续。
向您发送链接的尼日利亚王子不会知道您的会话 ID 是什么,即使他知道,他也无法使用网站使用的相同密钥和算法对其进行加密。
现在你就得到了它。一次一枚防伪令牌挫败尼日利亚王子。
(这里没有反对尼日利亚或尼日利亚人的意思。我确信他们是可爱的人。只是他们的王子有时表现得有点不好。):)
Here's a good tutorial on CSRF:
http://youtu.be/vrjgD0azkCw
Here is the general gist: You are logged in to your bank's website. Your bank puts a cookie on your machine so it can authenticate you. Every time you make a request to (ie. load a page from) yourbank.com, the browser sends the cookie to the web server and the code on the web server checks the cookie to make sure you're authenticated. Great.
However, while the cookie hasn't yet expired, you check your mail and open an email from a Nigerian Prince telling you to click on a link. You click on it (who can resist) and instead of taking you to the page the Prince has described, the link takes you to this URL:
http://yourbank.com/transfer.aspx?amt=1000000&from=myAccount&to=princeAccount
Because you're already authenticated at your bank (through the cookie), it thinks you're actually asking to transfer the money, so it does it.
This is obviously a bit of a contrived example, but it gets the point across. More realistically, the link might submit a request that changes your email address on a forum website that you belong to or something, so that they can get access to it.
So NOW, on to answering your specific question:
One way to combat this (used by Ruby and .NET and others) is to include an anti-forgery-token. Basically, when you request a page, the server includes a hidden field with an encrypted value. And when you submit the form, the website looks at the cookie to make sure you're authenticated, but it also looks at the encrypted value that the browser sends and make sure it's valid. The encrypted token would realistically be a session id that your account is tied to. So the server sees the cookie, identifies you as user 123, and then checks the encrypted form field token, decrypts the value and makes sure that unencrypted value matches your session or user id or something. If it does, it knows to proceed.
The Nigerian prince who sent you the link won't know what your session id is, and even if he did, he wouldn't be able to encrypt it with the same key and algorithm that the website is using.
And there you have it. Thwarting Nigerian princes one anti-forgery-token at a time.
(Nothing against Nigeria or Nigerians here. I'm sure they're lovely people. It's just their princes sometimes behave a bit poorly.) :)
出于安全原因,您无法使用 AJAX 从另一个域检索内容。
因此,其他网站无法获取您的令牌。
For security reasons, you cannot retrieve content from another domain using AJAX.
Therefore, other sites cannot get your token.