Closed Bug 1366818 (CVE-2021-38508) Opened 7 years ago Closed 3 years ago

Spoofing dialog and don't exit fullscreen mode

Categories

(Core :: DOM: Core & HTML, defect, P1)

54 Branch
defect

Tracking

()

VERIFIED FIXED
95 Branch
Tracking Status
firefox-esr78 --- wontfix
firefox-esr91 94+ verified
firefox93 --- wontfix
firefox94 + verified
firefox95 + verified

People

(Reporter: Laraweron, Assigned: Gijs)

References

Details

(Keywords: csectype-spoof, sec-moderate, Whiteboard: [adv-main94+][adv-esr91.3+])

Attachments

(15 files, 2 obsolete files)

Attached image dialog.jpg
User Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36

Steps to reproduce:

Open Poc
1.spoof.html.(Fake Message Box)
2.spoof2.html (Spoofing Notification window)
3.fullscreen.html (Don't exit fullscreen mode)


Actual results:

SetCustomValidity method displays a message on top of all Windows, under certain circumstances, this may lead to the substitution of the message browser
Attached file spoof(old_not work).html (obsolete) —
Attached file spoof2.html
Attached file fullscreen.html
Attachment #8870075 - Attachment description: spoof.html → spoof(old_not work).html
Attached file spoof.html
Component: Untriaged → DOM: Core & HTML
Product: Firefox → Core
I believe that this is a security error
Group: core-security
I'm bouncing this back to front-end. The "Core" back-end components seem to be handling things OK and just set state; it's the UX that's wrong for both examples. The popup is positioned and displayed from browser/modules/FormSubmitObserver.jsm

1) the popup is displayed relative to the form element, but no attempt is made to make sure the form element is visible or on-screen. Web Content must not be able to trigger Web-supplied text into a chrome element that can float outside the browser window. By positioning the element just off screen the message pointer bleeds into the browser chrome and can spoof a legit door hanger, or in this case try to cover up part of one of our own door hangers.

NB: the spoof2 example is not terribly convincing in Nightly, in part because we've changed our UI and things no longer line up. Ignore the sloppiness, assume that with more care this could be customized to each platform and version. Focus instead on the fact that a floating top-most element has escaped the "line of death" (https://textslashplain.com/2017/01/14/the-line-of-death/ )

2) the fullscreen example is annoying, but probably should be a separate bug. You can escape using hotkeys to switch to another tab, or Cmd-W to close the window. Why is this example able to eat the ESC that quits fullscreen, but not the others? In any case fullscreen content should never be able to evade ESC.

Gijs: what would be a better component for this bug?
Component: DOM: Core & HTML → General
Flags: needinfo?(gijskruitbosch+bugs)
Product: Core → Firefox
Group: core-security → firefox-core-security
> NB: the spoof2 example is not terribly convincing in Nightly, in part
> because we've changed our UI and things no longer line up. 

Changed the code for version 55 Firefox Nightly
Attached image Nightly.jpg
(In reply to Daniel Veditz [:dveditz] from comment #7)
> I'm bouncing this back to front-end. The "Core" back-end components seem to
> be handling things OK and just set state; it's the UX that's wrong for both
> examples. The popup is positioned and displayed from
> browser/modules/FormSubmitObserver.jsm
> 
> 1) the popup is displayed relative to the form element, but no attempt is
> made to make sure the form element is visible or on-screen.

Actually, this isn't quite true - we do make an 'attempt' to check the form element is visible, see bug 1319078. I'm not sure why the focus manager thinks opacity:0 elements are focusable... we can add lazy bounds checking for the scroll position stuff, and/or constrain at what positions we allow the popup to open in the first place.

> Web Content must
> not be able to trigger Web-supplied text into a chrome element that can
> float outside the browser window.

This sounds like we should just stop showing custom validity error messages at all, then. We don't have in-browser-content-anchored popups.

> By positioning the element just off screen
> the message pointer bleeds into the browser chrome and can spoof a legit
> door hanger, or in this case try to cover up part of one of our own door
> hangers.

I don't think any interaction is possible with these form validity popups.

> NB: the spoof2 example is not terribly convincing in Nightly, in part
> because we've changed our UI and things no longer line up. Ignore the
> sloppiness, assume that with more care this could be customized to each
> platform and version. Focus instead on the fact that a floating top-most
> element has escaped the "line of death"
> (https://textslashplain.com/2017/01/14/the-line-of-death/ )
> 
> 2) the fullscreen example is annoying, but probably should be a separate
> bug.

Yes.

> You can escape using hotkeys to switch to another tab, or Cmd-W to
> close the window. Why is this example able to eat the ESC that quits
> fullscreen, but not the others? In any case fullscreen content should never
> be able to evade ESC.

The form submit popup eats escape to hide that popup, and it's reshown every 50ms because the form is submitted every 50ms.

IMO we should use the popup blocker (ie require user input) to control form submissions and/or the showing of these validity messages, but I don't know if that would break the web. What do other browsers that implement custom validity form submission checking do with this stuff?

> Gijs: what would be a better component for this bug?

Typically form validation stuff has lived in Core::DOM, judging by e.g. bug 1088761 and bug 1319078, so I think the original component was correct... anyway, :jdai, are you able to take a look at this? I can help with reviews etc., but I don't have cycles to dive into this in detail right now.
Flags: needinfo?(gijskruitbosch+bugs) → needinfo?(jdai)
In the 55th version of Firefox, the notification message about the geolocation is added to the alert, but there is no such word when using the function. (navigator.mediaDevices.getUserMedia)
I changed the code for version 55 Firefox.
Example: http://laraweron.mysit.ru/ff/ff_night.html
I assume that the function (navigator.mediaDevices.getUserMedia)  requires a corresponding message.
Attached image Nightly_2.jpg
> > Gijs: what would be a better component for this bug?
> 
> Typically form validation stuff has lived in Core::DOM, judging by e.g. bug
> 1088761 and bug 1319078, so I think the original component was correct...
> anyway, :jdai, are you able to take a look at this? I can help with reviews
> etc., but I don't have cycles to dive into this in detail right now.

Sure. I would like to take this bug. I also set this bug to Core::DOM component. Feel free to reset component if anyone have concern.
Assignee: nobody → jdai
Group: firefox-core-security
Status: UNCONFIRMED → ASSIGNED
Component: General → DOM
Ever confirmed: true
Flags: needinfo?(jdai)
Product: Firefox → Core
Re-adding the sec flag.
Group: core-security
(In reply to :Gijs from comment #11)
> I don't think any interaction is possible with these form validity popups.

No, but they can cover other elements and gain some authority by being able to appear anchored outside the content window. The screenshots here might be about the worst you can do: try to elicit clicks on some other permission prompt by "replacing" the text. It's not terribly convincing if you see these a lot (there's a drop shadow across the top of the buttons, plus the font/style is all wrong) but might fool a more casual user. Maybe put up a message "from the browser" about some emergency patch and when the user clicks open up a fake Mozilla site as part of a social engineering attack.
Group: core-security → dom-core-security
Component: DOM → DOM: Core & HTML
After I tested other browsers behavior, Chrome and Safari have same behavior as firefox which means it'll keep showing popup window every small time period. The test is spoof2(Nightly-55ver).html.
Priority: -- → P3
Assignee: jdai → nobody
Status: ASSIGNED → NEW
See Also: → 1437219
Attached image Screenshot_2.jpg

After two years, this bug has not been fixed why ?
Test PoC https://karmaim.000webhostapp.com/2019.html

Flags: needinfo?(dveditz)
Flags: needinfo?(dveditz) → needinfo?(htsai)

Thanks for comments and reporting the issue. We weren't getting to the bug as we were working on other critical or higher priority issues according to the triage result. Thank you for the understanding.

Flags: needinfo?(htsai)

(In reply to Raphael from comment #18)

Created attachment 9106012 [details]
Screenshot_2.jpg

After two years, this bug has not been fixed why ?
Test PoC https://karmaim.000webhostapp.com/2019.html

Dear reporter,

I'm fixing bug 1551758, I hope it can fix this issue. Thank you for your patient.

(In reply to John Dai[:jdai] from comment #20)

(In reply to Raphael from comment #18)

Created attachment 9106012 [details]
Screenshot_2.jpg

After two years, this bug has not been fixed why ?
Test PoC https://karmaim.000webhostapp.com/2019.html

Dear reporter,

I'm fixing bug 1551758, I hope it can fix this issue. Thank you for your patient.

After fixed bug 1551758, It prevents keep showing popup window every small time period. However, it still show custom validity popups and cover part of door hanger in spoof2(Nightly-55ver).html.

(In reply to :Gijs (he/him) from comment #11)

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

I'm bouncing this back to front-end. The "Core" back-end components seem to
be handling things OK and just set state; it's the UX that's wrong for both
examples. The popup is positioned and displayed from
browser/modules/FormSubmitObserver.jsm

  1. the popup is displayed relative to the form element, but no attempt is
    made to make sure the form element is visible or on-screen.

Actually, this isn't quite true - we do make an 'attempt' to check the form
element is visible, see bug 1319078. I'm not sure why the focus manager
thinks opacity:0 elements are focusable... we can add lazy bounds checking
for the scroll position stuff, and/or constrain at what positions we allow
the popup to open in the first place.

The test spoof2(Nightly-55ver).html set opacity:1 at test() function. In bug 1319078, we did check form element visibility, however, we treat offscreen elements can be focused in here. AFAICK, focus manager are following as spec said for offscreen elements can be focused. According below comments, I think we should stop showing form validity error messages if the elements are not in the browser's viewport. Does that sounds make sense to you?

Web Content must
not be able to trigger Web-supplied text into a chrome element that can
float outside the browser window.

This sounds like we should just stop showing custom validity error messages
at all, then. We don't have in-browser-content-anchored popups.

By positioning the element just off screen
the message pointer bleeds into the browser chrome and can spoof a legit
door hanger, or in this case try to cover up part of one of our own door
hangers.

I don't think any interaction is possible with these form validity popups.

Flags: needinfo?(gijskruitbosch+bugs)

(In reply to John Dai[:jdai] from comment #21)

(In reply to John Dai[:jdai] from comment #20)

(In reply to Raphael from comment #18)

Created attachment 9106012 [details]
Screenshot_2.jpg

After two years, this bug has not been fixed why ?
Test PoC https://karmaim.000webhostapp.com/2019.html

Dear reporter,

I'm fixing bug 1551758, I hope it can fix this issue. Thank you for your patient.

After fixed bug 1551758, It prevents keep showing popup window every small time period. However, it still show custom validity popups and cover part of door hanger in spoof2(Nightly-55ver).html.

(In reply to :Gijs (he/him) from comment #11)

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

I'm bouncing this back to front-end. The "Core" back-end components seem to
be handling things OK and just set state; it's the UX that's wrong for both
examples. The popup is positioned and displayed from
browser/modules/FormSubmitObserver.jsm

  1. the popup is displayed relative to the form element, but no attempt is
    made to make sure the form element is visible or on-screen.

Actually, this isn't quite true - we do make an 'attempt' to check the form
element is visible, see bug 1319078. I'm not sure why the focus manager
thinks opacity:0 elements are focusable... we can add lazy bounds checking
for the scroll position stuff, and/or constrain at what positions we allow
the popup to open in the first place.

The test spoof2(Nightly-55ver).html set opacity:1 at test() function. In bug 1319078, we did check form element visibility, however, we treat offscreen elements can be focused in here. AFAICK, focus manager are following as spec said for offscreen elements can be focused. According below comments, I think we should stop showing form validity error messages if the elements are not in the browser's viewport. Does that sounds make sense to you?

I think it makes sense not to show the validation error message if the element is outside the viewport. We can probably check this in the parent, and check that the point at which we're anchoring the validation popup is within the bounds of the frame for the originating browsing context.

However, we probably want to make sure that on a normal, non-bad-actor page, we scroll broken form elements that show the validity error into view? Maybe? Or are there spec reasons not to do that?

Flags: needinfo?(gijskruitbosch+bugs) → needinfo?(jdai)

(In reply to :Gijs (he/him) from comment #22)

I think it makes sense not to show the validation error message if the element is outside the viewport. We can probably check this in the parent, and check that the point at which we're anchoring the validation popup is within the bounds of the frame for the originating browsing context.

However, we probably want to make sure that on a normal, non-bad-actor page, we scroll broken form elements that show the validity error into view? Maybe? Or are there spec reasons not to do that?

The spec doesn't define UI behavior for validation popup and any focusable invalid fields will show the error outline. I expect we will show validation popup at first invalid element in the viewport, and show the error outline for focusable invalid elements which including outside the viewport's invalid elements.

Flags: needinfo?(jdai)

(In reply to John Dai[:jdai] from comment #23)

(In reply to :Gijs (he/him) from comment #22)

I think it makes sense not to show the validation error message if the element is outside the viewport. We can probably check this in the parent, and check that the point at which we're anchoring the validation popup is within the bounds of the frame for the originating browsing context.

However, we probably want to make sure that on a normal, non-bad-actor page, we scroll broken form elements that show the validity error into view? Maybe? Or are there spec reasons not to do that?

The spec doesn't define UI behavior for validation popup and any focusable invalid fields will show the error outline. I expect we will show validation popup at first invalid element in the viewport, and show the error outline for focusable invalid elements which including outside the viewport's invalid elements.

OK. Then yeah, this makes sense - are you able to work on this?

Flags: needinfo?(jdai)

(In reply to :Gijs (he/him) from comment #24)

(In reply to John Dai[:jdai] from comment #23)

(In reply to :Gijs (he/him) from comment #22)

I think it makes sense not to show the validation error message if the element is outside the viewport. We can probably check this in the parent, and check that the point at which we're anchoring the validation popup is within the bounds of the frame for the originating browsing context.

However, we probably want to make sure that on a normal, non-bad-actor page, we scroll broken form elements that show the validity error into view? Maybe? Or are there spec reasons not to do that?

The spec doesn't define UI behavior for validation popup and any focusable invalid fields will show the error outline. I expect we will show validation popup at first invalid element in the viewport, and show the error outline for focusable invalid elements which including outside the viewport's invalid elements.

OK. Then yeah, this makes sense - are you able to work on this?

Yes, I'm working on it. :-)

Flags: needinfo?(jdai)

If the invalid form element offscreen, it won't display validation popup
for user.

Assignee: nobody → jdai
Status: NEW → ASSIGNED

I'm not very familiar with the door hanger, but basically, we should make the geolocation door hanger at the top of the window, otherwise, form invalid pop-up still can cover the geolocation door hanger. Maybe adding z-index to the door hanger to achieve it, but I could be wrong.

(In reply to John Dai[:jdai] from comment #27)

Created attachment 9119114 [details]
spoof_cover_screenshot.png

I'm not very familiar with the door hanger, but basically we should make door hanger at the top of the window, otherwise, form invalid pop-up still can cover the door hanger. Maybe adding z-index to the door hanger to achieve it.

They're both popups, I don't know that we can specify a relative ordering. I don't think z-index comes into it, because they're different OS-level widgets - but I could well be wrong. Neil, do you know?

Flags: needinfo?(enndeakin)

We could also just make sure that form validation popups hide permission doorhangers and vice versa.

(In reply to :Gijs (he/him) from comment #29)

We could also just make sure that form validation popups hide permission doorhangers and vice versa.

Upload chromium behavior for reference.

Gijs, Neil: Is it possible to enforce a rule where any doorhangers that are anchored to elements in web content are always displayed below doorhangers that are anchored to elements in browser chrome?

(In reply to Nihanth Subramanya [:nhnt11] from comment #31)

Gijs, Neil: Is it possible to enforce a rule where any doorhangers that are anchored to elements in web content are always displayed below doorhangers that are anchored to elements in browser chrome?

The popups are in the parent and the anchor is in content; the popup manager has no idea we're "anchoring to content" because the parent process has no reference to the content process element. We just pass some coordinates from the content process and anchor on those in the parent. So no, I don't think we can do what you suggest in a 'general' sense, because the popup manager is not aware we're anchoring to a content element.

Note that in addition to the approach in the (current version of the) patch, we should also sanitize coordinates sent by the child in the parent to avoid displaying popups outside of the browser viewport, to avoid the same attack being possible from a compromised child process.

We don't have a mechanism to change the level of a popup while it is open. The workaround is to just close the popups and reopen them in the order you want. It might be possible to implement something that just calls nsIWidget::Show or something similar to what it does.

Flags: needinfo?(enndeakin)

(In reply to Neil Deakin from comment #33)

We don't have a mechanism to change the level of a popup while it is open. The workaround is to just close the popups and reopen them in the order you want. It might be possible to implement something that just calls nsIWidget::Show or something similar to what it does.

Is it possible to set the level of a popup just before showing it? i.e. if we have a popup A already open, can we control whether a new popup B gets shown above or below it?

(In reply to :Gijs (he/him) from comment #32)

(In reply to Nihanth Subramanya [:nhnt11] from comment #31)

Gijs, Neil: Is it possible to enforce a rule where any doorhangers that are anchored to elements in web content are always displayed below doorhangers that are anchored to elements in browser chrome?

The popups are in the parent and the anchor is in content; the popup manager has no idea we're "anchoring to content" because the parent process has no reference to the content process element. We just pass some coordinates from the content process and anchor on those in the parent. So no, I don't think we can do what you suggest in a 'general' sense, because the popup manager is not aware we're anchoring to a content element.

Note that in addition to the approach in the (current version of the) patch, we should also sanitize coordinates sent by the child in the parent to avoid displaying popups outside of the browser viewport, to avoid the same attack being possible from a compromised child process.

Whoever is passing the coordinates should know though, right? Can we force consumers to declare their intent and rely on developers and reviewers to pass the right one?

Flags: needinfo?(enndeakin)

Is it possible to set the level of a popup just before showing it? i.e. if we have a popup A already open, can we control whether a new popup B gets shown above or below it?

Well, one can always implement code that does this, or implement any window ordering behaviour. But since we only have a need to open a popup frontmost, we don't have any code that manipulates the ordering of popups, either before or after they have been opened.

Implementing this would require work on each platform's widget code.

Flags: needinfo?(enndeakin)

This patch makes the door hanger pop-up on top of the window, form validation pop-up default set level by the parent so that we can make sure the door hanger will be top of form validation pop-up. Note: This patch only works well on MacOS, not for Linux now.

Hey, can you help us understand what the next step is here? Thanks!

Flags: needinfo?(jdai)

Hi Emilio,
Per comment 36, I made the notification pop-up at the top of the window on macOS so that the form validation pop-up will under notification pop-up, however, it requires some work on each platform. Is it possible to support at Layout? If not, maybe comment 33 is another way to approach. Thank you.

Flags: needinfo?(jdai) → needinfo?(emilio)

So is the issue that gtk widgets don't honor level="top"? That's not really a layout issue, it's a Widget :: Gtk issue.

I'm happy to poke at it if necessary, though it may be worth pinging the folks with more GTK background (Martin Stransky, Karl Tomlinson) first.

Also, does your patch work on Windows?

It's not clear to me what concrete thing you want to do with comment 33? We could theoretically support dynamic switching of popup levels, maybe. At least I think in GTK it is possible.

Flags: needinfo?(emilio)

Also, level="top" may ignore other windows that aren't Firefox, is that what you want?

How hard would it be to reimplement the form validation popup and display it in the child instead, using the same layers / anon content as the devtools inspector & co (so it can't be interfered with by web content)? This would also fix the positioning issues we've had with this generally, would mean it automatically goes away if the document unloads, etc. It'd also make it easier for this code to live in the child instead of requiring IPC at all... It could also potentially live more in C++ land which may be more comfortable for the DOM folks who've been working on this?

(In reply to Emilio Cobos Álvarez (:emilio) from comment #39)

So is the issue that gtk widgets don't honor level="top"? That's not really a layout issue, it's a Widget :: Gtk issue.

Yes, it seems the level="top" can't work on Linux platform.

I'm happy to poke at it if necessary, though it may be worth pinging the folks with more GTK background (Martin Stransky, Karl Tomlinson) first.

Also, does your patch work on Windows?

Yes, it work on windows, please check the attachment file.

It's not clear to me what concrete thing you want to do with comment 33? We could theoretically support dynamic switching of popup levels, maybe. At least I think in GTK it is possible.

Comment 33 seems to remember and recognize all the pop-up so that it can close all the pop-up then open the notification pop-up at front. I will redirect to GTK forks. Thank you.

Hi Karl,
Base on GTK background, do you think comment 33, comment 38 or comment 41 is more approachable? Thank you.

Flags: needinfo?(karlt)

Comment 41 sounds like the preferred solution to me. Pop-ups are only needed when there is a desire to extend some display beyond the bounds of the browser main window or above other windows. Each of those are non-goals for the prompt message.

Having content messages in a pop-up blurs the boundaries of chrome and content. Tooltips are also popups containing content messages, but I feel uncomfortable about them also.

I don't know how approachable the solution of comment 41 is due to existing dependence on existing infrastructure, but it would be worth checking and comment 41 seems to indicate that it has been achieved before. (I'm not clear that moving to C++ would be an advantage though.)

Having form validation messages implemented in the child would mean they would not look like native pop-ups, but that may be an advantage to clarify the chrome/content boundary.

I'm not clear on the distinction between comment 33 and comment 38.
Closing and re-opening windows (comment 33) depends on having a list of unrelated popups and would lead to some flickering. Essentially it is a way to implement level="top" (comment 38). There may be a better way, but I don't know because this is not something that is normally required.

Pop-ups are usually either transient (tooltips) or have focus and only one window has focus at a time, so that it can be dismissed with Esc, for example. If there is more than one pop-up, then they are related and have a hierarchy so that it is clear which has focus.
By only showing pop-ups when the app has focus, apps don't compete with each other to show the foremost window.

Here, both pop-ups are within the same app, but the same issues with competing for attention are involved, and I assume Esc does not dismiss one of the pop-ups. How would the user know which popup Esc would dismiss?

It is also a bug if content can steal focus without user action.

If comment 41 is not an option, then, rather than trying to set z-levels for pop-ups, I'd suggest ensuring that popups are dismissed when they (or their parent widgets) lose focus.

Flags: needinfo?(karlt)

Comment 41 would also fix some long-standing issues with these popups, like these sticking around when scrolling and so on.

Isn't comment 41 really hard because of same issues we've had with <select size=1> popup, when the document causing the popup is some cross-origin iframe. iframe which is triggering the popup maybe really small and using parent document's area to show the popup would be cross-origin information leak.

(In reply to Olli Pettay [:smaug] from comment #45)

Isn't comment 41 really hard because of same issues we've had with <select size=1> popup, when the document causing the popup is some cross-origin iframe. iframe which is triggering the popup maybe really small and using parent document's area to show the popup would be cross-origin information leak.

My understanding is that the highlighter code from the inspector uses native anon content and therefore isn't web-observable, so I wouldn't have thought so (ie even if we inserted in the parent document)? I mean, there might be mouseenter events or such, but I would not expect that to be any worse than with the chrome overlay we have now...

(In reply to Olli Pettay [:smaug] from comment #45)

Isn't comment 41 really hard because of same issues we've had with <select size=1> popup, when the document causing the popup is some cross-origin iframe. iframe which is triggering the popup maybe really small and using parent document's area to show the popup would be cross-origin information leak.

But <select> has to render outside of the viewport of the iframe to be usable. Maybe we don't have the same constraint with form popups. They're less critical IMHO.

My understanding is that the highlighter code from the inspector uses native anon content and therefore isn't web-observable, so I wouldn't have thought so (ie even if we inserted in the parent document)? I mean, there might be mouseenter events or such, but I would not expect that to be any worse than with the chrome overlay we have now...

In presence of spectre I think you can pretty much assume that every data that goes through the process can be observed, even if not trivially.

(In reply to Emilio Cobos Álvarez (:emilio) from comment #47)

But <select> has to render outside of the viewport of the iframe to be usable. Maybe we don't have the same constraint with form popups. They're less critical IMHO.

Really? How would we position the popup in an iframe which is very small? Or not show them at all? That would be rather breaking change.
(When <select> was discussed, it was suggested that small iframes with <select> would be rare, but it took like 5 minutes to find examples. So I have no particular trust that there aren't small iframes which trigger popups)

(In reply to Olli Pettay [:smaug] from comment #48)

Really? How would we position the popup in an iframe which is very small? Or not show them at all? That would be rather breaking change.
(When <select> was discussed, it was suggested that small iframes with <select> would be rare, but it took like 5 minutes to find examples. So I have no particular trust that there aren't small iframes which trigger popups)

I assume it'd just get clipped by the viewport of the iframe. Select is different because you need to see the popup to interact with it, and the popup can get much larger than the form validation popups.

So basically the popup wouldn't be shown at all if we want to show also the relevant form control.

John, are you actively working on this sec issue?

Flags: needinfo?(jdai)

(In reply to Neha Kochar [:neha] from comment #51)

John, are you actively working on this sec issue?

No, I'm not working on this sec issue.

Flags: needinfo?(jdai)

Jens, could you pls find another assignee for this if jdai isn't planning to work on this?

Flags: needinfo?(jstutte)
Attachment #8870075 - Attachment is obsolete: true

(In reply to Karl Tomlinson (:karlt) from comment #43)

Comment 41 sounds like the preferred solution to me. Pop-ups are only needed when there is a desire to extend some display beyond the bounds of the browser main window or above other windows. Each of those are non-goals for the prompt message.

Anti-goals, even.

Keep content-generated messages in content, like we've done with javascript alerts/prompts. We've long talked about the "line of death" in browser UI, but it's a "plane of death", too. If it web-generated content floats up into a new OS plane it becomes confusable with browser UI, or can be used to hide legit browser UI (as here). Looks cool, but any feature like it ends up causing us no end of problems.

Hi Olli, Emilio, can you briefly re-state what is the desired behavior now here and what should be implemented? From reading the comments I am not having the impression that we reached consensus already, but I might just not have enough context.

Flags: needinfo?(emilio)
Flags: needinfo?(bugs)

So there are multiple things that could be done here. Tweaking the z-index of the form message panel might be the easiest. Others like rendering them on the child etc are a bit trickier, as Olli noted in comment 50, and would probably at least need UX input.

I suspect Gijs is probably in a better position to assess the different trade-offs here, though he's on PTO... Perhaps Johann would have feedback?

Flags: needinfo?(emilio) → needinfo?(jhofmann)
Flags: needinfo?(jstutte)
Flags: needinfo?(gijskruitbosch+bugs)

(In reply to Emilio Cobos Álvarez (:emilio) from comment #56)

So there are multiple things that could be done here. Tweaking the z-index of the form message panel might be the easiest.

This isn't really that easy, I think? It's a panel right now, so it's not in the same widget level window as the main window, which is why it appears on top of everything else. To make it lower z-index than the full screen warning we'd either need a bunch of work on panel widget code (see comment 35), or have it no longer be a panel, instead absolutely positioning something on top of web content that lives inside the same widget window. I don't know how likely that is to cause issues; in the past there was an effort to split the browser up into different "zones" for web rendering / gfx's benefit, but I think that project didn't end up going anywhere. I don't know if making similar work harder is a problem. In this case we'd also need to re-implement its dismissal ourselves (ie hide it when other stuff gets focus or escape is pressed, which right now the panel code deals with for us).

Others like rendering them on the child etc are a bit trickier, as Olli noted in comment 50, and would probably at least need UX input.

I'm a little confused. Why can't we show them using the toplevel child? Yes, this might leak information to the top frame from the inner frame in the presence of spectre/meltdown; are there reasonable cases where this is problematic, the inner frame doesn't want to / can't use X-Frame-Options or similar, and the presence/absence of a form validation popup would be quite that interesting to the toplevel child? I'm struggling to imagine such a situation, especially as the toplevel likely can't engineer a situation where such a validation popup would appear for the inner frame (ie that'd depend on user input and/or the behaviour of the prospective victim site), and even where it does, its wording is likely not predictable. But either way, it doesn't really have any UX implications that way, right? (ni for this)

I suspect Gijs is probably in a better position to assess the different trade-offs here, though he's on PTO... Perhaps Johann would have feedback?

Other options that would help here would be not showing form validation warnings if the form is auto-submitted (no user interaction), or not re-showing the warning for the same document / browsing context more than once (but it may be tricky to keep track of that information).

Ultimately I think anything other than a band-aid is likely to need significant re-architecturing work, which does also mean it's more important we pick the right solution, which I guess is why this bug hasn't progressed much - it's hard to determine which solution is least-bad.

In terms of band-aids, we could add code to the form validation popup that checks for other open popups (checking with querySelectorAll + checking the popups' state properties) before allowing it to open, and/or hides itself if other panels/popups open (by listening for popupshowing events). Does that seem like a reasonable enough fix here? (ni for this also) Because perhaps then we should just opt for that rather than spend more time debating the pros and cons of the various options to completely redo the implementation...

Flags: needinfo?(jhofmann)
Flags: needinfo?(gijskruitbosch+bugs)
Flags: needinfo?(emilio)

(In reply to :Gijs (he/him) from comment #57)

Others like rendering them on the child etc are a bit trickier, as Olli noted in comment 50, and would probably at least need UX input.

I'm a little confused. Why can't we show them using the toplevel child? Yes, this might leak information to the top frame from the inner frame in the presence of spectre/meltdown; are there reasonable cases where this is problematic, the inner frame doesn't want to / can't use X-Frame-Options or similar, and the presence/absence of a form validation popup would be quite that interesting to the toplevel child? I'm struggling to imagine such a situation, especially as the toplevel likely can't engineer a situation where such a validation popup would appear for the inner frame (ie that'd depend on user input and/or the behaviour of the prospective victim site), and even where it does, its wording is likely not predictable. But either way, it doesn't really have any UX implications that way, right? (ni for this)

One could argue that on a small window a custom validation message might want to overflow the content area... But that's an issue as soon as we get away from <panel>s. I don't think the space there is a huge issue if we're willing to accept that, though I don't know if that would be acceptable security-wise.

I suspect Gijs is probably in a better position to assess the different trade-offs here, though he's on PTO... Perhaps Johann would have feedback?

Other options that would help here would be not showing form validation warnings if the form is auto-submitted (no user interaction), or not re-showing the warning for the same document / browsing context more than once (but it may be tricky to keep track of that information).

The user-interaction bit at least seems relatively straight forward. We have a HasValidUserGestureActivation on the window context.

Ultimately I think anything other than a band-aid is likely to need significant re-architecturing work, which does also mean it's more important we pick the right solution, which I guess is why this bug hasn't progressed much - it's hard to determine which solution is least-bad.

Nod.

In terms of band-aids, we could add code to the form validation popup that checks for other open popups (checking with querySelectorAll + checking the popups' state properties) before allowing it to open, and/or hides itself if other panels/popups open (by listening for popupshowing events). Does that seem like a reasonable enough fix here? (ni for this also) Because perhaps then we should just opt for that rather than spend more time debating the pros and cons of the various options to completely redo the implementation...

There may be multiple form validation popups, that's one of the tricky cases I guess. The popup manager does keep track of all the open popups so we could use that... I guess it depends on how urgently should we fix this, but not opposed to such a band-aid.

Flags: needinfo?(emilio)

That band-aid could in practice work rather well.

Assignee: jdai → nobody
Status: ASSIGNED → NEW

(In reply to Emilio Cobos Álvarez (:emilio) from comment #58)

(In reply to :Gijs (he/him) from comment #57)

In terms of band-aids, we could add code to the form validation popup that checks for other open popups (checking with querySelectorAll + checking the popups' state properties) before allowing it to open, and/or hides itself if other panels/popups open (by listening for popupshowing events). Does that seem like a reasonable enough fix here? (ni for this also) Because perhaps then we should just opt for that rather than spend more time debating the pros and cons of the various options to completely redo the implementation...

There may be multiple form validation popups, that's one of the tricky cases I guess. The popup manager does keep track of all the open popups so we could use that... I guess it depends on how urgently should we fix this, but not opposed to such a band-aid.

There's only 1 popup per parent browser window, and I guess I would expect that switching parent/browser windows will hide popups in the other window anyway. This appears to work for me, so the WIP patch I'm about to put up doesn't do anything explicit to deal with that case.

Flags: needinfo?(bugs)
Attached file Bug 1366818, r?emilio
Assignee: nobody → gijskruitbosch+bugs
Status: NEW → ASSIGNED
Attached file Bug 1366818 - part 2, r?emilio (obsolete) —
See Also: → CVE-2021-38497

Vulnerability fixed, what's next?

(In reply to Raphael from comment #63)

Vulnerability fixed, what's next?

Bug 1726621 may have helped a bit, but the problem in attachment 8870079 [details] is not fixed yet, AFAIK. I need to update the patches that I wrote here, add automated tests, and then land them - but I've been out for most of the past 7 weeks and I haven't gotten around to it.

I filed bug 1735327 for requiring user action for form validation UI to be shown (ie the current "part 2" patch here that I'll likely abandon - I'm not sure I'll find time to put it in 1735327, as doing this "properly" will also involve updating all the automated tests for this code...).

I'll work on getting part 1 ready to land in this bug, to address the sec issue.

Blocks: 1735429
Attachment #9236538 - Attachment is obsolete: true
Attachment #9236535 - Attachment description: Bug 1366818, part 1, r?emilio → Bug 1366818, r?emilio
Group: dom-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → 95 Branch

Comment on attachment 9236535 [details]
Bug 1366818, r?emilio

Beta/Release Uplift Approval Request

  • User impact if declined: sec-moderate issue (spoofing of browser messaging)
  • Is this code covered by automated tests?: Yes
  • Has the fix been verified in Nightly?: No
  • Needs manual test from QE?: Yes
  • If yes, steps to reproduce: Open attachment 8870300 [details]. The form validation popup with custom text should not appear persistently at the same time as the geolocation permission popup.
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): Relatively straightforward JS only changes to form validation panels opening/hiding, which have pre-existing automated tests (I'm adding a test for this issue too but it's not landing until we've landed this fix on supported branches or decided not to).
  • String changes made/needed: Nope

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: sec-moderate
  • User impact if declined: See above
  • Fix Landed on Version: 95
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): See above
  • String or UUID changes made by this patch: Nope
Attachment #9236535 - Flags: approval-mozilla-esr91?
Attachment #9236535 - Flags: approval-mozilla-beta?
Flags: qe-verify+

Changing the priority to p1 as the bug is tracked by a release manager for the current beta.
See What Do You Triage for more information

Priority: P3 → P1
QA Whiteboard: [qa-triaged]

Reproduced the issue with the the custom text pop-up being displayed on top of the geolocation permission pop-up using an old Nightly build from 2021-10-11. Verified that using latest Nightly build across platforms (Windows 10, Ubuntu 18.04 and macOS 11.6) this does not happen anymore. The text pop-up is displayed after the geolocation one is dismissed.

I am sincerely glad that after five years the error has been fixed. The expiration date of the error reward has not expired yet ?

Comment on attachment 9236535 [details]
Bug 1366818, r?emilio

Approved for 94.0b7.

Attachment #9236535 - Flags: approval-mozilla-beta? → approval-mozilla-beta+

Comment on attachment 9236535 [details]
Bug 1366818, r?emilio

Approved for 91.3esr.

Attachment #9236535 - Flags: approval-mozilla-esr91? → approval-mozilla-esr91+

Also verified that this is also fixed on 94.0b7 and latest esr91 build from treeherder across platforms (Windows 10, Ubuntu 18.04 and macOS 11.6).

Status: RESOLVED → VERIFIED
QA Whiteboard: [qa-triaged]
Flags: qe-verify+
Regressions: 1736545
Flags: sec-bounty?
Whiteboard: [adv-main94+]
Flags: sec-bounty? → sec-bounty+
Attached file advisory.txt
Whiteboard: [adv-main94+] → [adv-main94+][adv-esr91.3+]
Alias: CVE-2021-38508
See Also: → CVE-2023-32205
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.