genai
SECURITY LAB
IncidentsData exfiltration

ForcedLeak: Draining CRM Data from Salesforce Agentforce

High severitySeptember 2025LLM01: Prompt InjectionLLM02: Sensitive Information Disclosure
Status: Noma Security (Noma Labs); Salesforce fixed 8 Sep 2025 with Trusted-URL enforcement. No CVE assigned; vendor-rated CVSS 9.4
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.

WhenSeptember 2025
TargetSalesforce Agentforce (Web-to-Lead)
ResearcherNoma Security (Noma Labs)
TechniqueIndirect prompt injection + expired-allowlist-domain exfiltration
StatusNo CVE; vendor-rated CVSS 9.4; Salesforce fixed 8 Sep 2025
Attack flow
  1. 1An attacker submits a Web-to-Lead form whose Description field hides instructions
  2. 2An employee later asks Salesforce Agentforce to process that lead
  3. 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.

Replay this attack
Get an agent to leak its data through a rendered outbound URL — the exfiltration class behind ForcedLeak.
Open the live lab
Runs as a live, sandboxed lab. Sign-in required — this replay is a Pro lab. Recreates the attack class, not this exact branded bot.