Closed
Bug 1243178
(CVE-2016-1954)
Opened 9 years ago
Closed 9 years ago
CSP's report-uri (over-)writes files
Categories
(Core :: DOM: Security, defect)
Tracking
()
RESOLVED
FIXED
mozilla47
People
(Reporter: nicolas.golubovic+bugzilla, Assigned: ckerschb)
References
Details
(Keywords: reporter-external, sec-high, Whiteboard: [adv-main45+][adv-esr38.7+][post-critsmash-triage])
Attachments
(1 file, 1 obsolete file)
1.27 KB,
patch
|
dveditz
:
review+
ritu
:
approval-mozilla-aurora+
ritu
:
approval-mozilla-beta+
ritu
:
approval-mozilla-esr38+
dveditz
:
sec-approval+
|
Details | Diff | Splinter Review |
Firefox can be forced to (over-)write files on the user's host when prompted to report policy violations to a file:///, resource:// or chrome:// URL. While the last two are tricky to exploit since they most likely require vulnerable add-ons, the first is dead simple. The attacker does not have full control of the report, but can control multiple values inside of the report JSON structure.
For a demonstration of the issue you may visit the following link with a UNIX host and check your /tmp directory afterwards. It should contain a file called attack_works.html.
https://c.iceqll.eu/overwrite_resource.php
The attack sends the following CSP header and then violates it:
Content-Security-Policy: script-src 'none'; report-uri file:///tmp/attack_works.html
Works in:
- FF 42, 43, 44
The first tested version where it _does not work anymore_ is the Nightly Build (47.xx).
Why do I report the issue anyway? Two reasons:
- Maybe it was fixed by accident and the severity went unnoticed
- I am in the course of writing a thesis, so I'd love to have something to reference - and if this is a duplicate, I'd like to reference that. Sorry. I'm being very selfish :-/
Comment 1•9 years ago
|
||
I can't think of anything we changed recently that would "fix" this in Nightly, though we should limit report-uri to http(s) urls. Or at the very very least we need to run CheckMayLoad() on it so we're not loading URI_IS_DANGEROUS_TO_LOAD schemes!
Group: core-security → dom-core-security
Component: Security → DOM: Security
Flags: needinfo?(mozilla)
Keywords: sec-moderate
Comment 2•9 years ago
|
||
Christoph says this is likely fixed by bug 1188028, which would correspond to the beta channel (though I don't think we've released a 45 beta yet... end of the week). Would also be fixed on Dev Edition (Firefox 46).
Still, even though the AsyncOpen2() changes do the basic may-load checks, I'd still be happy to stomp only any report-uri that tries to set a non-http(s) URL.
Flags: needinfo?(mozilla)
Updated•9 years ago
|
status-firefox44:
--- → affected
status-firefox45:
--- → fixed
status-firefox46:
--- → fixed
status-firefox-esr38:
--- → affected
tracking-firefox-esr38:
--- → 45+
Depends on: 1188028
Comment 3•9 years ago
|
||
If this bug indeed allows overwriting files within extensions, this would allow code injection with high(er) privileges, right?
I'd rather err on the side of caution and call this higher than sec-moderate. Thoughts?
Reporter | ||
Comment 4•9 years ago
|
||
(In reply to Frederik Braun [:freddyb] from comment #3)
> If this bug indeed allows overwriting files within extensions, this would
> allow code injection with high(er) privileges, right?
Right. As shown in the PoC above, it is possible to smuggle HTML (and JS) into the report. When visited using a privileged scheme like chrome://xxx/content/ this will have full code execution on the host system. I have not tested with built-in chrome and resource URIs, but one possible scenario is the following:
- Add-on with em:unpack=true (this may not be required in all cases) registers content package with contentaccessible=yes
- Attacker knows that the add-on is activated on the victim's browser due to fingerprinting (trivial when contentaccessible=yes is given)
- Attacker overwrites an existing add-on HTML or XHTML file with the report-uri technique (e.g. chrome://addon-name/content/file.xhtml)
- On the next load of the overwritten file, the attacker's payload executes
=> JavaScript code execution in a privileged chrome context
However, I think a signature check which you will enforce in future versions might also mitigate this threat?
Assignee | ||
Comment 5•9 years ago
|
||
(In reply to Nicolas G from comment #4)
> - On the next load of the overwritten file, the attacker's payload executes
> => JavaScript code execution in a privileged chrome context
But the attacker can't control what will be written in the file. It will always be the CSP-report, no?
Reporter | ||
Comment 6•9 years ago
|
||
(In reply to Christoph Kerschbaumer [:ckerschb] from comment #5)
> But the attacker can't control what will be written in the file. It will
> always be the CSP-report, no?
That's true. However, take a close look at the written report (also from the above PoC):
{"csp-report":{"blocked-uri":"self","document-uri":"https://c.iceqll.eu/overwrite_resource.php","line-number":3,"original-policy":"script-src 'none'; report-uri file:///tmp/attack_works.html","referrer":"","script-sample":"<svg onload=alert(1)>","source-file":"https://c.iceqll.eu/overwrite_resource.php","violated-directive":"script-src 'none'"}}% qll@corellia /tmp %
A HTML parser will skip all the JSON gibberish it does not understand and will find the first < right there at the <svg onload=alert(1)> part. It will just take that out of the context and render it, thus executing the JavaScript payload.
Assignee | ||
Comment 7•9 years ago
|
||
I agree, this is a nifty idea. Exactly that's why we are introducing 'Security be Default' Network checks at the moment, by calling ascyncOpen2() on all channels. For CSP reports we are using asyncOpen2() since FF45 [1] which doesn't give you local file access.
The other thing that makes this kind of attack a little more difficult is, that the attack code has to fit within 40 chars [2] because we truncate the script sample. Not impossible to do, but definitely harder.
[1] https://hg.mozilla.org/integration/mozilla-inbound/rev/acc983ca0dec#l5.285
[2] http://mxr.mozilla.org/mozilla-central/source/dom/security/nsCSPContext.cpp#418
Comment 8•9 years ago
|
||
Raising severity rating. It's a low-ish sec-high, but web-accessible file destruction (even if writing useful content seems unlikely, though not impossible) is at least as bad as bug 1241100. We need this fixed on ESR 38
Keywords: sec-moderate → sec-high
Assignee | ||
Updated•9 years ago
|
Assignee: nobody → mozilla
Status: NEW → ASSIGNED
Assignee | ||
Comment 9•9 years ago
|
||
Given that we need a fix for ESR 38, I think what we actually want is that small fix within the parser so that a report-uri can not point to any other schemes than http:// or https://.
Also, using that approach, we spit out a console warning at CSP parsing, potentially something we want on trunk at some point anyway.
What do you think Dan?
Attachment #8712899 -
Flags: review?(dveditz)
Comment 10•9 years ago
|
||
Comment on attachment 8712899 [details] [diff] [review]
bug_1195172_csp_uri_reports.patch
Review of attachment 8712899 [details] [diff] [review]:
-----------------------------------------------------------------
Would like a new patch along the lines I mention, but if you feel strongly about keeping this an absolute minimum patch I could live with this.
::: dom/security/nsCSPParser.cpp
@@ +932,2 @@
> const char16_t* params[] = { mCurToken.get() };
> logWarningErrorToConsole(nsIScriptError::warningFlag, "couldNotParseReportURI",
this is OK as a quick fix. Might be good enough for ESR38 but will lead to a confusing error message in this case (could not parse a valid url?). It wouldn't be too much work to make this
if (failed)
current "couldNotParseReportURI code
else if (!isHttp)
same but use reportURInotHttpsOrHttp2
we already have that string and use it to log a warning in SendReports
https://mxr.mozilla.org/mozilla-central/source/dom/security/nsCSPContext.cpp#875
That SendReports warning-only check would then be redundant of course, but for the sake of a smaller ESR change we can leave it.
::: dom/security/test/TestCSPParser.cpp
@@ +504,5 @@
> { "connect-src http://www.example.com/foo%zz;",
> "connect-src 'none'" },
> { "script-src https://foo.com/%$",
> "script-src 'none'" },
> + { "report-uri file:///tmp/attack_works.html", "report-uri 'none'"},
The test kind of gives the game away, don't think we should check this in with the patch. Although the patch itself is pretty obvious. This will have to be a late-cycle check-in (in which case the test is OK).
More interested in adding the test to trunk though, so it'll be tested for the future. The current trunk code doesn't have this security bug, but it would not pass this test since the AsyncOpen2() check that prevents the bug happens at SendReports time.
Assignee | ||
Comment 11•9 years ago
|
||
As agreed over IRC, we should keep the change small. Since we are already logging a warning, we can simply add a 'continue' and skip the invalid URI, as we do for other errors that appear at that stage.
[1] Content Security Policy: The report URI (file:///tmp/attack_works.html) should be an HTTP or HTTPS URI.
Attachment #8712899 -
Attachment is obsolete: true
Attachment #8712899 -
Flags: review?(dveditz)
Attachment #8712945 -
Flags: review?(dveditz)
Comment 12•9 years ago
|
||
Comment on attachment 8712945 [details] [diff] [review]
bug_1195172_csp_reports_skip_non_http.patch
Review of attachment 8712945 [details] [diff] [review]:
-----------------------------------------------------------------
Nice and simple, and a more appropriate message. Thanks
r=dveditz
Attachment #8712945 -
Flags: review?(dveditz) → review+
Reporter | ||
Comment 13•9 years ago
|
||
Quick heads-up after some tests: You may already know this, but unpack=true is required and contentaccessible=yes is not. HTTPS Everywhere, for example, fits the description and can be disabled on recent Firefox versions by overwriting chrome://https-everywhere/content/about.xul, for example. This will make the signature check fail. Themes and other add-ons not subject to rigorous signature checks can be hijacked, as well as extensions when checks are disabled by a setting.
Updated•9 years ago
|
Flags: sec-bounty?
Comment 14•9 years ago
|
||
Comment on attachment 8712945 [details] [diff] [review]
bug_1195172_csp_reports_skip_non_http.patch
sec-approval+
Don't need this on aurora/beta, but we do want it on ESR-38
Attachment #8712945 -
Flags: sec-approval+
Hi Christoph, could you please nominate a patch for uplift to esr38? Thanks! I am also wondering whether this fix is already on 45, 46 and 47 because I don't see committs from m-b, m-a, m-c in this bug. Please confirm.
Flags: needinfo?(mozilla)
Assignee | ||
Comment 16•9 years ago
|
||
(In reply to Ritu Kothari (:ritu) from comment #15)
> Hi Christoph, could you please nominate a patch for uplift to esr38? Thanks!
> I am also wondering whether this fix is already on 45, 46 and 47 because I
> don't see committs from m-b, m-a, m-c in this bug. Please confirm.
In fact, the proper fix from a Security point of view landed within Bug 1188028 which was for 45. So at the moment only ESR is affected. Dan I chatted in person and since the patch within this bug is real simple we should land this patch on 45,46,47 and ESR. I'll file the uplift request.
Keywords: checkin-needed
Assignee | ||
Comment 17•9 years ago
|
||
Comment on attachment 8712945 [details] [diff] [review]
bug_1195172_csp_reports_skip_non_http.patch
[Approval Request Comment]
If this is not a sec:{high,crit} bug, please state case for ESR consideration:
User impact if declined:
Fix Landed on Version:
Risk to taking this patch (and alternatives if risky):
String or UUID changes made by this patch:
See https://wiki.mozilla.org/Release_Management/ESR_Landing_Process for more info.
Approval Request Comment
Users of webpages might be exposed to local file overwrite attacks using the report-uri directive, where instead of reporting to a URI JS might be written into a local file.
[Feature/regressing bug #]:
Most likely that was the CSP rewrite (Bug 925004).
[User impact if declined]:
Attack from Comment 0 could be mounted.
[Describe test coverage new/current, TreeHerder]:
Manual verification.
[Risks and why]:
Low, since it affects only pages that use CSP and use the report-uri directive.
[String/UUID change made/needed]:
no
Flags: needinfo?(mozilla)
Attachment #8712945 -
Flags: approval-mozilla-esr38?
Attachment #8712945 -
Flags: approval-mozilla-beta?
Attachment #8712945 -
Flags: approval-mozilla-aurora?
Comment on attachment 8712945 [details] [diff] [review]
bug_1195172_csp_reports_skip_non_http.patch
Sec-high and simple bug fix. Let's uplift to Beta45, Aurora46 and esr38.7
Attachment #8712945 -
Flags: approval-mozilla-esr38?
Attachment #8712945 -
Flags: approval-mozilla-esr38+
Attachment #8712945 -
Flags: approval-mozilla-beta?
Attachment #8712945 -
Flags: approval-mozilla-beta+
Attachment #8712945 -
Flags: approval-mozilla-aurora?
Attachment #8712945 -
Flags: approval-mozilla-aurora+
https://hg.mozilla.org/releases/mozilla-aurora/rev/7a7c3d89e43b
https://hg.mozilla.org/releases/mozilla-beta/rev/5154bb929236
https://hg.mozilla.org/releases/mozilla-esr38/rev/a5c4c18849b4
Flags: needinfo?(wkocher)
Updated•9 years ago
|
Group: dom-core-security → core-security-release
Flags: sec-bounty? → sec-bounty+
Updated•9 years ago
|
Group: core-security-release → dom-core-security
Comment 21•9 years ago
|
||
Keywords: checkin-needed
Comment 22•9 years ago
|
||
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla47
Updated•9 years ago
|
Whiteboard: [adv-main45+][adv-esr38.7+]
Updated•9 years ago
|
Group: dom-core-security → core-security-release
Updated•9 years ago
|
Alias: CVE-2016-1954
Comment 23•9 years ago
|
||
Confirmed issue in Fx44, verified fixed in Fx45.0.2.
Whiteboard: [adv-main45+][adv-esr38.7+] → [adv-main45+][adv-esr38.7+][post-critsmash-triage]
Updated•8 years ago
|
Group: core-security-release
Updated•9 months ago
|
Keywords: reporter-external
You need to log in
before you can comment on or make changes to this bug.
Description
•