ForcedLeak: Draining CRM Data from Salesforce Agentforce
On this page
Fill in a web lead form with hidden instructions, wait for an employee to ask the AI about it, and the CRM answers back to you.
| When | September 2025 |
|---|---|
| Target | Salesforce Agentforce (Web-to-Lead) |
| Researcher | Noma Security (Noma Labs) |
| Technique | Indirect prompt injection + expired-allowlist-domain exfiltration |
| Status | No CVE; vendor-rated CVSS 9.4; Salesforce fixed 8 Sep 2025 |
- 1An attacker submits a Web-to-Lead form whose Description field hides instructions
- 2An employee later asks Salesforce Agentforce to process that lead
- 3The agent exfiltrates CRM data to an image URL on an expired allowlisted domain
What happened
In 2025, Noma Security disclosed ForcedLeak: an indirect prompt injection against Salesforce Agentforce. A public Web-to-Lead form's Description field (up to 42,000 characters) accepted attacker instructions that lay dormant until an employee later asked the agent to process the lead — at which point it exfiltrated CRM data. Salesforce shipped Trusted-URL enforcement on 8 September 2025. No CVE was assigned; Noma rated it CVSS 9.4.
How the attack worked
The injected instructions told the agent to gather CRM data and send it to an image URL. The chosen domain — my-salesforce-cms.com — was still on Salesforce's content-security-policy allowlist but had expired, so the researchers re-bought it for about $5 and received whatever the agent 'rendered'.
A stale allowlist is an open doorThe exfiltration didn't beat the CSP — it used an allowlisted domain the vendor no longer owned.
Root cause
Untrusted lead content was processed as instructions, and the egress allowlist trusted a domain that had lapsed from the company's control.
What a test would have caught
Planting instructions in an ingestible CRM field and checking whether the agent acts on them or emits an outbound URL surfaces the injection; auditing allowlisted egress domains for ownership surfaces the channel.
How to prevent it
- Isolate untrusted fields (like public lead forms) from agent instructions.
- Continuously verify allowlisted egress domains are still owned by you.
- Constrain and log the data an agent can send outbound.
Feel it yourselfThe replay lab recreates the exfiltration class — get an agent to leak its data through a rendered outbound URL.
FAQ
How did untrusted data get into the agent?
The public Web-to-Lead form's Description field (up to 42k characters) accepts attacker text. It sits benign until an employee later asks Agentforce to process the lead — at which point the hidden instructions execute as an indirect injection.
What made the exfiltration channel work?
The stolen data was sent to an image URL on a domain still present on Salesforce's content-security-policy allowlist. The domain had lapsed, so the researchers bought it back for ~$5 and received the data — an expired-allowlist weakness, not a generic image beacon.
What's the fix?
Salesforce shipped Trusted-URL enforcement. Generally: isolate untrusted CRM fields from agent instructions, and continuously validate that allowlisted egress domains are still owned by who you think.