CSRF

跨站请求伪造(CSRF)是一种冒充受信任用户,向服务器发送非预期请求的攻击方式。这些非预期请求可能是通过在跳转链接后的 URL 中加入恶意参数来完成。

正常操作场景

  1. 用户行为:用户登录到银行网站 https://bank.example.com 并点击转账按钮。

  2. Referer字段:浏览器自动在发起转账请求时设置Referer头部为 https://bank.example.com/transfer-page(假设转账页面地址为 /transfer-page)。

  3. 服务器检查:服务器接收到请求后检查Referer字段,确认请求是从银行网站内部的合法页面发起的。

CSRF攻击场景

  1. 恶意操作:攻击者诱导用户访问一个恶意网站,如 https://malicious.com,该网站上有一个自动执行的请求或者隐藏的表单指向 https://bank.example.com/withdraw?account=Alice&amount=1000&for=Badman

  2. Referer字段:当用户(不知情地)在恶意网站上触发请求时,Referer头部会被设置为 https://malicious.com

  3. 服务器检查:银行服务器收到转账请求后检查Referer头部,发现请求是从一个外部域名(https://malicious.com)发起的,而不是银行自己的域名。

  4. 防御措施:由于Referer字段不匹配期望的值(即不是从 bank.example.com 发起的),服务器识别出这是一个可能的CSRF攻击,并阻止该请求。

预防措施

  • 添加校验token

由于CSRF的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再执行CSRF攻击。这种数据通常是窗体中的一个数据项。服务器将其生成并附加在窗体中,其内容是一个伪随机数。

当客户端通过窗体提交请求时,这个伪随机数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个伪随机数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个伪随机数的值,服务端就会因为校验token的值为空或者错误,拒绝这个可疑请求。

  • 检查Referer头

HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通常来说,Referer字段应和请求的地址位于同一域名下。以上文银行操作为例,Referer字段地址通常应该是转账按钮所在的网页地址,应该也位于bank.example.com之下。而如果是CSRF攻击传来的请求,Referer字段会是包含恶意网址的地址,不会位于bank.example.com之下,这时候服务器就能识别出恶意的访问。

这种办法简单易行,工作量低,仅需要在关键访问处增加一步校验。但这种办法也有其局限性,因其完全依赖浏览器发送正确的Referer字段。虽然http协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段。并且也存在攻击者攻击某些浏览器,篡改其Referer字段的可能。

Last updated