两年前,我有分享过一篇同源政策的文章,讨论两种同源政策对于网站安全的影响,今年以来,由于SameSite设置的推出,对于Cookie是否会送出的「预设条款」 ”出现变化,对许多网页应用程序制作产生影响,也对网络广告制作业产生冲击,
本篇文章将首先以同源政策说明 Cookie 的送出条款,再分享 SameSite 的设置,也会介绍几种情况:iframe 与表单的使用下,SameSite 设置对 Cookie 的影响。许多人经常忽略策略其实际SameSite设置不仅对 Cookie 送出有影响,对其写入也会有影响,另外,也谈到 iOS Safari 实际工作得不一样,最后补充充分开发时要注意的信息安全事项。
本篇文章包含
✔ Cookie 同源政策是什么?
注意事项
▍Cookie 的同源政策是什么?
上图所画的Scheme、Domain、Path,是判定Cookie是否跟随使用者连上的网站同源的判定要件(打钩图显示),端口并不在判定之列(打叉图显示) 。
根据 Cookie 的同源策略( Cookie Same Origin Policy ),只要连接上的网站其域名跟路径与 Cookie 一致,就会被视为同源。访问该网站时,Cookie 就会被送出,而 Scheme 的部分分,则要看Cookie是否有加入安全这个属性,若有加入上安全,便会判定是否是Https才会送出。详情可以参考我下面这篇文章。
同源政策同源政策!切安全的基础
作家任职于雅虎,粉丝团:《程式猴吃香草🍌》 | 线上课程:《经典猎客攻击教程:给每个人的网站安全入门》
medium.com
然而在SameSite 设置被现代浏览器广普采用之后,Cookie 送出的条款便多了要判断SameSite 的部分了。
▍SameSite 设置一次看懂
SameSite主要是针对Cookie 的一种安全机制,限制制作Cookie 只在第一情况下使用(即禁止停止第三方情况下的使用),实际上是将SameSite 确定权利放于在Http Response Header中, 属于Set-Cookie的一个属性。( MDN SameSite )
SameSite 属性限制制作了 Cookie 送出的情况,详细的 SameSite 规范,可以参考RFC6265bis,本文件介绍三种 SameSite 设置的常见的写法,了解以后可以适用于大部分情况:
➊ SameSite=严格
SameSite=Strict 会将 Cookie 限制在『第一方』的情况下使用,举例来说,当你浏览 facebook.com 时,此时 facebook.com 被视为『第一方』,当你登录脸图书网当在你的浏览器中存入『登录使用的 Cookie』 ,并限制为 『SameSite=Strict』 ,此时这个 Cookie 被视为第一方 Cookie ,因此您在浏览其他 facebook.com页面时,都被视为在『第一方』的情况下使用,所以Cookie会被带上,在您浏览时Cookie会被传送到facebook.com,保持登录状态。
但是,在你浏览部落格 medium.com 时,此时 medium.com 被视为第一方,先在 facebook.com 存入的 Cookie ,此时被视为『第三方』了,当你从 medium 点选facebook 连接连接到facebook 时,此时被视为『第三方』的facebook.com Cookie 不会被送出,您连接到facebook 需要重新登录。
➋ SameSite=松散
相对于 SameSite=Strict 的完全禁止『第三方』Cookie 使用情况,SameSite=Lax 允许部分分 HTML 标签情况下发送第三方 Cookie 。但允许的范围围先前只有 Cookie 同源政策时又有一些不同。
下表比『Lax』与『以前』(只有同源政策时),面对跨来源请求(Cross Request)时,送出Cookie的差异,可以一目了然,以绿色勾的图形显示可以发送:
➌ 相同站点=无;安全的
SameSite=None 相对于 Lax 又开放了更多第三方 Cookie 的使用情况,例如:iframe、AJAX、Image 。但是以 Chrome 浏览器的规定,此项设置必须配置上 Secure,限制在 Https 下载才可以产生效果。
在了解了 SameSite 属性的定义之后,我们来看看在几种情况下的设置。
▍SameSite 常见情况与注意事项
以下将探讨几种设定的情况与注意事项:
➊ iframe
iframe是常见的应用程序方式,例如:Facebook应用程序或者是Shopify App应用程序,都需要串接平台的SDK,让应用程序在iframe底部运行。
在这个实验里,我想强烈说明的是:
大多数人会把 SameSite 的设置重在『Cookie 的发送』,但实际上 SameSite 的设置也会影响到『Cookie 的写入』
而这个部分是其他文章比较没有探讨到,但是会构建应用程序出错的地方,在iframe底部,不管是在服务器端还是客户端的写入,都会跟踪SameSite Cookie 的设置有关系。为了测试,我准备了一个页面,将分别在服务器端与客户端端写入Cookies 。
(1) 从客户端端写入 Cookie 采集预设,并看 Cookie 是否送出
以下为范例程序代码(使用React),在客户端当页面挂载后,使用JavaScript写入Cookie hello_from_client
:
实践结果为,在 iframe 底部,预先设置 Chrome 会将 Cookie 视为 SameSite=Lax ,并且无法通过 JavaScript写入第三方 Cookies 。
(2) 从客户端端写入 Cookie 不使用 SameSite=None, Secure,并看 Cookie 是否送出
以下为范例程序代码(使用React),在客户端当页面挂载后,使用JavaScript写入Cookie hello_from_client
:
如下图所示,在 iframe 底部,将 Cookie 设置为 SameSite=Noe, Secure ,便可以通过 JavaScript 写入第三方 Cookies,并且可以正常传送到第三方。
(3) 从服务器端写入 Cookie 使用 SameSite=Lax,并看 Cookie 是否送出
以下为示例程序代码(使用Express.js),在页面加载时,写入Cookie hello_from_server
:
这个实验是想看说,虽然已经知道 SameSite=Lax 的 Cookie 无法在 iframe 中被发送出去,但是是否可以从服务器端写入呢?
经过实验结果,在iframe底部,从服务器端也无法使用 SameSite=Lax 的 Cookie 写入,这个点许多个使用iframe应用程序方式的网页要特别注意,若没有特殊设置,从服务器端也无法写入Cookie,而不是只有不能在客户端被送出的限制。
(4) 从服务器端写入 Cookie 使用 SameSite=None, Secure,并看 Cookie 是否送出
以下为示例程序代码(使用Express.js),在页面加载时,写入Cookie hello_from_server
:
如下图所示,在 iframe 底部,将 Cookie 设置为 SameSite=Noe, Secure ,便可以透过服务器端写入了,并且可以正常传送到第三方。
从以上的实验我们可以知道,设置 SameSite 除了控制 Cookie 的发送,也会影响 Cookie 的写入,启动时需要注意。
➋ 形式
另一种经常看到的情况是表单,很多人认为是 SameSite Cookie 之后,就可以不用担心 CSRF (Cross-Site Request Forgery) 了,但其实还是有风险的。
这里我想强调的是一个资讯安全风险,而且经常被大家忽悠的是:
预先设置的 SameSite=Lax 是允许 Form 做 GET 时,送出 Cookie 的
因此,若是你的API采用GET做一些会『更改状态』的操作,例如:删除文章或更改帐户等。那么你还有可能将你的应用程序设置于危险之中,遭遇到CSRF攻击。
➌ iOS Safari
许多手机版应用程序会在iphone 或ipad 上面执行,由于Apple 对隐私权的重看,Safari 对于Cookie 的传递更为严格,而不依照RFC 对于SameSite 的格式实现,甚至有出现 SameSite Cookie设定为无却仍然无法在第三方情况下使用的情况,这个点也是开发时需要注意的部分。
以下附上两个讨论链接以供参考:
▍结论
从以上文章中可以了解:
- 经验,SameSite的设置不仅影响Cookie的送出,也会影响Cookie的写入,不管是从客户端写入,还是从服务器端写入。
- SameSite=Lax 还有浅在风险,如果你对应用程序的 API 没有正确实施,还有可能生成 Cookie 被送出,遭到 CSRF 攻击。
- iphone 或者 ipad 的 Safari 上面对 Cookie 的传递更严格,有些并不依照 RFC 对 SameSite 的规范实现,要特别注意。