Closed Bug 1584582 (CVE-2021-23957) Opened 3 years ago Closed 2 years ago

iframe sandboxing bypass on Android via intent: url scheme

Categories

(Fenix :: General, defect, P1)

Unspecified
Android
defect

Tracking

(firefox-esr68 wontfix, firefox84 wontfix, firefox85 fixed, firefox86 fixed)

RESOLVED FIXED
Tracking Status
firefox-esr68 --- wontfix
firefox84 --- wontfix
firefox85 --- fixed
firefox86 --- fixed

People

(Reporter: eliya, Assigned: royang)

References

Details

(Keywords: sec-moderate, Whiteboard: [reporter-external] [client-bounty-form] [verif?] [fennec68.3?][post-critsmash-triage][adv-main85+])

Attachments

(2 files, 2 obsolete files)

Hi Team,

This bug is actively being exploited by a prolific malvertiser known as Zirconium in order to serve millions of forced mobile redirections via malicious ad campaigns.

Here's a reference for more information about Zirconium:

https://blog.confiant.com/uncovering-2017s-largest-malvertising-operation-b84cd38d6b85

The bug:

Consider an iframe with the following sandboxing attributes:

"allow-forms allow-pointer-lock allow-popups-to-escape-sandbox allow-popups allow-same-origin allow-scripts allow-top-navigation-by-user-activation"

These are standard sandbox attributes for ad serving, and they're generally meant to mitigate things like forced redirections that are uninitiated. Especially the "allow-top-navigation-by-user-activation" attribute.

Most browsers will block something like this in such an iframe:

top.location.href="http://malicious_landing_page";

Firefox on Android will prevent this redirection as well. However, it will not prevent spawning a redirect that's done in this manner:

location.href = "intent://malicious_landing_page/#Intent;scheme=https;package=com.android.chrome;end";

This payload will spawn Google Chrome from Firefox and open the malicious page without any user interaction. It will also spawn if the allow-popups attribute isn't present. All other major browser successfully prevent this.

This is currently being heavily abused in an ongoing malvertising campaign which is specifically targeting Firefox on Android. We strongly recommend that this be addressed with some urgency as that will have a direct impact on the malvertiser's financial success with this campaign.

This has been tested in the latest Firefox on Android 9 - Samsung Galaxy S8+ as well as several Browserstack instances.

Happy to answer any questions you might have.

Best,
Eliya

Flags: sec-bounty?

Chris, Stefan, who is responsible for handling security bugs for Fennec these days? Can you please get this in the right hands? Thank you.

Component: Security → General
Flags: needinfo?(sarentz)
Flags: needinfo?(cpeterson)
Product: Firefox → Firefox for Android

Thanks for the heads up, Eliya.

location.href = "intent://malicious_landing_page/#Intent;scheme=https;package=com.android.chrome;end";

@ Christoph and James: Fennec allows malicious JS to open ad pages in Chrome (using intent: URIs) without user interaction. Does this sound like a Gecko bug or a Fennec/GeckoView bug?

The Chrome team announced that forced redirects will be blocked in Chrome 64 scheduled for release on January 23.

Group: mobile-core-security
Flags: needinfo?(snorp)
Flags: needinfo?(sarentz)
Flags: needinfo?(cpeterson)
Flags: needinfo?(ckerschb)
OS: Unspecified → Android
Priority: -- → P1
Summary: iframe sandboxing bypass on firefox android via intent url scheme → iframe sandboxing bypass on firefox android via intent: url scheme
Whiteboard: [reporter-external] [client-bounty-form] [verif?] → [reporter-external] [client-bounty-form] [verif?] [fennec68.2?]

Chris, Stefan, who is responsible for handling security bugs for Fennec these days?

To answer your question: Stefan (Fennec engineering manager) and Ashley Thomas (Fennec product manager) are currently responsible for Fennec bug triage.

I think we have to call this "sec-moderate", but that doesn't mean it's not important and urgent to address a campaign in progress.

intents are effectively the same kind of evil as external helper apps or external content handlers on Desktop. We shouldn't be loading any that aren't on an explicit whitelist without asking the user first (an option to "remember this" is fine after that first ask).

Group: firefox-core-security
Type: task → defect
Flags: needinfo?(ckerschb)
Keywords: sec-moderate

Hi Daniel,

For what it's worth, I absolutely agree with what your'e saying and the whitelist approach, but it might be more secure to forbid an iframe from loading an intent without any user activation in the first place.

Just for some reference/context, I believe Chrome made a decision along these lines at some point:

https://developer.chrome.com/multidevice/android/intents

From my testing, it make sense. The functionality is still there if there's a link in the iframe along the lines of <a href="intent:..., but the scenario where a bad actor can cause forced actions is mitigated. It would still be a bit weird if a third party ad can land on a site and this causes the user to be prompted to open chrome or open slack for example.

Best,
Eliya

I think we tried a long time ago to require user interaction here in Fennec but it had some problems. We're facing a similar thing in GeckoView now (bug 1555337), which is why Fenix doesn't support intent urls yet.

Can we just disallow intent urls in iframes entirely? Or will that break some kind of login flow somewhere?

Flags: needinfo?(snorp)

Can we just disallow intent urls in iframes entirely? Or will that break some kind of login flow somewhere?

Who should make this decision? ckerschb? snorp?

If we don't know of any breakage, we could disable intent URIs in GeckoView Nightly and see if anyone complains. Or we could ask QA to do some manual testing of a build with intent URIs disabled.

Flags: needinfo?(ckerschb)
Product: Firefox for Android → GeckoView
Summary: iframe sandboxing bypass on firefox android via intent: url scheme → iframe sandboxing bypass on Android via intent: url scheme

If we disable intent URIs in GeckoView/Fenix without any big problems, would we backport this patch to Fennec ESR 68?

Whiteboard: [reporter-external] [client-bounty-form] [verif?] [fennec68.2?] → [reporter-external] [client-bounty-form] [verif?] [fennec68.3?]

James says this is a Fenix bug. Fenix is not vulnerable at the moment, but might be after they implement support for intent URIs. This bug can be a reminder to test this case in Fenix then.

firefox-esr68=wontfix because we won't fix for Fennec.

Component: General → Security: Android
Product: GeckoView → Fenix

Hi Team,

We are hoping to publish some research in the next few weeks on how this malvertiser leverages these types of browsers quirks in order to maximize the impact of their campaigns. This example is a great case and we would like to talk about it pubclicly. Can you please let us know if this interferes with your efforts towards a fix? If so, what do you consider a reasonable timeline?

Best,
Eliya

needinfo Chris for comment 10, since the talk would presumably include our shipping product (Fennec) where this is wontfixed and not our not-yet-release Fenix.

Can we just disallow intent urls in iframes entirely? Or will that break some kind of login flow somewhere?

Without telemetry I don't see how we can answer this (or shipping the change to see what breaks). I suspect most "open me in this app" will be links and not iframes, but that's an uneducated guess.

Flags: needinfo?(ckerschb) → needinfo?(cpeterson)

(In reply to Daniel Veditz [:dveditz] from comment #11)

needinfo Chris for comment 10, since the talk would presumably include our shipping product (Fennec) where this is wontfixed and not our not-yet-release Fenix.

Can we just disallow intent urls in iframes entirely? Or will that break some kind of login flow somewhere?

Without telemetry I don't see how we can answer this (or shipping the change to see what breaks). I suspect most "open me in this app" will be links and not iframes, but that's an uneducated guess.

^ redirecting to Emily Toop, GeckoView engineering manager.

(I'm no longer working on GeckoView these days.)

Flags: needinfo?(cpeterson) → needinfo?(etoop)

This bug does not affect Fenix, only Fennec and so is not required.

Flags: needinfo?(etoop)
Status: UNCONFIRMED → RESOLVED
Closed: 3 years ago
Resolution: --- → INVALID

It was filed against Fennec and is NOT "invalid" -- it's an active malvertising campaign. It got bounced to GeckoView in the mistaken assumption it was backend code, and then bounced back to the wrong front-end where the abused feature is not (yet?) supported. Moving back. Maybe it's wontfix given our intended migration to Fenix in that case, but not invalid.

Status: RESOLVED → REOPENED
Component: Security: Android → General
Ever confirmed: true
Product: Fenix → Firefox for Android
Resolution: INVALID → ---
Version: unspecified → Firefox 68
Flags: sec-bounty? → sec-bounty+

Agi/Christian we should verify Fenix/GV example behavior on this. AFIK we have implemented intent handling code in Fenix so this should still apply if we have not made any mitigations.

Status: REOPENED → NEW
Component: General → Security: Android
Flags: needinfo?(csadilek)
Flags: needinfo?(agi)
Product: Firefox for Android → Fenix
Version: Firefox 68 → unspecified

Agi is on PTO

Flags: needinfo?(agi)

I've verified that this is reproducible in Fenix and needs a fix in A-C's AppLinksInterceptor. We should check if it the load request is a subframe request and not handle/intercept it in this case.

Adding Roger.

Flags: needinfo?(csadilek)
Assignee: nobody → royang
Attachment #9193055 - Flags: review?(csadilek)
Comment on attachment 9193055 [details] [diff] [review]
applinks_subframe_request.patch

Review of attachment 9193055 [details] [diff] [review]:
-----------------------------------------------------------------

I've verified this prevents the forced redirect described above. Let's add a unit test for this case before landing on GH.
Attachment #9193055 - Flags: review?(csadilek) → review+

I've verified this prevents the forced redirect described above. Let's add a
unit test for this case before landing on GH.

Understood. Thanks

Fix merged in Android Component

Status: NEW → RESOLVED
Closed: 3 years ago2 years ago
Resolution: --- → FIXED

Can you please include a link to the AC commit that fixed this? Also, which AC version is it shipping in?

Group: mobile-core-security → core-security-release
Flags: needinfo?(royang)

Sure, this is the pr https://github.com/mozilla-mobile/android-components/pull/9218. This change was merged in AC 70. Thanks,

Flags: needinfo?(royang)
Whiteboard: [reporter-external] [client-bounty-form] [verif?] [fennec68.3?] → [reporter-external] [client-bounty-form] [verif?] [fennec68.3?][post-critsmash-triage]
Whiteboard: [reporter-external] [client-bounty-form] [verif?] [fennec68.3?][post-critsmash-triage] → [reporter-external] [client-bounty-form] [verif?] [fennec68.3?][post-critsmash-triage][adv-main85+]
Attached file advisory.txt (obsolete) —
Attached file advisory.txt (obsolete) —
Attachment #9198095 - Attachment is obsolete: true
Attached file advisory.txt
Attachment #9198121 - Attachment is obsolete: true
Alias: CVE-2021-23957

Hey Freddy - Is it appropriate to reference this CVE publicly yet? At what point does this issue become public?

Thanks,
Eliya

The 85.1.0 and 85.1.1 builds has been at a 25% rollout until about 10 Pacific/18 UTC today. We bumped to 99% and are planning on going to 100% early next week baring any major issues cropping up. Until we push to 100% there is no way for Google Play users to force the update. It is just how the Play Store works.

A few weeks after that should be fine see previous example in bug 1659381 comment 19 and bug 1659381 comment 23

Thanks Kevin!

Group: core-security-release
See Also: → 1730854
Component: Security: Android → General
You need to log in before you can comment on or make changes to this bug.