# 设置Cookie属性防止CSRF攻击
互联网上很多数据不能公开访问,比如银行账户。要访问自己的银行账户,就需要账户密码,由于HTTP是无状态的,一次HTTP请求登录后,下次再向服务器请求数据,服务器不知道你是谁,上一次的登录状态没有被保存。为了解决认证持久化问题,发明了cookie。
举例:客户端登录银行账户后,服务器设置cookie到浏览器,在cookie过期之前,这个客户端向服务器发起的HTTP请求都会带上cookie,不管请求是在银行的站点发起的,还是在别的站点发起的,由于cookie是对的,银行服务器都会执行对应的操作。
# CSRF
如果用户刚刚登陆过银行账户,又访问了恶意网站,恶意网站修改了银行账户转账请求的部分参数,然后发起HTTP请求,服务器收到了正确的cookie,执行了转账操作,这就是跨站请求攻击。跨站请求攻击,简称为CSRF。
跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。 —— 维基百科
CSRF的防御,可以增加token或者检查Referer。
# SameSite
CSRF的根本原因是:cookie在不该发送的时候发送出去了。为了解决这个问题,cookie增加了SameSite属性。它有三个值:
Set-Cookie: promo_shown=1; SameSite=Strict
Set-Cookie: promo_shown=1; SameSite=Lax
Set-Cookie: promo_shown=1; SameSite=None
Strict 跨站时,不发送cookie。就上面的例子来说,只有在Cookie的站点与浏览器URL栏中当前显示的站点匹配时,才会带上cookie。这有个问题,我们写博客经常会贴上Github链接,点击跳转后带上cookie会自动登录。如果SameSite设置为Strict,跳转到GitHub就不会自动登录。
Lax 默认值,部分跨站请求会发送cookie。只有这些标签发出的跨站请求会发送cookie
<a>
、<link rel="prerender">
、<form method="get">
,它很大程度上避免了CSRF攻击None 无论是否跨站都发送cookie。这跟SameSite出现之前默认行为一致
从chrome 80起
Set-Cookie: promo_shown=1;
等同于
Set-Cookie: promo_shown=1; SameSite=Lax