TL;DR
- Four campaigns, three entry routes, zero platform vulnerabilities. The routes are vishing an employee through the OAuth consent screen, compromising a vendor that already holds tokens for your org, and finding an Experience Cloud guest profile that leaves the Aura endpoint open.
- Salesloft Drift: August 2025. Google Threat Intelligence Group published on 27 August 2025 and dated the activity from "as early as Aug. 8, 2025 through at least Aug. 18, 2025", attributing it to UNC6395. The actor queried Cases, Accounts, Users and Opportunities looking for AWS keys, Snowflake tokens and passwords sitting in support case text.
- Gainsight: November 2025. GTIG identified more than 200 potentially affected Salesforce instances; Gainsight's own investigation found roughly 285. Salesforce revoked every access and refresh token for Gainsight-published apps and pulled them from AppExchange.
- Experience Cloud and Aura: March 2026. Salesforce published guidance on 7 March 2026 and updated it on 11 March. Attackers repurposed Mandiant's own AuraInspector tool against
/s/sfsites/aura, bundled up to 250 actions into one request, and used thesortByparameter to break the 2,000-record cap. - Klue: June 2026. ReliaQuest published on 17 June 2026. Note what it does not say: attribution was "currently unknown" and the initial access vector "unresolved". The Icarus name and the ShinyHunters Telegram claim both came later.
- Most secondary coverage has the dates wrong. The common error merges Drift and Klue into a single "June 2026 Salesloft Drift" campaign that never happened. Every date below has a primary source next to it.
- One audit covers all three routes, and it is mostly things you can check this afternoon: connected apps holding live refresh tokens, guest profile API access, and Event Monitoring for the query patterns.
What You'll Learn
- What actually happened in each campaign, with a primary source for every date
- Which actor designation means what, since six different names are in circulation for overlapping activity
- Why "not a platform vulnerability" is a true statement that does not reduce your exposure
- The audit that covers all three entry routes, and the order to run it in
- The durable detection signals, as opposed to the IP addresses that expired months ago
The Problem
If you go looking for what happened to Salesforce customers over the last year, you will find a great deal of coverage and a surprising amount of it is wrong in the same way.
The most common error merges two separate campaigns. One widely syndicated write-up describes a "Salesloft Drift OAuth Token Breach" running "between June 8 and June 18, 2026" and attributes it to "UNC6395 'Icarus'". Checked against the primary sources, that sentence contains three errors. Google Threat Intelligence Group dated the Salesloft Drift activity to 8 August through 18 August 2025, not June 2026. The June 2026 dates belong to the Klue incident, which involved a different vendor. And UNC6395 and Icarus are not the same designation for the same group: Microsoft attributes the Klue compromise to Storm-3138, while Icarus is the name used by whoever claimed the extortion.
That matters more than pedantry. If you believe the Drift campaign happened in June 2026, you will conclude your August 2025 token rotation was sufficient, and it was not, because Gainsight and Klue came afterwards. Dates are the load-bearing part of an incident timeline.
There is a second, quieter problem. Salesforce has said, correctly, that none of these incidents came from a vulnerability in its platform. On the Gainsight incident the company stated: "There is no indication that this issue resulted from any vulnerability in the Salesforce platform. The activity appears to be related to the app's external connection to Salesforce." On the Experience Cloud campaign it said: "It is important to note that Salesforce remains secure, and this issue is not due to any vulnerability inherent to our platform." Both statements are true. Neither reduces your exposure by a single record, because every one of these routes runs through configuration and trust decisions that belong to the customer. The absence of a CVE means there is no patch coming, so the work is yours.
Common questions this article answers:
- Which of these campaigns actually affected orgs like mine, and when?
- Are ShinyHunters, UNC6395, Storm-3138 and Icarus the same group?
- If none of it was a Salesforce vulnerability, what exactly am I supposed to fix?
- How would I know whether my org was touched?
Quick Answer
Four campaigns between August 2025 and August 2026 used three entry routes into Salesforce customer data. Route one is vishing: Microsoft describes attackers "impersonating IT support personnel" who "guided users through the OAuth consent workflow to grant access to a malicious application disguised as a legitimate Salesforce Data Loader tool". Route two is vendor compromise: an application you already authorised gets breached and its OAuth tokens are used against your org, which is what happened with Salesloft Drift in August 2025, Gainsight in November 2025 and Klue in June 2026. Route three is guest user misconfiguration: mass scanning of public Experience Cloud sites for guest profiles that permit API access, then extracting records through the Aura endpoint without any credentials at all, disclosed in March 2026. None of the three was a platform vulnerability, and Salesforce has said so on the record for two of them. The audit that covers all three has three parts: enumerate every connected app and external client app holding live refresh tokens and revoke the ones nobody can name, uncheck "API Enabled" on the guest user profile and "Allow guest users to access public APIs" in site settings, and query your Event Monitoring logs for the access patterns below. The detection signals that last are behavioural, not the IP addresses published in June, which have long since rotated.
The verified timeline
Every row cites the source the date comes from. Where sources disagree, the disagreement is in the notes.
| When | What | Primary source | Date published |
|---|---|---|---|
| 8 to 18 August 2025 | Salesloft Drift OAuth tokens abused to query Salesforce orgs. Attributed to UNC6395 | Google Threat Intelligence Group | 27 August 2025, updated 28 August |
| November 2025 | Gainsight-published apps used to access customer orgs. 200+ instances per GTIG, ~285 per Gainsight | CyberScoop, CSO Online | 20 and 21 November 2025 |
| 12 January 2026 | Mandiant releases AuraInspector, an open-source Aura misconfiguration auditing tool | RH-ISAC | 9 March 2026 |
| 7 March 2026 | Salesforce publishes Experience Cloud guest user guidance; updated 11 March | Salesforce security blog | 7 March 2026 |
| 9 March 2026 | Aura campaign detail: modified AuraInspector, boxcar'ing, sortBy bypass |
RH-ISAC | 9 March 2026 |
| 12 to 17 June 2026 | Klue integration abused; roughly 24 hours of querying, one burst of nearly a thousand queries in 15 minutes | ReliaQuest | 17 June 2026, updated 22 June |
| 21 June 2026 | A Telegram account claiming to be ShinyHunters takes credit for Klue | ReliaQuest | 22 June 2026 update |
| 13 July 2026 | Microsoft publishes its mapping of the intrusion paths across mid-2025 to mid-2026 | Microsoft Security Blog | 13 July 2026 |
| 21 to 25 August 2026 | McKesson: vishing, then Okta SSO takeover, then Salesforce and Snowflake extraction | Help Net Security, HIPAA Journal | 31 August 2026 |
Three rows in that table repay a closer look.
AuraInspector was released in January and weaponised by March. Mandiant built it so administrators could find access control misconfigurations in the Aura framework. Attackers modified it and pointed it at everyone else's sites. Roughly eight weeks separated the defensive tool from the offensive fork of it, which is a reasonable planning assumption for any future audit tool that maps an attack surface precisely enough to be useful.
ReliaQuest was careful in a way the coverage was not. Its report stated that "attribution is currently unknown", that it could not "independently verify if this Telegram account is operated by the authentic ShinyHunters group", and that "the initial access vector is unresolved". Later analysis from Obsidian Security on 25 June 2026 pointed at a compromised legacy credential associated with the integration. If you read a confident single-sentence explanation of how Klue was breached, it is running ahead of what the first responders published.
The most recent incident did not need a vendor at all. The McKesson claim from late August 2026 describes vishing, then Okta SSO account takeover, then movement into Salesforce and Snowflake. That is route one, and it does not care how well you have governed your AppExchange packages.
Who is actually who
Six designations are in circulation for overlapping activity, which is most of why the coverage is confusing. This is the taxonomy as the primary sources use it.
| Designation | Assigned by | What it refers to |
|---|---|---|
| UNC6040 | Google GTIG | Initial access via vishing |
| UNC6240 | Google GTIG | Extortion follow-on |
| UNC6395 | Google GTIG | The Salesloft Drift token theft cluster, August 2025 |
| Storm-3138 | Microsoft | The Klue compromise, June 2026 |
| Icarus | Self-assigned | The group claiming the Klue extortion |
| ShinyHunters | Self-assigned | Claims credit across most of the above |
The useful reading is that vendor naming tracks observed clusters of activity while the criminal naming tracks brands that claim credit, and the two do not map one to one. GTIG's assessment on the Gainsight incident was hedged in exactly the way you would expect: principal analyst Austin Larsen said "We assess this is likely the same threat cluster", not that it was.
For an admin, the practical consequence of all this is small. Whether Klue was Storm-3138 or Icarus changes nothing about what you configure. Treat the actor names as a way to read the sources accurately, not as an input to your controls.
Route one: vishing through the OAuth consent screen
Microsoft's 13 July 2026 analysis describes this one in the plainest terms. Attackers "conducted vishing attacks impersonating IT support personnel" and "socially engineered employees into authorizing attacker-controlled connected apps within their Salesforce tenant", guiding users "through the OAuth consent workflow to grant access to a malicious application disguised as a legitimate Salesforce Data Loader tool".
Every step in that chain is a supported feature working as designed. The user is real, the consent screen is genuine, the OAuth flow completes correctly, and the resulting token is valid. There is no exploit anywhere in it.
What makes it durable is the refresh token. Once granted, the app keeps access until somebody revokes it, and the natural moment to notice, the login, has already passed. This is the same property that makes the vendor compromises in route two work, and it is why token inventory rather than login monitoring is the control that matters.
Your defence is to remove the option. In Setup, under Connected Apps OAuth Usage and under the app policies for external client apps, restrict which users can authorise apps at all. An org where self-authorisation is off is an org where the phone call has nothing to sell.
Route two: your vendor gets breached
Three incidents, one shape. An application you deliberately authorised, with tokens you deliberately granted, is compromised at the vendor, and the tokens are then used against your org through ordinary API calls.
The Drift campaign shows what the attacker was actually after. GTIG documented queries against Cases, Accounts, Users and Opportunities, and identified the objective as harvesting credentials: AWS access keys beginning AKIA, passwords, and Snowflake tokens. The target was not your CRM data as such. It was the secrets your staff pasted into support cases, which is a category of exposure most orgs have never inventoried.
That detail should reframe the risk for anyone who concluded their CRM holds nothing sensitive. Free-text case bodies are where credentials go to be forgotten.
The Klue activity, per Obsidian Security's 25 June 2026 analysis, ran SOQL against /services/data/v59.0/query with QueryMore pagination, preceded by Global Describe calls to enumerate the schema. ReliaQuest recorded roughly 24 hours of activity, including a burst of nearly a thousand queries in 15 minutes and an exfiltration window of over six hours.
A day is a long time. That is not a window you miss because you were unlucky; it is a window you miss because nobody was looking at API volume.
Route three: guest users and the Aura endpoint
This one needs no tokens, no vendor and no phone call.
Per RH-ISAC's 9 March 2026 write-up, attackers mass-scanned public Experience Cloud sites and probed /s/sfsites/aura, using a modified build of Mandiant's AuraInspector. Two techniques made the extraction efficient. The first is boxcar'ing, bundling "up to 250 server-side actions into a single request" against serviceComponent://ui.force.components.controllers.lists.selectableListDataProvider.SelectableListDataProviderController/ACTION$getItems and aura://RecordUiController/ACTION$executeGraphQL. The second is manipulating the sortBy parameter to retrieve records "beyond the default 2,000-record threshold by altering the sort order".
Note what is absent: authentication. Where a guest user profile permitted API access, the records came out with no credentials involved.
Salesforce's own guidance, published 7 March 2026 and updated 11 March, lists the remediation. In its words, the two that close this route are to "Uncheck 'Allow guest users to access public APIs' in your site settings and uncheck 'API Enabled' in the guest user profile's System Permissions", and to confirm in Setup then Sharing Settings "that org-wide defaults for all objects are set to Private for external users and that Secure guest user record access is enabled".
The same advisory also recommends unchecking Portal User Visibility and Site User Visibility to stop guests enumerating internal members, disabling self-registration where it is not needed, reviewing Enhanced Personal Information Masking, and enabling Profile Filtering. That last one is now a Winter '27 release update rather than an optional hardening step, covered in the Winter '27 profile filtering post.
If you want to know whether anyone has already probed your sites, guest traffic in Event Monitoring answers it, and triaging guest traffic as scanner or breach covers how to tell the two apart.
The audit that covers all three
Run it in this order, because the first part is the one with a live token behind it.
1. Inventory every app that can act in your org. Connected apps, external client apps, and anything installed from AppExchange. For each, the questions are who authorised it, when it was last used, and what scopes it holds. An app nobody can name is a finding regardless of what it is. The gap between granted and used scopes is where most of the over-provisioning lives, and comparing granted against used walks through the queries.
2. Revoke what you cannot justify. Salesforce's response to Gainsight was to revoke every access and refresh token for the affected publisher's apps. You can do the same thing per app without waiting for an incident. Remember that revocation, not deactivation of a user, is what invalidates a refresh token.
3. Close the guest route. Uncheck "API Enabled" on the guest user profile and "Allow guest users to access public APIs" in each site's settings. Confirm external org-wide defaults are Private and Secure guest user record access is on. Then check the field-level security on Contact, Case, Lead and your custom objects, which Salesforce's advisory calls out as a manual review.
4. Restrict who can authorise apps at all. This is the control that answers the vishing route, and it is the only one of the four that a well-run org can get badly wrong while doing everything else correctly.
5. Turn the audit into a scheduled job. All of the above drifts. The EventLogFile baseline post covers doing this without paying for Shield.
What to look for in the logs
The IP addresses published in the June reporting have rotated and are useless now. The behavioural signals last. Obsidian Security's analysis of the Klue activity named several that generalise well:
- A user agent that changes. The integration had historically called with
python-httpx; the anomalous traffic usedpython-urllib/3.12and3.14. Any established integration has a stable user agent, and a change in it is a change in who is holding the token. - An API version that goes backwards. The traffic dropped from
v64.0tov59.0. Legitimate integrations move forward with their vendor's release cycle. Nothing legitimate downgrades six versions overnight. - Schema reconnaissance. Global Describe calls followed by object enumeration is what a script does on its first visit. Your real integrations already know your schema.
- Volume and shape. A thousand queries in fifteen minutes, or QueryMore pagination running for hours, against an integration whose normal pattern is a steady trickle.
The unifying property is that all four compare an integration against its own history rather than against a threshold. That is the practical lesson from this year: the traffic was authorised, well-formed and correctly authenticated, so the only thing that distinguished it was that it did not look like last week.
Frequently Asked Questions
Q: Was any of this a vulnerability in Salesforce?
A: No, and Salesforce has said so explicitly for two of the incidents. On Gainsight the company stated there was "no indication that this issue resulted from any vulnerability in the Salesforce platform" and that the activity "appears to be related to the app's external connection to Salesforce". On the Experience Cloud campaign it stated that "Salesforce remains secure, and this issue is not due to any vulnerability inherent to our platform". Both are accurate. The practical consequence is the uncomfortable one: no patch is coming, because there is nothing to patch. Every control that would have stopped these campaigns is a customer-side configuration or governance decision.
Q: Are ShinyHunters, UNC6395, Storm-3138 and Icarus the same group?
A: They are not interchangeable. UNC6040, UNC6240 and UNC6395 are Google GTIG designations for observed activity clusters, covering initial access, extortion follow-on and the Salesloft Drift token theft respectively. Storm-3138 is Microsoft's designation for the Klue compromise. Icarus is a self-assigned name used by whoever claimed the Klue extortion. ShinyHunters is a self-assigned brand that has claimed credit across most of this activity. Vendors name what they observe; criminals name themselves. GTIG's own language on the Gainsight link was that it assessed the campaign as "likely the same threat cluster", which is an analytical judgement rather than a confirmed identity.
Q: We revoked our Salesloft Drift tokens in August 2025. Are we covered?
A: Only against that one vendor. Gainsight followed in November 2025 and Klue in June 2026, and neither was predictable from the Drift response. The pattern is that any vendor holding a refresh token for your org is a route into it, so the durable control is a recurring inventory of every app that holds one, not a rotation triggered by whichever vendor was in the news. That is also the reason the McKesson activity in August 2026 matters: it reached Salesforce through vishing and SSO takeover, with no vendor involved at all.
Q: How would I know if my org was touched?
A: Start with the objects the actors actually queried, because that is documented. GTIG recorded queries against Cases, Accounts, Users and Opportunities in the Drift campaign, with the goal of harvesting AWS keys, Snowflake tokens and passwords from case text. So the first search is not in your logs at all: search your own Case bodies for credential patterns, because that tells you what an intruder would have found. Then work through Event Monitoring for the behavioural signals above, comparing each integration against its own history. If you have guest-enabled Experience Cloud sites, treat any data reachable through the guest profile as potentially already exposed, which is what FINRA advised its member firms to do in March 2026.
Q: Does this change anything about how we approach agents and MCP servers?
A: It is the same problem class arriving through a newer door. An MCP server registered in Agentforce is another external party your org has authorised to act, and outbound calls carry a shared service identity rather than a per-user one, so the attribution you lose is the attribution you would want during exactly this kind of investigation. Governing third-party MCP servers covers the controls that exist for that today, and the registration inventory belongs in the same recurring audit as your connected apps.
Key Takeaways
- Three routes, not one. Vishing through the consent screen, vendor token compromise, and guest user misconfiguration. Closing one does nothing for the other two.
- Check the dates before you rely on them. The most widely repeated error merges the August 2025 Drift campaign with the June 2026 Klue one. Every date here has a primary source next to it, and the first responders on Klue were explicit that attribution and initial access were unresolved.
- "Not a platform vulnerability" is true and unhelpful. It means no patch is coming and the work is yours.
- Refresh tokens are the persistence mechanism in two of the three routes, which makes token inventory more useful than login monitoring.
- Your support cases are the prize. The documented objective in the Drift campaign was credentials pasted into case text, not the CRM records themselves.
- Detection is comparison against history, not thresholds. A user agent change and an API version downgrade were the tells, and both are free to check.
What's Next?
Recommended reading:
- Which of Your Salesforce Connected Apps Use Less Than They're Granted?
- A Guest IP Got Flagged for Log4j: Scanner or Breach?
- Free Salesforce Event Monitoring: Build a Security Baseline Without Shield
- Governing Third-Party MCP Servers in Agentforce
- Migrating Connected Apps to External Client Apps
Action items:
- List every connected app and external client app in your org with a live refresh token, and mark each one with the person who owns the relationship. Revoke anything nobody claims.
- On every guest-enabled Experience Cloud site, uncheck "Allow guest users to access public APIs" and uncheck "API Enabled" on the guest user profile, then confirm external org-wide defaults are Private.
- Search your Case bodies for credential patterns, starting with
AKIA, and treat anything you find as already exposed. - Restrict who in your org can authorise a connected app, which is the only control that answers the vishing route.
- Record the current user agent and API version for each production integration, so that a change in either is something you can notice next time.
Resources & References
- Google Threat Intelligence Group: Data theft from Salesforce instances via Salesloft Drift
- Microsoft Security Blog: Defending SaaS-based applications against ShinyHunters OAuth abuse
- Salesforce: Protecting Your Data, Essential Actions to Secure Experience Cloud Guest User Access
- ReliaQuest Threat Spotlight: Integration abused in CRM data theft
- Obsidian Security: Technical analysis of the Klue attack
- RH-ISAC: ShinyHunters utilize public audit tool to scan for vulnerable Salesforce Aura instances
- FINRA Cybersecurity Alert: Salesforce Experience Cloud security incident
- CyberScoop: Hundreds of Salesforce customers hit by yet another third-party vendor breach
- Salesforce Help: Securely share your Experience Cloud sites with guest users
Responses
Checking your session.
Loading responses.