网络漏洞很猖獗,而且不断增加。维护你的用户的安全和隐私比以往任何时候都更重要。 不解决网络漏洞会导致声誉毁于一旦,并被监管机构处以巨额罚款,你还会失去用户的信任。
网站和网络应用程序很容易受到恶意软件、垃圾邮件和其他攻击–本文重点讨论其中一个攻击媒介–跨站请求伪造(CSRF)攻击。CSRF攻击特别令人不安,因为它们可以在用户不知情的情况下发生。开发人员或网站所有者也很难发现它们,因为恶意请求看起来与真实请求高度相似。
本文探讨了CSRF攻击,它是如何工作的,以及你可以采取哪些步骤来准备应对。
- 什么是CSRF攻击?
- CSRF攻击是如何工作的?
- GET请求的CSRF
- POST请求的CSRF
- 减轻CSRF攻击的3种方法
- 如何使用CSRF令牌防止CSRF攻击
- 如何利用Referrer标头来防止CSRF攻击
什么是CSRF攻击?
跨站请求伪造攻击,也被称为CSRF攻击,通过提交恶意请求,在不知不觉中欺骗认证用户,使其执行非预期的操作。
CSRF攻击是如何工作的。(图片来源: Okta)
通常情况下,CSRF攻击涉及改变状态的请求,因为攻击者没有收到回应。这类请求的例子包括删除记录、更改密码、购买产品或发送消息。这些都可以在用户不知情的情况下发生。
恶意攻击者通常使用社会工程,通过聊天或电子邮件向毫无戒心的用户发送一个链接。
当用户点击该链接时,它就会执行攻击者设置的命令。
例如,点击一个链接可以从用户的账户中转移资金。或者,它可以改变用户的电子邮件地址,使他们无法重新获得账户访问权。
CSRF攻击是如何工作的?
让用户在登录时发起一个改变状态的请求是CSRF攻击的第一步,也是最关键的一步。通过CSRF攻击,攻击者的目的是让已认证的用户在不知情的情况下向网站或网络应用程序提交一个恶意的网络请求。这些请求可以包括cookies、URL参数和其他在用户看来正常的数据类型。
要使CSRF攻击成功,必须发生以下条件:
- 一个经过验证的用户必须登录到一个使用cookies进行会话管理的网络应用程序。
- 攻击者必须创建一个改变状态的伪造请求。
- 由目标服务器处理的真正的请求不应包含不可预测的参数。例如,在启动状态改变请求之前,请求不应该期望有一个密码作为验证的参数。
完成CSRF攻击的最常见方法是在具有薄弱的SameSite cookie策略的应用程序中使用cookie。 网络浏览器自动地、通常是匿名地包括cookies,它们在用户向某个域发出的任何网络请求中保存该域所使用的cookies。
SameSite cookie策略定义了浏览器在跨站浏览情况下如何对待cookie。如果设置为严格,cookie就不会在跨网站浏览的情况下共享,从而防止CSRF攻击。如果设置为无,浏览器会在所有的跨网站上下文中附加cookie。这就使应用程序容易受到CSRF攻击。
当用户在不知情的情况下通过网络浏览器提交一个恶意请求时,保存的cookie会使该请求在服务器看来是合法的。然后,服务器通过改变用户的账户、改变会话状态或返回所请求的数据来响应该请求。
让我们仔细看看CSRF攻击途径的两个例子,一个是GET请求,另一个是POST请求。
GET请求的CSRF
首先,考虑一个金融银行网络应用程序使用的GET请求,攻击利用了GET请求和超链接传递。
假设转账的GET请求看起来是这样的:
GET https://xymbank.com/online/transfer?amount=1000&accountNumber=547895 HTTP/1.1
在上面的真实请求中,用户要求将1000美元转到 547895
的账户中,作为购买产品的付款。
虽然这个请求是明确、简单和实用的,但它使账户持有人暴露在CSRF攻击之下。这是因为该请求不需要攻击者可能不知道的细节。因此,为了发起攻击,攻击者只需要改变这个请求的参数(金额和账户号码),就可以创建一个可执行的伪造请求。
恶意请求对银行的任何用户都有效,只要他们正在进行cookie管理会话。
以下是伪造的向黑客账户(此处为 654585
)转账500美元的请求。请注意,下面的示例是CSRF攻击中涉及的步骤的高度简化版本,以供解释。
GET https://xymbank.com/online/transfer?amount=500&accountNumber=654585 HTTP/1.1
一旦完成,攻击者必须找出一种方法,诱骗用户在登录在线银行应用程序时发送此请求。实现这一点的方法之一是创建一个无害的超链接,以吸引用户的注意。链接可能如下所示:
href=”https://xymbank.com/online/transfer?amount=500&accountNumber=654585″>Click here to get more information</a>.
<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表单。为购买的产品发送1000美元的真正请求看起来是这样的:
Host: xymbank.com
Content-Type: application/x-www-form-urlencoded
Cookie: session=FRyhityeQkAPzeQ5gHgTvlyxHJYhg
amount=1000
account=547895
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,就可以使服务器处理传输。他们可以通过创建一个看起来无害的超链接,将用户带到一个看起来像这样的触发网页。
<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>
<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种方法
有几种方法可以防止和大大减轻对你的网站或网络应用的潜在CSRF攻击,包括:
- 使用CSRF令牌
- 使用referrer标头
- 选择一个注重安全的托管解决方案
如何使用CSRF令牌防止CSRF攻击
一个CSRF安全的网站会给每个会话分配一个唯一的令牌,并与服务器端和客户端浏览器共享它。每当浏览器发送一个敏感请求时,服务器都希望它包含指定的CSRF令牌。如果它有错误的令牌,服务器会放弃它。为了安全起见,CSRF令牌并不存储在客户端浏览器的会话cookies中。
CSRF令牌的潜在漏洞
虽然CSRF令牌是一个很好的安全措施,但这种方法并不是防攻击的。伴随着CSRF令牌的一些漏洞包括。
- 绕过验证 – 一些应用程序如果没有找到令牌就跳过验证步骤。如果攻击者获得了对包含令牌的代码的访问权,他们可以删除该令牌并成功执行CSRF攻击。因此,如果对服务器的有效请求看起来像这样。
POST body:
password=pass123&csrf_token=93j9d8eckke20d433
POST /change_password POST body: password=pass123&csrf_token=93j9d8eckke20d433
攻击者只需要删除令牌,然后像这样发送就可以执行攻击:
POST body:
password=pass123
POST /change_password POST body: password=pass123
- 池式令牌 – 一些应用程序维护一个令牌池来验证用户会话,而不是为一个会话指定一个特定的令牌。攻击者只需要获得池中的一个令牌就可以冒充网站的任何用户。
攻击者可以使用他们的账户登录到一个应用程序,以获得一个令牌,例如:
[application_url].com?csrf_token=93j9d8eckke20d433
而由于令牌是池化的,攻击者可以复制并使用该相同的令牌登录到不同的用户账户,因为你会再次使用它:
- CSRFs可以将令牌复制到cookie中 – 一些应用程序会将与令牌相关的参数复制到用户的cookie中。如果攻击者获得了这样的cookie,他们可以很容易地创建另一个cookie,把它放在浏览器中,并执行CSRF攻击。
因此,攻击者可以使用他们的账户登录到一个应用程序,并打开cookie文件,看到以下内容:
Csrf_token:93j9d8eckke20d433
然后他们可以使用这些信息创建另一个cookie来完成攻击
- 无效的令牌 – 一些应用程序不匹配CSRF令牌到用户会话。在这种情况下,攻击者可以真正地登录到一个会话中,获得与上述类似的CSRF令牌,并使用它来策划对受害者会话的CSRF攻击。
如何利用Referer Header防止CSRF攻击
另一个防止CSRF攻击的策略是使用referrer标头。在HTTP中,referrer标头表示请求的来源。它们通常被用来进行分析、优化和记录。
你也可以在服务器端启用检查referrer标头,以防止CSRF攻击。服务器端检查请求的来源,并确定请求的目标来源。如果它们匹配,那么该请求是允许的。如果不匹配,服务器会放弃该请求。
使用referrer标头像比使用令牌要容易得多,因为它不需要单独的用户识别。
Referrer标头的潜在漏洞
与CSRF标记一样,Referrer标头信息也有一些重要的漏洞。
首先,Referrer标头文件不是强制性的,有些网站会在没有Referrer标头文件的情况下发送请求。如果CSRF没有处理没有标头信息的请求的策略,攻击者可以使用标头信息的请求来执行状态改变的攻击。
此外,随着最近引入referrer策略,这种方法变得不再有效。这一规范防止了URL泄露给其他域,使用户对referrer标头中的信息有更多的控制。他们可以选择暴露部分referrer头信息,或者通过在HTML页面上添加一个元数据标签来禁用它,如下所示。
<meta name="referrer" content="no-referrer">
上面的代码为这个页面的所有请求删除了referrer头。这样做使得那些依赖referrer头的应用程序很难防止来自这样一个页面的CSRF攻击。
小结
跨站请求伪造(CSRF)是一种欺骗认证用户,使其无意中发起改变状态的请求的攻击。它们的目标是那些不能区分有效和伪造的状态改变请求的应用程序。
CSRF只能在那些依靠会话cookie来识别登录用户并具有弱的SameSite cookie策略的应用程序上取得成功。他们还需要一个接受不包含未知参数(如密码)的请求的服务器。黑客可以使用GET或POST来发送恶意攻击。
虽然使用CSRF令牌或强制执行referrer header验证可以防止一些CSRF攻击,但这两种措施都有潜在的漏洞,如果你不小心,就会使你的预防措施失去作用。