简介
CSRF(Cross-site request forgery)跨站请求伪造。与XSS一样,这里也出现了 cross-site,但是两者有很大的区别。
- XSS:主要指本网站运行了外部的脚本程序
- CSRF:主要指在外部网站运行程序,对本网站造成了影响
CSRF更通俗具体一点讲,指外部网站在用户不知情的情况下,对目标(被攻击)网站发出了请求。
原理
(图片来自互联网)
针对“访问网站会带上该网站的 cookie,而 cookie 中又可能包含用户的身份”这一特性,外部网站可以在用户不知情的情况下,向目标网站发出请求
危害
- 冒名发帖
- 冒名消费
- 冒名转账
防御
禁止来自第三方网站的请求带上 cookie
为了从源头上解决CSRF问题,Google 起草了一份草案来改进 HTTP 协议,那就是为 Set-Cookie 响应头新增 SameSite 属性,它用来标明这个 cookie 是个“同站 cookie”,同站 cookie 只能作为本网站 cookie,不能作为外部网站 cookie。
SameSite 有两个属性值,分别是 Strict 和 Lax:
- SameSite=Strict:严格模式,表明这个 cookie 在任何情况下都不可能作为第三方 cookie
- SameSite=Lax:宽松模式,比 Strict 放宽了点限制:假如这个请求是改变了当前页面或者打开了新页面,且同时是个 GET 请求,则这个 cookie 可以作为第三方 cookie。
目前为止只有 chrome 浏览器支持 SameSite 属性
使用验证码
如图所以示,我们可以在用户提交表单的地方加入验证码,阻止不经过用户感知,静默提交的行为。
使用 CSRF Token
同时将 token 写出表单和 cookie 当中,由于外部网站无法读取目标网站的 cookie,那么自然无法伪造正确的请求。
具体来讲,是使用了签名的机制。
- 表单中的 token 与 cookie 中的 token 都是后端生成的
- 表单中的 token 是原密码,而 cookie 中的 token 是原密码加密后得到的
举例来说:
表单中的 token 为 5678
cookie 中的 token 为 e2c83847505a87ed35aebb7465de62cf
加密规则:加密密码 = md5(原密码 + sermfjheuf&^w-w~~)
当请求发送到后台时,我们只需要校验一下 CSRF Token 是否匹配就行。
判断 Referer 请求头
当 Referer 请求头是外部网站时,我们就可以拒绝该请求。
由于 Referer 是浏览器自动为我们添加的,所以它也是可以伪造的,并不能完全信任