nsIPrincipal.origin mishandles IPv6 host literals
Categories
(Core :: Security: CAPS, defect, P2)
Tracking
()
People
(Reporter: ma1, Assigned: ckerschb)
Details
(Keywords: sec-moderate, Whiteboard: [post-critsmash-triage][adv-main76+])
Attachments
(2 files)
For codebase URIs with IPv6 host literals like http://[::1]/ nsPrincipal::GetOriginForURI() returns http:/::1/ because it just concatenates nsIURI.scheme + "://" + nsIURI.asciiHost + ":" + nsIURI.port, "forgetting" to special case IPv6 hosts enclosing them with brackets. This gets especially confusing and likely unsafe when explicit ports are added to the mix, potentially producing invalid URIs and/or duplicate strings for actually different origins.
Comment 1•9 years ago
|
||
This should probably use NS_GenerateHostPort instead of doing the the manual AppendInt thing... That said, is there a reason this can't just use nsContentUtils::GetAsciiOrigin instead of duplicating code? Presumably after we do the isChrome check.
Comment 2•9 years ago
|
||
It looks like this method is only used for app-y stuff.
Comment 3•9 years ago
|
||
CritSmash would like to rate this, but we need to understand where this code is used. Is this a URI parsing method that lives in a general location and is used for IPv6 hosts everywhere? Or is it just used - as Andrew asks - for something like apps or the like?
Reporter | ||
Comment 4•9 years ago
|
||
It lives in nsPrincipal, which is a "general location" mostly used for security checks. Direct callers: https://dxr.mozilla.org/mozilla-central/search?q=%2Bcallers%3A%22nsPrincipal%3A%3AGetOriginForURI%28class+nsIURI+*%2C+char+**%29%22 Callers of the "interesting" client nsScriptSecurityManager::CheckLoadURIWithPrincipal(): https://dxr.mozilla.org/mozilla-central/search?q=%2Bcallers%3A%22nsScriptSecurityManager%3A%3ACheckLoadURIWithPrincipal%28class+nsIPrincipal+*%2C+class+nsIURI+*%2C+uint32_t%29%22
Comment 5•9 years ago
|
||
I'm calling this moderate because we don't know of a place that will misuse this and end up with a security problem, but it's quite plausible that something's going to get into trouble.
Updated•9 years ago
|
Assignee | ||
Comment 6•4 years ago
|
||
We handle this correctly, I'll upload a test to make sure we don't regress that.
Assignee | ||
Comment 7•4 years ago
|
||
Assignee | ||
Comment 8•4 years ago
|
||
Dragana,
Tom pointed out that in the test (see attachment) prinicpal.host is not canonicalized, e.g.
"http://[20D1:0000:3238:DFE1:63:0000:0000:FEFB]/"
"http://[20D1:0:3238:DFE1:63::FEFB]/"
are the exact same, which implies that storage from one could be accessed by the other.
I tried to trace down the problem, and I think the problem happens within the creation of an nsIURI. Anyway, all the code within nsIURI seems critical. Is there even an easy fix to account for canonicalized IPV6 addresses?
Comment 9•4 years ago
|
||
Valentin, can you help Christoph here?
Comment 10•4 years ago
|
||
I'm not sure I understand. The URL parser turns the IPv6 into canonicalized versions, and principal.origin reflects the same canonical form.
Since "http://[20D1:0000:3238:DFE1:63:0000:0000:FEFB]/" always gets parsed as "http://[20d1:0:3238:dfe1:63::fefb]/", that shouldn't really be a problem. Or is there something else I'm missing?
Comment 11•4 years ago
|
||
That may the answer then. "The Principal object will construct a principal based on the url it is given; if the url is not canonicalized, it won't be a canonicalized principal. But there should be no way to construct a principal with a non-canonicalized url, so that behavior is okay."
In which case we ought to be able to assert in Principal if we receive a non-canonicalized url.
I'd propose sending a try run with a moz_assert, and then land a diagnostic assert behind a pref (on by default, but this enables people to turn the assert off), and monitor crashes and be prepared to backout. If Nightly is clean w.r.t this we could make it a release assert.
Comment 12•4 years ago
|
||
Comment 13•4 years ago
|
||
Updated•4 years ago
|
Updated•4 years ago
|
Comment 14•4 years ago
|
||
As per my discussion on slack with Christoph, there's nothing actionable here, in terms on manual testing. Thanks!
I'll remove the qe+ flag.
Updated•4 years ago
|
Comment 15•4 years ago
|
||
Updated•4 years ago
|
Updated•3 years ago
|
Description
•