我看到 csrf 是这样的:
首先有三个角色:
- 浏览器
- 目标网站(善良网站、实际要访问的网站),称为 a.com
- 恶意网站(坏蛋搞得网站),称为 b.com
csrf 攻击过程:
- 我在浏览器登录了 a.com,这个时候,浏览器把 a.com 的 cookie 存储在浏览器
- 然后我访问 b.com,但是 b.com 返回一个 html+css+js。我在浏览器操作的时候,这些 html+css+js 给我发送了一个 request 到 a.com 企图转走我的钱
- 但是。。。
- 但是 a.com 发现这个 request 的 cookie 不对,就拒绝了!(我认为 csrf 攻击是不可能实现的)
- 因为 现代化的浏览器,都是阻止了 html+css+js 获取 a.com 的存储在浏览器中的 cookie
一切都是安全的,有 csrf 什么事情?
b.com 根本不可能发出带 a.com cookie 的 request
因为我记得,浏览器带 cookie 的前提是「同源」:具有相同的协议(Protocol)、域名(Domain)和端口(Port)
但是 b.com 和 a.com 显然 Domain 不一样
所以,csrf 防护有什么用?
你的理解有偏差。
当你在 a.com 登录后,a.com 委托浏览器将 Cookie 存起来,这时候 Cookie 是存在 a.com 下的,这没有什么问题,浏览器在处理 a.com 的请求的时候就会自动带上这些 Cookie。
现在,当你访问 b.com ,b.com 并不需要去读取 a.com 的 Cookie ,他也读取不到。
它只需要构建一个 form 表单,向 a.com 提交一个请求,浏览器就发现这个之前还保存了 a.com 的 Cookie ,所以按照正常的方式给发送出去了,这便是 CSRF 的重点。
就像上面这样,b.com 并不需要知道你在 a.com 的 Cookie,他只要构建这样一个表单,剩下的浏览器就会自动处理(带上 Cookie)。
这是因为站点在向浏览器下发 Cookie 时,如果没有正确设置 SameSite 属性那浏览器就会给定默认值为 None,从而导致这些问题。
当然,自 Chrome 80 开始,如果站点设置 Cookie 时,没有指定 SameSite ,那么其默认值将会变成 Lax 而不是之前的 None。
但是这也并没有完全杜绝 CSRF。