DEV Community

Cover image for ForcedLeak: What Salesforce Agentforce's CVSS 9.4 Exploit Reveals About AI Agent Governance
Logan for Waxell

Posted on • Originally published at waxell.ai

ForcedLeak: What Salesforce Agentforce's CVSS 9.4 Exploit Reveals About AI Agent Governance

On September 25, 2025, Noma Security publicly disclosed ForcedLeak: a CVSS 9.4 vulnerability chain in Salesforce Agentforce that let an external attacker — using nothing but a public Web-to-Lead form and a $5 domain purchase — exfiltrate sensitive CRM data from any Salesforce organization running Agentforce. The attack required zero interaction from the victim. It left no obvious trail before Salesforce's patch. And it worked because the governance layer that should have sat between the agent's intent and its actions didn't exist.

Salesforce acted responsibly: they received Noma's report on July 28, 2025, implemented Trusted URLs Enforcement for Agentforce and Einstein AI on September 8, and allowed public disclosure on September 25. The patching timeline was reasonable. What the incident reveals isn't a failure of Salesforce's security team — it's a structural demonstration of what happens when an agentic system has broad tool access, processes untrusted input, and has no runtime enforcement layer between ingestion and action.

Indirect prompt injection in agentic systems is the attack class where malicious instructions are embedded in content that an AI agent will later retrieve and process — not delivered directly by the user, but planted in the environment the agent operates in: a web form, a document, an email, a database record. The agent encounters the poisoned content during a legitimate task and, having no mechanism to distinguish attacker instructions from legitimate data, executes both. Unlike direct injection (where the attacker is the user), indirect injection is zero-click from the victim's perspective. The employee doesn't do anything wrong. They ask their agent a normal question. The malicious payload was already waiting in the CRM.


How does indirect prompt injection work in enterprise AI agents?

The ForcedLeak attack chain has four steps, and each one is instructive.

Step 1: Planting the payload. Salesforce's Web-to-Lead feature includes a large-capacity description field — designed for prospects to describe their needs, with no meaningful length restriction on the payload an attacker could embed. Noma's researchers used this field to embed malicious instructions disguised as ordinary lead data. To a human reviewing the form submission, it looked like a normal inquiry. To the Agentforce AI processing that lead record, it looked like instructions.

Step 2: Waiting for a legitimate query. When a Salesforce employee later asked Agentforce to look up information about that lead — a completely routine business operation — the agent retrieved the lead record, including the poisoned description field. The agent's context window now contained both the employee's legitimate request and the attacker's hidden instructions.

Step 3: Data extraction and exfiltration. The hidden instructions told the agent to gather specific sensitive data from the CRM — contact details, deal values, pipeline records — and transmit it to an external server. The exfiltration mechanism used an image request: the agent generated a URL with the stolen data encoded as parameters, triggering an outbound HTTP call that carried the payload.

Step 4: The trusted channel. Here's where the expired domain enters. Salesforce's Content Security Policy included a whitelist of trusted URLs. One of them — my-salesforce-cms.com — had expired and become available for public purchase. Noma's researchers bought it for approximately $5. The attacker-controlled server was, from Salesforce's CSP perspective, a trusted destination. The exfiltration traffic was allowed through.

This is the OWASP LLM Top 10's LLM01 (Prompt Injection) in production, against a major enterprise AI platform, at critical severity. According to published research citing Wiz data, documented prompt injection attempts against enterprise AI systems reportedly increased 340% year-over-year in Q4 2025, with indirect injection accounting for over 80% of documented attack attempts. ForcedLeak is not an anomaly. It's an illustration of the category.


Why was ForcedLeak possible even with Salesforce's security controls?

Salesforce had security controls in place. They had a Content Security Policy. They had a domain whitelist. They had access controls on agent capabilities. None of it stopped the attack, and understanding why tells you something important about where AI agent security actually breaks.

The root cause wasn't that Salesforce had no controls. It was that the controls operated at the wrong layer.

The CSP whitelisted domains. But the CSP didn't evaluate whether the agent's outbound request was legitimate. It only checked whether the destination URL was on the list. The expired domain was on the list; therefore the request was allowed. No policy evaluated the content of the request — what data it contained, whether it originated from an automated agent workflow, whether the request pattern matched any known exfiltration signature.

The agent had CRM access. But nothing evaluated whether this specific agent session should be allowed to transmit CRM data to an external URL. The access permission was coarse-grained: the agent could access CRM records. The governance question — "should an agent processing a new lead inquiry be permitted to make outbound calls containing account data to a non-Salesforce domain?" — was never asked, because there was no layer that asked it.

This is the indirect prompt injection defense gap that runtime governance is designed to fill. CSPs, access controls, and trust policies are all valuable. They are not substitutes for a policy layer that evaluates each action the agent proposes to take before that action executes.


What data was at risk in the ForcedLeak attack?

The attack chain targeted the full contents of what Agentforce could see: lead contact information, email addresses, phone numbers, company details, deal stage and pipeline values, internal notes and activity history, and whatever else the agent's CRM access scope included. In a typical Agentforce deployment where the agent assists with sales workflows, that scope is broad.

The "Lethal Trifecta" — a framework coined by security researcher Simon Willison — describes what makes an agentic system vulnerable to this class of attack: access to private data, exposure to untrusted content, and an available exfiltration vector. Agentforce had all three. Most enterprise AI agents do. An agent that answers questions about customer accounts, processes inbound lead data, and makes outbound tool calls — the description of half the Agentforce use cases documented on Salesforce's own website — checks all three boxes.

Salesforce has over 150,000 customers. Agentforce launched to general availability on October 29, 2024. The potential blast radius of ForcedLeak, before the patch, was proportional to Agentforce's adoption footprint in the ten months between GA and disclosure.


How would runtime governance have caught ForcedLeak before it executed?

ForcedLeak wasn't inevitable. The attack worked because there was no enforcement layer between the agent's processing of the poisoned lead and its execution of the hidden instructions. A runtime governance policy operating at the infrastructure layer — evaluated before each tool call and output, not after — would have had multiple points to intercept the chain.

At input: An input validation policy scanning lead description fields for prompt injection patterns would have flagged the malicious payload at ingestion. Not blocked CRM lead creation — but flagged the specific record for human review before it entered the agent's context.

At tool call: A tool access policy restricting outbound HTTP requests from agent sessions would have blocked the exfiltration call entirely. The policy doesn't need to know the domain is attacker-controlled — it only needs to enforce the rule: "agent sessions processing new lead data are not permitted to make outbound requests to external URLs, regardless of domain allowlist status." The expired domain exploit becomes irrelevant when the tool call itself is gated.

At output: A content governance policy scanning any outbound request for structured data matching CRM records (name + email + company + deal value patterns) would have caught the data in transit. The exfiltration payload was the data — intercept the data, stop the leak.

At the controlled data interface: In a governed architecture, CRM data doesn't flow freely into agent context. The Signal and Domain pattern specifies what data agents receive and in what form — the agent gets processed lead attributes, not the raw description field contents. The attack payload never enters the context window.

Any one of these layers stops ForcedLeak. All of them together make the attack class structurally harder to execute. This is the argument for governance above the agent, not inside it: you can't modify the Salesforce CRM schema or Agentforce's prompt processing to add these controls. But you can add an enforcement layer that sits above the agent's execution and evaluates each proposed action before it runs.


How Waxell handles this

How Waxell handles this: Waxell's runtime governance policies are evaluated before each tool call and output, independent of the agent's own reasoning. For an indirect prompt injection scenario like ForcedLeak, three policy types apply directly: input validation policies (detecting injection patterns in ingested content before it enters agent context), tool access policies (restricting which outbound calls agent sessions can make, under what conditions), and content policies (scanning outbound requests for structured data matching sensitive record patterns). Waxell's controlled data interfaces let you define exactly what data enters agent context — so a raw, unvalidated form submission field never reaches the agent in the first place. Waxell's security guarantees are infrastructure-layer enforcement: they apply regardless of what framework built the agent, what the agent's model reasoned, and what instructions a poisoned record tried to embed.


Frequently Asked Questions

What is ForcedLeak?
ForcedLeak is a CVSS 9.4 (Critical) vulnerability chain in Salesforce Agentforce, discovered by Noma Security and reported to Salesforce on July 28, 2025. The vulnerability allowed an external attacker to exfiltrate sensitive CRM data by embedding malicious instructions in a Salesforce Web-to-Lead form. When an internal employee later queried Agentforce about the lead, the agent executed the hidden instructions — gathering CRM data and transmitting it to an attacker-controlled server via an expired whitelisted domain. Salesforce patched the issue on September 8, 2025 by implementing Trusted URLs Enforcement for Agentforce and Einstein AI.

What is indirect prompt injection in AI agents?
Indirect prompt injection is an attack where malicious instructions are embedded in content that an AI agent will later retrieve and process — not delivered directly to the agent by the user, but planted in the environment the agent operates in. In ForcedLeak, the poisoned content was a web form submission stored as a CRM record. When the agent processed the record during a legitimate task, it encountered and executed the hidden instructions. The victim (the Salesforce employee) performed no unusual action — the attack was entirely invisible to them. OWASP classifies this as LLM01 (Prompt Injection) and considers it the highest-priority risk category for deployed LLM applications.

Why can't allowlists and Content Security Policies prevent prompt injection attacks like ForcedLeak?
CSPs and domain allowlists operate at the request destination level — they check whether the URL being requested is approved. They don't evaluate whether the request itself is legitimate: whether it originates from an automated instruction, whether it contains sensitive data, or whether its pattern matches an exfiltration workflow. In ForcedLeak, the destination domain was on Salesforce's allowlist (it had been a legitimate Salesforce CMS domain), so the CSP passed the request. The attack exploited the assumption that a trusted destination means a trustworthy request. Runtime governance evaluates the request content and context, not just its destination.

What is the "Lethal Trifecta" for AI agent security vulnerabilities?
The Lethal Trifecta is a framework coined by security researcher Simon Willison for assessing indirect prompt injection risk in agentic systems. A system is vulnerable when three conditions are simultaneously present: access to private data (the agent can see sensitive information), exposure to untrusted content (the agent processes input from sources it doesn't fully control), and an available exfiltration vector (the agent can make outbound calls carrying data). If all three are present, the system has the structural prerequisites for a ForcedLeak-class attack. Most enterprise AI agents meet all three conditions by design. The mitigation is to address one or more legs of the trifecta with runtime governance controls.

Was Salesforce Agentforce uniquely vulnerable, or does this class of attack affect all enterprise AI agents?
The vulnerability chain involved a Salesforce-specific expired domain in their CSP, but the attack class — indirect prompt injection via user-controlled input fields that an agent later processes — affects any agentic system that processes external content and has outbound tool access. According to published research citing Wiz data, indirect prompt injection reportedly accounts for over 80% of documented prompt injection attempts against enterprise AI systems, with a 340% year-over-year increase in Q4 2025. Any AI agent that reads emails, processes support tickets, ingests form submissions, or browses the web as part of its workflow has exposure to this attack class. The ForcedLeak technical specifics are Salesforce's — the governance lesson is universal.

What should teams building enterprise AI agents do after ForcedLeak?
Three immediate actions: first, audit every untrusted content source your agents ingest — web forms, emails, documents, third-party API responses — and ask whether malicious instructions embedded in that content would be distinguishable from legitimate data. Second, review your agent's outbound tool call permissions: does any agent session need to make arbitrary external HTTP requests, or can that be scoped to a specific approved set? Third, add input validation at the governance layer — not as a prompt instruction, but as infrastructure-level enforcement that scans content before it enters agent context. These three measures address the three legs of the Lethal Trifecta that ForcedLeak exploited.


Sources

Top comments (0)