Three numbers from the last two weeks of June: 61 million records claimed from Sysco, 26 million from Madison Square Garden Sports, 2.2 million from Kodak. None of the intrusions behind those claims required guessing a password, phishing a one-time code, or beating multi-factor authentication. In each case the attacker held a valid OAuth token for a third-party application that Salesforce had already been told to trust, and used it to pull the customer database through the API exactly the way the integration was meant to.
The crew running most of this, operating under the ShinyHunters name and an adjacent extortion brand called Icarus, spent 2026 turning that method into an assembly line. Huntress, which tracks the group, documents the same pattern across victim after victim: get a token to a connected app, read the CRM, extort. The count of named organizations now runs from Nexstar and Ralph Lauren to JCPenney and the Council of Europe.
Who this is actually for
Read on if you run a SaaS platform of record with third-party apps connected to it over OAuth. The examples here are Salesforce, but the mechanism is identical on Google Workspace, Microsoft 365, Slack, GitHub, and HubSpot: any app you have granted delegated access. If your SaaS tenants have zero third-party integrations - no marketing app reading the CRM, no analytics connector, no AI assistant with a mailbox scope - this campaign is not aimed at you, and you can close the tab.
Everyone else has an inventory problem they have probably never counted. And to be precise about the nature of it: Salesforce did not ship a vulnerability. When the company disabled one of the compromised apps, it said plainly that the issue lived in a third-party app's connection rather than the platform. That is what makes the campaign awkward. You cannot patch it. You can only govern the trust you have already handed out.
The myth: your login controls guard the data
Most small teams believe their SaaS data is protected by the things that protect their logins: MFA, single sign-on, conditional access, a strong password policy. Those controls govern interactive human sign-ins. An OAuth connected app never signs in as a human. When you authorize an app, the platform issues it an access token and a long-lived refresh token scoped to whatever you approved, and very often that approval was the broad api or full scope. From then on the app calls the REST API carrying that token. No password, no MFA challenge, no interactive session, so the integration keeps working at three in the morning with nobody present. Steal or mint that token and you silently inherit every one of those privileges.
This is not theoretical. Google's Threat Intelligence Group traced the pattern back through the Salesloft Drift compromise of August 2025, when the actor GTIG tracks as UNC6395 used stolen Drift OAuth tokens to export data from more than 700 Salesforce customer instances. The part defenders keep missing is what happened next: the actor grepped the exports for AWS access keys beginning with AKIA, Snowflake credentials, and anything matching password, secret, or key. The CRM was the entry, not the prize.
There is a second detail in that report worth internalizing before an incident forces you to learn it: resetting the affected user's password does nothing to an active OAuth refresh token. The token is a separate credential with its own lifetime. If your response to "an integration was abused" is to rotate the human account's password and move on, the attacker's token keeps working until it expires or you explicitly revoke the app. The revocation, not the password reset, is the containment step.
How the token theft actually works
The 2026 wave industrialized the vendor-compromise version of this. Rather than stealing your token from you, the attacker compromises a vendor that already holds thousands of customers' tokens, then works down the list. The Klue incident is the clean example. ReliaQuest, which investigated it, reconstructed the sequence: the attacker got hold of a legacy credential for Klue's integration service - one the vendor had created to prototype a feature and never deactivated - generated OAuth tokens from it, and ran automated Python scripts against the Salesforce REST API. In at least one environment the scripts fired close to a thousand queries in fifteen minutes, pulling the CRM in a single roughly 24-hour burst.
Salesforce disabled the Klue app on June 11. By the time the dust settled, at least fourteen companies had publicly confirmed impact, including HackerOne, Huntress, OneTrust, LastPass, BeyondTrust, and Snyk - security vendors among them. One vendor breach, more than a dozen downstream CRM databases, none of the victims individually compromised.
Inside each environment the requests were mechanical. GTIG's reconstruction of the Drift campaign shows the actor first enumerating the object catalog, then running wide bulk queries against the query endpoint - a single SELECT against the User object pulling more than twenty fields per row, ordered by last-login date. To Salesforce it was a well-formed API session from an authorized app. To anyone reading the event logs afterward it was a burst of automated reads no salesperson would ever generate.
The reach does not stop at the CRM records. Support cases, onboarding notes, renewal fields, and integration descriptions routinely carry secrets in free text, because someone pasted an API key into a ticket to get help. That is why the Drift actor's whole objective was harvesting credentials to pivot into AWS and Snowflake. A breach that reads as "marketing data" on Monday can become a cloud-infrastructure incident by the following month, in a system with no obvious connection to the CRM at all.
Inventory the blast radius
Every remediation here starts with a list most teams do not have: which apps hold a live token, what they can reach, and when they last used it. In Salesforce that list is queryable. Run it with the CLI against production and read it top to bottom.
# Every connected app holding a live OAuth token: who authorized it, how
# often it is used, and when it last ran. A stale LastUsedDate on a broad
# scope is your first revocation candidate - and often the entry point.
sf data query --target-org prod --result-format csv \
--query "SELECT AppName, User.Username, LastUsedDate, UseCount \
FROM OAuthToken ORDER BY LastUsedDate ASC NULLS FIRST"
# Cross-check against the connected-app definitions themselves so you can
# see which ones any user can self-authorize versus admin-approved only.
sf data query --target-org prod \
--query "SELECT Name, OptionsAllowAdminApprovedUsersOnly, StartUrl \
FROM ConnectedApplication ORDER BY Name"
The Klue entry point was a credential the vendor forgot to turn off. Your equivalent is the row in that first query for an app nobody on the team can name. Kill its refresh token before you do anything else.
Detect the exfiltration pattern
Token abuse looks like the integration itself until you check three things: request volume, user-agent, and source IP. GTIG and ReliaQuest published the same tell - automated clients such as python-urllib, python-requests, and a custom Salesforce-Multi-Org-Fetcher string driving bulk queries from unfamiliar or Tor-exit addresses. If you license Salesforce Shield with Event Monitoring, hunt the API logs.
-- Salesforce Event Monitoring: pull the API/REST/Bulk event logs, then in
-- the parsed rows flag automation user-agents and single-client query
-- bursts no legitimate integration should ever produce.
SELECT EventType, LogDate, LogFileLength
FROM EventLogFile
WHERE EventType IN ('API','RestApi','BulkApi')
AND LogDate = LAST_N_DAYS:14
-- In the downloaded CSV: filter USER_AGENT for python-urllib / python-requests /
-- Salesforce-Multi-Org-Fetcher, and ROWS_PROCESSED spikes from one CLIENT_IP.
-- Cross-reference the ReliaQuest IoC IPs: 138.226.246.94, 212.86.125.24,
-- 213.111.148.90, 94.154.32.160.
No Shield license? Then you push the control up the stack instead of watching for the abuse. Set the connected app's IP Relaxation to "Enforce IP restrictions" and define Login IP Ranges on your integration users, so a token replayed from a random hosting provider is refused before it reads a single record.
Right-size the connected-app surface
- Revoke on sight: any OAuth token whose app you cannot assign an owner to gets its refresh token killed today. Dormant integrations are the Klue-style entry point.
- Retire the catch-all scopes. Grant the narrowest OAuth scope an app truly needs. A competitive-intelligence add-on does not need write access to every object in the org.
- Enforce IP restrictions on connected apps and login ranges on integration users, so a token only works from the vendor's known egress addresses.
- Cap refresh-token and session lifetimes so a stolen token expires in hours rather than months of quiet reuse.
- Remove the "API Enabled" permission from broad profiles and grant it only through a permission set to the accounts that genuinely need programmatic access, shrinking the set of users an app can act as.
- Fold third-party OAuth apps into your vendor-risk process: ask where the vendor stores your tokens, and whether prototype or test credentials get decommissioned.
- Scan CRM free-text and support-case fields for pasted secrets, and rotate whatever you find. The attacker is looking for exactly those.
Revoke the tokens no one remembers granting
The Salesforce records are the loss you can see. The AWS key or Snowflake token buried in a support case is the loss that surfaces a month later, in a system that has nothing to do with your CRM. Pull the OAuth inventory this week, revoke everything without a named owner, and put IP enforcement on the integrations that remain. That sequence would have blunted every intrusion in this wave, because all of them rode a trust relationship the victim had stopped tracking.
If your team has never counted the third-party apps wired into your platforms of record - Salesforce, Microsoft 365, Google Workspace, GitHub - that count is where we start a SaaS attack-surface review. It is usually a short afternoon, and it usually turns up at least one live token nobody remembers granting.
Do you know every app that can read your CRM?
We map the connected-app and OAuth attack surface across your SaaS platforms of record - Salesforce, Microsoft 365, Google Workspace, GitHub - and flag the over-scoped and orphaned integrations attackers go after. Book a session to review your third-party access.
