浏览器全面禁止第三方Cookie

第三方 Cookie

如果是你正常的正在逛着天猫,天猫会把你的信息写入一些 Cookie 到 .tmall.com 这个域下,然而打开控制台你会看到,并不是所有 Cookie 都是  .tmall.com 这个域下的,里面还有很多其他域下的  Cookie ,这些所有非当前域下的 Cookie 都属于第三方 Cookie,虽然你可能从来没访问过这些域,但是他们已经悄悄的通过这些第三方 Cookie来标识你的信息,然后把你的个人信息发送过去了。

而 .tmall.com 这个域下的 Cookie 都属于第一方 Cookie,那么为什么还需要第三方 Cookie 呢?再打开 taobao.com,你会发现你已经不需要再登录了,因为淘宝、天猫都属于阿里旗下的产品,阿里为他们提供统一的登录服务,同时,你的登录信息也会存到这个统一登录服务的域下,所以存到这个域下的 Cookie 就成了三方 Cookie

我们再打开已经完全禁用了第三方 Cookie 的 Safari,发现只剩下 .tmall.com 这个域下的 Cookie 了。

这时你会发现即使你已经登录了天猫,再访问淘宝也还是需要登录的,你已经无法享用这样的功能了,而三方 Cookie 可不仅仅就这么点用途,在 Web 开发中,三方 Cookie 的应用非常之广,下面我们再来具体看几个应用场景:

三方Cookie的用途

前端日志打点

大多数 Web 站点都会引用一些第三方 SDK 来进行前端异常或性能监控,这些 SDK 会通过一些接口将监控到的信息上传到他们的服务器。一般它们都需要标识每个用户来方便排查问题或者统计 UV 数据,所以当你一此请求这个站点的时候,它们可能会在你的站点上 set 一个 Cookie,后续所有的日志上报请求都会带上这个 Cookie 。

由于一般这些第三方 SDK 都是用于监控的通用服务,它们肯定会拥有自己独立的域名,比如 log.com,它在你的域名 mysite.com 下种下的 Cookie 就属于第三方 Cookie

广告营销神器 - Facebook Pixel

在电商业务中,追踪流量、导流量、转换率、销售额这些都是商家最关心的问题。这时候你就可以使用 Facebook Pixel,简单来说 Facebook Pixel 像素就是一串 JavaScript 代码,可以追踪广告的转化量、改进受众定位、使广告花费回报最大化。

当访客进入到被设有 Facebook Pixel 的页面时,便会触发这段代码。比如,查看了商品或者加入购物车, Facebook Pixel 便会向系统发送请求来记录这些行为,系统可以利用这些收到的行为信息进一步的做追踪和优化。

举一个实际例子,我们进入一个国外的电商网站 Brava Fabrics ,你会发现已经被写入了一堆 facebook.com 下的三方 cookie

我猜测这个 fr 应该就是用来标识我身份信息的 cookie,然后点击几个页面,在 network 里面找到了几个 facebook 发送的请求,下面是其中一个:

https://www.facebook.com/tr/?id=382444918612794&ev=PageView&dl=https%3A%2F%2Fbravafabrics.com%2Fcollections%2Fa-moment-of-bliss&rl=https%3A%2F%2Fbravafabrics.com%2F&if=false&ts=1586868288778&sw=1680&sh=1050&ud[ct]=eb045d78d273107348b0300c01d29b7552d622abbc6faf81b3ec55359aa9950c&ud[country]=eb045d78d273107348b0300c01d29b7552d622abbc6faf81b3ec55359aa9950c&v=2.9.15&r=stable&ec=0&o=30&fbp=fb.1.1586867082370.951509876&it=1586868284974&coo=false&rqm=GET

查看详情你会发现,有下面几个主要的参数:

dl: https://bravafabrics.com/collections/a-moment-of-bliss
rl: https://bravafabrics.com/

这时 facebook 已经知道了我从 https://bravafabrics.com/ 来到了 https://bravafabrics.com/collections/a-moment-of-bliss 这个页面,同时,这个请求会携带 fr=09wX7ui8MrvCh2SIa..BdNoGz.f.F6R.0.0.Belanb.AWXCDx 这个 Cookie

来到 facebook,当你登录后,facebook 会把刚刚这些 Cookie 和你的 facebook Id 关联起来,然后他就可以好好的分析你的行为了:

  • 有人在你的网站上完成了购买。

  • 有人注册进行试用,或者以其他方式将自己标识为你网站上的潜在客户。

  • 有人在你网站上的购买过程中输入他们的付款信息。

  • 有人将产品添加你网站上的购物车中。

  • 有人选择特定版本的产品,例如选择某种颜色。

  • 有人发起了结账,但没有付款

  • ...

而如此强大的追踪能力,只需要你复制一段 Facebook Pixel 的 JavaScript 脚本到你的页面上就可以了。而这一切能力就建立在一个小小的 Cookie 的基础上,因为有了这个 Cookie ,Facebook 才能将这些行为与它的账号体系进行关联。

无处不在的的 mmstat

再来看一个我们国内的例子,平时我们在国内的搜索引擎或视频网站上搜索到一些东西,然后打开购物网站就可以收到各种你兴趣的相关推荐,这已经是大众习以为常的事情了,各大购物网站、广告商,会通过第三方 Cookie 收集你的年龄、性别、浏览历史等从而判断你的兴趣喜好,然后带给你精准的信息推荐。

比如,我们在浏览百度、优酷、天猫等网站时,都能看到几个 .mmstat.com 这个域下的 Cookie

百度:

优酷:

天猫:

当你在百度、优酷、淘宝等进行一系列的操作时,.mmstat.com 已经悄悄的通过三方 Cookie 把你的个人信息运送到了他们那边。.mmstat.com 应该就是阿里旗下的大数据营销平台阿里妈妈旗下的域名(只是个人猜测)。打开阿里妈妈首页,可以看到,其号称是更懂消费者的数据金矿,已经建立起5亿用户的身份识别体系。你的每一次搜索、每一次购买、都会让它变的更精准,下一次你就收到更精准的推荐。

当然,三方 Cookie 只是众多获取你喜好信息的一种方式,只不过这种方式更便捷,成本更低。

浏览器的策略

最近几大浏览器针对 Cookie 策略的频繁改动,意味着三方 Cookie 被全面禁用已经不远了:

Firefox、Safari —— 默认禁用

在 Safari 13.1Firefox 79 版本中,三方 Cookie 已经被默认禁用,但是由于这些游览器市场份额较小,并没有给市场带来巨大的冲击。因为阿里的登录信息是统一存在一个三方 Cookie 下的,淘宝刚开始的处理方式,甚至是弹个框出来,告诉用户手动开启三方 Cookie :

但是这样的处理方式对于庞大的用户来讲肯定体验是极低的,解决方案可能是先将 Cookie 种在当前域下,所有就有了我们上面的测试结果,淘宝、天猫两个网站需要登录两次。

但是三方 Cookie做的事情远不止这些,等到 Chrome 全面禁用之前,一定要提前作出改变。

Chrome —— SameSite Cookie

还好由于三方 Cookie 对 Google 的广告业务影响较大,所以其没有立即进行禁用,而是一直陆续修改一些小的策略来对三方 Cookie 进行限制,比如 SameSite

SameSite 是 Chrome 51 版本为浏览器的 Cookie 新增的了一个属性, SameSite 阻止浏览器将此 Cookie 与跨站点请求一起发送。其主要目标是降低跨源信息泄漏的风险。同时也在一定程度上阻止了 CSRF 攻击。

SameSite 可以避免跨站请求发送 Cookie,有以下三个属性:

Strict

Strict 是最严格的防护,将阻止浏览器在所有跨站点浏览上下文中将 Cookie 发送到目标站点,即使在遵循常规链接时也是如此。因此这种设置可以阻止所有 CSRF 攻击。然而,它的用户友好性太差,即使是普通的 GET 请求它也不允许通过。

例如,对于一个普通的站点,这意味着如果一个已经登录的用户跟踪一个发布在公司讨论论坛或电子邮件上的网站链接,这个站点将不会收到 Cookie ,用户访问该站点还需要重新登陆。

不过,具有交易业务的网站很可能不希望从外站链接到任何交易页面,因此这种场景最适合使用 strict 标志。

Lax

对于允许用户从外部链接到达本站并使用已有会话的网站站,默认的 Lax 值在安全性和可用性之间提供了合理的平衡。Lax 属性只会在使用危险 HTTP 方法发送跨域 Cookie 的时候进行阻止,例如 POST 方式。同时,使用 JavaScript 脚本发起的请求也无法携带 Cookie

例如,一个用户在 A 站点 点击了一个 B 站点(GET请求),而假如 B 站点 使用了Samesite-cookies=Lax,那么用户可以正常登录 B 站点。相对地,如果用户在 A 站点提交了一个表单到 B站点(POST请求),那么用户的请求将被阻止,因为浏览器不允许使用 POST 方式将 Cookie 从A域发送到B域。

None

浏览器会在同站请求、跨站请求下继续发送 Cookies,不区分大小写。

策略更新

在旧版浏览器,如果 SameSite 属性没有设置,或者没有得到运行浏览器的支持,那么它的行为等同于 NoneCookies 会被包含在任何请求中——包括跨站请求。

但是,在 Chrome 80+ 版本中,SameSite 的默认属性是 SameSite=Lax。换句话说,当 Cookie 没有设置 SameSite 属性时,将会视作 SameSite 属性被设置为Lax 。如果想要指定 Cookies 在同站、跨站请求都被发送,那么需要明确指定 SameSite 为 None。具有 SameSite=None 的 Cookie 也必须标记为安全并通过 HTTPS 传送。这意味着所有使用 JavaScript 脚本收集用户信息的请求默认将不能携带三方 Cookie

然而这个改动并不会造成太大的影响,它只是给各大网站提了一个信号,因为你只需要把你想要发送的 Cookie 的属性手动设置为 none 即可:

真正可怕的是我们将无法直接指定 SameSite 为 None,只能用户自己去选择,这才是真正的默认禁用。

Chrome 也宣布,将在下个版本也就是 Chrome 83 版本,在访客模式下禁用三方 Cookie,在 2022 年全面禁用三方 Cookie,到时候,即使你能指定 SameSite 为 None 也没有意义,因为你已经无法写入第三方 Cookie 了。

使用一方 Cookie 替代 三方 Cookie

如果我们引入了一个三方的 SDK,比如 google analytics ,说明我们对其是信任的,它对我们的信息收集追踪都是在允许范围内的。所以这些 SDK 依然可以使用第一方 Cookie 来完成用户身份标识符。

比如,gtag.js 和 analytics.js 会设置以下 Cookie 用户标识用户信息:

但是,这些 Cookie 并不是第三方 Cookie,而是设在你的域下的第一方 Cookie,比如打开 twitter 的 Cookie 信息:

我们发现 _ga 、_gid 这两个 Cookie 正是设置在其自己域下面的。

如果使用正常的 Set-Cookie 的形式,google analytics 是无法直接将 Cookie 设置到 twitter.com 这个域下面的,而且 google analytics 发起的日志收集请求也无法携带 twitter.com 这个域下的 Cookie

打开 sdk 的代码我发现里面有使用 js 设置 Cookie 的代码:

并且,收集日志的请求中也又没携带任何 Cookie,而是把这信息带在了参数中:

这样的方式就模拟了使用三方 Cookie 标识用户信息的过程,并且完全可以替代它。总而言之禁用三方 Cookie 对这种三方 SDK 的影响并不大,只要稍微改变一下思维即可。

当然,由于 Safari 和 Firefox 已经全面禁用了三方 Cookie,一些广告营销服务也正在给出使用一方 Cookie 的替代方案,比如 Facebook Pixel

你允许了其读取一方 Cookie 就意味着它能获取你更多的数据,这意味着你需要承担更大的用户信息泄漏的风险。而且使用一方 Cookie 也不像使用三方 Cookie 那样灵活,在某些场景下也是有很大限制的。

浏览器指纹

三方 Cookie 的主要作用是标识你的身份,从而在你下一次访问时知道你是谁,那么如果有一种技术直接就可以获取你的唯一标识时,那么就不需要再存储 Cookie 了,这个技术就是 “浏览器指纹” 。

“浏览器指纹”是一种通过浏览器对网站可见的配置和设置信息来跟踪 Web 浏览器的方法,浏览器指纹就像我们人手上的指纹一样,每个人拥有一份接近于独一无二的配置。

如果单单拿出一个配置来讲可能很多人和你拥有一样的配置,比如下面的:

  • 系统版本:

    • 我的系统版本是 Mac OS X 10_14_6

    • 大约 11.91% 的人与我的配置相同

    • 大约每 8 个人中有一个和我配置相同

  • Chrome 版本:

    • 我使用的浏览器是 Chrome,并且版本是:81.0.4044.92

    • 大约 0.08% 的人与我的配置相同

    • 大约每 1250 个人中有一个和我配置相同

  • UTC+8 时间:

    • 我的UTC+8 时间是 2020.4.15 23:00:00

    • 大约 2.30% 的人与我的配置相同

    • 大约每 43 个人中有一个和我配置相同

如果单独看每个配置,那他们都不能作为你独一无二的特征,但是综合起来看呢?比如就看这三项,三项的配置与你都相同的人的概率就会大大减小了。以上只是一些简单的特征,比如系统版本,浏览器版本,这些只需要一个简单的 navigator.userAgent 属性就可以拿到。

像这样的属性还有非常多个,他们可能来自 HTTP HeaderJavascript attributes浏览器插件 等等

HTTP Header

上面的 HTTP Header 中就包含了大量的定制化特性,可以看到每一项配置中与我相同的概率是非常低的,然而这些信息属于普通的浏览器指纹,普通指纹可以理解为容易被发现并且容易修改的部分,而且你也可以轻易的篡改他们,有些配置比如 User-Agent 、language 使用 JavaScript 的 navigator 对象获取是最准确而且不会被篡改的。下面还有一些其他常见的 JavaScript 属性:

Javascript attributes

这里面包含一些使用 Javascript 很容易获取的一些配置:

  • Screen width:屏幕宽度

  • Screen height:屏幕高度

  • Cookies enabled:是否允许 Cookie

  • Content language:语言信息

  • List of fonts:字体信息

  • Timezone:时区信息

  • Navigator properties:Navigator 对象中包含的属性信息

  • ...

以上这些信息非常容易获取,而且带有的信息较少,最后生成出来的指纹可能碰撞的概率就越大,实际上通过 JS 能获取的远不止这些,下面还有一些重复率非常低的指标:

Canvas 指纹

Canvas 是 HTML5 中用于在网页上绘制 2D 图形元素。浏览器在绘制图形时,会调用操作系统的绘图接口,即便使用 Cavans 绘制相同的元素,但是由于系统的差别,不同浏览器使用了不同的图形处理引擎、不同的图片导出选项、不同的默认压缩级别、对抗锯齿、次像素渲染等算法也不同。

具体获取流程如下:在画布上渲染一些文字,再用 toDataURL 转换出来,你就会得到属于你的 Cavans 指纹:

    const canvas = document.getElementById("canvas-fingerprint");
    const context = canvas.getContext("2d");
    context.font = "18pt Arial";
    context.textBaseline = "top";
    context.fillText("canvas-fingerprint-test", 2, 2);
    return canvas.toDataURL("image/jpeg");

上面的图中可以看到,Canvas 指纹和我相同的概率是 <0.01% 的,可见这是一个在浏览器指纹中非常重要的指标。

WebGL

WebGL 是一种用于在网页上呈现3D图像的 JavaScript 浏览器API。网站可利用 WebGL 来识别你的设备指纹:

  • WebGL 报告 —— 完整的 WebGL 浏览器报告表是可获取、可被检测的。在一些情况下,它会被转换成为哈希值以便更快地进行分析。

  • WebGL 图像 —— 渲染和转换为哈希值的隐藏3D图像。由于最终结果取决于进行计算的硬件设备,因此此方法会为设备及其驱动程序的不同组合生成唯一值。这种方式为不同的设备组合和驱动程序生成了唯一值。

UUID 的计算

综合以上的指标特征,可以计算出一个属于你自己的唯一的 uuid,这就是你的 "浏览器指纹" 了。当然,计算时不能简单的将上述指标进行叠加,因为某些指标在一些场景下聚合度比较高,每个指标带来的信息量也不相同,一般每个指标都拥有一个自己的 "信息熵" :

信息熵(entropy)是接收的每条消息中包含的信息的平均量,熵越高,则能传输越多的信息,熵越低,则意味着传输的信息越少。

在计算 uuid 时,一般信息熵较大的指标会拥有较大的权重,这样可以大大降低碰撞率,提高 uuid 的准确性。

当然,这些也不用你自己去挨个费劲的去获取了,使用 clientjshttps://github.com/jackspirou/clientjs) 可以轻而易举的帮你获取这些指标,并最终获取 uuid

// Create a new ClientJS object
const client = new ClientJS();

// Get the client's fingerprint id
const fingerprint = client.getFingerprint();

// Print the 32bit hash id to the console
console.log(fingerprint);

你也可以单独获取这些信息:

  const client = new ClientJS();
  client.getBrowserData();
  client.getFingerprint();
  client.getCustomFingerprint(...);
  client.isCanvas();
  client.getCanvasPrint();
  client.getFlashVersion();
  client.isSilverlight();
  client.getSilverlightVersion();
  // 。。。

https://mp.weixin.qq.com/s?__biz=MzA4Nzg0MDM5Nw==&mid=2247485028&idx=2&sn=825cc4d01af35b724dd1b17d1fd40960&chksm=90320586a7458c90e2bd1470d950d99fdf37e9f2da972a4f0aa2f174c4b98ffba39dcb946479&mpshare=1&scene=23&srcid=0727W9slARPaZv2yXly2LP6p&sharer_sharetime=1595862503248&sharer_shareid=20223c38c6ff7e2635aaad8928615be2#rd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值