我正在尝试防止跨站请求伪造(CSRF),有两种情况:
- 从另一个网站进行POST请求,启用了AntiForgeryToken后失败。
- 我尝试从我的“恶意”JavaScript(在另一个网站上运行)首先获取页面的 GET 请求, 解析并提取 RequestVerificationToken,然后执行 POST 请求。这也失败了,但我不清楚原因是什么?
请问有人能够解释为什么吗?
我正在尝试防止跨站请求伪造(CSRF),有两种情况:
请问有人能够解释为什么吗?
这是一份关于CSRF的好教程:
简单来说,您登录银行网站并在机器上存放了银行的cookie,以便进行身份验证。每次您请求(即从)yourbank.com加载页面时,浏览器会将cookie发送到Web服务器,服务器上的代码会检查cookie以确保您已经进行身份验证。很棒。
然而,当cookie尚未过期时,您检查电子邮件并打开一个尼日利亚王子寄给您的链接。您点击它(谁能抵制),但链接却将您带到以下URL:
http://yourbank.com/transfer.aspx?amt=1000000&from=myAccount&to=princeAccount
因为您在银行已经进行了身份验证(通过cookie),所以银行认为您实际上正在要求转账,所以就会执行。
这显然是一个有点牵强的例子,但它清楚地传达了要点。更现实的情况是,该链接可能会提交一个请求,在论坛网站上更改您的电子邮件地址,以便他们可以获取到您的访问权限。
现在,回答您具体的问题:
一种解决这个问题的方法(Ruby和.NET等使用的方法)是包含一个防伪标记。基本上,当你请求一个页面时,服务器会包含一个带有加密值的隐藏字段。当你提交表单时,网站会查看cookie以确保你已经认证,但它还会查看浏览器发送的加密值并确保它是有效的。加密令牌实际上将是与您的账户相关联的会话ID。因此,服务器会看到cookie,将您识别为用户123,然后检查加密表单字段令牌,解密该值并确保未加密的值与您的会话或用户ID相匹配。如果匹配,则知道可以继续进行。
发送链接的尼日利亚王子不会知道您的会话ID,即使他知道,他也无法使用与网站相同的密钥和算法进行加密。
这就是方法。一次又一次地阻止尼日利亚王子通过防伪标记行骗。
(这里没有对尼日利亚或尼日利亚人有任何偏见。我相信他们是可爱的人。只是他们的王子有时会表现得有些糟糕。)
出于安全考虑,您不能使用AJAX从另一个域检索内容。
因此,其他网站无法获取您的令牌。