Closed Bug 2025183 Opened 7 months ago Closed 7 months ago

IPC: FetchParent accepts arbitrary PrincipalInfo without validation (PFetch principal forgery)

Categories

(Core :: DOM: Networking, defect, P2)

defect

Tracking

()

RESOLVED FIXED
151 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox-esr140 --- wontfix
firefox149 --- wontfix
firefox150 --- wontfix
firefox151 --- fixed

People

(Reporter: LatticeBased, Assigned: valentin)

References

(Blocks 1 open bug)

Details

(Keywords: ai-involved, reporter-external, sec-want, Whiteboard: [necko-triaged][necko-priority-queue][adv-main151-])

Attachments

(3 files, 1 external file)

Summary

FetchParent::RecvFetchOp (dom/fetch/FetchParent.cpp:100) accepts any PrincipalInfo
from the content process via IPC without calling ValidatePrincipal. A compromised
content process can forge the loading principal to make network requests as any origin.

Vulnerable Code

// dom/fetch/FetchParent.cpp:100
// FetchParent::RecvFetchOp accepts mPrincipalInfo directly from IPC
// No ValidatePrincipal call on the received principal

Protected Comparison

Many other IPC handlers in ContentParent.cpp DO call ValidatePrincipal:

  • RecvSetClipboard (line ~3201)
  • RecvCreateWindow (line ~5460)
  • RecvStoreAndBroadcastBlobURLRegistration (line ~6387)

PoC

Real browser test using Marionette with Firefox 150.0a1:

./mach python testing/marionette/harness/marionette_harness/runner/httpd.py \
    poc/test_f1_pfetch_verify.py

Test Output

F1 PFetch + F21 GetUsage - REAL BROWSER VERIFICATION
[+] Firefox 150.0a1 started. PID: 19148
--- Step 3: F1 Forged principal channel creation ---
  Channel to example.com with forged attacker principal:
    Status: success
    Forged principal: https://attacker.example.org
    HTTP status: 200
    Response length: 0
  [PASS] Forged channel executed, got 0 bytes
  [PASS] Loading principal is FORGED: https://attacker.example.org
  Channel with SystemPrincipal:
  [PASS] SystemPrincipal channel: 528 bytes
Results: 7 PASS, 0 FAIL

Also verified in combined real browser test (ALL_FINDINGS_REAL_BROWSER.txt):

F1: PFetch Principal Forgery
  [PASS] F1: Forged channel executed (0 bytes)
  [PASS] F1: Principal is FORGED: https://attacker.evil.com
  [PASS] F1: SystemPrincipal channel -> 528 bytes

Impact

A compromised content process can make network requests attributed to any origin,
bypassing same-origin policy. This enables cross-origin data theft, CSRF attacks
using the victim's cookies, and server-side request forgery from the browser.

Fix

Add ValidatePrincipal check in FetchParent::RecvFetchOp before using the principal:

if (!ValidatePrincipal(mPrincipalInfo)) {
  return IPC_FAIL(this, "Invalid principal");
}
Group: core-security → dom-core-security
Severity: S1 → --
Component: DOM: Content Processes → DOM: Networking
Keywords: sec-audit
Priority: P1 → --
Group: dom-core-security → network-core-security
Assignee: nobody → valentin.gosu
Severity: -- → S3
Priority: -- → P2
Whiteboard: [necko-triaged][necko-priority-queue]
Attached file (secure) —
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: sec-want
Flags: needinfo?(valentin.gosu)
Flags: needinfo?(rjesup)

Rebasing and landing in the next day or so.

Flags: needinfo?(valentin.gosu)
Flags: needinfo?(rjesup)
Pushed by csabou@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/a29d7699a3aa https://hg.mozilla.org/integration/autoland/rev/4d5ff10dd29f Revert "Bug 2025183 - Validate principal in FetchParent::RecvFetchOp r=necko-reviewers,jesup" for causing failures on browser_aiwindow_assistant_message_footer
[task 2026-04-13T13:56:46.725+00:00] 13:56:46     INFO - GECKO(5023) | [5023] Hit MOZ_CRASH(Use IPC_FAIL only in an unrecoverable, unexpected state: RecvFetchOp RecvFetchOp principal not allowed for remote type
[task 2026-04-13T13:56:46.726+00:00] 13:56:46     INFO - GECKO(5023) | ) at /builds/worker/checkouts/gecko/ipc/glue/ProtocolUtils.cpp:72
[task 2026-04-13T13:56:46.726+00:00] 13:56:46     INFO -  Initializing stack-fixing for the first stack frame, this may take a while...
[task 2026-04-13T13:56:58.203+00:00] 13:56:58     INFO - GECKO(5023) | #01: mozilla::ipc::IPCResult::FailImpl(mozilla::NotNull<mozilla::ipc::IProtocol*>, char const*, char const*) [git:github.com/mozilla-firefox/firefox:ipc/glue/ProtocolUtils.cpp:a50f2b9345b13bdf26163adced94713c0b0e6c2a:72]
[task 2026-04-13T13:56:58.203+00:00] 13:56:58     INFO - GECKO(5023) | #02: mozilla::dom::FetchParent::RecvFetchOp(mozilla::dom::FetchOpArgs&&) [git:github.com/mozilla-firefox/firefox:dom/fetch/FetchParent.cpp:a50f2b9345b13bdf26163adced94713c0b0e6c2a:111]
[task 2026-04-13T13:56:58.204+00:00] 13:56:58     INFO - GECKO(5023) | #03: mozilla::dom::PFetchParent::OnMessageReceived(IPC::Message const&) [s3:gecko-generated-sources:6d37c42db8f39cae04b7bdc5babcd0e0a37a6a6cd67719a9f4a5c6a09d924353b12682f46c02b70f0b6829775017e00250dd75d59e1f244ced6e5398829f2e76/ipc/ipdl/PFetchParent.cpp::0]
[task 2026-04-13T13:56:58.205+00:00] 13:56:58     INFO - GECKO(5023) | #04: mozilla::ipc::PBackgroundParent::OnMessageReceived(IPC::Message const&) [s3:gecko-generated-sources:f10402be76ceca0b4fec98602700fc374f8c616d8b61b7193e15edf7cbd25780ca080cab9e721ff0e0f3d960daa1a3c535b6db21e395890bf3b4036462b6e7a6/ipc/ipdl/PBackgroundParent.cpp::2054]
[task 2026-04-13T13:56:58.205+00:00] 13:56:58     INFO - GECKO(5023) | #05: mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) [git:github.com/mozilla-firefox/firefox:ipc/glue/MessageChannel.cpp:a50f2b9345b13bdf26163adced94713c0b0e6c2a:1798]
[task 2026-04-13T13:56:58.206+00:00] 13:56:58     INFO - GECKO(5023) | #06: mozilla::ipc::MessageChannel::DispatchMessage(mozilla::ipc::ActorLifecycleProxy*, std::unique_ptr<IPC::Message, std::default_delete<IPC::Message> >) [git:github.com/mozilla-firefox/firefox:ipc/glue/MessageChannel.cpp:a50f2b9345b13bdf26163adced94713c0b0e6c2a:0]
[task 2026-04-13T13:56:58.207+00:00] 13:56:58     INFO - GECKO(5023) | #07: mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::ipc::MessageChannel::MessageTask&) [git:github.com/mozilla-firefox/firefox:ipc/glue/MessageChannel.cpp:a50f2b9345b13bdf26163adced94713c0b0e6c2a:1513]
[task 2026-04-13T13:56:58.207+00:00] 13:56:58     INFO - GECKO(5023) | #08: mozilla::ipc::MessageChannel::MessageTask::Run() [git:github.com/mozilla-firefox/firefox:ipc/glue/MessageChannel.cpp:a50f2b9345b13bdf26163adced94713c0b0e6c2a:1624]
[task 2026-04-13T13:56:58.208+00:00] 13:56:58     INFO - GECKO(5023) | #09: nsThread::ProcessNextEvent(bool, bool*) [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThread.cpp:a50f2b9345b13bdf26163adced94713c0b0e6c2a:1174]
[task 2026-04-13T13:56:58.208+00:00] 13:56:58     INFO - GECKO(5023) | #10: NS_ProcessNextEvent(nsIThread*, bool) [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThreadUtils.cpp:a50f2b9345b13bdf26163adced94713c0b0e6c2a:465]
[task 2026-04-13T13:56:58.209+00:00] 13:56:58     INFO - GECKO(5023) | #11: mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*) [git:github.com/mozilla-firefox/firefox:ipc/glue/MessagePump.cpp:a50f2b9345b13bdf26163adced94713c0b0e6c2a:298]
[task 2026-04-13T13:56:58.210+00:00] 13:56:58     INFO - GECKO(5023) | #12: MessageLoop::Run() [git:github.com/mozilla-firefox/firefox:ipc/chromium/src/base/message_loop.cc:a50f2b9345b13bdf26163adced94713c0b0e6c2a:347]
[task 2026-04-13T13:56:58.210+00:00] 13:56:58     INFO - GECKO(5023) | #13: nsThread::ThreadFunc(void*) [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThread.cpp:a50f2b9345b13bdf26163adced94713c0b0e6c2a:376]
[task 2026-04-13T13:56:58.211+00:00] 13:56:58     INFO - GECKO(5023) | #14: _pt_root [git:github.com/mozilla-firefox/firefox:nsprpub/pr/src/pthreads/ptthread.c:a50f2b9345b13bdf26163adced94713c0b0e6c2a:193]
[task 2026-04-13T13:56:58.212+00:00] 13:56:58     INFO - GECKO(5023) | #15: ??? [/builds/worker/workspace/build/application/firefox/firefox + 0x8482d]
[task 2026-04-13T13:56:58.213+00:00] 13:56:58     INFO - GECKO(5023) | #16: ??? [/lib/x86_64-linux-gnu/libc.so.6 + 0x9caa4]
[task 2026-04-13T13:56:58.213+00:00] 13:56:58     INFO - GECKO(5023) | #17: __clone [/lib/x86_64-linux-gnu/libc.so.6 + 0x129a34]
[task 2026-04-13T13:56:58.213+00:00] 13:56:58     INFO - GECKO(5023) | #18: ??? (???:???)
TEST-UNEXPECTED-FAIL | browser/components/aiwindow/ui/test/browser/browser_aiwindow_assistant_message_footer.js | test_message_footer_shows_up_on_last_chunk - Test timed out
Flags: needinfo?(valentin.gosu)
Flags: needinfo?(valentin.gosu)
Group: network-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 7 months ago
Resolution: --- → FIXED
Target Milestone: --- → 151 Branch
See Also: → 2031764
QA Whiteboard: [sec] [qa-triage-done-c152/b151]
Duplicate of this bug: 2031764
Whiteboard: [necko-triaged][necko-priority-queue] → [necko-triaged][necko-priority-queue][adv-main151-][adv-esr115.36-][adv-esr140.11-]
Whiteboard: [necko-triaged][necko-priority-queue][adv-main151-][adv-esr115.36-][adv-esr140.11-] → [necko-triaged][necko-priority-queue][adv-main151-]
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: