观察浏览器加载外部资源(例如图像)所需的时间可能会泄露有关这些资源之前是否曾被访问过的信息。
解释:
例如,通过在第三方网站中嵌入 StackOverflow 徽标<image src="https://cdn.sstatic.net/Sites/security/img/sprites.svg?v=a1e0cd003b7d">
并观察其加载速度,该第三方可以推断访问者最近是否访问过 StackOverflow。
这是因为与尚未在浏览器缓存中且需要通过 Internet 传输的资源相比,缓存资源的加载时间要短得多。
可以通过多种方法观察加载时间。其中之一是附加一个 DOMonload
事件处理程序并测量从请求源到load
事件触发的持续时间。
这种方法有一些需要注意的缺陷:
- HTTP 响应标头可能会阻止或限制缓存
- 初始 DNS 解析可能需要一些额外的时间
- 资源 URL 可能包含一些变量标记
例子:
但是,它通常工作得很好。以下 Chrome 代码片段允许验证用户是否以及何时访问了 pornhub.com [NSFW]:
function cached(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = (event) => resolve(src);
img.onerror = (event) => reject(src);
img.src = src;
setTimeout(() => img.src = '', 10);
});
}
cached('https://bi.phncdn.com/www-static/images/pornhub_logo_straight.png?cache=2018011910').then(
src => console.log('visited between 24.01 and 28.01'),
src => console.log('not visited')
);
现在,上面的代码片段不健壮且不完整。通过添加更多资源 URL 以及目标网站请求这些 URL 的日期范围,可以创建一个非常详细的配置文件。当然,这是一个比较极端的例子来说明这一点。
问题:
- 通过浏览器缓存推断信息是一个已知问题,那么是否有可供用户或 Web 应用程序开发人员使用的对策来防御它?这个问题通常是如何解决的?
- 这种信息披露是否存在现实生活中的漏洞?