CSRF (Cross-Site Request Forgery) est un type d'attaque où un attaquant force le navigateur de la victime à envoyer une requête falsifiée à un serveur cible au nom d'un utilisateur authentifié. Selon OWASP, 2026, CSRF fait partie des dix risques les plus critiques pour les applications web. Dans le contexte du développement mobile, les attaques CSRF sont particulièrement dangereuses pour les API REST qui utilisent l'authentification par cookies. La falsification de requête inter-sites reste une menace pertinente malgré la mise en œuvre de mécanismes de protection modernes.
Points clés
CSRF (Cross-Site Request Forgery) est une attaque où un attaquant crée une requête falsifiée et force le navigateur de la victime à l'envoyer vers un serveur cible. Le serveur exécute la requête parce qu'il reçoit des informations d'identification de cookie valides de la session en cours de l'utilisateur. L'attaque est possible car le navigateur ajoute automatiquement des cookies à chaque requête vers le domaine cible, quel que soit le site d'origine de la requête. L'utilisateur peut même ne pas voir la page de l'attaquant — il suffit de charger un <img>, <form> ou <iframe> caché avec une URL malveillante. CSRF ne vole pas directement les données — l'attaque effectue des actions au nom de la victime (opérations de changement d'état), telles que le transfert d'argent, le changement de mot de passe ou la suppression de compte.
Les attaques CSRF ciblent exclusivement les opérations de changement d'état — les requêtes GET avec effets secondaires, POST, PUT et DELETE. Par exemple, une requête de changement d'adresse e-mail dans un compte personnel : si le serveur accepte la requête sans vérifier son origine, l'attaquant peut substituer sa propre adresse e-mail et initier une réinitialisation de mot de passe. L'attaque est particulièrement dangereuse pour les systèmes bancaires, les panneaux d'administration et les réseaux sociaux, où une seule action a des conséquences graves. Les API des applications mobiles qui utilisent des cookies pour l'authentification sont également vulnérables au CSRF si elles n'effectuent pas de vérifications supplémentaires.
Toute application web ou API où l'authentification est basée sur des cookies et où le serveur ne vérifie pas l'origine de la requête est vulnérable. Les applications mobiles qui utilisent WebView pour l'authentification via des formulaires web sont également à risque : le composant navigateur envoie automatiquement des cookies, et l'attaquant peut injecter une requête malveillante par chargement en arrière-plan. Selon HackerOne (2025), environ 12 % de tous les rapports de vulnérabilités dans les applications web sont liés à l'absence de protection CSRF.
La principale caractéristique de CSRF est son invisibilité pour la victime. L'utilisateur peut ne même pas se rendre compte qu'une attaque a eu lieu : la requête falsifiée est exécutée en arrière-plan et l'interface de l'application ne montre aucun signe de compromission. La seule façon de détecter CSRF est de surveiller les journaux du serveur ou de remarquer des changements soudains dans le compte. De plus, CSRF se combine facilement avec d'autres vulnérabilités comme XSS ou les redirections ouvertes, ce qui multiplie les dégâts.
Une attaque CSRF nécessite trois conditions : la victime est authentifiée sur le site cible, le serveur utilise l'authentification par cookies et la requête de l'attaquant est dirigée vers une URL d'action. L'attaquant crée une page HTML avec un formulaire, un script ou une image dont l'attribut src pointe vers l'URL cible. Le navigateur de la victime charge cette page et envoie automatiquement une requête au serveur avec le cookie de session actuel. Le serveur reçoit des cookies valides, ne vérifie pas la source de la requête et exécute l'opération.
<!-- Exemple d'attaque CSRF via un formulaire caché -->
<form action="https://bank.example.com/transfer"
method="POST" id="csrf-form">
<input type="hidden"
name="toAccount"
value="attacker-account">
<input type="hidden"
name="amount"
value="10000">
</form>
<script>document.getElementById("csrf-form").submit()</script>
Après le chargement de la page, le script soumet immédiatement le formulaire. Le navigateur joint le cookie de session de l'utilisateur à la requête POST vers bank.example.com. Le serveur de la banque vérifie le cookie, confirme que l'utilisateur est authentifié et exécute le transfert vers le compte de l'attaquant. La victime voit une page vide ou légitime, mais l'argent a déjà disparu.
Une caractéristique clé du protocole HTTP est l'absence de vérification intégrée de la source de la requête. Le navigateur ajoute des cookies à la requête si le domaine de la requête correspond au domaine du cookie. L'attaquant n'a pas besoin de connaître le contenu du cookie — le navigateur le fait automatiquement. La politique de même origine ne protège pas contre CSRF car l'attaque cible le serveur, pas la lecture de la réponse. Des mécanismes comme CORS sont également impuissants : les requêtes CSRF n'ont généralement pas besoin de lire la réponse pour causer des dégâts.
Les attaques CSRF sont classées selon la méthode de livraison de la requête malveillante. Chaque type utilise un élément HTML différent pour envoyer la requête, mais tous reposent sur l'envoi automatique de cookies par le navigateur. Le choix de la méthode dépend des objectifs de l'attaquant : les attaques GET-based nécessitent moins de code, les attaques POST-based contournent certaines défenses plus facilement, et les attaques XMLHttpRequest-based permettent la manipulation d'en-têtes.
| Type d'attaque | Vecteur de livraison | Méthode HTTP | Difficulté de détection |
|---|---|---|---|
| GET-based | <img>, <script>, <iframe> | GET | Élevée |
| POST-based | <form> caché + envoi automatique | POST | Moyenne |
| XHR-based | XMLHttpRequest avec CORS | Quelconque | Faible |
La méthode la plus simple : l'attaquant place une <img> sur une page avec une URL contenant des paramètres de requête. Le navigateur charge l'image et envoie une requête GET au serveur. Par exemple, <img src="https://api.example.com/delete?postId=123" /> supprime un enregistrement si le serveur traite DELETE via GET. Malgré le danger évident, certaines API utilisent encore GET pour les opérations de suppression ou de mise à jour.
Si le serveur accepte uniquement les requêtes POST, l'attaquant crée un formulaire caché avec la méthode POST et le soumet automatiquement via JavaScript. Le formulaire ne s'affiche pas à l'écran (tous les <input> ont type="hidden"), et autofocus + .submit() se déclenche sans clic de l'utilisateur. Les attaques POST-based ne fonctionnent pas si le serveur vérifie l'en-tête Content-Type, mais la plupart des API acceptent le format standard application/x-www-form-urlencoded.
XMLHttpRequest ou Fetch API permettent d'envoyer des requêtes avec des en-têtes arbitraires. Si le serveur a configuré CORS trop largement (Access-Control-Allow-Origin: *), l'attaquant peut envoyer n'importe quelle requête et lire la réponse. Cependant, pour une attaque CSRF, lire la réponse n'est pas nécessaire — il suffit d'exécuter l'action. Les navigateurs modernes envoient une requête preflight OPTIONS avant les requêtes non standard, ce qui peut bloquer CSRF XHR-based si le serveur est correctement configuré.
Les applications mobiles sont moins vulnérables au CSRF que les sites web car les applications natives utilisent rarement l'authentification par cookies. Au lieu de cela, les API mobiles utilisent plus souvent des jetons dans l'en-tête Authorization (jetons Bearer, JWT). Cependant, il existe des scénarios où une attaque CSRF est possible : WebView avec connexion web, applications hybrides et API avec sessions basées sur les cookies. Selon TechCrunch (2025), environ 18 % des API publiques d'applications mobiles supportent encore les cookies de session.
De nombreuses applications ouvrent des pages web dans WebView — autorisation OAuth, formulaires de paiement, visualisation de contenu. WebView est un navigateur complet à l'intérieur de l'application qui stocke les cookies de session. Si un attaquant trouve un moyen de charger son URL dans WebView (via une redirection ouverte ou un Deep Link), il peut effectuer une attaque CSRF exactement comme dans un navigateur normal. Protection — utilisez Chrome Custom Tabs ou SFSafariViewController au lieu de WebView pour les opérations critiques.
Les jetons JWT sont généralement stockés dans localStorage ou dans la mémoire de l'application et ne sont pas envoyés automatiquement — le développeur ajoute explicitement l'en-tête Authorization à chaque requête. Cela rend une attaque CSRF classique impossible. Cependant, si l'application stocke JWT dans un cookie (rare mais possible), le risque revient. Protection supplémentaire — lier JWT à une origine de requête spécifique via la revendication azp ou aud, ce qui empêche l'utilisation du jeton sur un domaine différent.
// Exemple de validation de jeton CSRF côté serveur dans Express
const csrfProtection = (req, res, next) => {
const token = req.headers['x-csrf-token'];
if (!token || token !== req.session.csrfToken) {
return res.status(403).json({ error: 'CSRF validation failed' });
}
next();
};
// Génération de jeton CSRF lors de la connexion
app.post('/api/login', (req, res) => {
const csrfToken = crypto.randomBytes(32).toString('hex');
req.session.csrfToken = csrfToken;
res.json({ csrfToken: csrfToken });
});
La protection moderne contre CSRF repose sur trois niveaux : les jetons CSRF côté serveur, l'attribut SameSite pour les cookies et la vérification de l'en-tête Origin. La combinaison de ces méthodes offre une protection contre 99 % des attaques CSRF sans impact significatif sur l'expérience utilisateur. Le choix de l'approche dépend de l'architecture de l'application : un site web peut n'avoir besoin que de SameSite=Lax, tandis qu'une API d'application mobile nécessite des jetons dans les en-têtes.
La méthode standard : le serveur génère un jeton unique, le lie à la session de l'utilisateur et l'envoie au client. Le client inclut le jeton dans chaque requête de changement d'état (dans un champ de formulaire caché ou dans l'en-tête X-CSRF-Token). Le serveur compare le jeton reçu avec celui stocké dans la session. Le jeton doit être cryptographiquement fort, aléatoire, d'au moins 32 octets et changer à chaque session ou opération. La durée de vie du jeton ne doit pas dépasser quelques heures.
L'attribut SameSite pour les cookies limite l'envoi de cookies lors de requêtes inter-domaines. La valeur Lax autorise les cookies uniquement pour les requêtes GET de navigation de niveau supérieur — suffisant pour la plupart des sites web. Strict bloque les cookies pour toutes les requêtes inter-domaines, y compris la navigation : l'utilisateur devra se réauthentifier en venant d'un autre site. Selon Chrome Platform Status (2026), SameSite=Lax est activé par défaut dans tous les navigateurs modernes, ce qui a réduit le nombre d'attaques CSRF de 67 %.
Le serveur peut vérifier les en-têtes Origin ou Referer des requêtes entrantes. Si la requête provient d'un domaine différent, elle est bloquée. Origin est plus fiable que Referer car il est toujours présent dans les requêtes POST et ne peut pas être désactivé par les politiques du navigateur. Implémentation : une liste blanche d'origines autorisées, comparée à la valeur actuelle de l'en-tête. Cette méthode est efficace mais difficile avec les applications mobiles, où les en-têtes Origin peuvent être absents ou falsifiés.
// Exemple de validation de jeton CSRF dans Spring Boot
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
fun securityFilterChain(
@Autowired http: HttpSecurity
): SecurityFilterChain {
return http
.csrf { it.csrfTokenRepository(
CookieCsrfTokenRepository.withHttpOnlyFalse()
) }
.sessionManagement {
it.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
}
.build()
}
}
Une méthode qui ne nécessite pas de stockage de jeton côté serveur : le serveur définit un cookie avec une valeur aléatoire, le client lit la valeur du cookie et la renvoie dans un en-tête ou dans le corps de la requête. Le serveur compare les deux valeurs. Si l'attaquant ne peut pas lire le cookie (politique de même origine), il ne peut pas falsifier le jeton. Cette méthode est plus simple à implémenter que le synchronisateur, mais nécessite HTTPS pour protéger le cookie contre l'interception.
CSRF et XSS sont des types d'attaques différents qui sont souvent confondus. CSRF exploite la confiance du serveur dans le navigateur de l'utilisateur : le serveur exécute la commande de l'attaquant parce que la requête arrive avec des cookies valides. XSS exploite la confiance du navigateur dans le contenu du serveur : le navigateur exécute un script injecté par l'attaquant dans la page. CSRF ne nécessite pas d'injection de code sur le site cible — il suffit d'envoyer une requête depuis un autre domaine. XSS, en revanche, nécessite de trouver un moyen d'injecter du JavaScript dans le code HTML de la page. Cependant, XSS peut contourner la protection CSRF : le script injecté lit le jeton CSRF de la page et l'envoie avec la requête.
| Caractéristique | CSRF | XSS |
|---|---|---|
| Cible de l'attaque | Serveur | Client (navigateur) |
| Vecteur | Falsification de requête | Injection de script |
| Nécessite du JavaScript sur le site de la victime ? | Non | Oui |
| Vol de données | Non (actions uniquement) | Oui |
| Protection | Jeton CSRF, SameSite, Origin | Échappement de sortie, CSP |
Comprendre la différence entre CSRF et XSS est essentiel pour construire une protection multicouche. Les jetons CSRF ne protègent pas contre XSS, et CSP (Content Security Policy) ne protège pas contre CSRF. Seule une combinaison de méthodes garantit la sécurité de l'application contre les deux types d'attaques. Dans les applications mobiles avec WebView, les risques sont doublés, il est donc recommandé aux développeurs d'appliquer au moins des jetons CSRF pour les requêtes API et Content Security Policy pour le contenu web.
Foire aux questions
CSRF force le serveur à effectuer une action au nom de l'utilisateur, tandis que XSS injecte un script malveillant dans le navigateur de la victime. CSRF ne nécessite pas d'injection de code sur le site cible — il suffit d'envoyer une requête depuis un autre domaine. XSS, contrairement à CSRF, peut voler des données et lire le contenu de la page.
Vérifiez si vous utilisez l'authentification par cookies et s'il y a une vérification de l'origine de la requête pour les opérations de changement d'état. Si l'API accepte POST/PUT/DELETE sans jeton CSRF, vérification de Origin ou SameSite — l'application est vulnérable. Utilisez OWASP ZAP ou Burp Suite pour une analyse automatisée.
Non, CORS ne protège pas contre CSRF. CORS est un mécanisme pour lire en toute sécurité les réponses inter-domaines, tandis que les attaques CSRF n'ont pas besoin de lire les réponses — elles n'ont qu'à envoyer une requête. Les requêtes CSRF via <form> ou <img> ne sont pas soumises aux restrictions CORS.
Si l'API utilise l'authentification par cookies — oui, la protection CSRF est obligatoire. Si l'API fonctionne avec des jetons Bearer dans l'en-tête Authorization, le risque CSRF est minimal car les jetons ne sont pas envoyés automatiquement par le navigateur. Cependant, pour les applications hybrides avec WebView, la protection reste recommandée.
SameSite est supporté par tous les navigateurs modernes depuis 2020. Pour les navigateurs anciens, utilisez les jetons CSRF comme méthode de protection principale. La combinaison jeton CSRF + SameSite offre une protection maximale même avec SameSite désactivé dans les navigateurs legacy.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi