无CSRF令牌的登录表单遭CSRF攻击的原理及相关疑问
一、先理清你困惑的攻击流程:原描述的问题与正确场景
你看到的那个攻击流程描述有错误,这才导致你搞不懂步骤4、5。真实的CSRF攻击登录表单的场景,根本不是利用受害者已登录的会话Cookie让攻击者拿到访问权,而是两种典型情况:
强制受害者切换到攻击者控制的账号
攻击者做的隐藏表单里,填的是他自己的账号和密码。当受害者点开恶意页面,浏览器会自动带上目标网站的Cookie(比如受害者之前登录过自己的账号,有现成的会话),提交这个登录请求。如果网站的登录逻辑是“新登录直接覆盖原有会话”,那受害者当前的会话会被换成攻击者的账号。这时候要是受害者在网站上操作(比如绑定银行卡、发起转账),全是在攻击者的账号下——比如攻击者的账号没完成实名认证,他就能诱导受害者帮自己完成认证,或者让受害者把钱转到攻击者账号关联的银行卡里。结合会话固定的组合攻击
攻击者先去目标网站拿一个未登录的会话ID(比如打开登录页就会收到的Cookie),然后做恶意页面,里面的登录表单填受害者的账号密码(他可能通过钓鱼、信息泄露拿到),同时让浏览器带上这个预先拿的会话ID。因为登录表单没CSRF令牌,网站会接受这个请求,之后这个会话ID就绑定到受害者的账号上了——攻击者拿着这个会话ID就能直接登录受害者的账号,拿到未授权访问权限。
二、就算其他接口都用CSRF令牌,登录表单加令牌的意义
别觉得登录表单是个例外,加CSRF令牌依然很有必要:
- 防上面说的账号切换攻击:不让攻击者随便把受害者的会话换成其他账号,保证用户会话的安全性。
- 断了会话固定+CSRF的组合攻击路子:会话固定本身需要诱导受害者登录,CSRF令牌能直接拦掉攻击者构造的登录请求。
- 统一安全策略:全站都做CSRF保护,避免出现安全短板,不给攻击者留可乘之机。
三、登录表单CSRF令牌的生成、伪造与验证逻辑
令牌怎么生成?
当用户打开登录页时,网站会生成一个CSRF令牌,和用户当前的**匿名会话(也就是还没登录的会话)**绑定。网站会把这个令牌存在服务器端(比如会话存储里),同时把令牌放到登录表单的隐藏字段里,或者通过响应头发给浏览器。
攻击者能伪造这个令牌吗?
不能。因为令牌和用户的匿名会话Cookie是绑定的,攻击者自己去登录页拿的令牌,是和他自己的匿名会话绑在一起的。他把这个令牌放到恶意表单里提交,网站会对比请求里的令牌和当前会话Cookie对应的令牌,不匹配就直接拒绝请求。
网站怎么区分令牌来源?
验证的时候网站会做两步:
- 检查请求里的CSRF令牌有没有,格式对不对。
- 从当前请求的会话Cookie里取出对应的令牌,和请求里的令牌做比对,完全一致才允许请求通过。
攻击者拿不到受害者会话对应的令牌,所以他构造的请求根本过不了验证。
内容的提问来源于stack exchange,提问作者Jayy

