Tu pensais que le phishing passait par des formulaires moisis et des fautes d’orthographe ? Réveille-toi. Le device code phishing est l’arnaque qui te fait cliquer sur « Autoriser » pendant que l’attaquant récolte un jeton valable. Pas de mot de passe. Pas de craquage. Juste toi, qui crois bien faire.
Pendant ce temps, les attaquants piochent aussi dans un vivier plus discret mais tout aussi meurtrier : les tokens d’API/OAuth — ces clĂ©s qu’on laisse vivre Ă©ternellement dans des scripts, pipelines ou comptes abandonnĂ©s. Si tu veux comprendre pourquoi ça sent pas bon, lis ce dossier sur les tokens et les fuites SaaS. secuslice – blog cybersĂ©curitĂ©
🎠Le scénario en clair — élégant, propre, efficace
- L’attaquant t’envoie un message ou t’ouvre une page qui te demande un code à quatre/six chiffres.
- Tu copies-colles le code depuis le mail/Teams/Slack vers une page qui ressemble Ă celle de ton IdP.
- Le flux OAuth échange ce code contre un token. L’attaquant l’obtient, et toi tu repars boire ton café.
Résultat : accès légitime à tes mails, fichiers, API. L’authentification est respectée dans les logs. Tu n’as rien à te reprocher. C’est tragique. Et magnifique pour l’attaquant.
🏢 Pourquoi ça marche si bien en entreprise
- Parce que l’utilisateur est programmé à obéir aux workflows.
- Parce que beaucoup d’organisations n’ont pas inventorier ni verrouillé les flows OAuth (device flow inclus).
- Parce que les tokens / refresh tokens ne déclenchent pas de MFA ni d’alarme standard.
- Parce que l’automatisation (CI/CD) et les devs fatigués distribuent des tokens comme des Post-it.
Si ton instance SaaS ressemble à un grand open-bar, félicitations : tu es attractif pour les voleurs de jetons.
🆚 Azure vs Google : nuances, pas miracles
Microsoft et Google ont des comportements différents sur l’expérience consentement et la visibilité des logs. Azure, flexible, peut aussi être permissif si tu laisses les paramètres par défaut; Google impose un peu plus de friction sur les scopes et les apps tierces. Cela dit, aucune des deux plateformes n’est immunisée : la défense repose sur configurationet gouvernance, pas seulement sur le fournisseur.
🛡️ La checklist SecuSlice (actionnable tout de suite)
- Désactiver le device code flow si personne ne s’en sert réellement.
- Whitelist des applications OAuth approuvées : pas d’inscription libre d’apps.
- Consent policies : exiger l’approbation admin pour les scopes sensibles.
- TTL courts pour les tokens et rotation automatique (scripts/cron/CI).
- Inventaire centralisé des tokens/clients et attribution claire d’un propriétaire.
- SIEM : ingérer les logs API/OAuth et alerter sur consentements suivis d’accès API.
- Secrets management : Vault, Secrets Manager — pas de tokens en clair dans les repos.
- Sensibilisation : phrase simple et répétée : « on ne colle pas de code sur un site non officiel. »
🔍 Détection : quoi surveiller dans le SIEM
- Consentement OAuth pour unÂ
client_id inconnu suivi immédiatement d’un accès Graph/IMAP/API. RefreshToken actif pour un compte inactif ou un ex-collaborateur.- Connexions API depuis des IPs anonymisantes ou pays non habituels.
- Apparition d’un nouveauÂ
client_id qui demande des scopes larges.
Alerter vite, révoquer les tokens, bloquer l’app, et lancer l’investigation.
🩺 Playbook d’urgence (3 gestes qui sauvent la baraque)
- Révoquer immédiatement les refresh tokens et sessions du compte compromis.
- Désactiver l’application OAuth suspecte (admin console).
- Auditer logs d’accès, API utilisés, et rechercher propagation via CI/CD.
Puis huiler la roue de la gouvernance pour que ça n’arrive plus (ou moins souvent).
👥 Message court à diffuser (prêt à copier/coller)
Objet : Alerte — nouvelle forme de phishing (code à coller)
Corps : Ne collez JAMAIS de code reçu par message sur une page non officielle. En cas de doute, contactez [email protected]. Si vous avez collé un code, signalez-le immédiatement.
Simple, clair, pas culpabilisant. C’est ce qu’il faut.
🎯 Conclusion : OAuth n’est pas une baguette magique
OAuth et les tokens sont indispensables. Ils sont aussi dangereux quand on les laisse vivre sans garde-fou. Le device code phishing expose la faiblesse humaine; les tokens exposés révèlent la faiblesse organisationnelle. Les deux ensemble, c’est la recette pour une compromission silencieuse.
🎯 Le bonus
Deux règles prêtes à coller, KQL (Microsoft Sentinel) et ELK (Elastic DSL), pour détecter un cas typique de device code phishing : un consentement OAuth inhabituel suivi d’activité API.
Objectif : spotter
- un nouvelÂ
client_id OAuth (non approuvé), - accord de consentement,
- puis accès Graph / IMAP / Gmail API similaire,
- dans les minutes/heures qui suivent.
Ces règles sont un socle. Tu pourras les durcir ensuite selon ton contexte.
🟦 KQL — Microsoft Sentinel
Détection d’app OAuth inconnue + obtention token + activité Graph dans la foulée
let timeframe = 1h;
let trustedApps = dynamic([
"00000003-0000-0000-c000-000000000000", // Microsoft Graph
"00000002-0000-0000-c000-000000000000" // Office 365 Exchange Online
]);
let SuspiciousConsent = AuditLogs
| where TimeGenerated > ago(timeframe)
| where ActivityDisplayName in ("Consent to application", "Add OAuth2PermissionGrant")
| extend AppId = tostring(parse_json(InitiatedBy).app.appId)
| where AppId !in (trustedApps)
| project TimeGenerated, UserId=tostring(TargetResources[0].id), AppId, AppName=TargetResources[0].displayName;
let OAuthTokenIssued = AADSignInLogs
| where TimeGenerated > ago(timeframe)
| where TokenIssuerType == "AzureAD"
| project TimeGenerated, UserPrincipalName, AppId, IPAddress, ClientAppUsed;
let GraphCalls = AADSignInLogs
| where TimeGenerated > ago(timeframe)
| where ResourceDisplayName contains "Microsoft Graph"
| project TimeGenerated, UserPrincipalName, IPAddress;
SuspiciousConsent
| join kind=inner OAuthTokenIssued on AppId
| join kind=inner GraphCalls on UserPrincipalName
| where GraphCalls.TimeGenerated > SuspiciousConsent.TimeGenerated
| sort by SuspiciousConsent.TimeGenerated desc
✅ Ce que ça alerte
- App OAuth non approuvée
- Consentement utilisateur
- Token émis
- Appel API Graph derrière
Le combo gagnant pour du device code phishing.
🟧 ELK — Elastic Query DSL (Elasticsearch)
MĂŞme logique : consentement + appel API Graph / Gmail API
{
"query": {
"bool": {
"must": [
{
"range": {
"@timestamp": { "gte": "now-1h" }
}
},
{
"terms": {
"event.action": [
"oauth2-authorization-grant",
"oauth2-consent"
]
}
},
{
"bool": {
"must_not": {
"terms": {
"oauth.client.id": [
"00000003-0000-0000-c000-000000000000",
"00000002-0000-0000-c000-000000000000"
]
}
}
}
}
]
}
}
}
Ajoute ensuite une detection rule ELK pour chainer avec des événements qui matchent :
resource.name: "Microsoft Graph" OR resource.name: "gmail.googleapis.com"
Ou si tu veux pousser le vice :oauth.client.id qui apparaît pour la première fois dans les 30 derniers jours dans ton index → bruit minime.
🧪 Option bonus — test rapide pour voir si ça remonte
Simule un consentement OAuth Ă la main.
Dans many orgs, les logs OAuth sont silencieux. Tu verras tout de suite si ton pipeline est sec.
🎯 Conseil d’archi défensif malin
Ne fais pas que détecter. Lister les apps OAuth autorisées dans un index Elastic et faire une join check.
Ça donne une règle plus robuste :
- App non listée
- Consent
- Token
- API call
C’est littĂ©ralement l’IDS de l’identitĂ©.
👊 Conclusion
Tu as maintenant :
- Une règle KQL solide
- La version ELK équivalente
- Le workflow de détection pensé “attaque moderne”
