iframe中cookie使用
# session/cookie流程
首次发起请求后,服务端返回sessionId后,之后每次请求中的cookie都会带上sessionId。
# CSRF 攻击
Cookie 往往用来存储用户的身份信息,恶意网站可以设法伪造带有正确 Cookie 的 HTTP 请求,这就是 CSRF 攻击。
举例来说,用户登陆了银行网站your-bank.com
,银行服务器发来了一个 Cookie。
Set-Cookie:id=a3fWa;
用户后来又访问了恶意网站malicious.com
,上面有一个表单。
<form action="your-bank.com/transfer" method="POST">
...
</form>
2
3
用户一旦被诱骗发送这个表单,银行网站就会收到带有正确 Cookie 的请求。为了防止这种攻击,表单一般都带有一个随机 token,告诉服务器这是真实请求。
<form action="your-bank.com/transfer" method="POST">
<input type="hidden" name="token" value="dad3weg34">
...
</form>
2
3
4
这种第三方网站引导发出的 Cookie,就称为第三方 Cookie。它除了用于 CSRF 攻击,还可以用于用户追踪。
比如,Facebook 在第三方网站插入一张看不见的图片。
<img src="facebook.com" style="visibility:hidden;">
浏览器加载上面代码时,就会向 Facebook 发出带有 Cookie 的请求,从而 Facebook 就会知道你是谁,访问了什么网站。
# X-Frame-Options
X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在 , 或者 中展现的标记。网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击。
# 三个值
- DENY:表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
- SAMEORIGIN:表示该页面可以在相同域名页面的 frame 中展示。
- ALLOW-FROM uri:表示该页面可以在指定来源的 frame 中展示。
总括:如果设置为 DENY,不光在别人的网站 frame 嵌入时会无法加载,在同域名页面中同样会无法加载。另一方面,如果设置为 SAMEORIGIN,那么页面就可以在同域名页面的 frame 中嵌套。
# 服务器端配置
# 配置 nginx
配置 nginx 发送 X-Frame-Options 响应头,把下面这行添加到 ‘http’, ‘server’ 或者 ‘location’ 的配置中:
## 表示该页面可以在相同域名页面的 frame 中展示
add_header X-Frame-Options SAMEORIGIN;
## 表示该页面可以在指定来源的 frame 中展示
#add_header X-Frame-Options "ALLOW-FROM http://domain.com";
2
3
4
5
# 配置 Apache
配置 Apache 在所有页面上发送 X-Frame-Options 响应头,需要把下面这行添加到 ‘site’ 的配置中:
Header always append X-Frame-Options SAMEORIGIN1
# 配置 TOMCAT
“点击劫持:X-Frame-Options未配置”;
因为项目使用的是tomcat服务器,我们不可能在每个页面去添加:
response.addHeader("x-frame-options","SAMEORIGIN");
因此我们使用过滤器,代码如下:
HttpServletResponse response = (HttpServletResponse) sResponse;
response.addHeader("x-frame-options","SAMEORIGIN");
2
# SameSite
# 作用
SameSite
的作用是防止跨站请求伪造(CSRF)攻击和保护用户隐私;
Chrome 计划将Lax
变为默认设置;SameSite的作用就是防止跨域传送cookie,从而防止 CSRF 攻击和用户追踪,此举是为了从源头屏蔽 CSRF 漏洞。
# 三个值
设置了Strict
或Lax
以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。
Strict:
Strict
最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。Set-Cookie: CookieName=CookieValue; SameSite=Strict;
说明:这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。
Lax:
Lax
规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。Set-Cookie: CookieName=CookieValue; SameSite=Lax;
导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。详见下表。
None:这时,网站可以选择显式关闭
SameSite
属性,将其设为None
。不过,前提是必须同时设置Secure
属性(Cookie 只能通过 HTTPS 协议发送),否则无效。Set-Cookie: widget_session=abc123; SameSite=None
//设置无效Set-Cookie: widget_session=abc123; SameSite=None; Secure
//设置有效
# 方案设置
# 背景
Google 在2020年2月4号发布的 Chrome 80 版本中默认屏蔽所有第三方 Cookie,即默认为所有 Cookie 加上 SameSite=Lax 属性,并且拒绝非Secure的Cookie设为 SameSite=None;
上述问题中,在当前系统访问第三方系统时,带了一些cookie过去,然后被这个SameSite机制拦截掉了。
可能在 Chrome 80 中受到影响的场景如下;
1、组件数据基于第三方网站的登录态返回相关用户数据的API请求;
2、HTTP 本地部署
# 解决方案
# 1.chrome设置
这种方式比较简单,手动禁用浏览器的限制功能,可参考文末链接;Chrome浏览器打开新标签页,地址栏中分别输入chrome://flags/#same-site-by-default-cookies
, chrome://flags/#cookies-without-same-site-must-be-secure
将这两个配置均设置为Disabled**(此策略不推荐,可用于应急系统访问)**
# 2.使用低版本浏览器
这也是一种解决方式,但是不推荐;从Chrome 51
开始,浏览器的Cookie
新增加了一个SameSite (opens new window)属性,用来防止CSRF
攻击和用户追踪。该设置当前默认是关闭的,但在Chrome 80
之后,该功能默认已开启。使用低版本浏览器,可选择70版。
# 3.https协议+SameSite=None【推荐】
这主要依赖运维和后端处理了,但是这种方式在以后新版浏览器中可能会失效,因为过两年浏览器将全面禁止三方cookie,到时候怎么设置都不起作用了;
设置response.setHeader(“Set-Cookie”, “HttpOnly;Secure;SameSite=None”),需设置https证书;
由于设置SameSite = None
,有SCRF
风险,所以,最佳方案是用token
代替Cookie
方式作验证。
# 4.token实现【推荐】
不使用cookie共享会话,使用token实现;
# 查看设置结果
在 Firefox 尝试加载 frame 的内容时,如果 X-Frame-Options 响应头设置为禁止访问了,那么 Firefox 会用 about:blank 展现到 frame 中。也许从某种方面来讲的话,展示为错误消息会更好一点。
# 相关链接
http://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html