我们向我们欣赏的网页构建者提出了同一个问题:今年你在构建网站方面学到了什么? 以下是他们的回答

我们要感谢我们的❥赞助商 Automattic,他们使本网站成为可能。他们制作了许多我们使用的优秀软件产品,例如 JetpackWooCommerceWordPress.com

我学会了热爱同源策略

今年我花了很多工作时间尝试(与优秀的 Noam Rosenthal 合作)标准化一项新的 Web 平台功能:一种修改图像固有大小和分辨率的方法。嘿!我们做到了! 但这确实是一次学习经历

这不是我第一次参与标准化工作,因此我们遇到的许多问题我或多或少都预料到了。浏览器出现了强烈的负面反馈底层原语出现了一些奇怪的、意想不到的问题完全重新思考 或者两次。但是我没想到的是,我们的提案——再次强调,它“仅仅”是关于修改图像的默认显示大小——会违反 Web 的基本隐私和安全原则。因为在今年之前,我并不真正理解这些原则。

让我稍微铺垫一下。我们试图做什么呢?

默认情况下,网页上的图像显示的尺寸与其本身的尺寸完全相同。嵌入一个 800×600 的图像?除非使用 CSS 或标记拉伸或缩小该图像,否则它的尺寸将完全是 800 CSS 像素宽,600 CSS 像素高。这就是图像的固有(也称为“自然”)尺寸。换句话说,默认情况下,网页上的所有图像都具有 1× 的固有密度

这很好,直到你尝试提供✨可变✨密度图像,并且无法访问 CSS 或 HTML。我的雇主Cloudinary这样的图像托管商经常遇到这种情况。

因此,我们着手为我们自己和 Web 上的其他人提供一个修改图像固有大小和分辨率的工具。经过几次重新思考,我们得出的解决方案如下

  1. 浏览器应该读取并应用包含在图像资源本身中的元数据,允许它们声明自己的预期显示大小和分辨率。
  2. 效仿最近的 image-orientation——默认情况下,浏览器会尊重并应用此元数据。但是你可以使用一些 CSS(image-resolution)或标记(srcsetx 描述符)覆盖或关闭它。

我们对此感到非常满意。它很灵活,建立在现有的模式之上,并且似乎解决了之前提议中提出的所有问题。唉,HTML 规范的编辑之一,Anne van Kesteren,说:不行。这行不通。而且image-orientation 也需要紧急重新考虑。因为这种模式(可以使用 CSS 和 HTML 打开和关闭 EXIF 元数据的效果)会违反“同源策略”。

呃……什么?

我们不是仅仅缩放和旋转图像吗?

坦白地说!在所有这一切之前,我或多或少地将同源策略等同于CORS错误,以及多年来它们给我带来的所有挫折。但是现在,同源策略不仅阻碍了我处理 fetch,还阻碍了一个主要的项目工作。我不得不向那些对 Web 上的安全和隐私了解比我更少的老板解释这种情况。是时候学习了!

以下是我学到的东西

  • 同源策略不是一条单一、简单、的规则。当然也不等于 CORS 错误。
  • 它是一种随着时间推移而发展起来的理念,并且在 Web 平台上实现不一致。
  • 总的来说,它的意思是:Web 的基本安全和隐私边界是。你和 Web 上的其他东西共享同一个源吗?你可以随心所欲地与之交互。如果不是,则可能需要跳过一些障碍。
  • 为什么是“可能”?嗯,许多跨源交互默认情况下是允许的!通常,在创建网站时,你可以写入跨源(通过表单向任何你想要的人发送 POST 请求)。你甚至可以嵌入你的网站访问者将在你的网站上看到的跨源资源(iframe、图像、字体等)。但是你不能做的是,自己查看这些跨源资源。在你的 JavaScript 中,如果没有特别授予的权限(通过我们老朋友 CORS),你不应该能够读取有关跨源资源的任何信息。
  • 一旦我最终理解了这一点,最让我震惊的事情是:默认情况下禁止跨源读取,因为作为最终用户,我们每个人看到的万维网都是不同的,并且网站不应该能够通过其访问者的眼睛看到其余的 Web。个人的各种本地浏览上下文(包括但不限于 cookie)意味着,当我访问 gmail.com 时,我看到的内容与你在地址栏中输入相同的 URL 并按下“回车”时看到的内容不同。如果其他网站可以从我的浏览器(带有我的 cookie)向 Gmail 发出请求并读取结果,那么——这将非常非常糟糕!

因此,默认情况下:你可以对跨源资源执行很多操作。但是防止跨源读取才是关键。当人们谈论“同源策略”时,他们或多或少谈论的是这些默认设置。

所有这一切与图像的固有大小和分辨率有什么关系呢?

假设有一个图像 URL——https://coolbank.com/hero.jpg,它会根据用户是否当前登录 coolbank.com 返回不同的资源。假设当您登录时显示的版本有一些 EXIF 分辨率信息,而您未登录时显示的版本则没有。最后,让我们假设我是一个邪恶的网络钓鱼者,试图找出你属于哪家银行,以便我能够伪造其主页,并诱使你将你的银行登录信息输入到我的恶意表单中。

所以!我在一个恶意页面上嵌入 https://coolbank.com/hero.jpg。我检查其固有大小。我使用 image-resolution: none 关闭 EXIF 大小调整,然后再次检查其大小。现在,即使 CORS 限制阻止我查看任何图像的像素数据,我也知道它是否包含任何 EXIF 分辨率信息——我已经能够跨源读取该图像的一小部分。现在,我知道你是否登录到 coolbank.com 并拥有其账户。

牵强附会?也许吧!但是 Web 是一个难以想象的大地方。而且,正如 Jen Simmons 曾经说过的那样,

浏览 Web 基本上就是在整天运行其他人的不受信任且可能具有恶意代码,毫无顾忌。Web 安全和隐私的底层原则(包括同源策略)使这种安全性成为可能,并且必须得到绝对的维护。我们无意中试图在同源策略中打开的漏洞起初看起来很小。一些看似无害的信息位。但是,无论多小的跨源读取都是跨源读取,而跨源读取是不允许的

我们如何修复我们的规范?我们通过使 EXIF 分辨率和方向信息在跨源环境中不可读取来使其不可关闭:在跨源上下文中,始终应用 EXIF 修改。一个 EXIF 指示应将其视为 400×300 的 800×600 图像的行为将完全像一个 400×300 图像一样,无论如何。一旦我们理解了问题,这是一个非常简单的解决方案。

作为奖励,一旦我真正理解了同源策略以及 Web 默认安全策略背后的原因,其他一些 Web 安全内容也开始变得清晰起来。

跨站点请求伪造 攻击利用了默认情况下允许跨源写入这一事实。如果 API 端点在响应 POST 请求的方式上不够谨慎,则可能会发生不良事件。同样,内容安全策略允许对允许哪些类型的嵌入进行细粒度控制,因为默认情况下,所有嵌入都是允许的,事实证明,这为跨站点脚本攻击打开了大门。以及 Web 安全功能的新字母组合——COOPCOEPCORPCORB——都是关于完全关闭跨源交互,修复多年来同源策略实现方式的一些不一致之处,并关闭任何/所有可能的跨源交互,以实现称为“跨源隔离”的稀有状态。在一个幽灵及其同类意味着跨源加载可被利用执行跨源读取的世界中,需要完全的跨源隔离才能在执行各种新颖且强大的操作时保证安全。

简而言之

  • Web 上的安全和隐私实际上非常出色,当你仔细想想的时候。
  • 它们是平台的默认策略的产物,这些策略都是关于限制跨交互。

  • 默认情况下,任何人都不能做的一件事就是跨域读取数据(没有特殊权限)。
  • 禁止读取的原因是,我们每个人看到的网页都不同,攻击者不应该能够通过潜在受害者的视角来查看网页。
  • 没有如果、但是或任何例外!同源策略中的任何漏洞,无论多么微小,都是被滥用的切入点。
  • 在 2020 年,我试图在同源策略中打开一个小小的漏洞(哎呀),然后了解了上述所有内容。

祝愿 2021 年在各个方面都更加安全和可靠。