检查推荐人是不是足以防止 CSRF 攻击?
Posted
技术标签:
【中文标题】检查推荐人是不是足以防止 CSRF 攻击?【英文标题】:Is checking the referrer enough to protect against a CSRF attack?检查推荐人是否足以防止 CSRF 攻击? 【发布时间】:2010-11-27 16:30:51 【问题描述】:检查引荐来源网址是否足以防止跨站点请求伪造攻击?我知道引荐来源网址可以被欺骗,但是攻击者有什么办法可以为客户做到这一点?我知道代币是常态,但这行得通吗?
【问题讨论】:
您应该包含您的编程语言/平台,因为存在许多开箱即用的解决方案(例如 ASP.NET MVC 的 AntiForgeryToken)。 【参考方案1】:这是一个 3 年前的问题,有四个不同的答案,基本上说明了同一件事:遵循规范,使用令牌,不要尝试使用推荐人。
虽然令牌仍然被认为是最安全的选项,但使用引用者通常要容易得多,而且也非常安全。只要确保查看所有 PUT/POST/PATCH/DELETE 请求,并在缺少引用者或来自错误域的情况下将其视为攻击。很少有(如果有的话)代理会删除此类请求的引用者。
另请参阅OWASP recommendation 关于检查引用标头作为 CSRF 保护:
检查引荐标头
虽然自己欺骗referer标头是微不足道的 浏览器,在 CSRF 攻击中是不可能的。检查 referer 是一种常用的在嵌入式上防止 CSRF 的方法 网络设备,因为它不需要每个用户的状态。这 当内存不足时,使引用者成为 CSRF 预防的有用方法 稀缺。
但是,检查referer被认为是较弱的 CSRF 保护。例如,开放式重定向漏洞可能是 用于利用受引用者保护的基于 GET 的请求 查看。需要注意的是 GET 请求永远不应该产生状态 更改,因为这违反了 HTTP 规范。
referer 检查也存在常见的实现错误。为了 例如,如果 CSRF 攻击源自 HTTPS 域,则 引用者将被省略。在这种情况下,缺少推荐人应该是 当请求执行状态时被认为是攻击 改变。另请注意,攻击者对 推荐人。例如,如果受害者的域是“site.com”,那么 攻击者的 CSRF 漏洞来自“site.com.attacker.com” 这可能会欺骗损坏的引用检查实现。可以使用 XSS 绕过推荐人检查。
【讨论】:
问题是“检查推荐人是否足够[...]?”。我对 OWASP 指南的解读是,答案是“不,还不够”。它仅作为整体战略的一部分有用。它还取决于检查是宽松的(允许空白标头)还是严格的(未通过空白标头)。从保护的角度来看,严格检查更有用,但会导致代理出现问题(如其他地方所述)。在一般网络上,去除了引荐来源标头的用户比例可能较低,但如果您与企业打交道,请谨慎行事,衡量并询问您的用户群。 还要考虑到,Referrer Policy (developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…) 允许取消设置 Referer 标头,这可能导致以下漏洞sjoerdlangkemper.nl/2017/06/21/…【参考方案2】:除其他外,对于浏览器(或公司代理)不发送引荐来源网址的用户,使用引荐来源网址不起作用。
【讨论】:
Cheekysoft:确实,Referrer 很容易被伪造,但这不是你不应该将它们用于 CSRF 保护的原因。能够执行 CSRF 攻击的攻击者无法伪造 Referer 标头。 您也可以检查 ORIGIN 标头 - 参见 people.mozilla.org/~bsterne/content-security-policy/… Google Chrome 实现了发送此标头,因此它始终出现在 POST 请求中 @Cheekysoft 攻击者如何在现代浏览器中伪造引荐来源网址? @Light 我的评论来自近 10 年前,虽然是真的,但即使在那时,它也可能需要在仅限 CSRF 的上下文中滥用浏览器插件。在 2009 年,从恶意 Flash 应用程序(取决于 crossdomain.xml)或 Java 小程序肯定会很容易。考虑到更锁定的现代浏览器,请参阅下面来自 Aleksander Blomskøld 的答案,以获得更集中的理解。【参考方案3】:唯一正确的答案是“除其他外,对于浏览器(或公司代理)不发送推荐人的用户,使用引荐来源网址不起作用。”话虽如此,这在当今非常罕见。所有说推荐人可以伪造的人都充满了它。除非您以其他方式(XSS/特洛伊木马/等)控制他人的浏览器,否则您不能伪造推荐人。如果您需要推荐人来使用应用程序,它们与 CSRF 令牌一样有效。只需确保您 100% 确保您的检查是正确的(例如,如果您使用正则表达式,请确保您从推荐人的开头“^”开始检查)。
【讨论】:
@ShadowWizard:CSRF 不是欺骗其他浏览器(人)在主网站上使用他的登录帐户做某事的手段吗?黑客使用什么浏览器并不重要。 @ShadWizard 我的声明是关于 CSRF 预防的。你的说法不是。 @ShadowWizard:如果攻击者给了用户一个恶意浏览器,那么 CSRF 是他最不用担心的。 那么受害者是谁? CSRF 是指远程站点/攻击者欺骗用户站点的用户/浏览器在用户站点上执行操作。 CSRF 令牌可以防止这种情况。远程站点/攻击者不能欺骗用户/浏览器更改它发送到用户站点的引荐来源网址。争论结束。【参考方案4】:是的。 如果你采取一些预防措施。
这是一个 12 岁的问题,这是第一个出现的结果,所以我要回答它。在这 12 年里,情况发生了很大变化。因此,虽然当时它可能是一个糟糕的选择,但现在它是一种易于实施且可靠的解决方案。
使用referrer 的主要疑问是请求中是否没有referrer 标头。这可能发生在多种情况下,例如攻击者省略引荐来源网址、从安全页面向不安全页面请求、代理或用户选择忽略它或通过元标记忽略它。
在上述所有情况下,您都应该严格忽略没有有效引荐来源的请求并使其失败。很明显,当攻击者忽略标题时您会失败,而您不能在页面的元标记中忽略它。如果用户决定选择忽略它,那是他们的选择,它会破坏功能,就像禁用 cookie 或 javascript 会破坏大多数网站一样。
从安全页面向不安全页面发送请求也不是什么大问题。因为在这12年里。 web 发生了很大变化,大多数网站实际上根本不需要处理不安全的端点,如果你这样做了,你就不会在地址栏中出现那个确保锁定的标志。
谈到安全端点,也不必担心代理或 ISP 会忽略标头,因为包括标头在内的整个请求都是加密的,而且拦截器根本无法检查标头,更不用说修改它们了,除非他们可以访问用户的设备,这总体上使其成为非常罕见的情况。
但是引荐人不能伪造吗?
伪造推荐人是一件既容易又困难的事情。它的可行性取决于你在这个过程中信任谁。让我们考虑一下这个糟糕的策略:
用户登录到网站example.com
和example.com/login
检查用户是否是有效用户,然后将用户重定向到example.com/sensitive
,example.com/sensitive
页面然后评估引荐来源,如果它来自example.com/login
,则打印敏感数据。这很糟糕,因为用户可以很容易地在他/她自己的浏览器上伪造引荐来源网址。但是防止 CSRF 攻击的整个想法不适用于您不信任用户的情况。当您不相信用户真正发送的请求时。这意味着为了伪造引荐来源网址,攻击者需要以某种方式修改用户的设备,如果攻击者拥有该访问权限,他们毕竟不会费心发送第三方请求。
那么,没什么好担心的?差不多了。
有两种棘手的情况可以想到简单的解决方案。
一个。没有正确检查推荐人。这是什么意思 ?假设您的域是 example.com
并且您只是检查 example.com
是否存在于引用字符串中。那么您可以错误地将example.com.evil.com
视为真正的请求。解决方案是检查example.com/
(我在我的本地php服务器中检查了这个并且工作正常。如果这不适用,您可能需要使用自己的环境进行测试并找到另一个解决方案)
B。考虑到来自您自己网站的重定向。如果您的网站有一个端点可以重定向到这样的外部资源:example.com/redirect?url=extenal.com
攻击者可以利用它并发出这样的请求example.com/redirect?url=example.com/sensitive
要解决这个问题,最好不要使用 GET 请求更改状态(修改数据库记录等)。作为预防措施,您还可以检查请求是否来自您的重定向端点,也不要在重定向端点中重定向到您自己的域。
【讨论】:
【参考方案5】:不是不够的,攻击者很容易为客户端做到这一点,正如你所问的,攻击者所要做的就是让用户点击他创建的链接,从那时起,就是游戏结束
攻击者将复制原始站点中使用的表单,并欺骗其余部分,因为现在代码在他自己的站点上,然后将其提交到受害站点
正如您在问题中提到的,令牌是防止 CSRF 的规范
【讨论】:
【参考方案6】:遵循规范:使用令牌。
检查引荐来源网址实际上什么也没做,因为无论如何请求都来自该页面!您试图防止的问题是在用户没有做任何事情的情况下请求页面;不是被击中的页面本身。
令牌是防止这种情况的方法。您生成一个,将其存储在会话中,并将其写入 html,然后在发布时检查您收到的一个,看看它是否与您期望的相匹配。如果没有,你就失败了。无论哪种方式,您都会在之后生成一个新令牌。
考虑到如果有多个页面,这可能会搞砸人们,这也可能是相关的;所以你可能想为每页制作一个不同的令牌。
【讨论】:
以上是关于检查推荐人是不是足以防止 CSRF 攻击?的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET MVC 中的 AntiForgeryToken 是不是可以防止所有 CSRF 攻击?