iframe中cookie使用

# session/cookie流程

首次发起请求后,服务端返回sessionId后,之后每次请求中的cookie都会带上sessionId。

# CSRF 攻击

Cookie 往往用来存储用户的身份信息,恶意网站可以设法伪造带有正确 Cookie 的 HTTP 请求,这就是 CSRF 攻击。

举例来说,用户登陆了银行网站your-bank.com,银行服务器发来了一个 Cookie。

Set-Cookie:id=a3fWa;
1

用户后来又访问了恶意网站malicious.com,上面有一个表单。

<form action="your-bank.com/transfer" method="POST">
   ...
</form>
1
2
3

用户一旦被诱骗发送这个表单,银行网站就会收到带有正确 Cookie 的请求。为了防止这种攻击,表单一般都带有一个随机 token,告诉服务器这是真实请求。

<form action="your-bank.com/transfer" method="POST">
   <input type="hidden" name="token" value="dad3weg34">
   ...
</form>
1
2
3
4

这种第三方网站引导发出的 Cookie,就称为第三方 Cookie。它除了用于 CSRF 攻击,还可以用于用户追踪。

比如,Facebook 在第三方网站插入一张看不见的图片。

<img src="facebook.com" style="visibility:hidden;">
1

浏览器加载上面代码时,就会向 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";
1
2
3
4
5

# 配置 Apache

配置 Apache 在所有页面上发送 X-Frame-Options 响应头,需要把下面这行添加到 ‘site’ 的配置中:

Header always append X-Frame-Options SAMEORIGIN1
1

# 配置 TOMCAT

“点击劫持:X-Frame-Options未配置”;

因为项目使用的是tomcat服务器,我们不可能在每个页面去添加:

response.addHeader("x-frame-options","SAMEORIGIN");
1

因此我们使用过滤器,代码如下:

HttpServletResponse response = (HttpServletResponse) sResponse;
response.addHeader("x-frame-options","SAMEORIGIN"); 
1
2

# SameSite

# 作用

SameSite的作用是防止跨站请求伪造(CSRF)攻击和保护用户隐私;

Chrome 计划将Lax变为默认设置;SameSite的作用就是防止跨域传送cookie,从而防止 CSRF 攻击和用户追踪,此举是为了从源头屏蔽 CSRF 漏洞。

# 三个值

设置了StrictLax以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。

  • StrictStrict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。

    Set-Cookie: CookieName=CookieValue; SameSite=Strict;

    说明:这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。

  • LaxLax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。

    Set-Cookie: CookieName=CookieValue; SameSite=Lax;

    导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。详见下表。

    image-20211028164245317

  • 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 中。也许从某种方面来讲的话,展示为错误消息会更好一点。

image-20211028143850848

# 相关链接

http://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html

上次更新: 2022/04/15, 05:41:29
×