Skip to content

跨站请求伪造 (CSRF) 攻击:它是什么、如何工作以及如何预防

CSRF 漏洞会欺骗应用程序中经过身份验证的用户,只需单击链接即可在该应用程序上执行危险活动。

您一定厌倦了 IT 安全团队一次又一次提醒您不要点击从可疑来源收到的可疑电子邮件中的任何可疑链接,对吗?但您有没有想过为什么,或者如果您单击它会发生什么?

CSRF 攻击如何运作

CSRF 攻击会诱骗已登录 Web 应用程序(银行帐户或公司门户)的用户在该应用程序上执行危险活动,例如转移资金、更改凭据,甚至授予对某些受保护资源的访问权限(想想:敏感公司数据或 AWS 账户)。

由于用户已经在一个选项卡中的应用程序上进行了身份验证,因此并不能阻止他们从另一选项卡执行这一危险活动。有一次你点击了一张有趣的猫图片;接下来,黑客将访问您的公司帐户。什么?那是怎么发生的?

开放 Web 应用程序安全项目 (OWASP) [2]是一个致力于提高软件安全性的基金会,对此漏洞的描述如下:

跨站点请求伪造 (CSRF) 是一种攻击,它迫使最终用户在其当前经过身份验证的 Web 应用程序上执行不需要的操作。在社会工程的帮助下(例如通过电子邮件或聊天发送链接),攻击者可能会诱骗 Web 应用程序的用户执行攻击者选择的操作。

如果受害者是普通用户,成功的 CSRF 攻击可以迫使用户执行状态更改请求,例如转移资金、更改电子邮件地址等。如果受害者是管理帐户,CSRF 可能会损害整个 Web 应用程序。

CSRF 攻击还有其他几个名称,包括 XSRF、“Sea Surf”、Session Riding、Cross-Site Reference Forgery 和 Hostile Linking。

例子 在 Twitter 的早期迭代中,您可以通过 GET 请求而不是网站当前使用的 POST 请求创建推文。这种疏忽使得 Twitter 容易受到 CSRF 攻击:它使得创建 URL 链接成为可能,单击该链接后,该链接将发布在用户的时间线上。

为什么你不应该点击可疑链接

第一步:黑客创建一个欺诈网站

攻击者创建一个执行某些危险活动的欺诈网站。一个非常简单的示例是一个包含表单的网站,该表单会使用 JavaScript 自动提交到您的应用程序。在这种情况下,提交表单会执行危险的活动,黑客所需要做的就是让您访问该网站。

html
<form action="https://your-bank.com/user/email" method="POST">
    <input type="email" value="malicious-email@example.com">
</form>
 
<script>
    document.forms[0].submit();
</script>

即使您不执行任何操作,该表单也会在您加载页面后立即提交。这就是为什么不要点击电子邮件或消息中收到的任何可疑链接如此重要的原因。

第二步:将链接发送给用户

攻击者将此链接或表单嵌入到外观正常的网页中,然后通过电子邮件发送给您,或将其链接到互联网上的许多地方,毫无戒心的用户可能会点击它们,例如社交媒体帖子或评论、图像、重复副本真实网站等

第三步:您点击链接,黑客就可以访问

现在,黑客所需要做的就是在您仍然登录银行网站的情况下诱骗您访问该页面。网站加载后,会将表单提交到银行网站,并传递浏览器 cookie

换句话说,假设受害者已经在一个选项卡中登录到网络应用程序(例如真正的银行网站或公司门户)。现在他们在另一个选项卡中打开上述电子邮件。然后他们点击电子邮件中的欺诈链接。此链接将他们带到自动提交上述欺诈表格的网页。

银行网站认为您是真正的用户(使用cookie)并执行黑客想要的危险操作。

CSRF 攻击如何在幕后运作

大多数 Web 应用程序使用浏览器 cookie来实现身份验证。 Cookie 是服务器发送到用户 Web 浏览器的一小段数据。浏览器存储 cookie 并将其与后续请求一起发送回同一服务器。这就是您在关闭选项卡甚至浏览器后仍保持登录许多 Web 应用程序的方式。

Cookie 与选项卡或窗口无关——它们与对域的请求有关。每当浏览器向 Web 服务器请求某个域(即 yourbank.com)时,浏览器拥有的该域的任何 cookie 都将在请求标头中发送。由于用户已经在第一个选项卡中登录银行应用程序,因此浏览器会发送第二个选项卡发出的请求中的 cookie。

收到欺诈请求后(当您单击电子邮件中的诈骗者链接时自动发生),服务器(Web 应用程序)会检查 cookie 并验证用户身份,因为 cookie 仍然有效。

现在应用程序认为有效的登录用户正在执行此请求。然而,这是攻击者创建的伪造请求。现在,此请求可以执行您的应用程序允许登录用户执行的任何操作,例如从银行帐户转帐。

如果您了解HTTP 协议的工作原理,您可能会认为单击链接或打开图像会发出 GET 请求,这是无害的。但正如上面的示例所示,攻击者可以轻松编写 JavaScript 代码,在单击链接或访问网页时动态创建和提交表单。

作为用户,在从可疑链接导航到外部网页之前,您应该始终小心。然而,作为构建这些 Web 应用程序的开发人员,您可以做更多的事情。让我们尝试了解如何防止对您的应用程序进行 CSRF 攻击。

如何防止 CSRF 攻击并确保用户安全

CSRF 攻击背后的主要问题是,在用户意外单击链接后(尽管他们的网站),服务器应用程序无法区分真实请求(来自真实用户的请求)与来自攻击者网站的伪造请求(IT人员多次告诉他们不要这样做)。

如果应用程序有一种方法可以识别来自真实用户的请求,然后它可以拒绝来自其他任何地方的所有其他请求,该怎么办?

我们可以通过指示服务器应用程序在 Web 应用程序的每个表单中插入唯一的随机令牌来解决此问题。当真实用户从真实应用程序提交表单时,此令牌会随之发送。

收到请求后,服务器检查此令牌是否存在并与之前创建的令牌匹配。它知道该请求来自真实用户,并且如果令牌存在且匹配,则该请求有效。如果令牌丢失或不匹配,它会拒绝请求。

由于令牌是随机的,攻击者无法猜测并将其插入到伪造的请求中。因此,服务器会拒绝所有伪造的请求,从而保证用户的安全。

您还应该使用反 CSRF cookie 来验证 JavaScript 发出的 HTTP 请求,这样您还可以保护 PUT 和 DELETE 请求。 JavaScript 需要从 HTML 中查询出反 CSRF 令牌,并在 HTTP 请求中将其传回服务器。

Released under the MIT License.