Vulnerability research

SalesBleed: how a sales lead could send CRM data outside

SalesBleed showed how an external sales lead could steer Agentforce into reading CRM data and sending it through links in a reply; the researchers confirmed cloud-side fixes, while operators still need to check action permissions, Slack confirmation and URL settings against actual browser and Slack behavior.

Warm-paper illustration of an incoming form, a records cabinet and an assistant producing an image and a message, connecting a sales lead to CRM access and outgoing content.
In this article

Asking a sales assistant to review a new lead is an ordinary use of the product. A prospective customer submits a form, an employee asks for a summary, and someone decides whether to follow up. That task needs one record explained. If the assistant follows instructions inside the record, queries other customers and places the results in an image address, its work has already exceeded the employee's request. The employee may never click the address: the software displaying the reply can make the request first.

SalesBleed, published by Zenity on September 24, 2026, demonstrated such a path in Salesforce Agentforce. A separate part of the research examined Slack actions that lacked confirmation and visible attribution to their invoker. These were researcher demonstrations. The URL fix was confirmed in August; Slack-related changes continued through September 21. In its subsequent response to SecurityWeek, Salesforce said it had no evidence at that time of exploitation against customers, had changed confirmation defaults for certain Slack actions, and was contacting customers about their configurations. This article uses public material checked on September 29.

The individual features all serve reasonable purposes. A form collects requirements, a query finds records, a reply can contain an image, and Slack previews links. Once an agent can combine them, text supplied in one record can influence its next query and the destination of the results. Our recommendation is to define the job narrowly before adding read and send capabilities. An employee's permission to access data, on its own, says little about whether a particular automated operation follows that employee's request.

1 CRM storage preserves the submitter's words

Salesforce Web-to-Lead turns website form submissions into leads. It handles collection and routing. Descriptions of a company or its requirements still come from the visitor after they reach the CRM. The default reCAPTCHA setting helps reduce unwanted submissions; it cannot decide whether a paragraph of business requirements is also trying to direct an assistant.

This is where indirect prompt injection enters the task. The employee makes a legitimate request, and the agent reads external material while carrying it out. Some of that material is treated as instructions for subsequent work. The person supplying it need not be the employee in the conversation or possess the employee's account. In this research, normal lead processing brought the stored text into the agent's active context.

How could another set of records become available? The standard QueryRecords action accepts natural-language conditions and can query supported standard and custom objects. One use may find a Lead; another may query Accounts. Zenity's exfiltration report describes a General CRM subagent with the query capability needed for both reads. The agent could stray from the task using access already available to its execution identity.

Those reads remain subject to the execution identity's permissions. Salesforce's action security guidance distinguishes execution contexts: employee agents in Lightning, mobile and Slack access data in the end user's context; customer-service agents have additional identity and access rules. An investigation therefore needs the actual identity, available actions and object permissions. The external form submitter and the employee who later processes the record are separate actors.

2 Displaying a reply can send a request

Reading data inside the service does not automatically make it visible to the external submitter. The next step in SalesBleed was to carry data in an address included in the reply. An image reference can cause a client to request that address; a link in Slack can cause its preview service to process it. Both consumers may produce network activity before the reader makes an additional click.

Salesforce already had output protection that replaced unapproved URLs with URL_Redacted. Zenity found that the old recognizer used a fixed set of top-level domains and missed valid suffixes outside that set, including .fun in its research. Braces and square brackets also caused the checker and the downstream renderer to disagree about where an address ended. Text missed by the checker could consequently remain usable as an address. The vendor has not published the internal implementation or patch code. The verifiable material here consists of the researchers' observed behavior, their remediation confirmations and current product documentation.

A harmless example helps explain why an unusual-looking address can remain parseable. SOSEC ran the following code offline with Node.js v24.19.0. It calls the URL constructor without making a DNS lookup or website request:

const value = new URL('https://demo.example.invalid/{note}');
console.log(value.hostname); // demo.example.invalid
console.log(value.pathname); // /%7Bnote%7D

The parser keeps the hostname and encodes the braces in the path. A filter recognizing only certain textual shapes can disagree with a program that actually consumes URLs. This check establishes only the local parsing behavior. It does not run Agentforce or test Salesforce's current filter. A repair for this class of problem needs to account for the input accepted by each output consumer and apply the allow rules to the same meaning.

An external lead reaches the agent, which queries CRM and produces a reply containing an address. Browser image loading and Slack link previews form separate branches that can send information in a DNS name to an external domain.
Illustration of the outgoing-data path. The browser and Slack preview service consume addresses separately; actual requests depend on rendering, preview settings and network controls. The agent's Slack message-writing action is discussed separately below.

DNS matters because a client commonly resolves a host before connecting to it. If data is placed in the hostname, the lookup name contains that data. Under the DNS resolution process, a cache may answer a request and network controls may block it. Once a query reaches an authoritative server for an attacker-controlled domain, however, the characters in the name have crossed the system's boundary. A later HTTPS failure cannot recall the information already carried by that query.

The origin of the request determines where investigators can see it. Browser image requests can appear in endpoint and browser network records. Slack previews originate from Slack's service, beyond the employee browser's logs. Looking only for a click, or only for a successful response from a destination website, misses this part of the sequence.

"Zero-click" has a specific meaning in this report: after an employee initiates the legitimate task, the demonstrated path does not require an additional click on a malicious link. The employee still processes a lead, the agent still needs the relevant query capabilities, and the output still needs a consumer that handles the address. Disabling images or previews removes the corresponding branch in that deployment; other clients require their own checks.

3 A Slack preview and a Slack write use different capabilities

A preview processes a link that has already appeared. Writing a message requires another capability: the agent must select a conversation, a thread and message content. Salesforce's Slack integration documentation lists search, thread replies and direct messages as distinct Slack Knowledge actions that administrators configure for the work. An agent restricted to reading CRM data does not acquire every Slack action merely because it can generate text.

Zenity's second report found that Reply to a Slack Thread lacked pre-execution confirmation and recipient-visible invoker attribution in its test configuration. Its comparison action, Send a Slack Direct Message, had both. The research considered an internal actor able to invoke the agent as well as external lead content reaching a workflow with CRM reads and Slack writes. The latter path still requires an agent equipped with those actions; it does not establish that any form can send to any Slack destination.

The two controls answer different questions. Confirmation lets the operator inspect the destination and content before a message leaves, and cancel it. Attribution tells recipients who invoked the agent. That label helps explain the source of the message, but it does not show that the named person carefully approved every sentence. The public report concerns visible attribution; we have not inferred a complete absence of internal vendor audit records from it.

A useful confirmation interface should show the destination conversation, the thread and the complete final text. A generic request to "run the action" gives the operator little to inspect. If the recipient or text can change after approval, the earlier consent no longer describes the final operation. These are SOSEC design recommendations; whether a particular configuration meets them requires an actual check.

Confirmation also costs a step. Teams sending frequent routine notifications may want to disable it. For a predictable task, we would first constrain the recipients, message structure and permitted data, then evaluate automatic sending. Open-ended CRM reads followed by arbitrary Slack messages carry a wider scope. Turning confirmation off removes the pre-send checkpoint; that setting alone does not restore a patched URL-recognition bypass.

4 Check the tenant after the cloud-side repair

SalesBleed has no single firmware release for an administrator to download. Zenity's detailed timeline records URL-bypass repair confirmation on August 19, invoker-attribution confirmation on August 20, and confirmation of all related fixes on September 21. We use those separate dates. Some news coverage summarized remediation as complete on August 19, omitting the subsequent Slack work. The current task is to inspect the active Agentforce actions and organization settings, and have the vendor confirm the applicable repair status for the tenant.

Following the data flow back, the earliest place to narrow the work is the read. Implement "summarize this lead" as an action that accepts the selected Lead ID and returns only the required fields. If the task must consult existing customers, enforce the matching conditions in a Flow or code. The interface then remains tied to the selected record even when the agent encounters another instruction. This reduces general-purpose querying flexibility and suits stable, sensitive tasks. An assistant intended for open-ended analysis needs stronger output checks to match its wider access.

Next check write actions. Does each agent need to reply to Slack threads, send direct messages or perform other external writes, and does confirmation remain enabled? The Agent Script reference defines require_user_confirmation as requiring confirmation before execution. It documents an available control, not the state of a particular live action. Existing agents, copied actions and manually changed settings should be evaluated through their actual behavior.

Then inspect allowed destinations. The current Trusted URLs guidance includes an important change that older tutorials can conceal: the default *.salesforce.com allowance was removed on February 28, 2026. Add business destinations by their precise domain and purpose. Restoring a broad wildcard merely to make a redacted link visible expands what the configuration accepts. Review organization settings and any URL allowances present in agent instructions together.

Permission to appear in a reply and permission to make a network request are separate controls. Salesforce output handling, a web page's content security policy, browser image loading and Slack previews each govern a part of the process. Passing an allowlist does not establish that data in the hostname or parameters is suitable for external disclosure. Remove unnecessary external-image and dynamic-link output. Where links serve a real task, constrain their destination and parameter sources so arbitrary CRM fields cannot become address components.

Teams maintaining their own Slack applications can use two independent fields from the official unfurling documentation to disable text-link and media previews:

{
  "unfurl_links": false,
  "unfurl_media": false
}

These are message-API controls for a custom application. They do not establish that Agentforce's built-in action exposes the same fields to administrators. With a built-in connector, check the options it actually offers and the behavior of its messages. If preview behavior cannot be controlled, restrict generated links and sending actions first. Those controls act closer to the request than a block on the employee's computer.

While repair status or settings remain uncertain, an operator can pause the affected agent's processing of external leads or remove unnecessary Slack writes. That interrupts the corresponding routing, summarization or notification workflow, so people need a replacement process. Web-to-Lead can continue collecting records where appropriate, with agent processing held until review. Returning to service should include a working normal task, limits on unnecessary actions and verified output handling; confirmation or restrictions temporarily removed during troubleshooting should not be left disabled by accident.

5 Verify one complete task

A configuration page shows where a switch is set. By itself, it cannot explain what the agent read or where it sent the result. We recommend following one lead-processing task in an authorized test environment with fictitious business data. Keep the source record, action inputs and outputs, final reply and requests from the interface together under the same session. The checks below are recommendations derived from the public mechanism; SOSEC has not run them in a Salesforce tenant.

Keep an ordinary control first. A test lead without instruction-like text should produce an accurate summary, expose the required fields and complete the expected workflow. Then check scope: when the process needs one Lead, can an associated action read an unrelated Account? If that access is intentional, record the conditions. A record absent from the final answer may still have been read.

Test display and sending separately. Observe whether a reply containing only test data loads an image in the browser or generates a Slack preview. Any test domain must be controlled by the organization, and logs should carry synthetic markers, never real customer data. For sending, check cancellation, approval and attribution: cancellation leaves no outgoing message; the approved content matches the final content; recipients can identify the invoker. A browser observation does not cover Slack's server-side requests, and one thread reply does not cover every write action.

Salesforce session tracing can organize interactions, actions, inputs, outputs and errors by session, helping identify the step where work diverged. Check availability, activation, retention and access first. Traces can contain sensitive business material themselves; convenient debugging does not justify giving every administrator or external support recipient the complete records.

For an existing anomaly, preserve the suspect lead's text, provenance and modification time, together with related sessions, actions, replies, Slack destinations and available network records. Instruction-like text left in CRM may influence the agent when read again, so isolate it from automatic processing after preservation. Previously transmitted data and messages need separate handling. Disabling an action limits subsequent use; it cannot retrieve content already seen by a recipient.

Missing records constrain the conclusion. Tracing that was never enabled, expired retention and Slack previews outside the corporate network leave different gaps. Investigators can state which period or step cannot be reconstructed while improving the current workflow. The vendor's disclosure-time statement about finding no customer exploitation does not replace an organization's review of its own records.

6 Let capabilities grow with the job

SalesBleed makes a practical deployment choice easier to see. Employees want fewer manual queries and less copying, so an assistant receives access to records and ways to package the results. Each additional action should have a clear purpose in the task and an identified consumer for its output. For a job such as summarizing one sales lead, access to that record, a reliable summary and a human follow-up path already provide value. Cross-object queries and automatic sending can follow when the work needs them, with checkable inputs, explicit recipients and appropriate confirmation. That assistant is easier to operate and easier to investigate when its behavior goes wrong.

7 References

  1. Zenity: Agentforce exfiltration research and remediation timeline, September 24, 2026
  2. Zenity: Slack confirmation, attribution and separate fixes, September 24, 2026
  3. SecurityWeek: reporting and Salesforce's response, September 25, 2026
  4. Salesforce: Web-to-Lead; Query Records
  5. Salesforce: action identity, access and data protection
  6. Salesforce: current Trusted URLs configuration and the 2026 wildcard change; 2025 URL-redaction release note
  7. Salesforce: Agentforce and Slack actions; Agent Script action definitions and confirmation
  8. Slack: link and media unfurling
  9. Salesforce: Agentforce session tracing
  10. Node.js: WHATWG URL parsing; RFC 1034: resolver algorithm
Research basis

Research basisReview of both original investigations, vendor configuration and action documentation, and the remediation timeline; an offline URL parsing check with no network access. Agentforce internals and patch code are not public. No customer tenant access, injection replay or independent vulnerability reproduction. Sources checked through 2026-09-29 06:00 UTC.

SourceZenity Labs, Salesforce and Slack documentation, and Salesforce's response to SecurityWeek

Evidence confidence High