了解 CSRF 攻击并锁定 CSRF 漏洞
已发表: 2022-11-21Web 漏洞猖獗且不断增加。 维护用户的安全和隐私比以往任何时候都更加重要。 不解决 Web 漏洞可能会导致声誉受损和监管机构的巨额罚款,并且您还会失去用户的信任。
网站和 Web 应用程序容易受到恶意软件、垃圾邮件和其他攻击——本文重点介绍一种此类攻击媒介——跨站点请求伪造 (CSRF) 攻击。 CSRF 攻击特别麻烦,因为它们可能在用户不知情的情况下发生。 开发人员或网站所有者也很难检测到它们,因为恶意请求看起来与真实请求非常相似。
本文探讨了 CSRF 攻击、它的工作原理,以及您可以采取的准备应对攻击的步骤。
什么是 CSRF 攻击?
跨站点请求伪造攻击,也称为 CSRF 攻击,通过在用户不知情的情况下提交恶意请求,诱使经过身份验证的用户执行意外操作。
通常,CSRF 攻击涉及状态更改请求,因为攻击者没有收到响应。 此类请求的示例包括删除记录、更改密码、购买产品或发送消息。 这些都可能在用户不知情的情况下发生。
恶意攻击者通常使用社会工程通过聊天或电子邮件向不知情的用户发送链接。
当用户点击链接时,它会执行攻击者设置的命令。
例如,点击一个链接可以从用户的账户中转移资金。 或者,它可以更改用户的电子邮件地址,阻止他们重新获得帐户访问权限。
CSRF 攻击如何运作?
让用户在登录时发起状态更改请求是 CSRF 攻击的第一步,也是最关键的一步。 通过 CSRF 攻击,攻击者旨在让经过身份验证的用户在不知不觉中向网站或 Web 应用程序提交恶意 Web 请求。 这些请求可以包含 cookie、URL 参数和其他对用户来说正常的数据类型。
要使 CSRF 攻击成功,必须满足以下条件:
- 经过身份验证的用户必须登录到使用 cookie 进行会话管理的 Web 应用程序。
- 攻击者必须创建一个改变状态的伪造请求。
- 目标服务器处理的真实请求不应包含不可预测的参数。 例如,在发起状态更改请求之前,请求不应期望将密码作为用于验证目的的参数。
完成 CSRF 攻击的最常见方法是在具有弱 SameSite cookie 策略的应用程序中使用 cookie。 Web 浏览器自动包含 cookie,并且通常是匿名的,它们会在用户发送到该域的任何 Web 请求中保存该域使用的 cookie。
SameSite cookie 策略定义浏览器在跨站点浏览上下文中如何处理 cookie。 如果设置为严格,则 cookie 不会在跨站点浏览上下文中共享,从而防止 CSRF 攻击。 如果设置为无,浏览器会在所有跨站点上下文中附加 cookie。 这使得应用程序容易受到 CSRF 攻击。
当用户在不知情的情况下通过 Web 浏览器提交恶意请求时,保存的 cookie 会导致该请求对服务器来说是合法的。 然后服务器通过更改用户帐户、更改会话状态或返回请求的数据来响应请求。
让我们仔细看看 CSRF 攻击途径的两个示例,一个使用 GET 请求,另一个使用 POST 请求。
GET 请求的 CSRF
首先,考虑金融银行 Web 应用程序使用的 GET 请求,其中攻击利用 GET 请求和超链接传递。
假设转账的 GET 请求看起来像这样:
GET https://xymbank.com/online/transfer?amount=1000&accountNumber=547895 HTTP/1.1
在上面的真实请求中,用户请求将 1,000 美元转入547895
的帐户作为购买产品的付款。
虽然此请求明确、简单且实用,但它会使帐户持有人面临 CSRF 攻击。 那是因为该请求不需要攻击者可能不知道的详细信息。 因此,要发起攻击,攻击者只需更改此请求的参数(金额和帐号)即可创建可执行的伪造请求。
恶意请求将对银行的任何用户有效,只要他们正在进行 cookie 管理的会话。
下面是将 500 美元转移到黑客帐户(此处为号码654585
)的伪造请求的外观。 请注意,以下示例是 CSRF 攻击所涉及步骤的高度简化版本,以供解释。
GET https://xymbank.com/online/transfer?amount=500&accountNumber=654585 HTTP/1.1
完成后,攻击者必须想出一种方法来诱使用户在登录其在线银行应用程序时发送此请求。 其中一种方法是创建一个无害的超链接来引起用户的注意。 该链接可能如下所示:
<a href="https://xymbank.com/online/transfer?amount=500&accountNumber=654585">Click here to get more information</a>.
鉴于攻击者已经找到了目标的正确电子邮件地址,他们可以通过电子邮件将其发送给许多银行客户。 那些在登录时单击该链接的人会触发从登录帐户向攻击者发送 500 美元的请求。
POST 请求的 CSRF
让我们看看如果同一家金融机构只接受 POST 请求,他们将如何遇到 CSRF。 在这种情况下,GET 请求示例中使用的超链接传递将不起作用。 因此,成功的 CSRF 攻击需要攻击者创建 HTML 表单。 为购买的产品发送 1,000 美元的真实请求如下所示:
POST /online/transfer HTTP/1.1 Host: xymbank.com Content-Type: application/x-www-form-urlencoded Cookie: session=FRyhityeQkAPzeQ5gHgTvlyxHJYhg amount=1000 account=547895
这个 POST 请求需要一个 cookie 来确定用户的身份、他们希望发送的金额以及他们想要发送的帐户。 攻击者可以更改此请求以执行 CSRF 攻击。
攻击者必须只向伪造的请求添加真正的 cookie,以使服务器处理传输。 他们可以通过创建一个看起来无害的超链接来做到这一点,该超链接将用户带到如下所示的触发网页:
<html> <body> <form action="https://xymbank.com/online/transfer" method="POST"> <input type="hidden" name="amount" value="500"/> <input type="hidden" name="account" value="654585" /> </form> <script> document.forms[0].submit(); </script> </body> </html>
我们已经在上面的表格中设置了金额和帐户参数。 一旦经过身份验证的用户访问该页面,浏览器就会在将请求转发到服务器之前添加会话 cookie。 服务器然后将 500 美元转发到黑客的帐户。
减轻 CSRF 攻击的 3 种方法
有几种方法可以防止和大大减轻对您的网站或 Web 应用程序的潜在 CSRF 攻击,包括:
- 使用 CSRF 令牌
- 使用引用标头
- 选择以安全为中心的托管解决方案,例如 Kinsta
如何使用 CSRF 令牌防止 CSRF 攻击
CSRF 安全网站为每个会话分配一个唯一的令牌,并与服务器端和客户端浏览器共享。 每当浏览器发送敏感请求时,服务器都希望它包含分配的 CSRF 令牌。 如果它有错误的令牌,服务器会丢弃它。 出于安全目的,CSRF 令牌不会存储在客户端浏览器的会话 cookie 中。
CSRF 代币的潜在漏洞
尽管 CSRF 令牌是一种出色的安全措施,但这种方法无法抵御攻击。 CSRF 令牌附带的一些漏洞包括:
- 验证绕过——一些应用程序如果找不到令牌则跳过验证步骤。 如果攻击者获得对包含令牌的代码的访问权限,他们可以删除该令牌并成功执行 CSRF 攻击。 因此,如果对服务器的有效请求如下所示:
POST /change_password POST body: password=pass123&csrf_token=93j9d8eckke20d433
攻击者只需移除令牌并像这样发送它即可执行攻击:
POST /change_password POST body: password=pass123
- 池化令牌——一些应用程序维护一个令牌池来验证用户会话,而不是为会话指定一个特定的令牌。 攻击者只需获取池中已有的令牌之一,即可冒充该站点的任何用户。
攻击者可以使用他们的帐户登录应用程序以获得令牌,例如:
[application_url].com?csrf_token=93j9d8eckke20d433
由于令牌被合并,攻击者可以复制并使用相同的令牌登录到不同的用户帐户,因为您将再次使用它:
- CSRF 可以被令牌复制到 cookie — 一些应用程序会将与令牌相关的参数复制到用户的 cookie 中。 如果攻击者获得了对此类 cookie 的访问权限,他们可以轻松创建另一个 cookie,将其放置在浏览器中,然后执行 CSRF 攻击。
因此攻击者可以使用他们的帐户登录应用程序并打开 cookie 文件以查看以下内容:
Csrf_token:93j9d8eckke20d433
然后他们可以使用此信息创建另一个 cookie 来完成攻击
- 无效令牌——某些应用程序不将 CSRF 令牌与用户会话匹配。 在这种情况下,攻击者可以真正登录会话,获取与上述类似的 CSRF 令牌,并使用它来编排对受害者会话的 CSRF 攻击。
如何使用 Referrer 标头防止 CSRF 攻击
另一种防止 CSRF 攻击的策略是使用引用标头。 在 HTTP 中,引用标头指示请求的来源。 它们通常用于执行分析、优化和日志记录。
您还可以在服务器端启用检查引用标头以防止 CSRF 攻击。 服务器端检查请求的来源并确定请求的目标来源。 如果它们匹配,则请求被允许。 如果不匹配,服务器将丢弃请求。
使用 referrer 标头比使用令牌容易得多,因为它不需要单独的用户标识。
Referrer 标头的潜在漏洞
与 CSRF 令牌一样,引用标头也有一些重大漏洞。
首先,引荐来源标头不是强制性的,有些网站会在没有它们的情况下发送请求。 如果 CSRF 没有处理无标头请求的策略,攻击者可以使用无标头请求来执行状态更改攻击。
此外,随着最近引入的推荐人政策,这种方法变得不那么有效了。 此规范可防止 URL 泄漏到其他域,使用户能够更好地控制引用标头中的信息。 他们可以选择公开部分 referrer header 信息,或者通过在 HTML 页面上添加元数据标签来禁用它,如下所示:
<meta name="referrer" content="no-referrer">
上面的代码删除了来自该页面的所有请求的引用标头。 这样做会使依赖引用标头的应用程序难以防止来自此类页面的 CSRF 攻击。
Kinsta 如何防止 CSRF 攻击
除了使用引荐来源网址标头和 CSRF 令牌之外,还有第三种更简单的选择:为您的网站和 Web 应用程序选择像 Kinsta 这样的安全托管服务,在攻击者和您的用户之间提供更强大和更安全的屏障。
除了自动备份、双因素身份验证和基于 SSH 协议的 SFTP 等关键安全功能之外,Kinsta 的 Cloudflare 集成还提供基于 IP 和防火墙保护的企业级保护。
具体来说,Kinsta 目前有大约 60 条自定义防火墙规则,以帮助防止恶意攻击并处理插件和主题中严重的未经身份验证的漏洞,包括寻找 CSRF 漏洞的特定漏洞。
概括
跨站点请求伪造 (CSRF) 是一种欺骗经过身份验证的用户无意中发起状态更改请求的攻击。 它们针对的是无法区分有效和伪造的状态更改请求的应用程序。
CSRF 只能在依赖会话 cookie 来识别登录用户并且具有弱 SameSite cookie 策略的应用程序上成功。 他们还需要一个服务器来接受不包含未知参数(例如密码)的请求。 黑客可以使用 GET 或 POST 发送恶意攻击。
尽管使用 CSRF 令牌或强制执行引荐来源标头验证可以防止某些 CSRF 攻击,但这两种措施都有潜在的漏洞,如果您不小心,可能会使您的预防措施失效。
迁移到像 Kinsta 这样的安全托管平台可以保护您的网站或 Web 应用程序免受 CSRF 攻击。 此外,Kinsta 与 Cloudflare 的集成可防止特定的 CSRF 攻击。