Closed Bug 1863863 (CVE-2023-6867) Opened 1 years ago Closed 1 year ago

PopupNotifications Clickjacking: Closing popup window activates parent window with permission popup

Categories

(Toolkit :: PopupNotifications and Notification Bars, defect, P1)

defect

Tracking

()

RESOLVED FIXED
122 Branch
Tracking Status
firefox-esr115 121+ fixed
firefox120 --- wontfix
firefox121 + fixed
firefox122 + fixed

People

(Reporter: sas.kunz, Unassigned)

References

Details

(Keywords: csectype-clickjacking, reporter-external, sec-moderate, Whiteboard: [Fixed by Bug 1865914][reporter-external] [client-bounty-form] [verif?][adv-main121+][adv-esr115.6+])

Attachments

(4 files)

i found a vulnerability where user can fall for clickjacking to allow permission

I tested on Firefox dev version 120.0b3 (64-bit)

steps to reproduce:

  1. open clickjack0.html then click open button
  2. Click the "click 5 fastly" button fastly.
Flags: sec-bounty?
Attached file clickjack0.html

Paul, is this just the timeout of 500ms not being long enough or is there a different explanation?

Component: Security → Site Permissions
Flags: needinfo?(pbz)
Summary: Clickjacking to allow permission → Clickjacking to allow permission (closing popup window)
Summary: Clickjacking to allow permission (closing popup window) → Clickjacking to allow permission (closing popup window unhides parent window with permission popup)

The timer shouldn't even be running when the victim is clicking on the button in the popup. When the prompt's tab loses focus the button needs to revert to the disabled[*] state, and when it regains focus the timer has to start from the beginning again. The fundamental attack is "User is doing something and boom!—an active button appears under their click". There are no end of ways to get to that state; the attack is not just with the initial appearance of the prompt. Focus might not even be a good enough defense—there have been ways to cover the prompt with things that don't have focus, or even that come from the attacking content itself—but it's a minimum indication the user is paying attention to something else.

[*] inert is a better experience than disabled. We don't need to call attention to the fact that the button is non-working. Ideally, in the non-attack case the user doesn't even have to know we've done this. The permission prompts look like they're already using inert, or else are styling the buttons to look like it.

fwiw this POC doesn't come close to work for me on Mac, even with a fresh profile to make sure I've got the default toolbar layout. The popup and permission prompt aren't even close.

Looks like the timeout not being long enough. I've tested it with security.notification_enable_delay set to 5000 to confirm the timeout is working as expected. We could experiment with increasing it, but that comes at the cost of increased friction for legitimate requests.

Flags: needinfo?(pbz)

(In reply to Paul Zühlcke [:pbz] from comment #4)

Looks like the timeout not being long enough. I've tested it with security.notification_enable_delay set to 5000 to confirm the timeout is working as expected. We could experiment with increasing it, but that comes at the cost of increased friction for legitimate requests.

I feel like we should just change the delay when the active window has changed, similar to the fullscreen fix you recently made. That shouldn't really matter for legit requests. Does that make more sense?

Flags: needinfo?(pbz)

Do you mean this case? https://searchfox.org/mozilla-central/rev/381c3f18a1896792e23a9503c1904aedac19aa06/toolkit/modules/PopupNotifications.sys.mjs#801
Do I read it right that this is when the window gets active again? We could introduce an offset there too.

I would argue we would increase friction here even more: If a user sees a notification in an inactive window and then directly wants to handle it. I'll attach a video to show what I mean.

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

(In reply to Paul Zühlcke [:pbz] from comment #6)

Do you mean this case? https://searchfox.org/mozilla-central/rev/381c3f18a1896792e23a9503c1904aedac19aa06/toolkit/modules/PopupNotifications.sys.mjs#801
Do I read it right that this is when the window gets active again? We could introduce an offset there too.

Yes.

I would argue we would increase friction here even more: If a user sees a notification in an inactive window and then directly wants to handle it. I'll attach a video to show what I mean.

Hm. Really what we want to optimize for here is whether the notification has actually been seen by the user. I don't know that we have any way of determining this. Emilio?

Separately, I'm honestly a bit surprised that we even bother showing the notification for non-foregrounded windows. Do we actually need to allow that at all, and/or could we just straight up hide the notification when the window deactivates and refuse to show these notifications in background windows at all? In what circumstances do legit websites need to do this?

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

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

Hm. Really what we want to optimize for here is whether the notification has actually been seen by the user. I don't know that we have any way of determining this. Emilio?

A more concrete suggestion here. AIUI we have visibility/occlusion detection for native windows on Windows/macOS/Linux. Furthermore, panels are basically windows in the native widget sense.

Can we extend the XUL popup manager code so that any panel/popup element gets a property that is:

  • 0 if/when the panel/popup is occluded / not user-visible
  • gets set to a now() timestamp when the panel/popup becomes fully visible (not occluded), at the native widget level?
Flags: needinfo?(pbz)
Summary: Clickjacking to allow permission (closing popup window unhides parent window with permission popup) → PopupNotifications Clickjacking: Closing popup window activates parent window with permission popup

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

Hm. Really what we want to optimize for here is whether the notification has actually been seen by the user. I don't know that we have any way of determining this. Emilio?

Not easily... Popups can overlap each other etc, and OSes don't give us super-precise occlusion tracking notifications in order to implement what comment 9 suggests: On macOS and Linux we only have effectively a "fully occluded" boolean (not sure on Windows). On Linux at least (not sure on Windows / macOS) we can't know that from popups at all (we use vsync to detect occlusion state and we get vsync from the top level).

Flags: needinfo?(emilio)

The severity field is not set for this bug.
:pbz, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(pbz)
Severity: -- → S2
Flags: needinfo?(pbz)
Priority: -- → P1

I'm adding a security delay extension when clicks happen within the security delay in Bug 1865914. This may help here too.

Verified that one of the changes we made for Bug 1865914 fixes the click spam issue as mentioned in comment 12. This isn't a dupe though since the mechanism of obscuring the parent window is different. Tested on Nightly 122.0a1 (2023-12-03) (64-bit) on Windows 11.

Status: NEW → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
See Also: → 1865914
Whiteboard: [reporter-external] [client-bounty-form] [verif?] → [reporter-external] [client-bounty-form] [verif?][Fixed by Bug 1865914]
Target Milestone: --- → 122 Branch
Whiteboard: [reporter-external] [client-bounty-form] [verif?][Fixed by Bug 1865914] → [reporter-external] [client-bounty-form] [verif?] [Fixed by Bug 1865914]
Component: Site Permissions → PopupNotifications and Notification Bars
Product: Firefox → Toolkit
Depends on: 1865914
Whiteboard: [reporter-external] [client-bounty-form] [verif?] [Fixed by Bug 1865914] → [Fixed by Bug 1865914][reporter-external] [client-bounty-form] [verif?]
Group: firefox-core-security → core-security-release
Flags: sec-bounty? → sec-bounty+
QA Whiteboard: [post-critsmash-triage]
Whiteboard: [Fixed by Bug 1865914][reporter-external] [client-bounty-form] [verif?] → [Fixed by Bug 1865914][reporter-external] [client-bounty-form] [verif?][adv-main121+]
Whiteboard: [Fixed by Bug 1865914][reporter-external] [client-bounty-form] [verif?][adv-main121+] → [Fixed by Bug 1865914][reporter-external] [client-bounty-form] [verif?][adv-main121+][adv-esr115.6+]
Alias: CVE-2023-6867
Duplicate of this bug: 1869980

Bulk-unhiding security bugs fixed in Firefox 119-121 (Fall 2023). Use "moo-doctrine-subsidy" to filter

Group: core-security-release
See Also: 1865914
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: