Open Bug 1696632 Opened 4 years ago Updated 2 years ago

User tracking (privacy violation) via cached HTTP 301 permanent redirects

Categories

(Core :: Networking: HTTP, defect, P3)

Firefox 86
defect

Tracking

()

UNCONFIRMED

People

(Reporter: regis44, Unassigned, NeedInfo)

References

Details

(Keywords: privacy, Whiteboard: [necko-triaged])

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36

Steps to reproduce:

It is possible to track users via a revived 'EverCookie' equivalent.
Note: Removing cookies does not help... users still can be identified.

I have set up a POC for this: http://0x41.link/

Actual results:

Users can be still tracked even thought the cookies have been removed.

Expected results:

User tracking should not be possible in this way, since it has an impact on users' privacy. Chrome Canary seems to handle this properly.

Group: firefox-core-security → network-core-security
Component: Untriaged → Networking: HTTP
Product: Firefox → Core
Summary: User tracking (privacy violation) via a revived 'EverCookie' equivalent → User tracking (privacy violation) via cached HTTP 301 permanent redirects

Could you submit some more detailed steps to reproduce?
If I clear the cache either via Ctrl-Shift-Delete or in History via Forget this site - the code refreshes.

Flags: needinfo?(regis44)

I guess this removes all the cache.
Please try with "Firefox developer tools"-> Storage and remove the "cookieTracker" cookie from there.

Flags: needinfo?(regis44)

(In reply to Valentin Gosu [:valentin] (he/him) from comment #1)

Could you submit some more detailed steps to reproduce?
If I clear the cache either via Ctrl-Shift-Delete or in History via Forget this site - the code refreshes.

I tried Forget this site as well as "Clear site data" in the Security section of the Page Info dialog, and both times the code persisted after a shift-reload. BUT I can't reproduce if devtools is open! If I open devtools and clear cookies in any of the ways discussed in this bug, the code refreshes.

(In reply to Nihanth Subramanya [:nhnt11] from comment #3)

(In reply to Valentin Gosu [:valentin] (he/him) from comment #1)

Could you submit some more detailed steps to reproduce?
If I clear the cache either via Ctrl-Shift-Delete or in History via Forget this site - the code refreshes.

I tried Forget this site as well as "Clear site data" in the Security section of the Page Info dialog, and both times the code persisted after a shift-reload. BUT I can't reproduce if devtools is open! If I open devtools and clear cookies in any of the ways discussed in this bug, the code refreshes.

I tried this on current Nightly on MacOS btw.

Aha. I can reproduce with devtools open, if "Disable cache" is NOT selected in the network panel.

In general, the POC goes like this:
The steps in the POC are the following:

  1. User visits e.g. http://0x41.link/.
  2. Gets redirected via JS to http://0x41.link/track/ if cookie is missing.
  3. /track/ is a 301 to /redirect/UNIQUE_ID which gets cached by browser.
  4. /redirect/UNIQUE_ID sets a cookie with the UNIQUE_ID
  5. When user visits /track/ again with clear cookies cached 301 redirect (/track/ to /redirect/UNIQUE_ID ) is being used that allows user identification

I'm not sure how bad this really is.
It seems like some people are actually counting on this behaviour.

Anne, does the fetch spec say anything about this? What do you think we should do?

Flags: needinfo?(annevk)

The stackoverlow link refers to how the cookies are being set during an HTTP redirect and that's actually fine., but the way how a 301 response is being cached and can be used to track users is a bit of a problem.

(In reply to Piotrek from comment #8)

The stackoverlow link refers to how the cookies are being set during an HTTP redirect and that's actually fine., but the way how a 301 response is being cached and can be used to track users is a bit of a problem.

I agree with your reading. This is more of me thinking about our options here.

  • Not caching redirects has performance implications.
  • Not setting cookies from (cached) redirects has web-compatibility implications.
  • I guess we could not cache redirects that also set a cookie - or enforce an quick expiration. But it would be nice if the behaviour was specified in a WHATWG document for web-compat reasons.

A solution could be also:
prevent cookies from being accepted/set by the browser for all responses from requests that were previously cached - but that would only be effective in case there weren't also any cookies sent with requests that were taken from the cache. Otherwise, it would be still possible to bind the 'UNIQUE_ID' tracking ID from GET param with an arbitrary cookie:

  • not accepting cookies issued by the web app that originate from cached responses (e.g. 301/302 redirects)
  • prevent sending any cookies that could be bound with the UNIQUE_ID tracking id (that was taken from the cache).

< I guess we could not cache redirects that also set a cookie - or enforce an quick expiration. But it would be nice if the behaviour was specified in a WHATWG document for web-compat reasons.

I was also thinking about preventing this, but then... it would be stil possible to return an HTTP 200 and set a cookie there and then redirect via JS.

What UI enables step 5 in comment 6? We shouldn't allow clearing cookies without also clearing other storage/caches.

Flags: needinfo?(annevk)

(In reply to Anne (:annevk) from comment #11)

What UI enables step 5 in comment 6? We shouldn't allow clearing cookies without also clearing other storage/caches.

I think that's done in the devtools > Storage, which allows you to delete individual cookies.
It's not something I expect most users would ever use. The other ways of clearing history/cookies/storage seem to work fine.
Note: the devtools also has a Right Click > Delete All from domain option.

If you can only get here through DevTools I would argue this is INVALID. There are many things that DevTools enable you to do that are insecure or bad for privacy, but useful when debugging a problem. (I'll reiterate here that I think it makes some sense to make DevTools harder to access in release, but that's still controversial.)

@Anne It seems that apart from DevTools it possible to get here when user unselects "Local Cache" (Ctrl + Shift + Delete ) or removes only "Cookies".

Piotr, how did you get there?

Looking around I see three problematic pieces of UI:

  • about:preferences, Clear Site Data; this distinguishes between "Cookies and Site Data", and "Cached Web Content". Now that we partition Cached Web Content we should no longer make that distinction, though reportedly the operation to selectively remove cache entries could still be expensive as we don't actually organize files by partition.
  • about:preferences, Clear History...; this distinguishes between "Cookies", "Cache", and "Offline Website Data"(!), and doesn't mention Site Data at all.
  • Presumably, address bar lock icon, "Clear Cookies and Site Data"; I'm expecting this to not include the cache because in about:preferences it doesn't either.

I guess cleaning this up didn't make the initial partitioning release.

Steven: not sure if this issue needs to remain hidden, but it's more of a privacy issue than a Networking "security bug" so I'll leave that to you.

Group: network-core-security → mozilla-employee-confidential
Flags: needinfo?(senglehardt)
Keywords: privacy
Flags: needinfo?(valentin.gosu)

(In reply to Daniel Veditz [:dveditz] from comment #16)

Steven: not sure if this issue needs to remain hidden, but it's more of a privacy issue than a Networking "security bug" so I'll leave that to you.

The POC is currently down, so I'd like to see that before we open this up. I'm not sure I fully understand the attack and would like to understand if this has implications for partitioning beyond just needing to make sure our data management UIs do something reasonable. Piotr: Can I ask you to bring the POC back up, or share the source?

(In reply to Anne (:annevk) from comment #15)

Looking around I see three problematic pieces of UI:

  • about:preferences, Clear Site Data; this distinguishes between "Cookies and Site Data", and "Cached Web Content". Now that we partition Cached Web Content we should no longer make that distinction, though reportedly the operation to selectively remove cache entries could still be expensive as we don't actually organize files by partition.
  • about:preferences, Clear History...; this distinguishes between "Cookies", "Cache", and "Offline Website Data"(!), and doesn't mention Site Data at all.
  • Presumably, address bar lock icon, "Clear Cookies and Site Data"; I'm expecting this to not include the cache because in about:preferences it doesn't either.

I guess cleaning this up didn't make the initial partitioning release.

No it didn't. And while we're planning to do some cleanup, addressing this inconsistency isn't currently on anybody's TODO.

Flags: needinfo?(senglehardt) → needinfo?(regis44)

(In reply to Steven Englehardt [:englehardt] from comment #17)

(In reply to Daniel Veditz [:dveditz] from comment #16)

Steven: not sure if this issue needs to remain hidden, but it's more of a privacy issue than a Networking "security bug" so I'll leave that to you.

The POC is currently down, so I'd like to see that before we open this up. I'm not sure I fully understand the attack and would like to understand if this has implications for partitioning beyond just needing to make sure our data management UIs do something reasonable. Piotr: Can I ask you to bring the POC back up, or share the source?

(In reply to Anne (:annevk) from comment #15)

Looking around I see three problematic pieces of UI:

  • about:preferences, Clear Site Data; this distinguishes between "Cookies and Site Data", and "Cached Web Content". Now that we partition Cached Web Content we should no longer make that distinction, though reportedly the operation to selectively remove cache entries could still be expensive as we don't actually organize files by partition.
  • about:preferences, Clear History...; this distinguishes between "Cookies", "Cache", and "Offline Website Data"(!), and doesn't mention Site Data at all.
  • Presumably, address bar lock icon, "Clear Cookies and Site Data"; I'm expecting this to not include the cache because in about:preferences it doesn't either.

I guess cleaning this up didn't make the initial partitioning release.

No it didn't. And while we're planning to do some cleanup, addressing this inconsistency isn't currently on anybody's TODO.

Sure, no problem. I moved it here: https://evercookie.0x41.link/

Flags: needinfo?(regis44)

Yes, the Data Sanitization UI has a lot of known shortcomings that I've repeatedly tried to get prioritized over the years. However, within our traditional framework of thought we have not considered bad/confusing UI a security risk (I guess I'm open to have a discussion on whether that is appropriate).

Presumably, address bar lock icon, "Clear Cookies and Site Data"; I'm expecting this to not include the cache because in about:preferences it doesn't either.

It does clear caches:

https://searchfox.org/mozilla-central/rev/4e87b5392eafe1f1d49017e76f7317b06ec0b1d8/browser/modules/SiteDataManager.jsm#493

the same way that the site data manager will also clear caches. The distinction in the "Clear Site Data" menu in about:preferences was mostly added because we found that there are users who are looking to specifically clear their cache, nothing else, to either fix issues or free up disk space. This is a tricky problem to solve, I guess the best thing to do would be to allow clearing only cache but not only site data.

To verify that this cache is indeed partitioned I created a test page that frames the POC (note if you're testing in Nightly, you must have sameSite lax by default disabled since the test page doesn't set samesite=None):

You'll see two different IDs under each top-level eTLD+1 when partitioning is enabled (which is great). As expected, clearing site data for either of these top-level origins does not clear the embedded frame's cache (either via "Clear cookies and Site Data" in the identity panel or "Manage Data" in about:preferences#privacy). That will be addressed by Bug 1646215.

When the POC site is visited directly there's a lot of strangeness in our UI:

  1. Clicking "Clear Cookies and Site Data..." in the identity panel on the POC index page does not clear the ID. Why? I suspect because the POC is hosted on evercookie.0x41.link and thus that's the key the UI uses to clear data with. The cached redirect is on tracker.0x41.link, so it isn't cleared. We could have "Clear Cookies and Site Data..." clear the entire eTLD+1 (e.g., 0x41.link). Note that if this button is clicked when the user is on the base domain (i.e., currently visiting 0x41.link) then all subdomains are cleared (see Bug 1646215 Comment 7 as an example), so there's precedence for this. At the very least we should always clear by eTLD+1 when partitioning is active.
  2. Given (1), you'd expect that clicking "Manage Data..." in about:preferences#privacy and clearing evercookie.0x41.link would also leave the cached redirect from tracker.0x41.link around. But in this case it's cleared, and thus the ID is reset. Perhaps this "Manage Cookies and Site Data" UI is wired to always clear cache for the base domain?
  3. The domain tracker.0x41.link is never displayed in the "Manage Cookies and Site Data" UI, presumably because we don't display origins that just have cached data stored. So if no cookie is set there's no way to clear only the data for this origin.
  4. Going into Menu --> History --> "Show all History" and right clicking a history item from https://evercookie.0x41.link and clicking "Forget about this site" likewise does not clear the ID, presumably because we key by origin for this operation. Again, this should likely be eTLD+1 for partitioned storage.

So my takeaways are:

  • When partitioning is active: ensure our various UIs clear data by top-level eTLD+1, rather than origin. And ensure that data partitioned underneath these sites are also cleared (as we're planning to do in Bug 1646215).
  • When partitioning is not active: also consider clearing data by top-level eTLD+1 rather than origin (maybe we get this for free with the partitioning work), and consider having an origin/site show up on the Cookies and Site Data Management UI if any type of data is stored underneath that origin.

Note that changing the data management UIs to work on eTLD+1 doesn't remove the concern; the cached redirect could just as easily be cross-site. Ultimately partitioning and a more generic version of redirect tracking prevention are needed to fully mitigate the risk. Given this, this falls into a class of tracking issues that are already public, so I feel comfortable removing the sec label on this.

Group: mozilla-employee-confidential
Depends on: 1646215
No longer blocks: dfpi-mvp-ui

Me to check if this is fixed or not.

Flags: needinfo?(valentin.gosu)
Flags: needinfo?(valentin.gosu)
Severity: -- → S4
Priority: -- → P3
Whiteboard: [necko-triaged]
You need to log in before you can comment on or make changes to this bug.