Skip to content

Where It Went Wrong, 2024–2026

Module 4 of 5 in the chapter External Client Apps, Tokens and Their Lifecycle, chapter 13 of Securing Salesforce: Identity and Access. Each module stands on its own.

The question this module answers: How did the 2024 to 2026 attacks on Salesforce customers get in, and which controls close each door?

Between 2024 and 2026, many companies lost Salesforce data to attackers. If you followed the news, you might think Salesforce was broken into. It wasn’t, and the people who investigated say so in plain words.

Google’s threat intelligence team, which investigated one campaign: “In all observed cases, attackers relied on manipulating end users, not exploiting any vulnerability inherent to Salesforce” (S14). Salesforce, on its Trust site: “there is no indication that the Salesforce platform has been compromised, nor is this activity related to any known vulnerability in our technology” (S13). And Salesforce’s framing, earlier the same year: “Cybersecurity is a shared responsibility between a provider and their customers” (S12).

So the attackers didn’t come through the wall. They came through the doors this course is about: people, apps and tokens. That’s why it belongs in an identity course. Integration Architect’s chapter 13 tells the same story from the integration side; here it’s the identity side.

The doors, and what closes them Three identity doors, how each worked, and what closes it. A person approving an app: a caller posing as IT support had people enter a code at /setup/connect, or approve a renamed app; closed by pre-authorized apps only, the device flow for local apps only, uninstalled apps restricted, and API Access Control. A partner's stored tokens: a trusted integration's valid tokens were used elsewhere, and data was exported and searched for secrets; closed by tokens that can't travel far: few scopes, an IP allowlist, rotation, DPoP and a revoke runbook. An identity provider account phished at the identity provider: the attacker signs in once and reaches every app behind it; closed by strong MFA at the identity provider, and high assurance for sensitive apps. Footnote: no platform vulnerability in any of them, in Salesforce's and the investigators' own words; the doors were people and tokens. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.58.0", "built": "2026-11-05", "id": "DGM-IAM-AT-04", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.5.0", "theme": "stevetecharc 1.4.0"} THE DOOR HOW IT WORKED WHAT CLOSES IT A person approving an app a caller posing as IT support A code, or a renamed app entered at /setup/connect, or approved Pre-authorized apps only the device flow for local apps; uninstalled apps restricted; API Access Control A partner's stored tokens a trusted integration Valid tokens, used elsewhere data exported, searched for secrets Tokens that can't travel far few scopes; IP allowlist; rotation; DPoP; a revoke runbook An identity provider account phished at the identity provider Every app behind it the attacker signs in once Strong MFA at the identity provider and high assurance for sensitive apps through closed by through closed by through closed by No platform vulnerability in any of them, in Salesforce's and the investigators' own words. The doors were people and tokens. HOW TO READ IT an identity door the controls from this course © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Here’s how it worked. Someone called an employee, pretending to be from IT support. In Salesforce’s words, they were “prompting users to navigate to the login.salesforce[.]com/setup/connect page in order to add a malicious connected app”, and “the malicious connected app is a modified version of the Data Loader app published under a different name and/or branding” (S12). Google, which tracks the group as UNC6040, describes the same thing: the victim is guided “to approve a version of the Data Loader app with a name or branding that differs from the legitimate version”, or to “enter a ‘connection code’” (S14).

Now look at that page: /setup/connect. Have you seen it before? It’s the device flow’s verification page from chapter 9 (chapter 9’s S7). The caller had a code on their own device, and talked the employee into typing it in. The employee was being Priya at the TV, approving a device that wasn’t hers.

So what closes this door?

  • The device flow, restricted. From November 30, 2026, it works only for local external client apps with a localhost callback (chapter 9). A code for someone else’s app no longer works.
  • Uninstalled apps, restricted. Since September 2025, only users with Approve Uninstalled Connected Apps, or Use Any API Client, can use an app that isn’t installed in your org (the shared security record).
  • Pre-authorized apps only, with permitted users through a permission set (module 2), and API Access Control for the whole org (module 2).
  • Know who holds Use Any API Client. It walks past both (S16).
  • And people. IT support will never ask you to type a code into Salesforce over the phone. Say so, often.

The second door wasn’t a person at all. A trusted integration held valid OAuth tokens for many companies’ Salesforce orgs. Google, which tracks the group as UNC6395, found that from August 8, 2025, to at least August 18, the attacker used “compromised OAuth tokens associated with the Salesloft Drift third-party application” and “systematically exported large volumes of data from numerous corporate Salesforce instances” (S15). On August 20, Salesloft and Salesforce revoked the tokens (S15).

Two details to notice. The attacker then searched the data for secrets people had pasted into records, cloud access keys and passwords (S15). And they deleted their query jobs, but “logs were not impacted” (S15): the trail was still there for anyone who looked.

What closes this door? Everything in module 3, plus module 2’s scopes:

  • Few scopes, so a stolen token reaches little.
  • An IP allowlist, so a token used from somewhere else gets nothing.
  • Rotation and the idle limit, so old tokens die.
  • DPoP, so a stolen token is useless without the app’s private key.
  • A revoke runbook, ready before the partner calls: which app, who pulls the plug.
  • No secrets in records. Ever. A field is not a vault.

In January 2026, Salesforce widened its advisory: attackers were going after identity provider accounts too, with fake login pages and phone calls. “If an IdP account is compromised, attackers may attempt to access connected applications” (S13). That’s single sign-on’s strength, turned around: one sign-in reaches everything behind it (chapter 4).

What closes it is mostly at the identity provider: strong, phishing-resistant MFA there. Salesforce added its own requirement in Summer ‘26: phishing-resistant MFA for privileged accounts (the shared security record). And on the Salesforce side, high assurance for the apps that reach the most sensitive data (module 2).

There was a fourth door in these years, public Experience Cloud sites with guest users who could see too much. That one isn’t about apps; chapter 14 covers it.

Salesforce’s other answer has been to close the doors that hand around a password, a live session, or a token in the open. Here’s the list, with dates.

What's been retired, and why What's been retired or restricted, what each handed around, and what to use instead. The username-password flow, for connected apps, retiring 2027-02-20, handed her password to the app; instead, the web server flow with PKCE, or client credentials, chapters 8 and 9. The user-agent flows, retiring 2027-02-20, put the access token in the browser after the # in the address; instead, the web server flow with PKCE, chapter 9. SOAP API login(), retiring in Summer '27, traded a username and password for a session; instead, an external client app and OAuth, chapter 8. Session IDs in outbound messages, removed from 2026-02-23, sent a live session out in every message; instead, OAuth for the callback, with the listener getting its own token. The device flow on other apps, local apps only from 2026-11-30, offered a code anyone can be talked into at /setup/connect; instead, a local app with a localhost callback, chapter 9. Footnote: dates checked 2026-11-07; each one still works somewhere until its date, so find yours first. {"author": "Steve Simpson", "blueprint": "1.0.1", "builder": "standard 1.59.0", "built": "2026-11-07", "id": "DGM-IAM-AT-05", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.5.0", "theme": "stevetecharc 1.4.0"} RETIRED OR RESTRICTED WHAT IT HANDED AROUND INSTEAD Username-password flow connected apps; 2027-02-20 Her password given to the app Web server flow with PKCE or client credentials · ch 8, 9 User-agent flows 2027-02-20 The access token in the browser after the # in the address Web server flow with PKCE · ch 9 SOAP API login() Summer '27 A password for a session username and password in the call An external client app and OAuth · ch 8 Session IDs in outbound messages from 2026-02-23 A live session, sent out in every message OAuth for the callback the listener gets its own token Device flow on other apps local apps only from 2026-11-30 A code anyone can be talked into at /setup/connect A local app with a localhost callback · ch 9 handed around instead handed around instead handed around instead handed around instead handed around instead Dates checked 2026-11-07. Each one still works somewhere until its date: find yours first. HOW TO READ IT retired or restricted, with the date what to use instead © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge
  • The username-password flow, for connected apps, retires February 20, 2027 (chapter 5). It handed her password to the app.
  • The user-agent and hybrid user-agent flows retire February 20, 2027 (chapter 9). The token sat in the browser.
  • SOAP API login() is retired in API versions 31.0 to 64.0 “effective with the Summer ‘27 release”, “already unavailable in 65.0+” (S17). A username and password for a session. Salesforce: “we recommend migrating to external client apps and OAuth” (S17).
  • Session IDs in outbound messages: “you can no longer send session IDs in outbound messages starting February 23, 2026. Instead, use OAuth to authenticate” (S18).
  • The device flow is restricted to local apps with a localhost callback from November 30, 2026 (chapter 9). Door 1’s connection code.

Each still works somewhere until its date. Find yours first: the Insights page (module 1), Login History, and the app list.

Beyond the exam: what AI changes. Agents and MCP servers are apps with tokens too, and every door here is open to them. Chapter 17 takes it further.

Module 5: Checkpoint 2. Steve Trucking’s apps and tokens, and the end of Part 2.

  • Which doors your org still has open, door by door.
  • Who holds Use Any API Client and Approve Uninstalled Connected Apps.
  • The revoke runbook for every partner integration.
  • A plan and a date for every retired mechanism you find.
  • What people are told: no codes over the phone, no secrets in records.