Closed Bug 2017643 (CVE-2026-4692) Opened 7 months ago Closed 6 months ago

Privileged UI interaction via spoofing RDM

Categories

(DevTools :: Responsive Design Mode, defect, P1)

defect

Tracking

(firefox-esr115149+ fixed, firefox-esr140149+ fixed, firefox148 wontfix, firefox149+ fixed, firefox150+ fixed)

RESOLVED FIXED
150 Branch
Tracking Status
firefox-esr115 149+ fixed
firefox-esr140 149+ fixed
firefox148 --- wontfix
firefox149 + fixed
firefox150 + fixed

People

(Reporter: tjr, Assigned: ochameau, NeedInfo)

References

(Regression)

Details

(4 keywords, Whiteboard: [adv-main149+][adv-ESR140.9+][adv-ESR115.34+])

Attachments

(6 files)

Attached file repro.patch —

I was asked a long time ago in Bug 1949500 if a content process could possibly synthesize input events that reach the privileged UI. Now that I can have claude look for me, I could determine from my phone that the answer is yes, and a repro is attached.

I didn't have claude write up a full description, it seems pretty simple - my understanding is it uses SetInRDMPane and then sends negative coordinates to be outside the content area. I've tested it locally, and it turns on the sidebar for me (if I had it off). Fiddling with the coordinates let it click other buttons also.

Here is the code in the parent where this is read.

Child processes shouldn't be able to declare themselves to be in RDM.

Keywords: sec-high

This code was "added" in bug 1957522, but I think that just moves a similar bypass from RecvSynthesizeNativeTouchPoint.

Nicolas, this is a sec-high sandbox escape. Can you help get this triaged?

Flags: needinfo?(nchevobbe)

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

Child processes shouldn't be able to declare themselves to be in RDM.

FWIW this is currently allowed because there is no CanSet method for the InRDMPane synced field on BrowsingContext (only a DidSet): https://searchfox.org/firefox-main/rev/1f43fe5ffadde0b6898daf607cabb3335dd75d6f/docshell/base/BrowsingContext.h#1304. Assuming this shoulkd only ever be set in the parent process on toplevel BCs, this should probably have a check like ExplicitActive's (https://searchfox.org/firefox-main/rev/1f43fe5ffadde0b6898daf607cabb3335dd75d6f/docshell/base/BrowsingContext.cpp#3063), checking IsTop() && !aSource && XRE_IsParentProcess() (which indicates that it's parent-process only).

TBH we should probably require CanSet for all synced fields, and also go through and make sure that the existing ones are properly hardened, as I sure see a lot of CanSet methods which just call IsTop(). I remember at one point during Fission I had considered changing how we generate the tables for synced fields so that we could make the bulk of CanSet restrictions declarative within the macro so folks are less likely to forget to add it, but it never happened.

Nicolas, this is a sec-high sandbox escape. Can you help get this triaged?

I'm not sure I understand how the attack works.
The attached patch conveniently exposes a triggerExploitIPC function on the global that is used to dispatch the touch event with the negative Y.

I failed to reproduce the exploit only using JS and having RDM + touch simulation enabled: if I'm manually creating and dispatching mousedown/mouseup event and dispatching those, they're not handled by the RDM touch simulation code https://searchfox.org/firefox-main/rev/3c52c9c886f7b0423001cef86abfafcf97f2b90a/devtools/server/actors/emulation/touch-simulator.js#21-22,24,29,36,41,43,46,50,56,59-60,63

const EVENTS_TO_HANDLE = [
  "mousedown",
...
  "mouseup",
...
];
...
class TouchSimulator {
...
  constructor(windowTarget) {
...
    this.simulatorTarget = windowTarget.chromeEventHandler;
...
  }
...
  start() {
...
    EVENTS_TO_HANDLE.forEach(evt => {
...
      this.simulatorTarget.addEventListener(evt, this, true, false);
    });
...
  }

If the attack can only happen if the content process is compromised (how?) so that it can "implement/provide" something that does the same as TriggerExploitIPC, this doesn't really feel like an RDM issue, or at least, not something that the DevTools team can fix.

Nika, since you looked into this a bit, maybe you can set a priority?

Flags: needinfo?(nchevobbe) → needinfo?(nika)

(In reply to Nicolas Chevobbe [:nchevobbe] from comment #6)

If the attack can only happen if the content process is compromised (how?) so that it can "implement/provide" something that does the same as TriggerExploitIPC, this doesn't really feel like an RDM issue, or at least, not something that the DevTools team can fix.

This is a content process sandbox escape exploit, not a JS exploit. The problem is not directly exposed to IPC without the content process being compromised, but we care about hardening the IPC layer such that you can't trigger things like this from a hardened content process.

Nika, since you looked into this a bit, maybe you can set a priority?

This is high priority, as it is a sandbox escape which allows dispatching arbitrary user input events which impact arbitrary chrome browser UI.

Flags: needinfo?(nika) → needinfo?(nchevobbe)

Looks like a regression from bug 1957522 which moved the assertion from !automation to !automation && !rdm.

Keywords: regression
Regressed by: 1957522

(In reply to Alexandre Poirot [:ochameau] from comment #8)

Looks like a regression from bug 1957522 which moved the assertion from !automation to !automation && !rdm.

I think that just moved the escape hatch from RecvSynthesizeNativeTouchPoint to RecvDispatchTouchEvent, so I expect we'd have had the same problem before that.

Attached file (secure) —
Assignee: nobody → poirot.alex
Status: NEW → ASSIGNED
Attached file (secure) —
Severity: -- → S2
Priority: -- → P1

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

(In reply to Alexandre Poirot [:ochameau] from comment #8)

Looks like a regression from bug 1957522 which moved the assertion from !automation to !automation && !rdm.

I think that just moved the escape hatch from RecvSynthesizeNativeTouchPoint to RecvDispatchTouchEvent, so I expect we'd have had the same problem before that.

Oh yes, I missed the code move. Good catch, it is rather bug 1772634.

Regressed by: 1772634
No longer regressed by: 1957522
Flags: needinfo?(nchevobbe)

Comment on attachment 9548362 [details]
(secure)

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: (first time I'm going through such a sec-bug, nor am I a profitient C++ dev)
    See comment 0. Seems easy to reach parent once content is compromised?
  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: Unknown
  • Which branches (beta, release, and/or ESR) are affected by this flaw, and do the release status flags reflect this affected/unaffected state correctly?: Since Fx 103, so all branches
  • If not all supported branches, which bug introduced the flaw?: Bug 1772634
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: Should be easy if there is any merge conflict.
  • How likely is this patch to cause regressions; how much testing does it need?: Low risk. Testing should only be about being able to toggle RDM on/off.
  • Is the patch ready to land after security approval is given?: Yes
  • Is Android affected?: No
Attachment #9548362 - Flags: sec-approval?

Comment on attachment 9548362 [details]
(secure)

sec-approval+ to land now and request uplifts

Attachment #9548362 - Flags: sec-approval? → sec-approval+

Please do NOT land the test until on or after May 5. I'm setting a bugbot reminder for you

Flags: in-testsuite?
Whiteboard: [reminder-test 2026-05-05]
Status: ASSIGNED → RESOLVED
Closed: 6 months ago
Resolution: --- → FIXED
Target Milestone: --- → 150 Branch
Group: firefox-core-security → core-security-release

The patch landed in nightly and beta is affected.
:ochameau, is this bug important enough to require an uplift?

For more information, please visit BugBot documentation.

Flags: needinfo?(poirot.alex)

firefox-beta Uplift Approval Request

  • User impact if declined: This sec-high will exists in 148 if not uplifted.
  • Code covered by automated testing: no
  • Fix verified in Nightly: no
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: Naive fix in this BrowsingContest flag only used by DevTools and WebDriver Bidi.
  • String changes made/needed: no
  • Is Android affected?: yes
Attachment #9551499 - Flags: approval-mozilla-beta?
Attachment #9551499 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
QA Whiteboard: [sec] [uplift] [qa-triage-done-c150/b149]
Attachment #9552143 - Flags: approval-mozilla-esr140?
Attachment #9552144 - Flags: approval-mozilla-esr115?
Attachment #9552143 - Flags: approval-mozilla-esr140? → approval-mozilla-esr140+
Attachment #9552144 - Flags: approval-mozilla-esr115? → approval-mozilla-esr115+
Flags: needinfo?(poirot.alex)
Whiteboard: [reminder-test 2026-05-05] → [reminder-test 2026-05-05][adv-main149+][adv-ESR140.9+][adv-ESR115.34+]
Alias: CVE-2026-4692

2 months ago, dveditz placed a reminder on the bug using the whiteboard tag [reminder-test 2026-05-05] .

ochameau, please refer to the original comment to better understand the reason for the reminder.

Flags: needinfo?(poirot.alex)
Whiteboard: [reminder-test 2026-05-05][adv-main149+][adv-ESR140.9+][adv-ESR115.34+] → [adv-main149+][adv-ESR140.9+][adv-ESR115.34+]
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: