静态页面上的 CSRF 保护

信息安全 Web应用程序 xss csrf
2021-08-21 23:53:52

我有一个有表格的静态网站。表单提交到 Rails 端点,该端点捕获提交的数据。静态站点和 Rails 端点在同一个域上,在不同的子域上,所有流量都完全在 HTTPS 上。

我了解 Rails CSRF 如何用于服务器生成的表单。但就我而言,这些表单位于静态 HTML 页面上。我知道所有请求标头都可以伪造,所以不能依赖它。

如果在这种情况下不可能有一个强有力的解决方案,那么我的最后一个选择是转向服务器生成的表单(我现在想避免)。

任何有关解决此问题的好方法的建议都将受到欢迎。或任何指向已经执行此操作的系统或库的指针。

我可以对 HTTPS POST 请求(在我的情况下)实施 REFERER 检查——够了吗?这不能被欺骗吗?

CSRF 预防备忘单说:虽然在您自己的浏览器上欺骗referer 标头是微不足道的,但在CSRF 攻击中是不可能做到的。- 这个我不太明白。

任何帮助将非常感激。

3个回答

就个人而言,我不建议使用 Referer 标头来阻止 CSRF 攻击。它有两个问题:

  • 首先,它很脆弱。对Referer 标头的攻击由来已久,涉及(各种)插件(例如Flash)漏洞、浏览器API 中的错误(例如XHR)和重定向。需要明确的是,我并不是说检查 Referer 一定是不安全的。我只是认为我认为它更脆弱,我会对使用 CSRF 令牌的解决方案更有信心。

  • 其次,一些浏览器和公司防火墙出于隐私原因阻止了 Referer 标头,这意味着您将被迫阻止合法用户。因此,Referer 标头根本不是一个好的解决方案。

我建议您使用 CSRF 令牌,而不是使用 Referer 标头。

我可以使用我想要的任何标头和值向您的服务器发出任何请求。因此,攻击者可以很容易地向您发送一个数据包,其中包含他挑选的引荐来源网址。但是你是如何在 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.phpCSRF 攻击仅在受害者已经登录时才有效,否则攻击者可以自己加载 URL。如果您已登录,登录页面可能只是将您直接重定向到返回 URL。现在,如果您写usermgmt.php?action=delete&userid=1为返回 URL 会怎样?它将从 login.php 重定向到 usermgmt.php,并且 usermgmt.php 收到的referer 将是https://example.com/login.php?returnto=x. 这似乎完全合法,但事实并非如此。

此外,出于隐私原因,某些浏览器可能不包含推荐人,这会破坏网站。我不知道有没有安装特殊插件的浏览器有这个选项(“功能”?),但你永远不知道。

所以最好的解决方案是使用 CSRF 令牌,如果你要为更多的受众托管一些东西,我当然会这样做,但如果它是针对一个封闭的用户组,你可能可以检查推荐人。

它实际上是您需要保护自己的 Rails 端点。它需要区分您的静态页面和互联网上其他人的恶意页面。

我同意让 rails 端点检查引用者是一种授权访问的脆弱方式。

一种可能性是让 rails 端点有一个不受 CSRF 保护的路由,并且什么都不做,但让 CSRF cookie 被设置。“空形式”。在进行其他 AJAX 调用之前,您域上的所有静态站点都可以访问它。

据推测,如果您使用的是 AJAX,那么您在同一个域中,这意味着您可以看到 cookie。如果该端点是从另一个站点命中的,他们将不会获得 cookie,因为它们位于不同的域中。