这项研究是与 UCOSP(本科生顶点开源项目)计划合作进行的。UCOSP 通过将加拿大本科生与行业导师联系起来,促进开源软件开发,以练习分布式开发和数据项目。
团队成员包括以下 Mozilla 员工:Martin Lopatka、David Zeber、Sarah Bird、Luke Crouch、Jason Thomas
2017 年暑期实习生 - 爬虫实现和数据收集:Ruizhi You、Louis Belleville、Calvin Luo、Zejun (Thomas) Yu
2018 年暑期实习生 - 探索性数据分析项目:Vivian Jin、Tyler Rubenuik、Kyle Kung、Alex McCallum
作为 健康互联网 的倡导者,我们 Mozilla 一直越来越关注当前以广告为中心的网络内容生态系统。基于网络的广告技术不断发展,越来越复杂地 程序化模型,用于根据个人的人口特征和兴趣进行目标定位。当前系统背后的财务基础激励着将优化放在首位,而不是其他任何东西。这反过来又让广告商对数据产生了难以满足的胃口,他们积极迭代模型以驱动人类点击。
我们在线使用的大多数内容、产品和服务,无论是媒体机构还是科技公司提供的,都全部或部分由广告和各种形式的营销提供资金。
–Timothy Libert 和 Rasmus Kleis Nielsen [链接]
我们已经讨论了对 Web 形态 的潜在不利影响,以及内容孤岛如何 阻碍观点的多样性。现在,Mozilla 系统研究小组呼吁采取行动。帮助我们寻找描述、揭示和阐明人与页面之间复杂交互的模式!
受普林斯顿大学 Steven Englehardt 和 Arvind Narayanan 最近发布的 Web 普查 的启发,我们调整了 OpenWPM 爬虫框架,以执行类似的爬取操作,收集有关各种网站上 JavaScript 执行的丰富信息。这使我们能够深入分析 Web 跟踪,以及对客户端-页面交互的一般探索,以及对现代 Web 上使用的不同 API 的调查。
简而言之,我们着手探索用户访问网页后触发的不可见或不明显的 JavaScript 执行事件序列,以及用户检索内容时启动的所有第一方和第三方事件。为了帮助进行更多探索和分析,我们提供了我们的 有关 JavaScript 执行的完整数据集 开源。
以下部分将介绍数据集、如何收集数据以及在此过程中做出的决定。我们将分享我们发现的一些见解的示例,并提供有关如何参与相关 “过度脚本化 Web:Mozilla 数据分析挑战” 的信息,我们已经与 Mozilla 的开放创新团队 于今天启动 了这项挑战。
数据集
2017 年 10 月,几位 Mozilla 员工和一群加拿大本科生 fork 了 OpenWPM 爬虫存储库,以开始进行调整,以便收集有关现代网站与 Firefox 网络浏览器之间不可见交互的大量信息。
准备种子列表
我们在准备数据集时爬取的 页面主列表 本身是从我们 2017 年 11 月进行的初步浅层爬取中生成的。我们运行了一个 深度为 1 的爬取,以 Alexa 的前 10,000 个网站列表 为种子,使用 4 台不同的机器,4 个不同的 IP 地址(所有地址都在加拿大互联网服务提供商提供的住宅非 Amazon IP 地址中)。爬虫使用 Requests Python 库实现,除了成功加载页面的指示之外,没有收集任何信息。
在 4 次并行浅层爬取的并集表示的 2,150,251 个页面中,我们选择使用 4 个列表的交集,以剔除动态生成(例如个性化)的出站链接,这些链接在它们之间有所不同。这意味着减少到 981,545 个 URL,这些 URL 形成了我们主要 OpenWPM 爬取的种子列表。
主要集合
以下工作流程描述了(在高级别上)此数据集中包含的页面信息收集。
- Alexa 前 10k(截至 2017 年 11 月 1 日的 10,000 个流量最大的页面)
- 使用 python Requests 库进行预爬取,访问每个页面
- Request 库请求该页面
- 该页面发送响应
- 捕获响应中的所有 href 标签,深度为 1(从 Alexa 页面开始)
- 对于每个 href 标签,所有有效的页面(以“http”开头)都添加到链接集中。
- 使用 Request 库并行检查链接集并集(2,150,251),这给了我们 981,545 的交集列表。
- 列表 981,545 中的 URL 集被传递到更深层的爬取中,以进行 JavaScript 分析,形式为并行化。
- 每个页面都被发送到我们改进了的 OpenWPM 版本,以记录 JavaScript 的执行情况,持续 10 秒。
window.location
被哈希为 JavaScript 执行位置的唯一标识符(以确保唯一的来源归属)。- 当 OpenWPM 遇到 iFrame 内的内容时,会报告该内容的位置。
- 由于我们使用
window.location
来确定内容的位置元素,因此每次遇到 iFrame 时,该位置都可以拆分为页面的父级位置和 iFrame 位置。 - 通过 WebSocket 执行数据收集和聚合,将所有与位置哈希链接的活动关联起来,以编译爬取数据集。
有趣的是,对于 Alexa 前 10,000 个网站,我们的深度为 1 的爬取产生了托管在 41,166 个 TLD 上的属性,跨越了我们 4 个副本的并集,而它们交集中的 981,545 个页面中只有 34,809 个唯一的 TLD 保留下来。
一个 修改版的 OpenWPM 被用来记录可能用于浏览器从这些页面跟踪数据的 JavaScript 调用。收集的 JavaScript 执行跟踪被写入 s3 存储桶,以便以后聚合和分析。根据粗略的临时分析,定义了几个额外的参数。
例如,捕获大多数 JavaScript 活动所需的每个页面的最小停留时间被设置为每页 10 秒。这是根据对种子列表 URL 的随机抽样进行的,结果显示在没有新 JavaScript 执行之前的时间存在很大差异(从没有 JavaScript 到看起来像无限循环的自引用 JavaScript 调用)。选择这个停留时间是为了在捕获大多数页面上的大多数 JavaScript 活动和最小化完成完整爬取所需的时间之间取得平衡。
在 Data Leak 存储库中构建的几个探针被移植到我们的混合爬虫中,包括用于监控发生在 iFrame 元素(可能托管在第三方域上)内部的 JavaScript 执行的探针。事实证明,这将为爬取数据中的页面之间的关系提供很多见解。
探索性工作
在 2018 年 1 月,我们开始分析我们创建的数据集。在对大量数据进行清理以处理现实世界中差异的混乱之后,我们只剩下了一个巨大的 Parquet 数据集(约 70GB),其中包含大量潜在见解。下面总结了三个示例分析。最重要的发现是,我们只是触及了这些数据可能包含的见解的表面。
检查会话重放活动
会话回放 是一种服务,允许网站跟踪用户与页面的交互——从他们如何浏览网站,到他们的搜索,再到他们提供的输入。可以把它想象成用户在网页上整个会话的“视频回放”。由于某些会话回放提供商可能会记录个人信息,例如个人地址、信用卡信息和密码,因此这会对隐私和安全构成重大风险。
我们探索了在我们的爬取数据集中的页面中会话回放使用率以及一些相关功能的发生率。为了识别潜在的会话回放,我们获得了 普林斯顿 WebTAP 项目 列表,其中包含 14 个 Alexa 排名前 10,000 的会话回放提供商,并检查了对属于该列表的脚本 URL 的请求。
在我们数据集中页面加载的 6,064,923 个不同脚本引用中,我们发现 95,570 个 (1.6%) 是针对会话回放提供商的。这转化为 4,857 个不同的域名 (netloc) 发出此类请求,占总域名 87,325 个的 5.6%。请注意,即使访问了属于会话回放提供商的脚本,也不一定意味着网站上正在使用会话回放功能。
考虑到向会话回放提供商发出请求的页面集,我们还研究了这些请求中 SSL 使用的一致性。有趣的是,大多数此类请求都是通过 HTTPS (75.7%) 发出的,而发出这些请求的页面中 49.9% 是通过 HTTPS 访问的。此外,我们发现没有通过 HTTPS 访问的页面向通过 HTTP 发出请求的会话回放脚本发出请求,这令人惊讶,但令人鼓舞。
最后,我们检查了向会话回放提供商发出请求的站点中 TLD 的分布情况,并将此与整个数据集中 TLD 的分布情况进行了比较。我们发现,除了 .com 之外,.ru 占访问此类脚本的站点的比例惊人地高 (约 33%),而 .ru 域名仅占所有爬取页面的 3%。这意味着我们数据集中 65.6% 的 .ru 网站正在向潜在的会话回放提供商脚本发出请求。但是,这可以用以下事实来解释:Yandex 是主要的会话回放提供商之一,它提供了一系列其他分析服务,这些服务对俄语网站很有吸引力。
Eval 和动态创建的函数调用
JavaScript 允许使用 eval()
函数或通过创建新的 Function()
对象从字符串动态创建函数调用。例如,此代码将打印两次 hello
eval("console.log('hello')")
var my_func = new Function("console.log('hello')")
my_func()
虽然动态函数创建有其用途,但它也会让用户容易受到注入攻击,例如 跨站点脚本,并且可能被用来隐藏恶意代码。
为了了解动态函数创建如何在 Web 上使用,我们分析了其在我们的数据集中普遍存在、位置和分布。最初对 10,000 个随机选择的页面进行了分析,并针对整个数据集进行了验证。就普遍存在而言,我们发现 3.72% 的总函数调用是动态创建的,这些调用来自我们数据集中爬取的 8.76% 的网站。
这些结果表明,虽然动态函数创建的使用率并不高,但它在 Web 上仍然很常见,可能会成为潜在问题。查看每个页面的调用频率表明,虽然一些网页动态创建所有函数调用,但大多数网页往往只有 1 或 2 个动态生成的调用 (这通常占页面执行的所有调用的 1-5%)。
我们还检查了这种做法在被调用的脚本中的程度。我们发现它们属于一个相对较小的脚本主机子集 (平均每个 URL 大约 33 个调用),表明相同的 JavaScript 文件被多个网页使用。此外,大约 40% 的这些是已知的跟踪器 (使用 disconnectme 实体列表 识别),尽管只有 33% 托管在与使用它们的网页不同的域中。这表明 Web 开发人员可能甚至不知道他们正在使用动态生成的函数。
加密劫持
加密劫持是指未经授权使用用户的计算机或移动设备来挖掘加密货币。随着加密货币的普及,越来越多的网站正在使用基于浏览器的加密劫持脚本。这是一种生成收入的简单方法,也是用广告使网站膨胀的可行替代方法。在由 Vivian Jin 编写的 完整的加密劫持分析 中,可以找到通过客户端 JavaScript 执行进行加密挖掘的出色背景介绍。
我们调查了我们数据集中表示的网站中加密劫持的普遍性。从 adblock-nocoin-list GitHub 仓库 中获得了潜在的加密劫持主机列表 (共 212 个站点)。对于在页面访问事件上发起的每个脚本调用,我们检查脚本主机是否属于该列表。在我们数据集中页面加载的 6,069,243 个不同脚本引用中,只有 945 个 (0.015%) 被识别为加密劫持主机。其中一半以上属于 CoinHive,最初的脚本开发人员。仅发现一次使用 AuthedMine。从爬取到的域的角度来看,我们发现 49 个域 (占 29,483 个不同域的 0.16%) 发出了对加密劫持脚本的调用。
但是,重要的是要注意,加密劫持代码可以通过除了在脚本标记中包含主机脚本之外的其他方式执行。它可以被伪装、偷偷地在 iframe 中执行,或者直接在第一方脚本的函数中使用。用户也可能会遇到最终导致包含挖掘脚本的页面的重定向循环。检测率低也可能是由于爬取覆盖的站点的流行程度,这可能会劝阻站点所有者实施明显的加密劫持脚本。加密劫持的实际比率可能更高。
我们发现使用加密劫持的大多数域是流媒体网站。这并不令人意外,因为用户在观看视频内容时会更长时间地打开流媒体网站,并且挖掘脚本可以执行更长时间。一个名为 52pk.com 的中国综合性网站在我们分析中发现的 945 个加密劫持脚本调用中占了 207 个,是我们观察到的用于加密劫持调用的最大域。
另一个有趣的事实:虽然我们的加密劫持主机列表包含 212 个候选者,但我们发现其中只有 11 个在我们数据集中处于活动状态,约占 5%。
局限性和未来方向
虽然这是一个丰富的数据集,可以进行许多有趣的分析,但它在可见性方面存在局限性,主要体现在通过 JS API 调用发生的的行为。
我们使用数据集调查的另一个功能是 Evercookies 的存在。Evercookies 是网站使用的一种跟踪工具,用于确保用户数据 (例如用户 ID) 永久存储在计算机上。Evercookies 通过利用一系列技巧 (包括对各种可用存储机制进行 Web API 调用) 在浏览器中持久存在。最初尝试通过搜索一致的值传递给可疑的 Web API 调用来搜索此数据中的 evercookies。
Acar 等人,“网络永远不会忘记:野生环境中的持久跟踪机制”,(2014) 开发了技术 用于大规模查看 evercookies。首先,他们提出了一种检测标识符的机制。他们将这种机制应用于 HTTP cookie,但指出它也可以应用于其他存储机制,尽管需要进行一些修改。例如,他们查看 cookie 过期时间,这在 localStorage 的情况下不适用。对于此数据集,我们可以尝试复制他们的方法,以针对 window.document.cookie
和 window.localStorage
的 set 调用。
他们还查看了 Flash cookie 重新生成 HTTP cookie 和 HTTP 重新生成 Flash cookie。我们的数据集不包含有关 Flash cookie 存在的信息,因此需要额外的爬取才能获得此信息。此外,他们使用了多次爬取来研究 Flash 重新生成,因此我们必须复制该过程。
除了我们缺乏有关 Flash cookie 的信息之外,我们还缺乏有关 HTTP cookie 的信息,这是设置 cookie 的第一种机制。了解最初设置了哪些 HTTP cookie 可以作为调查随后用于重新生成和 evercookies 的其他存储技术的补充和验证。
除了 HTTP 和 Flash 之外,Samy Kamkar 的 evercookie 库 文档了十多种用于存储用作 evercookie 的 ID 的机制。其中许多机制无法通过我们当前的数据集检测到,例如 HTTP Cookie、HSTS 固定、Flask Cookie、Silverlight 存储、ETag、Web 缓存、Internet Explorer userData 存储等。评估每种技术的流行程度将是对文献的有用贡献。我们还看到了持续重复爬取的价值,以识别流行程度的变化,并解释随着新技术的发现而出现的技术。
但是,可以继续分析当前数据集以了解 Samy 描述的一些技术。例如,window.name 缓存
被列为一种技术。我们可以查看我们数据集中此属性,也许可以通过应用 Acar 等人概述的相同 ID 技术,或者通过查看调用序列来查看。
结论
在我们对这些数据的初步探索中,很快发现网页上表面的 JavaScript 执行量只能说明故事的一部分。我们观察到了一些脚本与网页的内容服务功能并行运行的示例,这些脚本似乎执行了各种其他功能。到目前为止进行的分析已经取得了一些激动人心的发现,但更多信息仍然隐藏在大量可用的数据集中。
我们呼吁所有感兴趣的个人参与探索。欢迎您参加 Overscripted Web:Mozilla 数据分析挑战,帮助我们更好地了解现代 Web 的一些隐藏工作原理!
注意:为了能够在一个集中位置响应所有感兴趣的竞赛参与者和好奇的读者,我们已关闭此帖子的评论。我们鼓励您将相关问题和讨论带到竞赛仓库:https://github.com/mozilla/overscripted
鸣谢
特别感谢 Steven Englehardt 对 OpenWPM 工具的贡献以及在整个项目中提供的建议。我们还感谢 Havi Hoffman 对本文早期版本提供的宝贵编辑意见。最后,感谢多伦多大学的 Karen Reid 协调 UCOSP 项目。