这会保护我免受Etag跟踪吗?

7
背景:ETag跟踪在这里有很好的解释,也在维基百科上提到过。
我在回答“如何防止ETag跟踪?”时写了一个答案,这促使我写下这个问题。
我有一个浏览器端的解决方案,可以防止ETag跟踪。它不需要修改当前的HTTP协议。这是一个可行的ETag跟踪解决方案吗?
我们不是把自己的ETag告诉服务器,而是询问服务器的ETag,然后将其与我们已有的ETag进行比较。
伪代码:
If (file_not_in_cache)
{
    page=http_get_request();     
    page.display();
    page.put_in_cache();
}
else
{
    page=load_from_cache();
    client_etag=page.extract_etag();
    server_etag=http_HEAD_request().extract_etag();

    //Instead of saying "my etag is xyz",
    //the client says: "what is YOUR etag, server?"

    if (server_etag==client_etag)
    {
        page.display();
    }
    else
    {
        page.remove_from_cache();
        page=http_get_request();     
        page.display();
        page.put_in_cache();
    }
}

我的解决方案的HTTP对话示例:

客户端:

HEAD /posts/46328
host: security.stackexchange.com

服务器:

HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
ETag: "EVIl_UNIQUE_TRACKING_ETAG"
Content-Type: text/html
Content-Length: 131

案例1,客户端具有相同的ETag:
Connection closes, client loads page from cache.

案例2,客户端ETag不匹配:
GET...... //and a normal http conversation begins.

需要修改HTTP规范的一些额外内容

以下内容可以视作理论材料,HTTP规范可能不会很快改变。

1. 减少HEAD开销

值得注意的是,存在轻微的开销,服务器必须两次发送HTTP头:一次响应HEAD请求,一次响应GET请求。一种理论解决方案是修改HTTP协议并添加一个新方法来请求无头内容,然后客户端仅请求HEAD,如果ETags不匹配,则请求内容。

2. 防止基于缓存的跟踪(或至少使其更加困难)

虽然Sneftel提出的解决方案不是ETag跟踪技术,但它确实在人们使用我提出的“HEAD,GET”序列时进行跟踪。解决方法是限制ETags的可能值:ETag必须是内容的校验和。客户端检查此值,如果校验和与服务器发送的值不匹配,则不使用缓存。

附注:修复第二个问题还将消除以下Evercookie跟踪技术:pngData、etagData、cacheData。结合Chrome的“仅保留本地数据,直到我关闭浏览器”功能,可以消除所有evercookie跟踪技术,除了Flash和Silverlight cookies。


既然您在StackOverflow上发布了这个问题,那么您实际上想要解决的编程问题是什么?这似乎是一个请求评论和意见的问题,而不是SO的用途,很可能会因“寻求意见”原因而被关闭。 - Mike 'Pomax' Kamermans
我正在尝试通过修改浏览器请求页面的方式来防止etag跟踪。这是一个编程问题,因为实现它涉及修改浏览器的工作方式而不是HTTP协议。我不是在寻求意见,而是在寻找客观上的反对意见,并寻找可能阻止其正常工作的缺陷。然而,这与安全和网络密切相关,我同意这可能更适合在不同的网站上讨论。我只能等待SO团队的决定。 - Hello World
我已从问题中省略了“意见”一词。 - Hello World
你是如何实现 load_from_cache() 的?我不熟悉任何允许直接访问缓存的 JavaScript 机制。此外,如果在你的 HEAD 请求中没有提供 ETag 或任何 cookie(或任何其他标识自己的方式),你很可能会得到一个新的 ETag,这似乎和清除缓存一样有用。 - apsillers
请注意这只是伪代码,我还没有实现load_from_cache。这个想法是修改浏览器的源代码,与Javascript无关。关于您的第二个参数:除非内容改变,否则不应该获得新的Etag,而不管您的HEAD请求看起来像什么。如果您每次请求都获得一个新的Etag,那么服务器正在做一些不好的事情,不使用缓存对于那个具体的请求是安全的做法。这比清除缓存更有用,因为它相当于仅清除Etag跟踪服务器的缓存。 - Hello World
最好的解决方案是在浏览器的私人模式下完全禁用etag缓存(目前您可以在正常模式下设置etag并在用户开始私人模式后识别用户)。我看不到任何可避免此类跟踪的解决方法 - 只有跟踪实现会有所不同。 - Manuel Arwed Schmidt
3个回答

5

这听起来很合理,但是有一些变通方法。假设主页总是使用相同的etag(以便返回访问者可以从缓存中加载),但页面本身每次加载时引用了一个与前面不同的图片。您对此图片的GET或HEAD请求将唯一地标识您。尽管这不算是基于etag的攻击,但它仍然利用了您的缓存来识别您。


太棒了!我想我也找到了一个对策。我会修改我的问题来考虑这个。 - Hello World
问题已更新。假设HTTP协议更改已应用,人们是否会对缓存跟踪免疫?我坚信是的。 - Hello World
几个问题:(1)mtime有时被用作etag;这将防止正确缓存,因为它无法得到适当的验证。(2)MD5有时用于etag;这容易受到碰撞攻击的影响。 - Sneftel
(1)我在“2. 防止缓存跟踪”中提出的是标准化Etag应该是什么。 (2)我不明白这与碰撞攻击有什么关系,您能进一步解释吗? - Hello World
1
(2) 碰撞攻击的存在意味着主机可以向您提供许多不同的页面,所有这些页面都具有相同的哈希值。这会使您相信使用缓存的(但仅适用于您)页面来请求链接的资源。 - Sneftel
显示剩余3条评论

3
只要使用任何缓存,即使有HTTP更改,都存在潜在的漏洞。假设主页面包括100个图像,每个图像从2个潜在的图像池中随机抽取一个。
当用户返回该网站时,她的浏览器重新加载页面(因为校验和不匹配)。平均而言,这100张图片中会有25张是以前缓存过的。这种组合几乎肯定可以被用来进行个人指纹识别。
有趣的是,这几乎完全就是DNA亲子鉴定的工作原理。

谢谢,这非常有启发性。然而,它是关于利用缓存而不是直接利用ETag的。我的解决方案(没有HTTP更改)仍然可以对抗纯ETag攻击。您已经证明了缓存跟踪确实更难停止,即使进行了HTTP更改。我将发布一个关于基于缓存的跟踪的单独问题。 - Hello World
非常不关键,只是好奇:你是如何得出数字25的? - Hello World
抱歉,应该是50。25是我之前考虑的一个想法,其中每对中的一个项目是每次加载时随机生成的。 - Sneftel
这种特定的技术在当前形式下会失败。平均而言:第一次访问后会请求50张图片,第二次访问后会请求25张图片,等等。经过几次访问后,浏览器几乎肯定不会请求任何图片,跟踪将丢失。尽管您的观点仍然有效,我看到了问题。 - Hello World
为了最大限度地提高实用性,应使用多组图像,并设置循环缓存过期日期。这将确保在合理的重访频率范围内,至少有一组图像能够提供有效的指纹识别。 - Sneftel

0

服务器可以检测到你对某些资源进行了 HEAD 请求,但没有跟随相同资源的 GET 请求。这就像在玩扑克牌时的提示。

只要有一些资源被缓存,你就会存储信息。每当你不重新请求页面上命名的资源时,服务器都可以推断出这些信息。

以这种方式保护你的隐私需要付出代价,即每次访问都必须下载页面上的所有资源。如果你曾经缓存过任何内容,那么服务器可以从你对其发出的请求中推断出相关信息。

特别是在移动设备上,带宽更昂贵且速度通常较慢,每次访问都下载所有页面资源可能是不切实际的。我认为在某种程度上,你必须接受与网站互动中可能被检测和分析的模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接