navigation-timing icon indicating copy to clipboard operation
navigation-timing copied to clipboard

Using navigationStart as a baseline may expose cross-origin timing information

Open noamr opened this issue 2 years ago • 69 comments

When we have a navigation with cross-origin redirects, we're hiding redirectStart and redirectEnd from the final document.

However, because the timeOrigin for all the navigation timing entries is the navigation start, the redirect timing info can (somewhat) easily be inferred.

Consider the following:

  • User clicks a link to domain A at timestamp ts1 (e.g. a search engine click handler URL or an ad broker like outbrain)
  • Domain A takes a while to handle the request
  • The request redirects to domain B at timestamp ts2
  • Domain B handles the request and serves the document
  • ts1 is available to the document, directly or indirectly, as it's the navigationStart which is the base timestamp for all navigation timing / resource timing entries (as well as the timeOrigin).

I believe we have three ways to go about it (but maybe there are more):

  • Enable all the navigation timing properties, based on the notion that the cross-origin information is already exposed by navigationStart.
  • Change navigationStart to be the timestamp of the first redirect in the current origin redirect chain
  • Make use of TAO (in its current form or with some amendments) to give redirect chains the opportunity to expose their timing to the destination.

This came from discussing whether to enable or zero-out navigation timing properties. See previous discussions here, here and here.

Thoughts?`

noamr avatar Sep 30 '21 07:09 noamr

@yoavweiss @annevk @npm1 @sefeng211 @achristensen07

noamr avatar Sep 30 '21 07:09 noamr

Also @bdekoz @mikewest @arturjanc

yoavweiss avatar Sep 30 '21 07:09 yoavweiss

If "current origin redirect chain" means the origin boundary is not crossed therein, that option seems reasonable to me. The current model does indeed seem problematic.

https://github.com/w3c/resource-timing/issues/220 is also related.

annevk avatar Sep 30 '21 09:09 annevk

If "current origin redirect chain" means the origin boundary is not crossed therein, that option seems reasonable to me.

Yes, it means something like "after all the redirects that are not same-origin as the document's final origin are complete"

noamr avatar Sep 30 '21 09:09 noamr

This does need fixing. I oppose the first option. The third option seems most like what we do with other cross-origin timing exposure.

achristensen07 avatar Sep 30 '21 15:09 achristensen07

I think I agree with @annevk and @achristensen07. This does seem like something we ought to change, and the third option seems like the most robust (and consistent) way of doing so. I think the second is justifiable from a security standpoint as well, but I'm not sure the complexity it introduces is worthwhile.

mikewest avatar Sep 30 '21 16:09 mikewest

Note that (3) includes (2) inside it, in the cases where TAO headers are not there.

With option 3 I want to be careful when we overload the meaning of TAO (see concerns here). Though it could be that since TAO was ignored inside redirects so far it's not a problem since it's new usage of an existing header.

Perhaps a good way to go about it would be that the TAO Header would have to specify the same origin as the Location header, rather than *, like this:

Location: my-site.com/page.html
Timing-Allow-Origin: my-site.com

Not having the above in a cross-origin redirect would push the navigation start time (and timeOrigins) to the beginning of the next fetch after this redirect, and having it would act as if this redirect is same-origin for the purposes of navigation timing.

noamr avatar Sep 30 '21 16:09 noamr

As I noted in https://github.com/w3c/resource-timing/issues/220 accounting for TAO here is in essence a new model and therefore also a source of complexity. For Resource Timing we have a document A that fetches B which redirects to C. B and C need to consent. Here we have a document A that is navigated to B which redirects to C. B needs to consent? I think it's acceptable, but it's quite a bit different.

annevk avatar Sep 30 '21 16:09 annevk

I have to say that the second and third options are not mutually exclusive - we could set navigation time at the first same-origin redirect and extend it backwards pending on an opt-in from the cross-origin redirects.

Note that in any case, we'd need some point in time for navigation start even if there's no opt-in. At worst, we can have that be the request to the eventual request for the document, but setting it to the first request in the last same-origin portion of the redirect chain doesn't seem overly complex.

yoavweiss avatar Sep 30 '21 16:09 yoavweiss

As I noted in w3c/resource-timing#220 accounting for TAO here is in essence a new model and therefore also a source of complexity. For Resource Timing we have a document A that fetches B which redirects to C. B and C need to consent. Here we have a document A that is navigated to B which redirects to C. B needs to consent? I think it's acceptable, but it's quite a bit different.

I agree that TAO may not be the opt-in we want here.

yoavweiss avatar Sep 30 '21 16:09 yoavweiss

I agree that TAO may not be the opt-in we want here.

Opting for a new opt-in? 😬

noamr avatar Sep 30 '21 16:09 noamr

Yoav pointed out that in cases where the redirection domain is trying to help the source and destination track the user, and the user agent has blocked the query parameters they had been using to do this, this timing information might help them continue to transfer at least a partial identifier. I don't think the navigational-tracking threat model (https://github.com/privacycg/nav-tracking-mitigations/issues/12) is developed enough to be much help in making decisions here, but heads up that the Privacy CG might come back to this later.

jyasskin avatar Sep 30 '21 16:09 jyasskin

Yoav pointed out that in cases where the redirection domain is trying to help the source and destination track the user, and the user agent has blocked the query parameters they had been using to do this, this timing information might help them continue to transfer at least a partial identifier. I don't think the navigational-tracking threat model (privacycg/nav-tracking-mitigations#12) is developed enough to be much help in making decisions here, but heads up that the Privacy CG might come back to this later.

Hmm this makes it more interesting - it means that if we accept this as a threat to be mitigated, the user agent should have a say in this for the purpose of tracking prevention and not just the two domains, which means something along option (2) would be the (only?) way to go (the "navigation" starts from the last same-origin chain).

Note that if we go with option (2), some value will be lost for RUM. Sites that load "slowly" will only know what happened from the point the redirect chain arrived at their domain, and they would have no insight into delays caused by 3rd party redirects.

noamr avatar Sep 30 '21 17:09 noamr

Indeed. As long as query parameters are allowed to be passed with the navigation URLs, acting against this doesn't matter much. So for now, I don't think we should take that into account.

But if and when we start mitigating query parameters as an information-passing channel, we'd need to also mitigate the redirection timing channel, either by not exposing it entirely, or have browsers lie about those times in smarter ways (e.g. for known trackers, when they're highly variable, etc).

yoavweiss avatar Oct 01 '21 05:10 yoavweiss

There are user agents doing experiments around query parameters (and some might have shipped?) so we might as well account for it now.

annevk avatar Oct 01 '21 07:10 annevk

I agree this is an area we should remain vigilant on to see how it develops, but I don't believe we have consensus on the threat model and what the solutions to this threat would look like. So it seems premature to e.g. eliminate an opt-in option before that settles.

yoavweiss avatar Oct 01 '21 07:10 yoavweiss

Maybe, I have to say that since we have some tentative plans in this area, I'm actually hesitant now to support an opt-in model here.

annevk avatar Oct 01 '21 07:10 annevk

^^ @miketaylr

It's true that we could go with option (2) and expand it later with an opt-in, once things in that area settle.

It may also be interesting to think about the incentive model here - if this would make redirectors unaccountable for their performance, that'd not be a great outcome. An opt-in model may not be effective in driving such accountibility.

yoavweiss avatar Oct 01 '21 07:10 yoavweiss

^^ @miketaylr

It's true that we could go with option (2) and expand it later with an opt-in, once things in that area settle.

Feels to me from this discussion that this might be the way forward as a first step, while contemplating the opt-in. Interesting if something else would come up in TPAC.

It may also be interesting to think about the incentive model here - if this would make redirectors unaccountable for their performance, that'd not be a great outcome. An opt-in model may not be effective in driving such accountibility.

I'm not sure a redirecting URL is accountable for timing to its destination... Maybe it's accountable to the domain that started the navigation, e.g. where the banner was?

Maybe the interested party in this information is neither domain, but rather the user (and the user agent), and user agents should be encouraged to show some UI indication during a cross-origin navigation redirect ("You are now redirected via Outbrain" or such), to show the user that the delay comes from an ad broker etc and not from the originating domain / destination domain, rather than counting on the origin/destination URLs to do something about it? </Thoughts.>

noamr avatar Oct 01 '21 14:10 noamr

Just to clarify, sounds like this applies to https://w3c.github.io/hr-time/#dfn-time-origin as well? If it does then this would be a pretty big change impacting any high resolution timestamps received by developers.

npm1 avatar Oct 01 '21 15:10 npm1

Just to clarify, sounds like this applies to https://w3c.github.io/hr-time/#dfn-time-origin as well? If it does then this would be a pretty big change impacting any high resolution timestamps received by developers.

Indeed! We'll definitely have to be careful about rolling this out.

yoavweiss avatar Oct 01 '21 15:10 yoavweiss

See demo here. A minimal use case without an intermediate domain.

The originating domain does some form processing of POST before redirecting to a URL at a different domain. Because the timeOrigin includes the time it took to process the POST at the originating domain, in this case the destination domain can detect whether the user subscribed to a newsletter.

noamr avatar Oct 04 '21 06:10 noamr

Hey folks!

As someone working in performance full-time, I have some concerns regarding this proposal, and its impact on well-established metrics like TTFB.

Unless I'm misunderstanding the proposal, wouldn't option 2 ("Change navigationStart to be the timestamp of the first redirect in the current origin redirect chain") mean that we would be redefining TTFB and all metrics that build upon it to mean different things on different situations? That is:

  • In-origin redirects only if there's no TAO or alternatively proposed header
  • Both in-origin redirects and cross-origin redirects if TAO or alternatively proposed header are present

This seems inconsistent and difficult to account for, given that RUM libraries don't have any visibility into the HTTP headers on the document.

Furthermore, would this also change the definition of TTFB and all metrics that build upon it for native browser measurements, such as the ones taken for the Chrome User Experience Report? If not, this could be even worse, as it would remove the last bit of visibility we have into what happens before a request gets to the ultimate origin. At Automattic, we've relied on this information in the past to understand what is happening before a request gets to the origin, so that we can find unnecessary redirects where it's impractical or impossible to set up TAO across authentication chains, URL shortening services, etc.

It's extremely important for us to be able to account for every portion of the time that goes into TTFB or a higher-level metric, when we're being ranked for it via CrUX.

In general, Navigation Timing is a well established API that is relied upon by every RUM library out there, so it seems dangerous to redefine the meaning of the most fundamental value that the entire API relies on.

sgomes avatar Oct 15 '21 17:10 sgomes

Thank you @sgomes, yes, this voice has to be heard to. Seems like the implications of this on RUM metrics would be pretty big. That would have to be weighed against the current breach of same-origin policy. Hoping for a lively discussion at TPAC.

noamr avatar Oct 15 '21 17:10 noamr

It's unclear to me how excluding redirect time in the timeOrigin prevents any realistic attack.

For this attack to work today, we need:

  • a redirector which forwards to a site we own
  • which leaks privacy / security sensitive info through it's redirect time
  • and has users which navigate to our pages via that redirector

Suppose we exclude redirect time from the timeOrigin. For the above attack to work, I already need users on a site I own. If I then modify links on my site to:

  • record the click timestamp
  • forward to the redirector which forwards back to the site I own

then I'm still able to measure the redirect time and execute the attack.

tdresser avatar Oct 18 '21 13:10 tdresser

I think the bigger problem is that when navigating from A to B, B gets to learn when the action on A happened, in quite some precision.

While currently there are many side channels through which A and B can keep tabs on the user, at some point this timing channel might be all that's left and it seems rather unfortunate that it's there.

annevk avatar Oct 18 '21 13:10 annevk

Another possible solution(?) is to do some extreme coarsening on the time between navigation start and the first redirect of the last origin. It would keep the time base roughly the same and would still measure some heavy redirect delays, but without exposing high resolution timing information to third parties.

noamr avatar Oct 18 '21 17:10 noamr

I think it's important to understand if this is exposing cross-origin information that's a problem that's putting users at risk today, or if it's a side-channel that would become a problem once we would block all other side-channels that enable navigations from A to B to currently communicate. @tdresser's example countered my scenario I had for the former, showing that this will not block it.

yoavweiss avatar Oct 19 '21 06:10 yoavweiss

Exposing cross-origin redirects in navigationStart violates the spirit of cross-origin policy regardless of those attacks, as it exposes time the user spent at the original domain or intermediate domains. It's like saying to websites: "by redirecting to a different origin location, you're also sending timing information as part of the redirect".

I see it less as "exposing to attacks", but rather volunteering usage information to domains without permission.

noamr avatar Oct 19 '21 06:10 noamr

The description of the issue looks complicated and some folks in the thread seem to understand the leak differently. From what I understand, the attack scenario here is that a final website B could infer some information about redirectors used on a website A. E.g. clicking on google search, twitter links, facebook since these all are proxied through. This indeed seems like too much information for a website B to have.

Change navigationStart to be the timestamp of the first redirect in the current origin redirect chain

Which means

Yes, it means something like "after all the redirects that are not same-origin as the document's final origin are complete"

Seems reasonable to me.

Though, I can't come up with any useful attack that would abuse this inferred information. We don't expose any information about how many redirects occurred, so for a website B to guess that a redirect occurred, and how many times, is rather tough without other side-channels (maybe potentially document.referrer). I don't think that it's a side channel on its own.

It looks weird though that we expose the information about load time including all the redirects that occurred. This could provide false information about performance.

terjanq avatar Oct 21 '21 15:10 terjanq