Aller au contenu
SDETRole
SDETRole

Glossaire · Sécurité

Cross-site scripting (XSS)

En anglais : Cross-site scripting

Également appelé : XSS, faille XSS, cross site scripting, XSS stocké

Définition

Le XSS est une faille où une saisie non fiable s’exécute comme script dans le navigateur d’un autre utilisateur, permettant à un attaquant d’agir à sa place.

Le cross-site scripting (XSS) se produit lorsqu’une application prend une saisie d’un utilisateur et l’insère dans une page sans encodage approprié, si bien que le navigateur la traite comme du HTML ou du JavaScript au lieu de texte. Le script s’exécute alors avec la session de la victime sur le site vulnérable : il peut lire les données de la page, envoyer des requêtes au nom de l’utilisateur ou modifier ce qu’il voit. Dans l’OWASP Top 10 2021, il est regroupé sous A03 Injection.

Les trois types

  • Stocké. La charge utile (payload) est enregistrée (un commentaire, un nom de profil, un ticket de support) et servie à tous ceux qui la consultent. C’est généralement le plus grave.
  • Réfléchi. La charge utile se trouve dans la requête, souvent un paramètre d’URL comme un terme de recherche, et est renvoyée telle quelle dans la réponse.
  • Basé sur le DOM. Du JavaScript côté client lit des données contrôlées par l’attaquant (par exemple location.hash) et les écrit dans la page via un sink dangereux comme innerHTML.

Ce que vérifie un testeur

Placez un marqueur inoffensif dans chaque champ affiché ensuite (à vous, aux autres utilisateurs, aux administrateurs dans un back-office) et regardez s’il revient sous forme de texte ou de balisage actif. Une vérification automatisée avec Playwright, uniquement pour des tests autorisés :

import { test, expect } from '@playwright/test';

test('comment body is rendered as text, not HTML', async ({ page }) => {
  const probe = '<img src=x onerror="window.__xssProbe=1">';

  await page.goto('/posts/1');
  await page.getByLabel('Comment').fill(probe);
  await page.getByRole('button', { name: 'Post comment' }).click();

  // Escaped output shows the literal characters on screen
  await expect(page.getByText(probe)).toBeVisible();
  // and the handler never ran
  expect(await page.evaluate(() => (window as any).__xssProbe)).toBeUndefined();
});

Vérifiez aussi les contextes de sortie au-delà du HTML simple : valeurs dans des attributs, dans des scripts inline, dans des URL (liens javascript:) et dans les éditeurs de texte riche, car chacun nécessite un encodage différent.

Défenses à vérifier

  • Un encodage de sortie par défaut. Les frameworks modernes (React, Angular, Vue) échappent le texte automatiquement ; cherchez les échappatoires comme dangerouslySetInnerHTML, v-html ou innerHTML.
  • Une sanitisation du HTML pour les fonctionnalités qui acceptent réellement du balisage.
  • Un en-tête Content Security Policy qui bloque les scripts inline, comme seconde ligne de défense.
  • Des cookies de session HttpOnly, pour qu’un XSS réussi ne puisse pas simplement lire le cookie de session.

Ne testez jamais sur des systèmes qui ne vous appartiennent pas ou pour lesquels vous n’avez pas d’autorisation écrite.

Saisissez un terme pour rechercher sur SDETRole.

Recherche plein texte par Pagefind · s’exécute dans votre navigateur Ouvrir la page de recherche →