Closed Bug 1543804 (CVE-2019-11712) Opened 6 years ago Closed 5 years ago

Cross-origin requests can be made with NPAPI plugins by following 308 redirects

Categories

(Core Graveyard :: Plug-ins, defect, P2)

defect

Tracking

(firefox-esr6068+ verified, firefox66 wontfix, firefox67 wontfix, firefox68+ verified, firefox69+ verified)

VERIFIED FIXED
mozilla69
Tracking Status
firefox-esr60 68+ verified
firefox66 --- wontfix
firefox67 --- wontfix
firefox68 + verified
firefox69 + verified

People

(Reporter: gsmiley, Assigned: jimm)

Details

(Keywords: reporter-external, sec-high, Whiteboard: [reporter-external] [client-bounty-form] [verif?][post-critsmash-triage][adv-main68+][adv-esr60.8+])

Attachments

(9 files)

Cross-origin requests can be made with NPAPI plugins such as Flash which can allow an attacker to perform Cross-Site Request Forgery attacks using otherwise inaccessible HTTP headers such as Content-Type. This can be achieved by sending a request to an attacker controlled server (same-origin request) which will then respond with a 308 redirect with the “Location” header set to the target origin/vulnerable endpoint.

Once the browser receives this 308 redirect, the request is made to the cross-origin endpoint, and in Flash’s case, an immediate request for the target endpoints crossdomain.xml file is requested. However, since the browser has already responded to the 308 redirect, CORS has been violated.

Reproduction Steps:

A modular exploit has been attached including: csrf.html, csrf.as, and firefoxHttpRedirector.py. On a web server under your control, run the firefoxHttpRedirector.py script in the same folder as the csrf.html and compiled flash applet (csrf.swf) files. The command would look something like:

sudo python firefoxHttpRedirector.py --port 80 --target https://vulnerableapp123.com/api/endpoint

Then, once the web server has started, emulate a victim by constructing a CSRF request in the following format:

http://<attack_server>/csrf.html?attackerUrl=http://<attack_server>/&md=POST&jsonData={“foo”:”bar”}&headers=Content-Type:application/json

Where the URL parameters are as follows:

attackerUrl - server where the firefoxHttpRedirector.py script is running
md - HTTP method/verb to use in the request to the target server (GET or POST)
jsonData - body data to be sent to the target server (the parameter is jsonData but any format would work)
headers - headers to include in the request, such as Content-Type

Once the appropriate URL has been constructed, navigate to that URL and note how Firefox
follows the redirection to the target server with the body and headers intact.
I have setup an attack server which can be used as a PoC upon request. Currently I have it configured to be inaccessible however if there’s issues setting up the exploit, I can provide that URL.

Expected behavior:
Firefox does not follow the 308 redirect or waits for a CORS evaluation before following the redirect.

Observed behavior:
Firefox follows the 308 redirect.

Tested versions:
Firefox 66.0.3 x64 (Windows 7 6.1.7601)
Firefox 66.0.2 x64 (Windows 10 10.0.17134)
Firefox ESR 60.6.1esr x64 (macOS Sierra 10.12.6)

References:
https://bugzilla.mozilla.org/show_bug.cgi?id=1436241
https://blog.appsecco.com/exploiting-csrf-on-json-endpoints-with-flash-and-redirects-681d4ad6b31b
https://github.com/sp1d3r/swf_json_csrf

Flags: sec-bounty?
Attached file csrf.html
Attached file csrf.as
Attachment #9057660 - Attachment mime type: application/octet-stream → text/plain

See also bug 1436241. Kyle, looks like you fixed that, any chance you could take a look here?

Group: firefox-core-security → core-security
Type: task → defect
Component: Security → Plug-ins
Flags: needinfo?(kyle)
Product: Firefox → Core

Have there been any updates?

Looks like the code in https://searchfox.org/mozilla-central/source/dom/plugins/base/nsPluginStreamListenerPeer.cpp#578 needs to check for 308 in addition to 307.

Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: sec-high

Jim, can you help find someone to look into this? Thanks.

Flags: needinfo?(jmathies)

Since it's sec-high and looks like a simple return code addition to something I've already worked in, I'll look into it.

Flags: needinfo?(kyle)
Flags: needinfo?(jmathies)

We already don't allow cross origin POST redirects on 307 redirects,
this adds extra guards to make sure we don't allow them on 308s
either.

Assignee: nobody → kyle

Comment on attachment 9060863 [details]
Bug 1543804 - Don't allow cross-origin POST redirects on 308 codes;

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Pretty easily. It's obvious that we're adding a check for a loading mechanism
  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: Yes
  • Which older supported branches are affected by this flaw?: All of them
  • If not all supported branches, which bug introduced the flaw?: None
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: This code hasn't been changed in a while (since the last security issue for 308s), so it shouldn't be too difficult.
  • How likely is this patch to cause regressions; how much testing does it need?: Basic testing of the posted STRs should be fine. This is in plugins, which are slated to be much more difficult to access soon anyways.
Attachment #9060863 - Flags: sec-approval?

This is too late to make this cycle. This has sec-approval+ for June 5, 2019, so we can get it in the next one.

Whiteboard: [reporter-external] [client-bounty-form] [verif?] → [reporter-external] [client-bounty-form] [verif?][checkin on June 5, 2019]
Attachment #9060863 - Flags: sec-approval? → sec-approval+

My last day at Mozilla is May 17th, so we'll need someone else to take over this bug since it's going to be a bit before it lands. :jimm, since this is plugins related, will you be able to continue this?

Flags: needinfo?(jmathies)

(In reply to Al Billings [:abillings] from comment #10)

This is too late to make this cycle. This has sec-approval+ for June 5, 2019, so we can get it in the next one.

68 nightly soft freeze has been extended to May 13. Can we get sec approval to land it in 68 before the soft freeze?

Flags: needinfo?(abillings)

(In reply to Neha Kochar [:neha] from comment #12)

(In reply to Al Billings [:abillings] from comment #10)

This is too late to make this cycle. This has sec-approval+ for June 5, 2019, so we can get it in the next one.

68 nightly soft freeze has been extended to May 13. Can we get sec approval to land it in 68 before the soft freeze?

No. As the sec-approval request says about constructing an exploit from the path:

"Pretty easily. It's obvious that we're adding a check for a loading mechanism"

I don't want us to check this in and have it sitting on trunk for six weeks or more waiting for someone to reverse engineer a 0day of a sec-high related issue. The reason for sec-approval is to narrow this window, especially for more dangerous security issues.

Flags: needinfo?(abillings)
Flags: needinfo?(jmathies)
Assignee: kyle → nobody
Priority: -- → P2

Jim: we need someone to shepherd this patch into Beta 68 in June (see sec-approval comment). Assigning to you for now.

Assignee: nobody → jmathies
Group: core-security → dom-core-security
Flags: needinfo?(jmathies)
Whiteboard: [reporter-external] [client-bounty-form] [verif?][checkin on June 5, 2019] → [checkin on June 5, 2019][reporter-external] [client-bounty-form] [verif?]

https://hg.mozilla.org/integration/autoland/rev/2292724aa3f9

This grafts cleanly to Beta and ESR60 as-landed. Please nominate it for uplift when you get a chance, Jim.

Assignee: jmathies → kyle
Whiteboard: [checkin on June 5, 2019][reporter-external] [client-bounty-form] [verif?] → [reporter-external] [client-bounty-form] [verif?]

Re-assigning to Jim for the uplift, per comment 14.

Assignee: kyle → jmathies
Assignee: jmathies → kyle
Group: dom-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla69
Assignee: kyle → jmathies
Flags: needinfo?(jmathies)

Comment on attachment 9060863 [details]
Bug 1543804 - Don't allow cross-origin POST redirects on 308 codes;

Beta/Release Uplift Approval Request

  • User impact if declined: This fix addresses an undisclosed sec issue in plugin code.
  • Is this code covered by automated tests?: Yes
  • Has the fix been verified in Nightly?: Yes
  • Needs manual test from QE?: No
  • If yes, steps to reproduce:
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): might break something corner case in plugin networking.
  • String changes made/needed:

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: This fix addresses an undisclosed sec issue in plugin code.
  • User impact if declined:
  • Fix Landed on Version: 69
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): might break something corner case in plugin networking.
  • String or UUID changes made by this patch:
Attachment #9060863 - Flags: approval-mozilla-esr60?
Attachment #9060863 - Flags: approval-mozilla-beta?

Comment on attachment 9060863 [details]
Bug 1543804 - Don't allow cross-origin POST redirects on 308 codes;

sec fix, approved for 68.0b9

Attachment #9060863 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Flags: sec-bounty? → sec-bounty+
Flags: sec-bounty+ → sec-bounty?
Summary: Cross-origin requests can be made with NPAPI plugins by following 308 redirects. → Cross-origin requests can be made with NPAPI plugins by following 308 redirects
Flags: sec-bounty? → sec-bounty+

Are you going to be accepting this on ESR60? It has a nomination.

Flags: needinfo?(jcristau)
Flags: needinfo?(jcristau) → needinfo?(pascalc)
Flags: qe-verify+
Whiteboard: [reporter-external] [client-bounty-form] [verif?] → [reporter-external] [client-bounty-form] [verif?][post-critsmash-triage]
QA Whiteboard: [qa-triaged]

Comment on attachment 9060863 [details]
Bug 1543804 - Don't allow cross-origin POST redirects on 308 codes;

Plugin sec issue, approved for 60.8esr.

Flags: needinfo?(pascalc)
Attachment #9060863 - Flags: approval-mozilla-esr60? → approval-mozilla-esr60+

Trying to verify this issue I used the following steps:

  1. I ran the following command in terminal and started my webserver - sudo python firefoxHttpRedirector.py --port 80 --target https://vulnerableapp123.com/api/endpoint (Note: All 3 files were in the same folder from where I started the server)
  2. Opened the latest Firefox Nightly and Used this URL in a new tab - http://localhost:80/csrf.html?attackerUrl=http://localhost:80/&md=POST&jsonData={“foo”:”bar”}&headers=Content-Type:application/json

Actual Results:
In the Network tab I'm getting the exact same 3 Requests in all versions of Firefox , Release 67, Beta 68.0b8, Beta 68.0b12 and Nightly 69.0a1 (2019-06-21):

200 GET localhost http://localhost/csrf.html?attackerUrl=http://localhost:80/&md=POST&jsonData={%E2%80%9Cfoo%E2%80%9D:%E2%80%9Dbar%E2%80%9D}&headers=Content-Type:application/json

308 GET localhost favicon.ico

   GET https://vulnerableapp123.com/api/endpoint

I'm not sure what I'm missing here reproducing this issue and also not sure what I should be seeing on the builds that have the fix.

Flags: needinfo?(jmathies)
Flags: needinfo?(gsmiley)
Attached file 308_log.txt
Flags: needinfo?(gsmiley)
Attached file csrf.swf

Hi Rares,

I'm not sure why it is not working for you.
I have attached a log of the exploit working with the
provided files on Firefox version 60.7.0esr.
I have also attached the compiled csrf.swf file.

On builds that have been fixed, you should see the 308 redirect
from the attack server, then you should see the browser not follow that
redirect.

Hi Gregory, Thank you for the updates, can you please confirm that this issue is Fixed on your end Using our latest Builds ? you can find them here:

ESR - https://index.taskcluster.net/v1/task/gecko.v2.mozilla-esr60.latest.firefox.macosx64-opt/artifacts/public/build/target.dmg

Beta and Nightly -
https://www.mozilla.org/en-US/firefox/channel/desktop/

Please let us know so we can mark this issue accordingly.

I've tried to reproduce this issue in older versions of Firefox as well as our latest nightly but I couldn't see any difference and I'm sure the problem is in my environment, it would help us a lot if you could recheck this issue in our latest builds. Thank you

Flags: needinfo?(gsmiley)

Hi Rares,

Thanks for providing the builds.
I will currently be traveling this week and do not have my macbook with me,
however i tested the exploit against Firefox Quantum Version 68.0b12 (64-bit)
using the beta channel and can confirm that it is not vulnerable. I have attached
a HAR file which shows how the server responds with a 308 redirect code, and the
browser does not follow the redirect code to vulnerableapp123.com. If you could
send me the taskcluster ESR build for a windows 10 64 bit system I can test that
as well.

Flags: needinfo?(gsmiley)

Hi Gregory,
Thanks for taking the time for this issue, here is the build for ESR: https://index.taskcluster.net/v1/task/gecko.v2.mozilla-esr60.latest.firefox.win64-opt/artifacts/public/build/target.zip

You can also find our Firefox Nightly here as well: https://www.mozilla.org/en-US/firefox/channel/desktop/ the fix should be there also. Thanks a lot

Flags: needinfo?(gsmiley)

I went ahead and checked the ESR build you linked (60.7.3esr) and confirmed it is not vulnerable.
Everything looks good. The HAR file for the beta nightly build, is attached in my previous post
so that's good too. You can see in ESR it follows the same behavior where it receives the 308
redirect and does not follow it to the other domain. Let me know if you need anything else.
I am more than happy to help.

Flags: needinfo?(gsmiley)

Thank you Gregory, Based on Comment 30 and Comment 33 I will mark this issue Verified as Fixed.

Status: RESOLVED → VERIFIED
QA Whiteboard: [qa-triaged]
Flags: qe-verify+
Flags: needinfo?(jmathies)

I actually had not confirmed the patch on Firefox 69. However I just performed those tests on the nightly build (69.0a1) and can confirm that version is also patched. I have attached another HAR file to demonstrate that.

Whiteboard: [reporter-external] [client-bounty-form] [verif?][post-critsmash-triage] → [reporter-external] [client-bounty-form] [verif?][post-critsmash-triage][adv-main68+][adv-esr
Whiteboard: [reporter-external] [client-bounty-form] [verif?][post-critsmash-triage][adv-main68+][adv-esr → [reporter-external] [client-bounty-form] [verif?][post-critsmash-triage][adv-main68+][adv-esr60.8+]
Alias: CVE-2019-11712
Group: core-security-release
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: