Closed Bug 1657026 (CVE-2020-26954) Opened 4 years ago Closed 4 years ago

Any websites can run with PWA privileges on Fenix


(Fenix :: General, defect)



(firefox-esr78 wontfix, firefox82 wontfix, firefox83 fixed)

Tracking Status
firefox-esr78 --- wontfix
firefox82 --- wontfix
firefox83 --- fixed


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



(Keywords: csectype-other, sec-moderate, Whiteboard: [reporter-external] [client-bounty-form] [verif?][adv-main83+])


(3 files, 2 obsolete files)

Attached file dummy_manifest.json

Fenix has a public interface that allows any apps to inject arbitrary PWA manifest for any origin.
That can be used for installing malicious PWAs on victim's device silently.
The installed PWA runs in fullscreen so spoofing address bar is possible by their contents.
Also through the malicious PWA's manifest, fake share_target (tries to steal victim's shared contents) can be registered (below).

The root cause is that LauncherActivity in Fenix is publicly accessible (below).
That activity receives MANIFEST_PATH key from incoming intent and store the specified manifest file to internal manifest database (below).

Here is the demo.

  1. Save attached dummy_manifest.json file to your PC and send it to the connected Android device through ADB.
adb push dummy_manifest.json /data/local/tmp/dummy_manifest.json
  1. Inject the manifest for via org.mozilla.gecko.WEBAPP intent.
adb shell am start -a org.mozilla.gecko.WEBAPP -d '' -n org.mozilla.fenix/org.mozilla.gecko.LauncherActivity --es MANIFEST_PATH /data/local/tmp/dummy_manifest.json
  1. Then, is shown in fullscreen (without address bar). That means PWA for is injected.

  2. Once inject the PWA, you can invoke through mozilla.components.feature.pwa.VIEW_PWA intent. Then, it runs again in fullsreen.

adb shell am start -a mozilla.components.feature.pwa.VIEW_PWA -d ''

  1. If you choose Delete browsing data from Setting menu, injected PWA can not be cleared.
    You need to remove all storage data of Fenix or re-install.
Flags: sec-bounty?
Attached image Demo
Group: firefox-core-security → mobile-core-security
Type: task → defect
Component: Security → General
Product: Firefox → GeckoView

Sebastian, are you the right person to look at this and bug 1657055 ? They look pretty serious.

Flags: needinfo?(s.kaspari)
Flags: needinfo?(s.kaspari)

I can take a look and if necessary find someone on the team to continue.

sec-moderate, I think this requires a "bad app", right?

Yes, bad app is required so I agree with you!

Assignee: nobody → tigeroakes

Assigning this to Tiger who has agreed to take a look at this.

I've got a PR ready in Fenix to validate the manifest location inside the app files before reading it. Is something like "validates manifest folder" obscure enough for a Fenix bug/PR title?

Is something like "validates manifest folder" obscure enough for a Fenix bug/PR title?

Yup that sounds fine. Thank you for picking this up to quickly.

Flags: needinfo?(tigeroakes)
Component: General → Security: Android
Product: GeckoView → Fenix

Stefan, is Tiger still working on it? If not, can you please reassign. Thanks!

Flags: needinfo?(sarentz)

Looks like this was merged in August

Closed: 4 years ago
Flags: needinfo?(sarentz)
Resolution: --- → FIXED

What version of Fenix did (will?) this ship in? We will need an advisory for it.

Flags: needinfo?(kbrosnan)
Flags: sec-bounty? → sec-bounty+
Group: core-security-release

Sebastian would you have a look? I was not able to see any behavior difference between 80.x and Nightly 83. Using the steps in comment 0 crashes with the display already required. If I kill the app between the two adb shell commands then it works.

Flags: needinfo?(s.kaspari)
Resolution: FIXED → ---
Assignee: tigeroakes → s.kaspari

In 80 I see us pick up the manifest and save it to disk for later and using the values from the manifest. In 83 the manifest gets rejected (since it is not in the expected location) and we launch in a "custom tab fallback mode" just loading the URL. So this looks good and as intended.

Along the way I found a possible crash (I used some invalid manifest) and opened a PR to catch parsing errors.

Using the steps in comment 0 crashes with the display already required.

I didn't run into this one. Maybe we can look at this outside of this bug. If we can extract some STRs for the "display already acquired" bug then this would be helpful for something else. :)

Closed: 4 years ago4 years ago
Flags: needinfo?(s.kaspari)
Resolution: --- → FIXED
Group: mobile-core-security
Flags: needinfo?(kbrosnan)
Whiteboard: [reporter-external] [client-bounty-form] [verif?] → [reporter-external] [client-bounty-form] [verif?][adv-main83+]
Attached file advisory.txt (obsolete) —
Attached file advisory.txt (obsolete) —
Attachment #9187097 - Attachment is obsolete: true
Attached file advisory.txt
Attachment #9187316 - Attachment is obsolete: true
Alias: CVE-2020-26954
See Also: → CVE-2021-23976
Group: core-security-release
Component: Security: Android → General
OS: Unspecified → Android
You need to log in before you can comment on or make changes to this bug.