Closed Bug 1295945 (CVE-2017-5385) Opened 4 years ago Closed 4 years ago

HTML documents sent with multipart/x-mixed-replace ignores Referrer-Policy response header

Categories

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

defect

Tracking

()

VERIFIED FIXED
mozilla51
Tracking Status
firefox51 --- verified

People

(Reporter: sdna.muneaki.nishimura, Assigned: baku)

References

Details

(Keywords: csectype-disclosure, sec-moderate, Whiteboard: [domsecurity-active][post-critsmash-triage][adv-main51+])

Attachments

(2 files, 1 obsolete file)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7

Steps to reproduce:

Following two URLs return a HTML document with "Referrer-Policy no-referrer" in a response header.

#1. MIME: text/html
http://mallory.csrf.jp/x-mixed-replace/referrer/index.html
#2. MIME: multipart/x-mixed-replace
http://mallory.csrf.jp/x-mixed-replace/referrer/bad.php

The hyperlink in #1 sends no REFERER header but the hyperlink in #2 sends REFERER.



Actual results:

This means that a HTML document sent with multipart/x-mixed-replace ignores Referrer-Policy response header. This can be a cause of sensitive information leakage.



Expected results:

Referrer-Policy header should be applied to documents with multipart/x-mixed-replace.
Group: firefox-core-security → core-security
Component: Untriaged → DOM: Security
Product: Firefox → Core
This seems to be a bug in parsing the referrer-policy header, not the referrer-policy handling in general. Adding a |referrerpolicy="no-referrer"| attribute to the link makes the referrer policy work correctly.

Thomas, can you have a look what's going on here?
Flags: needinfo?(tnguyen)
Just a quick look, referrer-policy is ignored when the channel is multipart-channel [1]

Add the following code to query multipart channel works
  if (!httpChannel) {
    nsCOMPtr<nsIMultiPartChannel> multipart = do_QueryInterface(aChannel);
    if (multipart) {
      nsCOMPtr<nsIChannel> baseChannel;
      multipart->GetBaseChannel(getter_AddRefs(baseChannel));
      httpChannel = do_QueryInterface(baseChannel);
    }
  }

We could easily fix and add referrer-policy parsing in multipart-channel, but I am not very sure others header in [2]. Seems that all that headers are ignored in multipart-channel. 

[1] https://dxr.mozilla.org/mozilla-central/source/dom/base/nsDocument.cpp#8608
[2] https://dxr.mozilla.org/mozilla-central/source/dom/base/nsDocument.cpp#8632
Flags: needinfo?(tnguyen)
> We could easily fix and add referrer-policy parsing in multipart-channel,
> but I am not very sure others header in [2]. Seems that all that headers are
> ignored in multipart-channel. 
> 
> [1]
> https://dxr.mozilla.org/mozilla-central/source/dom/base/nsDocument.cpp#8608
> [2]
> https://dxr.mozilla.org/mozilla-central/source/dom/base/nsDocument.cpp#8632

Ni who may have idea on this.
Flags: needinfo?(bugs)
(In reply to Thomas Nguyen[:tnguyen] (use ni? plz) from comment #2)
> Seems that all that headers are ignored in multipart-channel. 

FWIW, we do query the CSP header from multipart channels:
https://dxr.mozilla.org/mozilla-central/source/dom/base/nsDocument.cpp#2695
:) Thanks Christoph.
Edit:
All that headers in [2] are ignored in multipart-channel,
[2] https://dxr.mozilla.org/mozilla-central/source/dom/base/nsDocument.cpp#8632
Or maybe :baku has idea about these headers :)
Flags: needinfo?(amarchesini)
Attached patch referrer.patch (obsolete) — Splinter Review
Assignee: nobody → amarchesini
Flags: needinfo?(amarchesini)
Attachment #8782481 - Flags: review?(bugs)
Group: core-security → dom-core-security
(In reply to Thomas Nguyen[:tnguyen] (use ni? plz) from comment #5)
> All that headers in [2] are ignored in multipart-channel,
> [2]
> https://dxr.mozilla.org/mozilla-central/source/dom/base/nsDocument.cpp#8632

FWIW, X-Frame-Options header is in the list but it works well (not ignored).
http://mallory.csrf.jp/iframe.php?sandbox=0&url=http://mallory.csrf.jp/x-mixed-replace/xfo/
(In reply to Muneaki Nishimura from comment #8)

I could successfully reproduce it.

There are 2 ways to set response headers in multipart/mixed-* data.
One is to set it in HTTP header (1) and another one is to specify in each fragment part of HTTP response body (2).

Firefox ignores Referer-Policy header in (1)(2) but ignores X-Frame-Options in (2).
Following PHP code can reproduce it.

<?php
header("Content-Type: multipart/x-mixed-replace;boundary=boundary");
header("X-FRAME-OPTIONS: DENY"); // (1) Not ignored
header("Referrer-Policy no-referrer"); // (1) Ignored

echo("--boundary\r\n");
echo("Content-type: text/html\r\n");
echo("X-FRAME-OPTIONS: DENY\r\n"); // (2) Ignored
echo("Referrer-Policy no-referrer\r\n"); // (2) Ignored
echo("\r\n");
echo("<a href=/referer_stealer.php>Link</a>\r\n");
echo("--boundary\r\n");
?>
Can you upload also the php file so that I can test it locally?
I want to see if my patch covers both headers.
Flags: needinfo?(sdna.muneaki.nishimura)
I uploaded the test PHP code as attached.

Steps to reproduce is below:
1. Deploy 3 files in your local server and open "index.html" with Firefox.
2. If a page (content.php) is shown in an iframe X-Frame-Options header is ignored.
3. Click a link in "content.php" and then Firefox navigates to "check.php".
4. If REFERER header is shown Referrer-Policy header is ignored.
Flags: needinfo?(sdna.muneaki.nishimura)
See Also: → 1296471
Status: NEW → ASSIGNED
Whiteboard: [domsecurity-active]
Comment on attachment 8782481 [details] [diff] [review]
referrer.patch

I don't understand the patch. In nsDocument::RetrieveRelevantHeaders First we try to get the http channel using GetHttpChannelHelper. That deals with multipart channels too. But if that fails, we explicitly QI to nsIMultiPartChannel and try to get http channel again.
Flags: needinfo?(bugs)
Attachment #8782481 - Flags: review?(bugs) → review-
Attached patch referrer.patchSplinter Review
Attachment #8782481 - Attachment is obsolete: true
Attachment #8783871 - Flags: review?(bugs)
Comment on attachment 8783871 [details] [diff] [review]
referrer.patch

Does it make sense to copy refresh and content-disposition from http channel? Maybe it does.
multipart/x-mixed-replace should be quite rarely used these days.
Attachment #8783871 - Flags: review?(bugs) → review+
Flags: sec-bounty?
https://hg.mozilla.org/mozilla-central/rev/b5ad370c93f5
Status: ASSIGNED → RESOLVED
Closed: 4 years ago
Flags: in-testsuite?
Resolution: --- → FIXED
Target Milestone: --- → mozilla51
This is a security issue for sites relying on this header, not something that can attack Firefox itself. A malicious site can't use this, but a non-malicious site could accidentally leak information it was trying to keep hidden. Because multipart/x-mixed-replace is extremely uncommon this doesn't seem exceptional enough to rate a bug bounty.
Flags: sec-bounty? → sec-bounty-
Group: dom-core-security → core-security-release
Flags: qe-verify+
Whiteboard: [domsecurity-active] → [domsecurity-active][post-critsmash-triage]
I've managed to reproduce this issue with Nightly from 2016-08-17 using STR from comment 0.

This is verified fixed on 51.0b14 (20170112171116) across platforms: Windows 10 x64, Ubuntu 16.04 x64 LTS and Mac OS X 10.11.6. The hyperlink in #1 sends no referer header as well as hyperlink in #2.
Status: RESOLVED → VERIFIED
Flags: qe-verify+
Whiteboard: [domsecurity-active][post-critsmash-triage] → [domsecurity-active][post-critsmash-triage][adv-main51+]
Alias: CVE-2017-5385
Group: core-security-release
Flags: sec-bounty-hof+
You need to log in before you can comment on or make changes to this bug.