24

我正在尝试防止 CSRF 并有两个场景:

  1. 从另一个站点内进行 POST 并在我启用 AntiForgeryToken 时失败
  2. 我已经尝试从我的“恶意”Javascript(在另一个站点上运行)首先执行页面的 GET,解析它并提取 RequestVerificationToken,然后执行 POST。这也失败了,但我不清楚为什么?

谁能解释一下为什么?

4

2 回答 2

76

这是一个关于 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 是什么,即使他知道,他也无法使用网站使用的相同密钥和算法对其进行加密。

你有它。一次阻止尼日利亚王子一个防伪令牌。

(这里没有反对尼日利亚或尼日利亚人。我相信他们是可爱的人。只是他们的王子有时表现得有点糟糕。):)

于 2014-01-23T04:55:14.923 回答
6

出于安全原因,您不能使用 AJAX 从另一个域检索内容。

因此,其他站点无法获取您的令牌。

于 2011-01-31T15:57:34.750 回答