游客发表
2017年,跨站某大型电商平台爆出漏洞:攻击者只需诱导用户访问一个精心构造的请求链接,就能在用户不知情的伪造情况下,修改其账户的漏洞绑定手机号。整个过程悄无声息,跨站用户甚至不会收到任何验证码提醒——因为修改请求是请求从用户自己的浏览器发出的,服务器完全信任了这次“合法”操作。伪造
这就是漏洞CSRF(Cross-Site Request Forgery),跨站请求伪造。跨站它的请求核心逻辑简单得可怕:服务器无法区分“用户主动发出的请求”和“攻击者伪造的请求”。浏览器自动携带Cookie的伪造特性,成了攻击者最趁手的漏洞武器——只要用户登录着目标网站,浏览器就会自动在每次请求中带上会话凭证,跨站而服务器对此毫无戒心。请求
我见过太多开发者对CSRF不以为然。伪造他们觉得:“我的接口有Token验证啊,别人伪造不了。”可问题是,Token如果放在URL参数里,Referer头一旦泄露,Token就等于裸奔。还有的人把Token放在Cookie里,那更是自欺欺人——Cookie是自动携带的,攻击者根本不需要读取Token,只要让浏览器发出请求就够了。
真实的攻击场景往往是这样:攻击者在论坛、评论区甚至邮件里埋下恶意链接。链接指向的是银行转账接口,参数已经拼接好。受害者只要点击,浏览器就会带着他的登录状态,发起一笔转账。整个过程不需要窃取密码,不需要破解验证码,甚至不需要知道受害者的账户余额——只要受害者恰好登录着银行网站,攻击就成功了。
更阴险的是,CSRF还能配合其他漏洞使用。比如某个网站存在XSS漏洞,攻击者先注入一段脚本,脚本里嵌着CSRF攻击代码。用户访问了被注入的页面,脚本在用户浏览器里运行,自动向修改密码的接口发出请求。这种组合拳打下来,服务器端几乎没有任何防御手段能拦住——因为请求本身是“真实”的。
防御CSRF的思路,说到底就是打破“浏览器自动携带凭证”这个默认行为。最有效的办法是给每个用户生成一个随机的、绑定在会话中的Token,放在请求头或表单隐藏字段里。攻击者无法预测这个Token,所以伪造的请求会因为没有Token而被拒绝。另一种思路是校验Referer头,但这个方法不太靠谱——Referer有时候会被浏览器省略,有时候又会被代理服务器改写,误伤率太高。
还有个容易被忽略的细节:CSRF不仅针对GET请求,POST请求同样危险。很多开发者以为POST就安全了,实际上攻击者只需要用表单自动提交就能发起POST请求,根本不需要JavaScript。所以,别把防御重心放在HTTP方法上,Token校验才是硬道理。
我自己调试过不少CSRF漏洞,有个感觉特别深:这个漏洞之所以泛滥,是因为它“太安静”了。不像SQL注入会报错,不像XSS会有弹窗,CSRF攻击发生后,一切看起来都正常——用户没收到异常提醒,服务器日志里全是合法请求。等到用户发现账户里少了钱,或者密码被改了,攻击者早就溜之大吉。
说到底,CSRF考验的是开发者对“信任边界”的理解。服务器信任了浏览器的自动行为,却忘了浏览器是用户手中的工具,也是攻击者可以利用的跳板。把每个请求都当成“不可信”的,加上Token校验,再配合SameSite Cookie属性——这三点做到了,CSRF基本就断了路。剩下的,就看开发者愿不愿意多写那几行代码了。
友情链接