我可以使用我想要的任何标头和值向您的服务器发出任何请求。因此,攻击者可以很容易地向您发送一个数据包,其中包含他挑选的引荐来源网址。但是你是如何在 CSRF 攻击中解决这个问题的呢?
CSRF 的工作原理是我将您发送到我控制的网页,然后该网页将您的浏览器重定向到该网页以执行 CSRF。例如,我可以(通过该攻击页面)将您发送到https://example.com/usermgmt.php?action=delete&user=1
,这可能会让您无意中删除用户 ID 1。
您的浏览器所做的是将 REFERER 标头(在加载 usermgmt.php 时)设置为它来自的任何位置,例如http://malicious.tld
. 如果 usermgmt.php 检查了referer,它会注意到它不是来自同一个域。因此,您不能(默认情况下)欺骗 CSRF 的引用者。
这里的一个问题是登录页面之类的东西。考虑一下:https://example.com/login.php?returnTo=index.php
。CSRF 攻击仅在受害者已经登录时才有效,否则攻击者可以自己加载 URL。如果您已登录,登录页面可能只是将您直接重定向到返回 URL。现在,如果您写usermgmt.php?action=delete&userid=1
为返回 URL 会怎样?它将从 login.php 重定向到 usermgmt.php,并且 usermgmt.php 收到的referer 将是https://example.com/login.php?returnto=x
. 这似乎完全合法,但事实并非如此。
此外,出于隐私原因,某些浏览器可能不包含推荐人,这会破坏网站。我不知道有没有安装特殊插件的浏览器有这个选项(“功能”?),但你永远不知道。
所以最好的解决方案是使用 CSRF 令牌,如果你要为更多的受众托管一些东西,我当然会这样做,但如果它是针对一个封闭的用户组,你可能可以检查推荐人。