HTTP请求本身是无状态的,服务端收到请求后并不知道请求者是谁;所以为了记录用户的标识信息,来提供更好更便捷的网络服务,Cookie应运而生。
一个网站签发的Cookie只能由这个网站(domain)使用。假设用户在访问example.com时,浏览器存储了一个Cookie,那么用户在访问相同domain(example.com)的HTTP服务时,浏览器都会带上这个Cookie(比如www.example.com, demo.example.com, abc.example.com)。反之,如果访*.xyz.com时,浏览器就不会带上任何example.com的Cookie。
CSRF
跨站请求伪造(英语:Cross-site request forgery),是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
问题的根源在于:浏览器允许网站A向和自己无关的网站B发起请求(并携带网站B的Cookie)。
发现了这个问题后,很快在2016年就引入了Cookie的SameSite属性,禁止跨站请求携带Cookie,从而确保了能够携带Cookie的请求一定是用户在浏览器自己的网站期间发出来的。
Cookie的SameSite属性
用户首先访问了www.dominio-X.com
,这个dominio-X在用户登录过程中存储了Cookie A和Cookie B,其中Cookie A是普通的Cookie没有SameSite属性,Cookie B拥有SameSite属性。
这个之后,用户通过浏览器访问了一个恶意网站www.dominio-Y.com
,这个恶意网站会向www.dominio-X.com
发送请求,这时可以看到,普通的Cookie A会在用户不知情的情况下被携带一并传送过去,而拥有SameSite的Cookie B浏览器会发现虽然Cookie B是属于dominio-X
的,但是和发起的网站dominio-Y
并不一样,跨站了(Cross Site),此时浏览器就会阻止Cookie B的传输,保护了用户。
SameSite的取值范围
- Strict 完全禁止跨站传递Cookie,比如A网站通过超链接跳转B网站也不行,必须用户手动输入这个B网站浏览器才允许使用B网站的Cookie。 过于严格,很少使用。
- Lax 相对宽松(reLax)的规则,大部分情况也不允许跨站传递Cookie,但是对于较为安全的场景:超链接跳转,get类型的Form表单,是允许的。 这个模式是大部分浏览器的SameSite的默认取值(当服务端SetCookie没有制定SameSite时,大部分现代浏览器会默认使用Lax)。 使用Lax已经能够杜绝CSRF攻击。
- None 完全没有限制。 老版本浏览器默认仍然会使用None作为SameSite的默认取值。 大部分现代浏览器默认是Lax。 以及None默认过于危险,如果要使用SameSite=None则浏览器会要求网站服务使用https才行。
参考资料: