Prévenir l'Account Takeover (ATO) avec Auth0 : détection et réponse
L'Account Takeover est la compromission d'un compte légitime. Stratégies de détection en temps réel et de réponse automatique avec Auth0.
Par Auth0.Expert · 2025-05-01 · 11 min de lecture
Prévenir l'Account Takeover avec Auth0
TL;DR
L'Account Takeover (ATO) survient quand un attaquant prend le contrôle d'un compte légitime. Les coûts sont énormes : fraude financière, perte de données, dommage réputationnel. Ce guide présente la détection et la réponse automatique.
---
Les vecteurs d'ATO
Avant de protéger vos utilisateurs, il est crucial de comprendre les principales méthodes utilisées par les attaquants pour prendre le contrôle d'un compte.
- Credential stuffing : utiliser des mots de passe volés d'autres services
- Phishing : voler les credentials via un faux site
- SIM swapping : usurper le numéro de téléphone pour le MFA SMS
- Session hijacking : voler un cookie ou un token actif
- Password reset abuse : exploiter une vulnérabilité dans le reset
---
Détection en temps réel : signaux d'ATO
Ce script Action Post Login Auth0 détecte en temps réel les signaux potentiels d'attaque ATO lors de la connexion utilisateur, en attribuant un score de risque et en adaptant la sécurité (MFA, alerte).
// Action Post Login : score d'anomalie ATO
exports.onExecutePostLogin = async (event, api) => {
const user = event.user;
const req = event.request;
const namespace = 'https://yourapp.com/';
let atoRisk = 0;
const signals = [];
// Signal 1: Changement de pays
if (user.app_metadata?.last_country &&
user.app_metadata.last_country !== req.geoip?.country_code) {
atoRisk += 30;
signals.push(`country_change:${user.app_metadata.last_country}→${req.geoip?.country_code}`);
}
// Signal 2: IP compromise (AbuseIPDB)
if (req.geoip?.is_tor) {
atoRisk += 40;
signals.push('tor_exit_node');
}
// Signal 3: Heure inhabituelle pour cet utilisateur
const loginHour = new Date().getUTCHours();
const lastHour = user.app_metadata?.typical_login_hour;
if (lastHour && Math.abs(loginHour - lastHour) > 8) {
atoRisk += 15;
signals.push(`unusual_hour:${loginHour}`);
}
// Signal 4: Premier login après longue inactivité
const daysSinceLastLogin = user.last_login
? (Date.now() - new Date(user.last_login)) / 86400000
: 0;
if (daysSinceLastLogin > 90) {
atoRisk += 20;
signals.push(`inactive_${Math.round(daysSinceLastLogin)}d`);
}
// Décision basée sur le score
if (atoRisk >= 60) {
// Risque élevé : MFA obligatoire + alerte
api.multifactor.enable('any', { allowRememberBrowser: false });
await notifySecurityTeam(user.email, atoRisk, signals, req.ip, event.secrets);
} else if (atoRisk >= 30) {
// Risque modéré : MFA
api.multifactor.enable('any');
}
// Mettre à jour les données de référence
api.user.setAppMetadata('last_country', req.geoip?.country_code);
api.user.setAppMetadata('typical_login_hour', loginHour);
// Injecter le score dans le token pour l'API
api.accessToken.setCustomClaim(`${namespace}ato_risk`, atoRisk);
api.accessToken.setCustomClaim(`${namespace}ato_signals`, signals);
};
async function notifySecurityTeam(email, risk, signals, ip, secrets) {
await fetch(secrets.SLACK_WEBHOOK, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `🚨 *ATO Risk Alert*
User: ${email}
Score: ${risk}/100
IP: ${ip}
Signals: ${signals.join(', ')}`
}),
});
}
Ce code détecte plusieurs comportements anormaux à la connexion pour calculer un score de risque ATO, déclenchant MFA ou une alerte si besoin.
---
Réponse automatique graduée
Cette logique backend applique des actions automatiques selon la gravité du risque ATO, pour limiter l'impact (blocage, reset de mot de passe, suivi).
# Backend : réponse aux alertes ATO basée sur le score
async def handle_auth_event(payload: dict):
ato_risk = payload.get('https://yourapp.com/ato_risk', 0)
user_id = payload['sub']
if ato_risk >= 80:
# Suspendre immédiatement
await auth0.block_user(user_id)
await send_user_email_alert(user_id, 'account_suspended')
await create_security_incident('ato_high_risk', user_id, ato_risk)
elif ato_risk >= 50:
# Forcer reset de mot de passe
await auth0.trigger_password_reset(user_id)
await send_user_email_alert(user_id, 'security_review')
elif ato_risk >= 30:
# Logger pour analyse ultérieure
await log_suspicious_activity(user_id, ato_risk)
Ce code prend automatiquement des mesures de sécurité adaptées selon le score de risque de takeover détecté.
---
Détection post-login : activités suspectes
Après la connexion, surveillez les comportements inhabituels pour identifier les attaques ATO potentielles, comme l'export massif de données.
// Surveiller les actions suspectes après login
// (appels API inhabituels, données massives exportées, etc.)
async function checkPostLoginBehavior(accessToken, action) {
const payload = await verifyToken(accessToken);
const userId = payload.sub;
// Vérifier si l'action est normale pour cet utilisateur
const userHistory = await getUserActionHistory(userId);
const isUnusual = !userHistory.commonActions.includes(action);
if (isUnusual && action.startsWith('export:')) {
// Exporter des données = action sensible inhabituelle
await createReviewRequest(userId, action);
await notify_security_team(userId, action);
}
}
Ce script contrôle s'il y a des actions post-login anormales et alerte votre équipe sécurité si besoin.
---
Honeypot : piéger les attaquants ATO
Créer un compte leurre permet de détecter rapidement un comportement malveillant ciblant vos utilisateurs.
// Créer un "fake account" que seul un attaquant essaierait d'utiliser
// Si quelqu'un se connecte à ce compte → ATO en cours sur votre système
exports.onExecutePostLogin = async (event, api) => {
const HONEYPOT_EMAILS = ['[email protected]', '[email protected]'];
if (HONEYPOT_EMAILS.includes(event.user.email)) {
// Ne jamais bloquer (pour logger l'attaquant)
// Mais alerter immédiatement
await fetch(event.secrets.ALERT_WEBHOOK, {
method: 'POST',
body: JSON.stringify({
alert: 'HONEYPOT_LOGIN',
ip: event.request.ip,
user_agent: event.request.user_agent,
timestamp: new Date().toISOString(),
}),
});
}
};
Ce bloc permet d'alerter en temps réel si un attaquant accède à un compte honeypot dédié.
---
Checklist anti-ATO
Pour renforcer la défense globale, voici les bonnes pratiques à appliquer en complément des réponses techniques.
- [ ] Breached Password Detection activée
- [ ] MFA obligatoire (ou adaptatif avec seuil bas)
- [ ] Monitoring des changements de pays
- [ ] Alerte email utilisateur sur tout nouveau login
- [ ] Logs streaming vers SIEM avec règles ATO
- [ ] Procédure de réponse à incident documentée
- [ ] Formation des équipes support (vérification d'identité pour reset)
- [ ] SMS MFA désactivé pour les comptes privileged (SIM swap)
---
> 🚨 Programme ATO : nous déployons un système complet de détection et de réponse ATO adapté à votre secteur (fintech, e-commerce, SaaS).
Autres articles
- Auth0 et OAuth 2.0 : architecture complète pour comprendre les flux d'autorisation
- OpenID Connect sur Auth0 : ID Token, UserInfo et discovery endpoint expliqués
- Configurer SAML 2.0 avec Auth0 : guide complet pour l'entreprise
- Migrer des Rules vers les Auth0 Actions : guide pas à pas
- Architecture multi-tenant avec Auth0 : organisations, isolation et bonnes pratiques
- Validation des JWT Auth0 : RS256 vs HS256, JWKS et pièges communs
- Concevoir son architecture de tenants Auth0 : dev, staging, prod
- Configurer un domaine personnalisé Auth0 : login.votredomaine.com étape par étape