Closed Bug 1865689 (CVE-2024-0751) Opened 1 year ago Closed 1 year ago

Privilege escalation through devtools.inspectedWindow.eval

Categories

(WebExtensions :: Developer Tools, defect, P1)

defect

Tracking

(firefox-esr115122+ fixed, firefox120 wontfix, firefox121 wontfix, firefox122+ fixed)

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

People

(Reporter: robwu, Assigned: robwu)

References

Details

(Keywords: csectype-priv-escalation, sec-moderate, Whiteboard: [adv-main122+][adv-esr115.7+])

Attachments

(5 files)

Attached file devtools-eval.zip

devtools.inspectedWindow.eval has denylist-based access checks (source), which are incomplete. view-source:-URLs can be used to bypass access scheme-based restrictions, including moz-extension:-URLs and restricted domains such as AMO.

The attached test case demonstrates the vulnerable primitive; at the end of this report I have also included a description to escalate privileges through this primitive.

STR:

  1. Load the attached extension (devtools-eval.zip) at about:debugging or through web-ext. It adds a panel "DevTools eval" to the devtools. This devtools panel executes code in the inspected page and prints the results.
  2. Navigate to https://example.com/ and click on the panel's button.
  3. Navigate to about:debugging, click on "This Nightly" and inspect a moz-extension:-URL of another extension. Then click on the panel's button.
  4. View the source of the page at tab 3.

Expected:

  • step 2 execution succeeds (included in the STR to show how successful execution looks like).
  • step 3 execution error (other moz-extension: may be more privileged).
  • step 4 execution error (other extension may be more privileged)

Actual:

  • step 2 as expected.
  • step 3 as expected (this was fixed in bug 1425197).
  • step 4 unexpectedly succeeds, demonstrating that devtools.inspectedWindow.eval is able to run scripts in the context of other extensions in some cases.

Notes:

  • The view-source:-document has the same (storage) principal as the extension. This allows reading of other extension's content.

  • At the surface, it seems that extension APIs are not injected in this context.

  • But extension APIs can be accessed indirectly, as follows:

    1. Install an extension that has web_accessible_resources (e.g. uBlock Origin). An alternative is to visit about:config, set devtools.aboutdebugging.showHiddenAddons to true and inspect the WebCompat add-on's manifest.json from about:debugging (after a reload).
    2. Through the devtools, open a popup to get a handle to an extension page that has access to extension APIs:
    • uBlock Origin: w = window.open(origin + "/web_accessible_resources/README.txt")
    • WebCompat: w = window.open(origin + "/shims/mochitest-shim-1.js");
    1. Verify that privileged extension APIs are available (e.g. tabs API):
    • w.browser.tabs.getCurrent({})
  • The above extra notes show the extra impact on extension URLs. The same also applies to restricted domains such as AMO.

  • Access checks are deny-list-based, at https://searchfox.org/mozilla-central/rev/42acdc9cd5ae89222bdceeeaed7bacac755be48f/devtools/server/actors/addon/webextension-inspected-window.js#537-540,552,554 . An allowlist would probably make more sense here.

  • The other-extension bypass happens because the scheme is view-source:, which is also part of nodePrincipal, and therefore window.document.nodePrincipal.addonId is "".

view-source: urls are normally supposed to be same-origin with their innerURL. We'd like the right results to come out of principal comparisons rather than have everyone remember to special-case things like "view-source" -- because they won't remember, or new people won't even realize they are something they have to deal with. It sounds like a view-source principal should have an addonId when it's a view of an extension source (and maybe some other addon-related properties).

any use of schemeIs() could be trouble and needs careful handling, and you're right that a deny-list of schemes is more dangerous than an allow-list. We do have a load flag URI_LOADABLE_BY_EXTENSIONS, but it's not used where I'd expect so maybe it's more vestigial.

Duplicate of this bug: 1866642
Assignee: nobody → rob
Severity: -- → S3
Priority: -- → P1
Whiteboard: [addons-jira]

and report a static error instead of including the URL in the message.

Note: the first patch fixes the issue by performing precise access checks, comparable to content scripts. It also replaces the three distinct error messages with just one static message. The original messages included the URL / origin of the tab whose access was denied. This is mostly to minimize unnecessary information exposure through extension APIs and has no significant security impact (the same information is available through other extension APIs with the right permissions).

If an external party carefully examines the patch, they may observe that the patch introduces a new check for quarantined domains. The visibility of this check is not a problem, because devtools are not included in the attacks that we are trying to defend against with the feature (introduced in bug 1834825). The extra check is primarily for consistency and future-proofing against new attacks.

I have attached the test case for view-source:-URLs in a separate patch, in case we want to land it separately.

Pushed by rob@robwu.nl: https://hg.mozilla.org/integration/autoland/rev/79cb126ce193 Clarify access checks in devtools.inspectedWindow.eval r=rpl,devtools-reviewers,ochameau

Adding reminder so that we don't forget to eventually land the test case (second patch) that highlights the exploitable part of this vulnerability.

Whiteboard: [addons-jira] → [addons-jira][reminder-landing 2024-06-01]

The individual test ran as expected when prefs was next to the file.
But when the whole directory is selected, the test runner refuses to
run the test due to the following error:

The 'prefs' key must be set in the DEFAULT section of a manifest.

This patch fixes the issue by moving prefs to DEFAULT. This is okay
because the other test in the test manifest is independent of the pref.

Pushed by sstanca@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/146756ad85b8 Fixup browser.toml - move prefs to DEFAULT. CLOSED TREE
Group: firefox-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 122 Branch

Comment on attachment 9368085 [details]
Bug 1865689 - Clarify access checks in devtools.inspectedWindow.eval

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: Fixes a privilege escalation bug in extensions. Exploitation requires (1) user to install a malicious extension with the "Extend developer tools to access your data in open tabs" permission and (2) user to open the developer tools for any tab. With this, the extension can execute code in restricted documents, including other extensions and addons.mozilla.org (which should never be scriptable by any extension).
  • User impact if declined: A malicious devtools extension can escalate privileges.
  • Fix Landed on Version: 122
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): The patch only changes behavior in the affected component, by replacing a denylist-based check with an allowlist-based check. The conditions for the allowlist are liberally chosen to allow anything conceivably acceptable, and reject accesses that we reject intentionally. All relevant scenarios are covered by unit tests.
Attachment #9368085 - Flags: approval-mozilla-esr115?
Attachment #9368424 - Flags: approval-mozilla-esr115?
QA Whiteboard: [post-critsmash-triage]
Flags: qe-verify-

Comment on attachment 9368085 [details]
Bug 1865689 - Clarify access checks in devtools.inspectedWindow.eval

Approved for 115.7esr.

Attachment #9368085 - Flags: approval-mozilla-esr115? → approval-mozilla-esr115+

Comment on attachment 9368424 [details]
Bug 1865689 - Fixup browser.toml - move prefs to DEFAULT

Approved for 115.7esr.

Attachment #9368424 - Flags: approval-mozilla-esr115? → approval-mozilla-esr115+

The test fails because test2.example.com cannot be loaded, and that in turn happens because http3 is enabled on the specific test configuration. I reproduced the failure locally on the ESR115 branch with:

./mach test devtools/shared/commands/inspected-window/tests/browser_webextension_inspected_window_access.js --headless --log-mach-verbose --use-http3-server

The required registration for test2.example.com (*.example.com) was added in https://hg.mozilla.org/mozilla-central/rev/1f68fb3f63169376727ad402c5b34eb2c8efdec1 , which landed in 116.

I recommend to uplift https://hg.mozilla.org/mozilla-central/rev/1f68fb3f6316 - I don't expect any regressions because this merely adds a few extra domains; hosts that previously did not resolve with --use-http3-server will load as expected. Once this sticks, the two patches above can be relanded without changes.

Alternatively, reland with skip-if = http3 added below [browser_webextension_inspected_window_access.js]. For simplicity, consider squashing both patches together (and only retain the first commit message) and then add skip-if.

Flags: needinfo?(rob)
Attachment #9368085 - Flags: approval-mozilla-esr115+ → approval-mozilla-esr115?
Attachment #9368424 - Flags: approval-mozilla-esr115+ → approval-mozilla-esr115?

Comment on attachment 9368085 [details]
Bug 1865689 - Clarify access checks in devtools.inspectedWindow.eval

Approved for 115.7esr.

Attachment #9368085 - Flags: approval-mozilla-esr115? → approval-mozilla-esr115+

Comment on attachment 9368424 [details]
Bug 1865689 - Fixup browser.toml - move prefs to DEFAULT

Approved for 115.7esr.

Attachment #9368424 - Flags: approval-mozilla-esr115? → approval-mozilla-esr115+
Whiteboard: [addons-jira][reminder-landing 2024-06-01] → [addons-jira][reminder-landing 2024-06-01][adv-main122+][adv-main115.7+]
Whiteboard: [addons-jira][reminder-landing 2024-06-01][adv-main122+][adv-main115.7+] → [addons-jira][reminder-landing 2024-06-01][adv-main122+][adv-esr115.7+]
Alias: CVE-2024-0751

Making Firefox 122 security bugs public. [bugspam filter string: Pilgarlic-Towers]

Group: core-security-release

I'll land the test now since the bug has become public.

Whiteboard: [addons-jira][reminder-landing 2024-06-01][adv-main122+][adv-esr115.7+] → [adv-main122+][adv-esr115.7+]
Pushed by rob@robwu.nl: https://hg.mozilla.org/integration/autoland/rev/f79dfa292d1c Add test case for view-source in devtools r=rpl,devtools-reviewers,ochameau
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: