具有不安全、不正确或缺少SameSite属性的Cookie
1、概述
最近,用APPSCAN对网站进行扫描,结果报了一个“具有不安全、不正确或缺少SameSite属性的Cookie”的漏洞。
2、分析
2.1、Samesite属性是个啥?
为了从源头上解决CSRF(跨站请求伪造)攻击,Google起草了一份草案来改进HTTP协议,那就是为Set-Cookie响应头新增Samesite属性,它用来标明这个 Cookie是个“同站 Cookie”,同站Cookie只能作为第一方Cookie,不能作为第三方Cookie,Samesite 有两个属性值,分别是 Strict
、Lax
和None
。
2.2、Strict
Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
这个规则过于严格,可能造成非常不好的用户体验。
aaa.com设置了如下Cookie:
Set-Cookie: CookieName=123456; SameSite=Strict;
我们在bbb.com下发起对aaa.com的任意请求,CookieName这个Cookie不会被包含在Cookie请求头中。就好像淘宝网站用来识别用户登录与否的 Cookie 被设置成了 Samesite=Strict,那么用户从百度搜索页面甚至天猫页面的链接点击进入淘宝后,淘宝都不会是登录状态,因为淘宝的服务器不会接受到那个 Cookie,其它网站发起的对淘宝的任意请求都不会带上那个 Cookie。
2.3、Lax
Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。
导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。详见下表。
请求类型 | 示例 | 正常情况 | Lax |
---|---|---|---|
链接 | <a href="…"></a> | 发送Cookie | 发送Cookie |
预加载 | <link rel=“prerender” href="…"> | 发送Cookie | 发送Cookie |
GET表单 | <form method=“GET” action="…"> | 发送Cookie | 发送Cookie |
POST表单 | <form method=“POST” action="…"> | 发送Cookie | 不发送Cookie |
iframe | <iframe src="…"></iframe> | 发送Cookie | 不发送Cookie |
AJAX | $.get("…") | 发送Cookie | 不发送Cookie |
Image | <img src="…"> | 发送Cookie | 不发送Cookie |
设置了Strict=Lax
以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。
aaa.com设置了如下Cookie:
Set-Cookie: CookieName=123456; SameSite=Lax;
当用户从bbb.com点击链接进入aaa.com时,CookieName这个 Cookie 会被包含在 Cookie 请求头中,也就是说用户在不同网站之间通过链接跳转是不受影响了,但假如这个请求是从 bbb.com 发起的对 aaa.com 的异步请求,或者页面跳转是通过表单的 post 提交触发的,则CookieName也不会发送。
2.4、None
Chrome 80.0将SameSite的默认值设为Lax,。这时,网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。
下面的设置无效:
Set-Cookie: widget_session=abc123; SameSite=None
下面的设置有效
Set-Cookie: widget_session=abc123; SameSite=None; Secure
3、修复
PHP设置:
从PHP7.3开始,setcookie函数支持数组设置
setcookie($name, $value, [
'expires' => time() + 86400,
'path' => '/',
'domain' => 'domain.com',
'secure' => true,
'httponly' => true,
'samesite' => 'None',
]);
PHP7.3一下,通过hack方式实现
setcookie('sessionKey', $sessionKey, $expired, '/; secure; SameSite=none;');
Nginx设置:
location ^/abc/ {
proxy_cookie_path / "/; secure; SameSite=None";
}
Sprintboot设置:
参考:https://juejin.cn/post/6867050293595799560
更多推荐
所有评论(0)