当前位置:首页 > 时尚

csrf攻击

一个深夜,攻击你登录银行账户查看余额。攻击页面一切正常,攻击但你不知道的攻击是,另一个浏览器标签页里,攻击一张精心构造的攻击图片请求刚刚发出。几秒钟后,攻击你的攻击钱转走了。没有密码泄露,攻击没有木马入侵,攻击你什么都没做错——只是攻击浏览了一个带恶意代码的网页。这就是攻击CSRF攻击,跨站请求伪造。攻击

CSRF的攻击可怕之处在于它根本不和你正面对抗。攻击者不需要看到你的攻击密码,不需要破解你的验证码,甚至不需要知道你的卡号。他只需要知道你登录某个网站后,浏览器会自动携带认证Cookie。这个机制本是为了方便用户,却被攻击者用来借刀杀人。

我见过一个真实案例。某论坛用户发了个帖子,里面嵌了一张图片链接,指向电商网站的“修改收货地址”接口。图片URL被精心构造,参数里预填了攻击者的地址。论坛用户只要浏览这个帖子,浏览器就会自动请求那个图片地址。如果用户恰好登录着电商网站,请求就会携带有效的会话Cookie。服务器收到请求,以为是用户本人操作,地址就改了。等用户下单买完东西,包裹已经寄到了攻击者手里。

整个过程里,服务器完全被蒙在鼓里。它只看到一条合法请求,带着合法凭证,来自合法用户。HTTP协议是无状态的,服务器靠Cookie识别用户,而Cookie会自动附加在每个同域请求上。这是设计使然,也是漏洞根源。

防御CSRF的思路其实很直白——让攻击者无法构造出“合法”的请求。最常用的办法是加入不可预测的Token。服务器在渲染表单时生成随机Token,存在用户会话里,用户提交时带上这个Token,服务器比对一致才放行。攻击者没法预知Token值,自然造不出有效请求。这招简单有效,但很多老系统懒得改。

另一个思路是检查请求来源。HTTP头的Referer字段能显示请求从哪个页面发出,攻击者的恶意请求Referer通常不是正规网站。但这招不够可靠——有些浏览器或代理会屏蔽Referer,有些老版本浏览器允许JS伪造Referer。所以它只能作为辅助手段。

还有一个更彻底的办法:彻底放弃Cookie认证,改用自定义请求头。比如在AJAX请求里手动加一个自定义Header,携带认证信息。跨域请求要带自定义Header,必须经过预检请求,而预检请求会暴露真实意图,服务器可以直接拒绝。但这要求整个网站都改成AJAX架构,对传统表单提交的站点来说工程量大得吓人。

说到底,CSRF之所以存在,是因为Web的信任模型太粗糙了。服务器默认“带着我Cookie的请求就是我发出的”,忽略了请求可能是第三方网页间接发起的。这就好比你把家门钥匙给了门卫,门卫又轻信每个拿着钥匙的人都是你本人。真正解决问题,要么让钥匙更难复制,要么让门卫学会辨别来者。

前阵子我检查一个内部管理系统,发现它的删除操作直接用了GET请求。我试着在浏览器地址栏输入删除链接,页面刷新后,一条记录就没了。如果把这个链接发给已登录的管理员,他一点开,数据就丢了。这种低级错误在真实系统里比比皆是——开发时图省事,用GET处理写操作,等于把CSRF的大门焊死了还要贴上“欢迎光临”。

CSRF攻击的诡异之处在于,它攻击的不是用户,而是用户和服务器之间的信任关系。受害者全程在线,全程“自愿”,全程毫不知情。这种攻击方式提醒我们,安全不只是防外贼,还得防着那些看似无害的“顺手牵羊”。

分享到: