Closed Bug 1883557 Opened 2 years ago Closed 2 years ago

alert dialog not cleared after iframe navigation to another website

Categories

(Toolkit :: Content Prompts, defect)

defect

Tracking

()

VERIFIED FIXED
126 Branch
Tracking Status
firefox126 --- verified

People

(Reporter: sas.kunz, Assigned: Gijs)

References

Details

(Keywords: csectype-spoof, reporter-external, Whiteboard: [reporter-external] [client-bounty-form] [verif?])

Attachments

(7 files, 1 external file)

Attached file alertdialog1.html —

I found vulnerability that the alert dialog could have been displayed on another website lead to spoof (in iframe)

steps to reproduce:

  1. open alertdialog1.html (the iframe src is http://103.186.0.20/alertdialog.html)
  2. wait until 3 seconds then it will be redirect to https://permission.site
  3. the alert dialog from http://103.186.0.20/alertdialog.html is shown on https://permission.site

OS : windows 10
Firefox Nigthly 125.0a1 (2024-03-03) (64-bit)

Flags: sec-bounty?

update for steps to reproduce:

  1. download alertdialog1.html
  2. open alertdialog1.html (the iframe src is http://103.186.0.20/alertdialog.html)
  3. wait until 3 seconds then it will be redirect to https://permission.site
  4. the alert dialog from http://103.186.0.20/alertdialog.html is shown on https://permission.site

i also tested on Firefox Nightly 125.0a1 (2024-03-04) (64-bit) Desktop Version

Attached file alertdialog2.html —

another using google docs

  1. download alertdialog2.html
    2.open alertdialog2.html (the iframe src is http://103.186.0.20/alertdialog2.html)
  2. wait until 3 seconds then it will be redirect to https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1
  3. the alert dialog from http://103.186.0.20/alertdialog2.html is shown on https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1

update poc using google doc

  1. download alertdialog2.html
    2 .open alertdialog2.html (the iframe src is http://103.186.0.20/alertdialog2.html)
  2. click the button then it will be redirect to https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1
  3. the alert dialog from http://103.186.0.20/alertdialog2.html is shown on https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1

Could you please attach the contents of the two iframe pages to this bug? The 2 HTML files you have attached so far don't show anything interesting. Thanks.

Flags: needinfo?(sas.kunz)
Assignee: nobody → continuation
Attached file iframe1.html —
Flags: needinfo?(sas.kunz)
Attached file iframe2.html —

the iframe1.html for the alertdialog1.html and iframe2.html for the alertdialog2.html

I can reproduce the behavior shown in the video, although it isn't super consistent, because the alert often doesn't appear at all.

However, the fancy iframe navigation the 2 test cases are doing isn't necessary. Just popping up an alert on the top page gives the same behavior, including the part where the iframe gets grayed out, so this feels like it must be deliberate behavior. I'm not sure of the history here. In the test cases here, the top level page and the "alert" don't have to be the same origin, and the top level page isn't doing anything besides loading the iframe page in an iframe, so maybe the test cases here give you some advantage when the top level page is innocent, and is allowed to enclose the page being attacked, and can somehow be convinced to load an arbitrary attacker page?

(My example doesn't work when run from Bugzilla but it does when I run it from file:// or localhost )

See Also: → CVE-2024-1547

including the part where the iframe gets grayed out

Never mind this part. I guess the alert dialogue just makes the entire page gray.

I'm kind of guessing here, but it does look like the attacker iframe is active when the alert pops up (at least when it works), so maybe the issue is that we aren't dismissing the existing alert when we do an iframe navigation the way we do for a top level navigation? I'm not sure how the latter mechanism works. I'll see if I can find how that is supposed to go.

If I'm reading this correctly, an alert goes away on top level navigation because we listen for some events here, but only on the top level window.

(In reply to Andrew McCreight [:mccr8] from comment #13)

(My example doesn't work when run from Bugzilla but it does when I run it from file:// or localhost )

(In reply to Andrew McCreight [:mccr8] from comment #13)

(My example doesn't work when run from Bugzilla but it does when I run it from file:// or localhost )

pada bagian ini anda kurang menambahkan setTimeout("window.location.href='https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1'",100);

to be :

async function myDisplay() {
setTimeout("window.location.href='https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1'",100);
let myPromise = new Promise(function(resolve) {
setTimeout(function() {window.alert('Hello This is from: '+document.domain)}, 300);
});

}

in this section you don't need to add setTimeout("window.location.href='https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1'",100);

to be :

async function myDisplay() {
setTimeout("window.location.href='https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1'",100);
let myPromise = new Promise(function(resolve) {
setTimeout(function() {window.alert('Hello This is from: '+document.domain)}, 300);
});

}

The origin of the iframe must be different from the top level page to distinguish where the dialog alert originates from

(In reply to Hafiizh from comment #18)

in this section you don't need to add setTimeout("window.location.href='https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1'",100);

to be :

async function myDisplay() {
setTimeout("window.location.href='https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1'",100);
let myPromise = new Promise(function(resolve) {
setTimeout(function() {window.alert('Hello This is from: '+document.domain)}, 300);
});

}

sorry you forgot add setTimeout("window.location.href='https://docs.google.com/document/d/1IMZCZYDsoG05-Z8NNFrzfIjkJrmFSpPnchVjWcSCehg/edit?pli=1'",100);

I will give an example: top window page origin: xxx.com , iframe origin: yyy.com in the yyy.com there is a button to go to the google doc page then the victim clicks the button and the alert dialog from yyy.com appears on the google doc page so that the victim believe that it is from the google doc page because it appears on the google doc page

Assignee: continuation → nobody
Keywords: csectype-spoof
Summary: alert dialog could have been displayed on another website lead to spoof in iframe → alert dialog not cleared after iframe navigation to another website

The user has no idea what frames are or aren't present on the page. The alert does say the origin of the message, and for all the user knows that page is still in a frame somewhere. And what can an alert (or prompt()) do? It's misleading, but people don't need this trick to create misleading web content.

Maybe we can clear alerts by detecting the frame navigation, but we don't have to keep it a hidden security bug.

Group: firefox-core-security

Confusingly this seems like something we ought to already have on file but I can't see anything.

Component: Security → Content Prompts
Product: Firefox → Toolkit

https://searchfox.org/mozilla-central/rev/6b1e306175c2284958fb185bab388021e2890ed0/browser/base/content/browser.js#9372 seems to close content prompts on navigation for toplevel navigation, but that won't run for subframes. We can't "just" do the same thing for subframes either because subframe navigation shouldn't close toplevel prompts - we'll need a more complex solution.

Flags: needinfo?(gijskruitbosch+bugs)

Note that this leaves the "old" tab prompt implementation in a broken
state. I'm removing them in the next patch in this stack.

Assignee: nobody → gijskruitbosch+bugs
Status: NEW → ASSIGNED
Flags: needinfo?(gijskruitbosch+bugs)
Blocks: 1705440
Pushed by gijskruitbosch@gmail.com: https://hg.mozilla.org/integration/autoland/rev/79dfddac72f9 clear prompts when actors are destroyed, r=mconley
Pushed by gijskruitbosch@gmail.com: https://hg.mozilla.org/integration/autoland/rev/fec85b4e8ea7 clear prompts when actors are destroyed, r=mconley

Oops. Test failures should be fixed with the updated version of the patch in bug 1705440.

Flags: needinfo?(gijskruitbosch+bugs)
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 126 Branch
Flags: sec-bounty? → sec-bounty-
Flags: qe-verify+

I've replicated this issue using Nightly 125.0a1 (2024-03-04) on Windows 10 x64 following the STR from Comment 2.
Verified as fixed in the latest Firefox 126.0 version on Windows 10 x64, macOS 13, and Ubuntu 22.04, as the issue no longer occurs.

Status: RESOLVED → VERIFIED
Flags: qe-verify+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: