翻译自:medium.com/compass-sec…javascript
过去十年,我教个人学生五个 cookie 属性:“path, domain, expire, HttpOnly, Secure”。可是如今咱们有了一个新属性 -SameSite。你知道新引入的 SameSite cookie 属性的细节吗?一种新的防止跨站点请求伪造(cross site request forgery)的 http 安全特性。该值能够设置为 Strict
或 Lax
。php
SameSite示例: Set-Cookie: jsessionid=oIZEL75SLnw; HttpOnly; Secure; SameSite=Stricthtml
下面会有 DEMO 演示,请确保您使用 FireFox 或 Chrome 等浏览器进行演示、比较结果。使用开发人员工具来观察网络堆栈。java
SameSite 阻止浏览器将 cookie 与跨站点请求一块儿发送。主要目标是下降跨来源信息泄露的风险。它还提供了一些针对跨站点请求伪造攻击的保护。该标志的可能值为 Lax
或 Strict
。浏览器
假设您有一个电子银行网站,而且交易表单容易出现跨站点请求伪造漏洞。假设电子银行客户(受害者)已经经过身份验证(cookie),攻击者让受害者点击 xsrf 连接,这将在建立非法交易。这种 xsrf 连接能够经过电子邮件、Twitter、Facebook、公共博客或任何其余基于超文本标记语言的系统进行传播。现代安全的电子银行解决方案可使用随机 xsrf token 来抵御这种类型的攻击。可是为了这篇文章,让咱们假设电子银行是脆弱的,而且不包含这样一个随机的xsrf令牌。安全
在 SameSite 以前,通过身份验证的受害者点击准备好的 xsrf 页面,而后进行交易。这是由于浏览器具备与电子银行的会话 cookie,所以会将会话 cookie 添加到电子银行交易请求中。可是若是浏览器不添加会话 cookie 呢?这正是 SameSite 所作的。若是连接来自外部站点,浏览器不会将cookie 添加到已经过身份验证的网站。在 SameSite=Strict
的状况下,浏览器通常不会添加 cookie。若是 SameSite=Lax
,则若是用户单击顶级网址,浏览器将发送 cookie。作下面的演示,了解 Strict
和 Lax
的区别。cookie
翻了墙也没法访问,网站已经坏掉了网络
为了 SameSite cookie 属性,我建立了一个简短的演示页面。它由两个网站组成。第一页是设置一些 cookies,第二页是从第一个站点请求一个网址。所以,您如今能够用 Firefox、Chrome 或者 Safari 测试 cookies 是否被发送到第一页。session
首先,您须要加载第一个演示页面,它设置了四个不一样的 cookies。dom
请检查 cookies 是否已在 Chrome 中设置。使用“Application”选项卡中的内置开发工具。请看下图。
Cookie MyBamBut 没有设置 SameSite 属性 (过去 10 年前的设置) Cookie MyBamButNone 设置 SameSite=None Cookie MyBamButStrict 设置 SameSite=Strict Cookie MyBamButLax 设置 SameSite=Lax
Chrome 接受了四个 cookies 中的三个。SameSite 设置为“无”的 cookie 被拒绝。
如您所见,第二页有一个顶级网址(href),并从第一页的域名加载一个 <img src>
。
使用与第 1 步和第 2 步相同的 Chrome 浏览器访问第二个演示页面。打开开发工具,点击“Network ”并从新加载页面。点击“printheaders.php”,检查哪些 cookies 是由 Chrome 发送的。分析请求标题。
正如您在上面的图片中看到的,Chrome 只是添加了没有设置 SameSite 属性的 cookie。SameSite=Strict
和 SameSite=Lax
未发送到第一个演示页面。Cool — 这就是你想要的,一个很酷的 xsrf 防护手段。
如今让咱们来看看若是你点击顶级连接,Chrome 是如何表现的。请点击第二个演示页面上的 PrintHeaders
连接,并按照步骤 3 再次分析请求头。
在下图中,您能够看到点击顶级网址时,第一个演示页面发送了哪些 Cookies。
Chrome 将 MyBamButLax 添加到第一个演示页面的 HTTP 请求中。可是 MyBamButStrict 从未被发送到第一个演示页面。所以,设置SameSite=Strict
其实是拒绝 xsrf
攻击。
原做者还漏了一种场景,在 iFrame 中使用的坑,把以下 b.com
页面当成 iFrame 嵌入 a.com
页面
<body>
<script> // 状况一:不设置 document.cookie="b-cookie=b;domain=.b.com;path=/" document.cookie="b-cookie1=b1;domain=.b.com;path=/" console.log(document.cookie); // b-cookie=b;b-cookie1=b1; // 状况二:设置 SameSite document.cookie="b-cookie=b;domain=.b.com;path=/;SameSite=lax" document.cookie="b-cookie1=b1;domain=.b.com;path=/" console.log(document.cookie); // b-cookie1=b1; </script>
</body>
复制代码