我在回答“如何防止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。
load_from_cache()
的?我不熟悉任何允许直接访问缓存的 JavaScript 机制。此外,如果在你的HEAD
请求中没有提供 ETag 或任何 cookie(或任何其他标识自己的方式),你很可能会得到一个新的 ETag,这似乎和清除缓存一样有用。 - apsillers