什么是 CSRF(跨站请求伪造)? 如何防御它?

更新时间 1/23/2024

在当今数字化时代,互联网已经成为我们日常生活中不可或缺的一部分。我们将更多的活动转移到网络上,例如购物、社交媒体、银行交易等。在金融交易越发普遍时,网络安全也开始造成更大影响。

CSRF(Cross-site request forgery)跨站请求伪造是互联网上最常见的攻击手段之一,让我们来了解一下吧。

概念

CSRF 攻击利用目标网站在请求来源检查等方面的缺陷,诱使用户在已登录的目标网站上执行恶意请求。攻击者通常使用与目标网站域名类似的地址,诱导用户点击,通过在其中嵌入恶意代码,通过伪装加载图片或是隐藏表单的方式,向目标网站发起请求,执行隐蔽的未授权操作。诸如修改用户密码、银行转账等攻击目的,可能对用户造成很大损失。

下面举个具体的例子。

举例

想象一下,有一个名为 e-bank.com 的网站向用户提供电子银行服务,其中包含一个名为 /transfer 的页面用于提交转账请求。

当用户访问 e-bank.com/transfer 页面时,会展示由用户填写的表单,当用户填写完成表单提交时,则向页面地址本身发送 HTTP POST 请求,发送用户填写的收款人和金额等参数。

此时攻击者可以构建一个恶意页面,其中包含一个不可见表单并将提交地址指向 e-bank.com/transfer,攻击者预先在表单参数中设置好特殊的收款账户和金额,当用户受到欺骗点击进入这个恶意页面时,浏览器加载执行 JavaScript 代码,将表单提交。

如果用户没有在 e-bank.com 上注册或登录,转账请求当然不可能被执行。但一旦用户刚刚使用过这个服务,登录状态尚未过期,则转账请求就可能被执行成功。

这就是 CSRF 攻击,原理简单,潜在危害巨大,索性现在已经有很多成熟的手法用于阻止攻击。下面我来介绍一下。

解决方案

对于这个问题的解决可以分为两个部分,主动和被动。

HTTP method 限制和 Referer 限制

我们作为开发者可以在服务上对关键敏感地址进行更严格的限制,比如:

  • 对于需要提交数据的地址,禁止使用 HTTP GET 请求,而是强制使用 POST 等请求方式。这将对攻击者构造恶意页面造成一些困难。

  • 进一步的,我们可以限制 HTTP 请求头中的 Referer 字段,这个值将在浏览器页面上发起请求时被主动添加,用于指定请求的来源页面。作为网站开发者,我们限制 Referer 请求头,仅允许它来自我们已知的正常地址,而阻止恶意请求。

这是一种最简单的主动保护手段,成本较低,但仍存在被攻击的可能性。

CSRF Token

CSRF Token 是一种通行的成熟方案,它结合服务器端 Session 机制来阻止 CSFR 攻击。

具体来说,在那些需要保护的页面上,服务器端程序会在输出的表单中插入一个隐藏的输入字段,插入一个随机生成的字符串 CSRF Token;同时在服务器侧生成一个 Session,在其中存储这个随机字符串并设置过期时间。

这样,当用户请求页面时,服务器将初始化 Session,数据存储在服务器侧,同时在客户端浏览器设置 Cookie,其中包含 Session ID 以关联服务器侧的 Session。在 Session 中将存储 CSRF Token,同时向表单插入 token。当用户提交表单时,这个 CSRF Token 将被发送,服务器侧程序将这个 token 与 Session 中存储的部分进行比对,如果验证通过则执行后续逻辑,而失败时则返回错误。同时,一个新的 CSRF Token 也会插入表单,并在下次用于提交。

这也是主动的保护手段,需要一定的工作量,但提供了更强的保护力。

跨域保护

我们有时还会听到一种名为 CORS 的技术,它是一套用于指示浏览器是否允许跨域请求的规范。

现代浏览器均支持这一规范,一个现有页面上发起 Fetch/XHR 请求时,浏览器会首先发送一个 HTTP OPTIONS 请求用于预先检查目标服务是否允许当前来源的地址发起请求,服务器将以响应头的方式返回一个列表以指示浏览器,什么来源、哪种 HTTP method、包含什么样的请求头的请求是允许发送的,浏览器会遵守这些指示,在客户端阻止被禁止的请求。

这也是主动的保护手段,通过在服务器侧的配置,可以直接阻止浏览器发起请求。但需要注意的是,尽管正常用户不了解也不太可能这样做,但这个功能可以被客户端侧关闭。

三方 Cookie 将被阻止

我们开发的服务有时 Cookie 存储用户 Session ID,以维持登录状态。Cookie 支持 SameSite 设置,通过配置一个合理的选项,我们可以让浏览器不向跨域站点发送 Cookie。这样,尝试进行 CSRF 攻击的人将总会在其攻击目标站点上收到未登录的状态。

进一步,随着 HTTP Cookie 机制被滥用于追踪客户端,浏览器开发者决定开始逐步限制并禁止第三方 Cookie,即当一个域名 A 上的页面尝试向 B 发起调用时,即使它通过 CORS 规则检查而允许发起请求,浏览器也不会向那个跨域的站点发送 Cookie。

Chrome Timeline Example

总结

作为 API 网关,Apache APISIXAPI7 Enterprise 支持上面提到的 CSRF Token 和 CORS 两种保护手段,可以用于阻止 CSRF 攻击。

总的来说,阻止 CSRF 攻击是不可能通过单一手段解决的,必须结合多种手段,比如服务器端、浏览器、HTTP 协议等技术上的集合使用达到保护目的。

微信咨询

获取方案