More than seven hundred organisations were potentially exposed in August 2025 and not one of them had a password stolen. Nobody bypassed a second factor, nobody exploited a CVE in their infrastructure. The attacker took the OAuth tokens of a commercial chatbot those companies had connected to their CRM long before, and used them to ask the API for the data, politely, exactly the way that application did every morning. On 13 July 2026 Microsoft published the full map of a year-long run of this technique. It is worth reading even if you do not have Salesforce, because the part that fails is not a Salesforce part: it is consent, and you have that too.
We run Microsoft 365 tenants and we have spent years pushing clients towards the same things: mandatory MFA, Conditional Access, and lately SMS out, passkeys in. That work needed doing and we would do it again. But here comes the uncomfortable part, and we would rather say it ourselves: none of it touches this class of attack. Not because it is badly built, but because the attack does not go through the sign-in.
One year, two attack chains, no passwords
Microsoft's report covers mid-2025 to mid-2026 and describes two attack chains against customer SaaS instances: consent abuse driven by phone calls, and the compromise of integrated vendors. Neither is a software bug; both abuse a mechanism working exactly as designed. You will read elsewhere that there were "three paths", counting misconfigured guest-user permissions: that framing comes from the press coverage. In Microsoft's own text, guest access sits in the hardening recommendations, not among the intrusion chains.
Look at what they have in common. There is no password stolen from the end customer. There is no strange sign-in from a strange country. In both cases, the attacker gets in using an authorisation the victim granted themselves, months or years earlier, probably on a Tuesday afternoon and probably without thinking twice.
MFA answers a different question
An OAuth token is not a password. It is a permission already signed. When a user clicks "Accept" on that consent screen almost nobody reads, the platform issues the application a pass to act on their behalf, plus a refresh token so it can renew that pass by itself without bothering anyone again. From then on the application calls the API as often as it likes. There is no login screen. There is no MFA challenge. There is no interactive sign-in that could look suspicious, because there is no sign-in.
Put as briefly as we can manage: MFA protects the moment somebody proves who they are. Consent decides what a third party may do in your name from then on. Two different questions, and the industry has spent five years answering the first one en masse. Almost nobody has ever reviewed the second.
Now translate it to your tenant
In Microsoft 365 these are called enterprise applications, and underneath, service principals. Every tool anybody ever connected — the PDF signer, the CRM, the time-tracking app, the accountant's connector, the meeting assistant that summarises your minutes — has its record there with its permissions. There are two families, and the difference matters far more than it looks:
- Delegated permissions: the application acts on behalf of a user and inherits what that user can do. The small print, which changed recently and is worth keeping current: by default any user can grant permissions that do not require administrator approval, but new tenants start on the Microsoft-managed policy ("let Microsoft manage your consent settings"), which already excludes the juicy ones:
Mail.Read,Mail.ReadWrite,Files.Read.All,Sites.Read.All, the calendar and chat permissions, and EWS, IMAP and POP in Exchange Online. In plain terms: in a recently created tenant a user can no longer give away their mailbox; in a 2019 tenant nobody has touched, it depends which setting it is on. Check before assuming anything. - Application permissions: the application acts on its own, with no user behind it. There is nobody to ask for MFA. And with no user, the Conditional Access policies you wrote for your people do not apply to it. Conditional Access for workload identities does exist, but it needs specific licences and — this is the part almost nobody knows — the documentation itself warns that it does not cover third-party SaaS or multitenant applications. Precisely the ones in this story.
And now the detail we find most interesting in the whole documentation set, because it cuts the other way. Alongside that managed policy, another one ships enabled by default — the mail client policy — which hands exactly those mail permissions back to the user for six specific applications: Apple Mail, Thunderbird, Spark, eM Client and the Android and Samsung mail clients. The door Microsoft closed in the main policy is left ajar for half a dozen popular clients, none of which is yours or administered by you. We are not saying it is wrong — it is a reasonable usability call and they are well-known apps — we are saying you probably did not know, that it is in the official documentation, and that it is exactly the sort of thing to check before claiming nobody in your tenant can grant access to their mailbox.
And it does not end there: delegated and application permissions are not the only route in. Microsoft's own documentation points out that directory roles, Exchange RBAC for applications and Teams resource-specific consent also grant access. Which means there is more than one list to look at, and they are not on the same screen.
The inventory almost nobody has
The click-based version lives in the Entra admin centre, under Enterprise apps → All applications → the application itself → Permissions, with two tabs: admin consent and user consent. An important warning that appears in the documentation and surprises everybody the first time: consents on the user tab cannot be revoked from the portal. For those you need Graph or PowerShell. And since that screen is one sheet per application, it navigates terribly once there are two hundred, we always start with the full list:
Connect-MgGraph -Scopes "Directory.Read.All","Application.Read.All"
# Precargamos las entidades de servicio en memoria: si no, se hace
# una llamada a Graph por cada concesion y acabas con throttling
$sp = @{}
Get-MgServicePrincipal -All | ForEach-Object { $sp[$_.Id] = $_.DisplayName }
# Consentimientos delegados del tenant: quien los dio, a quien y para que
Get-MgOauth2PermissionGrant -All | ForEach-Object {
[pscustomobject]@{
App = $sp[$_.ClientId]
Alcance = $(if ($_.ConsentType -eq 'AllPrincipals') { 'TODO EL TENANT' } else { 'un usuario' })
Permisos = $_.Scope
}
} | Sort-Object App | Export-Csv .\consentimientos.csv -NoTypeInformation -Encoding UTF8
That query answers three things at once: which applications hold permissions, whether the grant was made by an admin for the whole organisation or by a single user for themselves, and which specific scopes it covers. The first time you run it in the tenant of a fifty-person company the list is usually longer than anybody expected, with a couple of names that not even the person who authorised them recognises any more. And that is where the conversation worth having starts.
Application permissions, the ones that act with no user, need a second query, and this one takes a while because it walks every service principal in the directory:
# Permisos de aplicacion: los que no necesitan a nadie delante.
# Ojo: saldran tambien muchas apps de primera parte de Microsoft;
# el trabajo esta en las que NO reconozcas.
Get-MgServicePrincipal -All | ForEach-Object {
$roles = Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $_.Id
if ($roles) {
# Editor = tenant que publica la app, NO es el publicador verificado
[pscustomobject]@{ App = $_.DisplayName; Editor = $_.PublisherName; Asignaciones = $roles.Count }
}
} | Sort-Object Asignaciones -Descending
What to look at, line by line
Having the list is not the same as being done. These are the criteria we run it through, and several come straight out of Microsoft's investigation guidance. One warning first, because it is only fair to say it: the pretty filters — community use, last authorised, how many users authorised it — live in Defender for Cloud Apps and app governance, which are not in every plan. If your licence does not include them the criteria still hold; what changes is that you pull the information from Graph and the audit log instead of a screen that hands it to you.
- Permissions that do not match what the app does. The example the documentation itself uses is a clock app with full access to every mailbox. It sounds like a joke until you find one.
- Applications authorised by very few users. Counter-intuitive but useful: the more common and widely used an application is, the more likely it is to be legitimate. One a single person authorised deserves a look.
- An old "last authorised" date. It usually flags applications nobody uses any more and nobody will miss. They are the best place to start cleaning, because the risk of breaking something is low.
- A suspicious name, publisher or website — those are the guide's own terms. Not proof of anything on its own, but combined with high permissions it changes the order of the queue. Requiring a verified publisher is a different thing and lives in the consent settings, not on this screen.
- Who granted consent, and when. It is in the audit log. If the name on it no longer works there, you have two problems, not one.
The button that does not do what you think
Here is, for us, the most important thing in the whole article, and it is a sentence from Microsoft's documentation that deserves framing: changes to user consent settings only affect future consent operations; existing grants remain unchanged and users keep their access with the permissions granted earlier.
In plain terms: if tomorrow you switch off user consent and go to lunch feeling good, you have shut the door everyone who was going to come in already came through. What was granted stays granted. It is future hygiene, not a clean-up. The clean-up is the other, boring one: going through the list application by application and removing what does not belong.
And when you do revoke, two more caveats that are also in the documentation and worth being clear about before telling a client "it is sorted". First: revoking the permission does not stop the user re-consenting next time the application asks; if you want it gone, you have to block consent or take the application out of the picture. Second, token physics: an access token already issued lives out whatever life it has left — Microsoft documents a random value between 60 and 90 minutes, and two hours for clients such as Teams and Microsoft 365 in tenants without Conditional Access — so the cut is not instant. The real cut comes when the application tries to renew and cannot.
Closing the door without closing the business
The textbook recipe is "turn off user consent" and move on. We do apply it, but not at nine on a Monday with no warning, and here we will take a position against what you read around. Two reasons. The first is operational: you break integrations people use daily that appear in no inventory of yours, because nobody asked your permission to set them up. The second runs deeper, and it is the one that actually worries us: if you block the path and offer none, the alternative the user finds is always worse. They copy the file to their personal account, forward the mail to their Gmail, install the tool on their home laptop. You won the consent screen and lost the data.
So this is the order we follow, and the hard setting comes last and with company. First the inventory, which is also the only part that breaks nothing. Second, cleaning out what is no longer used, starting with anything that has not been authorised in a year. Third, harden above what already ships with the tenant: move from the Microsoft-managed policy to the verified-publisher-plus-low-impact one, which are not the same thing even though both sound alike in the dropdown. And fourth, the admin consent workflow, so that when somebody needs a new tool they have a button to press and a person who answers within a sane timeframe. Without that fourth step, the first three last six weeks.
There is one more detail of the campaign we do not want to slip past, because it is the one closest to what could happen to a small company tomorrow. One of the two chains starts with a phone call. Somebody impersonates IT support and gets an employee to authorise an application with a believable name. Same old script, different objective: they no longer want the password, they want the "Accept". No setting saves you from that if people do not know what they are signing; which is why we have more respect for user training than for half the products sold to solve this. The same thing we wrote about hotel wifi and Microsoft 365 credentials: the link under attack is the person, not the protocol.
What we are not going to tell you
We are not going to tell you to disconnect your integrations. It would be a comfortable headline and a stupid one: the value of having the CRM talking to email is real and we have built it many times ourselves. Nor are we going to tell you Microsoft is doing it wrong. The consent mechanism is sound and infinitely better than the alternative, which was handing out passwords. What fails is not the mechanism, it is that nobody treats it as what it is: a list of third parties with a key to your house, which should be reviewed the way you review who has VPN access or who is still a domain admin.
One last thing, and it is the one we find hardest to write: we do not have a number for how many mail-reading applications sit in the average Spanish SME tenant. We have not measured it and we are not going to invent it. What we can tell you is the look on the other side of the table the first time we open that screen with a client watching and an application shows up that was authorised by somebody who no longer works there. We have never had to explain why the review was worth doing; it explains itself.
We run Microsoft 365 environments with the connected-application inventory inside the regular review, not as an emergency when this month's vendor makes the headlines; and we do it with the same criteria we bring to a Zero Trust model, which at bottom says the same thing: no permanent access by default, not even for an application that was once useful to you. We do not resell anybody's licences and we get no commission for integrating one tool over another, so when we say "this app can go", it can go.
We close with the question that actually matters, and it is not whether you have MFA. It is this: if tomorrow the vendor of one of the applications connected to your tenant made the headlines, how long would it take you to say what permissions you granted, who granted them and what data it could reach? If the answer involves "we would have to look into it", the work this article is about has not been done. It takes a morning, and it is far better done on an ordinary Tuesday than on headline day.
And if your August to-do list was already full, a heads-up: 31 August is the real EWS deadline in Exchange Online, which is also about applications with access to your mail. Both jobs go well in one sitting, because the starting list is practically the same.
Sources (verified): the two attack chains, the dates and the Salesloft Drift (August 2025), Gainsight (November 2025) and Klue (June 2026) incidents come from "Defending SaaS-based applications against ShinyHunters OAuth abuse", published by Microsoft Security on 13 July 2026, and from The Hacker News' coverage, the source of the figures of more than 700 potentially exposed organisations and more than 200 affected instances. The August 2025 campaign and its 8–18 August window are documented by Google Threat Intelligence. Everything about Microsoft 365 comes from the official documentation: the default user consent behaviour, the consent policies and the warning that changes only affect future consent operations, from "Configure how users consent to applications"; the Microsoft-managed policy as the default for a new tenant, the exact list of permissions it excludes, and the mail client policy enabled by default with its six applications (Apple Mail, Thunderbird, Spark, eM Client, Android and Samsung), from "Manage app consent policies"; reviewing and revoking permissions, the fact that user-tab consents cannot be revoked from the portal, the note that revoking does not prevent re-consent, and the mention of directory roles, Exchange RBAC and Teams resource-specific consent, from "Review permissions granted to enterprise applications"; the criteria for investigating suspicious apps, from "Investigate and remediate risky OAuth apps"; the licensing requirement and the exclusion of third-party SaaS and multitenant applications, from "Conditional Access for workload identities"; and the access token lifetime (a random value between 60 and 90 minutes, and two hours for clients such as Teams and Microsoft 365 in tenants without Conditional Access), from "Access tokens in the Microsoft identity platform". Ours, not our sources': that MFA and consent answer different questions, the four-step order, the objection to switching off user consent without offering an alternative, and everything in what we are not going to tell you.
Who holds permanent permission over your Microsoft 365?
We pull the connected-application inventory with you, separate what is used from what is not, and put in writing who approves the next one. In a morning, without breaking what works.
Talk to everyWAN