什么是Cookie?
HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的HTTP协议记录稳定的状态信息成为了可能。
如何创建Cookie?
服务器收到 HTTP 请求时,服务器可以在响应头里面添加一个 Set-Cookie 选项。浏览器收到响应后通常会保存下 Cookie,之后对该服务器每一次请求中都通过 Cookie 请求头部将 Cookie 信息发送给服务器。另外,Cookie 的过期时间、域、路径、有效期、适用站点都可以根据需要来指定。 例如:
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
[页面内容]
Cookie存在什么安全问题?
Cookie在浏览器的设计上是会在下次的同域请求中自动带上的,而且在DOM(Document Object Model)中提供了读写cookie的方法,所以从XSS的方式或是CSRF的方式都有可能利用Cookie的安全漏洞攻击网站。
XSS形式
利用xss漏洞注入script,通过document.cookie获取/修改cookie信息。
CSRF
利用Cookie自动携带的机制,达成盗用用户凭证完成敏感操作的效果。
浏览器方面给我们提供了什么Cookie相关的安全策略?
1. 限制访问 Cookie
Secure 属性和 HttpOnly属性可以确保Cookie被安全发送,不被第三方修改。
- 标记为Secure 的Cookie只应该(从Chrome 52 和 Firefox 52 开始,http协议下的站点无法使用该标记)通过被HTTPS协议加密过的请求发送给服务端。
document.cookieAPI无法访问带有HttpOnly属性的cookie,可缓解XSS攻击。
2. SameSite
SameSite 是HTTP响应头 Set-Cookie 的属性之一。它允许您声明该Cookie是否仅限于第一方或者同一站点上下文。
从Chrome 80版本后,SameSite属性被默认设置为 Lax 值(重要)
Lax(默认值)
Cookies允许与顶级导航一起发送,并将与第三方网站发起的GET请求一起发送。这是浏览器中的默认值。
Strict
Cookies只会在第一方上下文中发送,不会与第三方网站发起的请求一起发送。
None
Cookie将在所有上下文中发送,即允许跨域发送。 以前 None 是默认值,但最近的浏览器版本将 Lax 作为默认值,以便对某些类型的跨站请求伪造 (CSRF) 攻击具有相当强的防御能力。 使用 None 时,需在最新的浏览器版本中使用 Secure 属性。
浏览器对于SameSite政策的修改会导致什么问题?
SameSite 的默认值从 None 改为 Lax,会导致原来利用第三方cookie作用户凭证的请求无法正常使用,常见于<iframe>嵌入场景,一般形式为接口返回无权限/登录状态等错误。 解决方案:
- 设置凭证cookie的SameSite属性为None(服务端配置),如涉及敏感操作,不建议该方案。
- 不使用cookie存取用户凭证。