Same-site cross-origin iframes can request notification permission (and with wrong prompt on Android)
Categories
(Core :: DOM: Notifications, defect)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox-esr115 | --- | unaffected |
| firefox-esr128 | --- | unaffected |
| firefox-esr140 | 145+ | fixed |
| firefox141 | --- | wontfix |
| firefox142 | --- | wontfix |
| firefox143 | --- | wontfix |
| firefox144 | --- | wontfix |
| firefox145 | + | verified |
People
(Reporter: apapedulimu, Assigned: saschanaz)
References
(Regression)
Details
(4 keywords, Whiteboard: [adv-main145+][adv-ESR140.5+])
Attachments
(6 files)
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Steps to reproduce:
- Go to https://dev.apapedulimu.click/index.php?url=https://long-domain-tester-accounts-subdo-tester-domain-accounts-google.comvulnerability.bug.apapedulimu.click/test.html
- Click "Request Notification" Button
- Observe the notification permission prompt that appears. Youβll notice that the prompt displays the top-level domain (dev.apapedulimu.click) as the source of the request β not the actual origin (*.google.comvulnerability.bug.apapedulimu.click) of the embedded iframe that triggered the request.
Actual results:
When a cross-origin iframe requests notification permission via Notification.requestPermission(), Firefox shows the top-level (main frame) origin in the permission prompt instead of the origin that actually initiated the request.
As a result, the user sees a trusted domain (e.g., dev.apapedulimu.click) requesting the permission, while in reality, the request originated from an embedded third-party domain (e.g., *.google.comvulnerability.bug.apapedulimu.click).
This allows an attacker to spoof the origin shown in the permission dialog, misleading users into granting notification access to an untrusted or malicious domain.
Expected results:
Browsers should show the actual origin making the request β in this case, (*.google.comvulnerability.bug.apapedulimu.click).
The prompt should display the origin of the requester (iframe), just like Firefox Desktop correctly does.
| Reporter | ||
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
| Reporter | ||
Comment 1•1 year ago
|
||
Hi Team,
Iβd like to clarify that using a long URL is not necessary to reproduce this issue. By following the steps below, youβll see that the notification request originates from dev.apapedulimu.click, as shown in the attached screenshot.
Steps to Reproduce:
- Open this URL:
https://dev.apapedulimu.click/index.php?url=https://labs.apapedulimu.click/browser/notif.html - Click Request Notification
Let me know if you need any additional details.
Best,
Nosa Shandy
Updated•1 year ago
|
Comment 2•1 year ago
|
||
Kagami: I think you're doing notification stuff. According to this testcase notifications are allowed to be requested by a framed site, in the framed-site's own name without having to do the permission-policy related "allow" attribute on the frame. Is that right? Seems very inconsistent with all the other permissions.
But the android behavior of showing the top-level domain would only be correct if there was "permission forwarding" via permission-policy allow so either way it looks broken on Android. Just not sure if it's broken on desktop also.
| Assignee | ||
Comment 3•1 year ago
|
||
It's not supposed to open prompts at all, this is a regression π¬
| Assignee | ||
Updated•1 year ago
|
Updated•1 year ago
|
| Assignee | ||
Comment 4•1 year ago
•
|
||
But I'm very confused about the test case. It seems Fission doesn't separate the processes between the parent and the iframe, even though they are cross origin? I see only one process for the tab when there should be two.
RequestPermission ends up thinking it's requested via a first party princpal and does not block the request.
| Assignee | ||
Comment 5•1 year ago
•
|
||
navigator.storage.getDirectory() also gets the unpartitioned storage. I fear this is more than just notification.
Comment 6•1 year ago
|
||
(In reply to Kagami Rosylight [:saschanaz] (they/them) from comment #4)
But I'm very confused about the test case. It seems Fission doesn't separate the processes between the parent and the iframe, even though they are cross origin? I see only one process for the tab when there should be two.
They are different origins, but same-site, IIUC.
Comment 7•1 year ago
|
||
(Also the original test case is on Android which doesn't have Fission at all.)
| Assignee | ||
Comment 8•1 year ago
|
||
Ah. TIL we don't partition for same sites.
Back to the missed question:
According to this testcase notifications are allowed to be requested by a framed site, in the framed-site's own name without having to do the permission-policy related "allow" attribute on the frame. Is that right? Seems very inconsistent with all the other permissions.
The intention is basically to not allow any third party permission request nor notifications.
Comment 9•1 year ago
|
||
Set release status flags based on info from the regressing bug 1914417
| Assignee | ||
Comment 10•1 year ago
|
||
The new behavior doesn't match Chrome either, back to Notification.
(I wonder how severe this is if it's same site)
| Assignee | ||
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Comment 11•1 year ago
|
||
(In reply to Nosa Shandy from comment #1)
Iβd like to clarify that using a long URL is not necessary to reproduce this issue. By following the steps below, youβll see that the notification request originates from dev.apapedulimu.click, as shown in the attached screenshot.
Yes, the underlying problem is not about URL truncation or spoofing.
Years ago most folks working on browsers realized that cross-origin iframes requesting a permission was inherently spoofy. Even if the permission dialog says the real origin name, many users are likely to assume it's the top-level site asking because that's the only URL they see associated with the page. So we ended up with Permissions Policy, where cross-origin frames can only use a permission if the top-level page explicitly delegates its to the iframe. And when it has, the prompt the user sees shows the name of the top-level site, because that is the site that will get the permission (if the user saves it). If granted, the framed site can now use the permission because it's delegated.
The Notification API isn't part of the Permission-Policy model. Years ago Chromium and Firefox agreed it should be restricted to same-origin frames only. Safari, however, still has the original behavior of asking for the permission in the name of the framed site. That restriction was broken (by bug 1914417 according to Kagami) and Firefox desktop reverted to its old Safari-matching behavior.
The newer Firefox for Android front end never had to deal with notifications as a special case, so it apparently assumes any permission request must be following the Permission-Policy inheritance model. If there are any other non-standard permissions that could still be a problem after this Notification API regression is fixed. It may mean that the GeckoView layer is not forwarding the requesting origin to the front-end.
Comment 12•1 year ago
|
||
The permission seems to be saved with the domain shown in the prompt. On Desktop the permissions is granted to https://long-domain-tester-accounts-subdo-tester-domain-accounts-google.comvulnerability.bug.apapedulimu.click, and you can go there by itself and see that it works. On Android the permission is not granted to the subdomain and visiting that on its own does not have a remembered permission, but it acts as if dev.apapedulimu.click has a remembered delegated permission
| Reporter | ||
Comment 13•1 year ago
|
||
Thanks so much for the clarification Daniel Veditz, really appreciate the detailed response!
Just to confirm:
Will this be considered a security vulnerability, since it allows cross-origin iframes to trigger permission prompts (which shouldnβt be allowed)? Or is it being tracked as a functionality issue?
Either way, Iβm looking forward to the next update. Let me know if I can help retest anything as things move forward!
Updated•1 year ago
|
| Reporter | ||
Updated•1 year ago
|
| Assignee | ||
Comment 15•1 year ago
|
||
I'm confused by the lack of sec tag at all now, and my question in comment #10 still applies.
| Assignee | ||
Updated•1 year ago
|
Comment 16•1 year ago
|
||
Set release status flags based on info from the regressing bug 1914417
Updated•1 year ago
|
Comment 17•1 year ago
|
||
re: question in comment 10: -- yes, it's "less bad" that it's not full cross-origin, but it's still wrong.
| Assignee | ||
Updated•1 year ago
|
| Assignee | ||
Comment 18•1 year ago
|
||
Bug 1988751 sounds like the right and easiest fix.
Comment 19•11 months ago
|
||
I assume we'll want to backport bug 1988751 to Beta & ESR140? Please nominate if yes.
Updated•11 months ago
|
Updated•11 months ago
|
Updated•11 months ago
|
Updated•11 months ago
|
| Assignee | ||
Comment 20•11 months ago
|
||
Err, it's actually not ABA, it's AA...
Updated•11 months ago
|
| Assignee | ||
Comment 21•11 months ago
|
||
Including same sites.
| Assignee | ||
Comment 22•11 months ago
|
||
Updated•11 months ago
|
Comment 23•11 months ago
|
||
The bug is marked as tracked for firefox144 (beta) and tracked for firefox145 (nightly). However, the bug still has low severity.
:hsinyi, could you please increase the severity for this tracked bug? If you disagree with the tracking decision, please talk with the release managers.
For more information, please visit BugBot documentation.
| Assignee | ||
Comment 24•11 months ago
|
||
Reviewers sure should have CC...
Updated•11 months ago
|
Comment 25•11 months ago
|
||
Comment 26•11 months ago
|
||
Comment 27•11 months ago
|
||
Backed out for causing mochitest failures @test_notification_crossorigin_iframe.html.
Updated•11 months ago
|
| Assignee | ||
Updated•11 months ago
|
Comment 28•11 months ago
|
||
Comment 29•11 months ago
|
||
Comment 30•11 months ago
|
||
firefox-esr140 Uplift Approval Request
- User impact if declined: Misleading permission prompt with different domain
- Code covered by automated testing: yes
- Fix verified in Nightly: yes
- Needs manual QE test: no
- Steps to reproduce for manual QE testing:
- Risk associated with taking this patch: low
- Explanation of risk level: Reverting to the previous behavior
- String changes made/needed: N/A
- Is Android affected?: yes
| Assignee | ||
Comment 31•11 months ago
|
||
Including same sites.
Original Revision: https://phabricator.services.mozilla.com/D267012
Comment 32•11 months ago
|
||
I was able to repro this issue using an affected Nightly build (2025-08-04) with STR from comment 1 on Win 11.
The issue is verified as fixed on latest Nightly 145.0a1 under Win 11, macOS 15 and Ubuntu 24.
Updated•11 months ago
|
Updated•11 months ago
|
Updated•11 months ago
|
Comment 33•11 months ago
|
||
| uplift | ||
Updated•10 months ago
|
Comment 34•10 months ago
|
||
Updated•10 months ago
|
Comment 35•8 months ago
|
||
Comment 36•8 months ago
|
||
Updated•3 months ago
|
Description
•