Open Bug 1751105 Opened 3 years ago Updated 1 year ago

localhost cross-port requests bypass CORS checks (treated as same-origin) with HTTPS-only mode enabled

Categories

(Core :: DOM: Security, defect, P3)

Firefox 96
defect

Tracking

()

People

(Reporter: Matthew.Holt, Unassigned)

References

(Blocks 1 open bug)

Details

(Whiteboard: [domsecurity-active])

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0

Steps to reproduce:

  1. Enable HTTPS-only mode (make sure http://localhost is NOT an exception)
  2. Load http://localhost
  3. Run "fetch('http://localhost:1234/foo', { mode: 'cors' });" in <script> tag or in devtools console. (The results of this experiment are the same even without "mode: cors")

For expected results, either disable HTTPS-only mode or add http://localhost as an exception, and try again.

Actual results:

The request is made without the Origin header, even though the request is cross-origin (http://localhost:80 -> http://localhost:1234).

Expected results:

The request should be made with the Origin header set to "http://localhost" regardless of HTTPS-only mode.

Notice how origin header is missing.

Originally from Twitter thread: https://twitter.com/mholt6/status/1483965631372300288

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

Component: Untriaged → DOM: Security
Product: Firefox → Core
Assignee: nobody → lyavor
Status: UNCONFIRMED → NEW
Ever confirmed: true

That error is also affecting https-first

I could not reproduce this

Summary: Cross-origin requests treated as same-origin with HTTPS-only mode enabled → Cross-origin requests treated as same-origin with HTTPS-only mode enabled (localhost only?)
Severity: -- → S2
Priority: -- → P2
Whiteboard: [domsecurity-active]

Daniel, what did you try? Here's a tweet documenting where an Edge engineer was able to reproduce it: https://twitter.com/ericlaw/status/1483972139241857027 - can you post a screenshot or video? It's quite reproducible from multiple platforms.

I can reproduce the issue, but couldn't identify the root cause using rr. The function SetOriginHeader checks whether the request method is GET or HEAD and then bails out early, which can't be right either way or is it?
If so, why would it change with HTTPS-Only mode?

If that function did run, then we'd use the referrer information for the value of the Origin header.
What I do note though, if it were we seem to lose the referrer and sometimes repair it, but only in the DocumentLoadListener, which is probably too late?

Maybe someone from the networking team can help shed a light on this? I'm too new to all of this to make any sense of this...

Daniel, what did you try?

Sorry for the drive-by triage last January and not noticing this reply. It was easier for me to test on a named server and I did not try localhost specifically. Since localhost was not mentioned in the summary I incorrectly assumed it was simply a convenient test server for you. But I did at least add it as a question to the summary and triage the bug onto Freddy's plate who was able to confirm it correctly.

Note the same happens for the http://127.0.0.1 (and other) loopback IP address (bug 1778291), though localhost<-->127.0.0.1 checks are correct because the host is "spelled" differently.

Christoph pointed out CheckInsecureUpgradePreventsCORS as suspect. It definitely compares only hostnames and skips ports. When that was added for upgrade-insecure-request it checked at the end that the request would in fact be upgraded before returning the answer, and that would have correctly taken localhost into account. Now it's used for multiple features and maybe something downstream forgets to make an equivalent check, or better, that broader check needs to be built back into CheckInsecureUpgradePreventsCORS so people don't have to remember to check multiple things.

There's also nsHTTPSOnlyUtils::IsSafeToAcceptCORSOrMixedContent that should be checked, but that exempts localhost so maybe it's not the problem.

Summary: Cross-origin requests treated as same-origin with HTTPS-only mode enabled (localhost only?) → localhost cross-port requests bypass CORS checks (treated as same-origin) with HTTPS-only mode enabled
Severity: S2 → S3
Priority: P2 → P3

We'll get to it eventuall - But clearly not as fast as previously stated.

Assignee: t.yavor → nobody
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: