Closed Bug 1721303 Opened 3 years ago Closed 3 years ago

Adding "Alt-Used" header breaks cross-domain requests from Service Worker

Categories

(Core :: DOM: Networking, defect, P2)

Firefox 90
defect

Tracking

()

RESOLVED FIXED
93 Branch
Tracking Status
firefox93 --- fixed

People

(Reporter: maxim, Assigned: kershaw)

References

Details

(Whiteboard: [necko-triaged])

Attachments

(2 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36

Steps to reproduce:

High-level (may be fixed soon):

  1. Go to app.borderwise.com
  2. Open dev tools, make sure that service worker is installed and running
  3. Reload the page, observe 408 errors in the network tab

Low-level:

  1. Issue this request:
await fetch("https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js", {
    "credentials": "omit",
    "headers": {
        "Accept": "*/*",
        "Accept-Language": "en-US,en;q=0.5",
        "Alt-Used": "cdnjs.cloudflare.com",
    },
    "referrer": "https://app.borderwise.com/",
    "method": "GET",
    "mode": "cors"
});

(because these are the headers that are in the request that is intercepted by self.addEventListener('fetch', ...) in the service worker).
2. Observe:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js. (Reason: header ‘alt-used’ is not allowed according to header ‘Access-Control-Allow-Headers’ from CORS preflight response).

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js. (Reason: CORS request did not succeed).

Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.

Actual results:

Fetch from the service worker throws "TypeError: NetworkError when attempting to fetch resource."

This happens in Stable (90.0.1 (64-bit)), Beta (91.0b4 (32-bit)) and Nightly (92.0a1 (2021-07-19) (64-bit)).
But doesn't happen in Developer (91.0b4 (64-bit))
None of these have any extensions. And have been refreshed.
Also, this issue is NOT happening in the same version of stable Firefox on PCs that are in our corporate network, using the corporate proxy. I assume this is related to HTTP/2 support or self-signed certificates.

Also, this issue is NOT happening in Chrome, Edge and Safari.

Expected results:

I expect the "alt-used" header to either not be added to the request (I've seen specs and don't understand why it's being added in our case).

Or, I expect "alt-used" header to be included in the safe headers list 9https://fetch.spec.whatwg.org/#cors-safelisted-request-header)

The Bugbug bot thinks this bug should belong to the 'Core::DOM: Networking' component, and is moving the bug to that component. Please revert this change in case you think the bot is wrong.

Component: Untriaged → DOM: Networking
Product: Firefox → Core

A bit more context: we're re-creating these requests using new Request, so the request mode is changing from no-cors to cors. And Alt-Used header, which is copied into the new request is not allowed in the cors request mode.

Update: issue was fixed on our website by cloning requests instead of recreating them, so it will no longer reproduce.
Still, I'm concerned about the Alt-Used header here, and how it's not consistent across different browsers, versions and PCs.

I expect the "alt-used" header to either not be added to the request (I've seen specs and don't understand why it's being added in our case).

I think it's because that AlternateService is really used.

Or, I expect "alt-used" header to be included in the safe headers list 9https://fetch.spec.whatwg.org/#cors-safelisted-request-header)

Anne, what do you think about this?

Flags: needinfo?(annevk)

Reading https://datatracker.ietf.org/doc/html/rfc7838#section-5 I would expect Alt-Used to be added by the browser when it adds Host headers and the like, which is after a request goes through a service worker. So I agree with OP that it is unexpected that the request going to the service worker includes it. (It's a bit unfortunate that it expanded the set of headers that goes across origins, but okay.)

(It does make me wonder whether it's problematic that web developers can set this header, but they can only really use it cross-origin if the receiving servers allows it, so maybe it's fine.)

Flags: needinfo?(annevk)

These are the raw headers that I see right now for app.borderwise.com in stable FF:

GET /ajax/libs/angular.js/1.5.8/angular.min.js HTTP/1.1
Host: cdnjs.cloudflare.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://app.borderwise.com/
Alt-Used: cdnjs.cloudflare.com
Sec-Fetch-Dest: script
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: cross-site
Connection: keep-alive

As you can see, Host matches Alt-Used (cdnjs.cloudflare.com === cdnjs.cloudflare.com), which doesn't make sense to me.

From the example in the spec, I understand that Alt-Used is used to present when the host that is being actually used doesn't match the Host header?

Host: origin.example.com
Alt-Used: alternate.example.net

Spec says

When using an alternative service, clients SHOULD include an Alt-Used header field in all requests.

But it doesn't say that this header should only be added when it's actually needed. So I guess FF is within the spec, but still, it's a bit weird to me...

To be clear, that part is not the problem here (although it might also be problematic if it doesn't match other browsers). From what I gather the problem here is that the Alt-Used header appears on the Request object that is handed to the fetch event in a service worker. That should only happen if a web developer had set that header in their fetch() or XMLHttpRequest call. The browser should add the header at a similar moment in time to where it adds the Host header.

(There's an interesting question here what should happen if the browser plans to set it, but the web developer already has. I filed https://github.com/whatwg/fetch/issues/1272 on that.)

Oh, right, I see now, makes total sense. Thanks for the clarification. And for filing the issue as well!

Eden, could you take a look?
The code that copies all headers to service workers is here.

Flags: needinfo?(echuang)

We should just set alt-used header with type nsHttpHeaderArray::eVarietyRequestDefault (here and on a couple of more places). The rest will just work.

(In reply to Dragana Damjanovic [:dragana] from comment #10)

We should just set alt-used header with type nsHttpHeaderArray::eVarietyRequestDefault (here and on a couple of more places). The rest will just work.

After talking to Eden, we think it'd better to address this issue at necko side.
Also thanks Dragana for pointing out how to fix this.

Assignee: nobody → kershaw
Severity: -- → S3
Flags: needinfo?(echuang)
Priority: -- → P2
Whiteboard: [necko-triaged]
Pushed by kjang@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/a893d45ad4f9
Avoid exposing Alt-Used to service workers, r=necko-reviewers,dragana
Status: UNCONFIRMED → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → 93 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: