
Un collecteur et serveur de payload Blind XSS (Cross-Site Scripting) léger construit avec Flask
Un collecteur et serveur de payloads Blind XSS (Cross-Site Scripting) léger, construit avec Flask. Il sert un payload JavaScript qui capture les données du navigateur de la victime (cookies, localStorage, extraits du DOM, etc.) et les transmet à un tableau de bord adossé à SQLite, protégé par HTTP Basic Auth.
/p.js sert un payload JS autonome utilisant sendBeacon ou fetch/c (JSON/FormData) et GET /c.gif (balise pixel compatible CSP)/events liste les événements capturés, /events/<id>/view affiche les détails complets/payloads propose 14 variantes de payloads XSS ainsi qu'un éditeur JS personnaliséADMIN_USER / ADMIN_PASSWORDbxss.db la reconstruit à neufDockerfile et docker-compose.yml inclus# Set credentials
echo "ADMIN_USER=admin" > .env
echo "ADMIN_PASSWORD=your-admin-password" >> .env
# Build and run
docker compose up -d --build
Tableau de bord : http://127.0.0.1:8089/events (le navigateur demandera une authentification Basic)
pip install -r requirements.txt
export ADMIN_USER="admin"
export ADMIN_PASSWORD="your-admin-password"
gunicorn -b 127.0.0.1:8080 --workers 2 --threads 4 wsgi:app
/payloads (après authentification) pour copier une charge utile XSS./events.| Méthode | Chemin | Description |
|---|---|---|
| GET | /p.js | JavaScript de la charge utile XSS |
| POST | /c | Reçoit du JSON/FormData depuis la charge utile |
| GET | /c.gif | Balise pixel (compatible CSP) |
| Méthode | Chemin | Description |
|---|---|---|
| GET | /events | Les 500 derniers événements |
| GET | /events/<id> | Détail de l'événement au format JSON |
| GET | /events/<id>/view | Détail de l'événement au format HTML |
| GET/POST | /payloads | Générateur de charges utiles + éditeur JS personnalisé |
| Méthode | Chemin | Description |
|---|---|---|
| GET | /_healthz | Vérification de l'état |
| Variable | Valeur par défaut | Description |
|---|---|---|
ADMIN_USER | admin | Nom d'utilisateur du tableau de bord |
ADMIN_PASSWORD | (requis) | Mot de passe du tableau de bord — le démarrage échoue s'il n'est pas défini |
DB_PATH | ./bxss.db | Chemin de la base de données SQLite |
PUBLIC_URL | (vide) | URL de base publique pour les charges utiles générées (à utiliser derrière un tunnel/proxy inverse ; revient à l'hôte de la requête par défaut) |
TRUST_PROXY | (vide) | Définir à 1 pour faire confiance à X-Forwarded-For/CF-Connecting-IP pour l'IP du client (uniquement derrière un proxy inverse de confiance ; requis dans ce cas, sinon tous les clients partagent l'IP du proxy pour la limitation de débit) |
MAX_BODY | 524288 | Taille maximale du corps du collecteur (octets) |
RATE_LIMIT_COUNT | 60 | Nombre maximal de requêtes du collecteur par fenêtre (par IP) |
RATE_LIMIT_WINDOW | 60 | Fenêtre de limitation de débit en secondes |
LOG_LEVEL | INFO | Niveau de journalisation Python |
Le JS personnalisé est édité et stocké via la page d'administration
/payloads(persisté dans la tablesettingsde SQLite) et ajouté à/p.js. Il n'est plus lu depuis un fichier.
blindxss-lite/
├── wsgi.py # WSGI entry point
├── requirements.txt # Python dependencies
├── Dockerfile # Container image
├── docker-compose.yml # Compose config
├── .env # Credentials (don't commit)
└── app/
├── __init__.py # App factory, CORS, health check
├── config.py # Config + .env loader
├── db.py # SQLite layer
├── collectors.py # /p.js, /c, /c.gif
├── events.py # /events admin
├── payloads.py # /payloads admin
├── utils.py # Helpers + Basic Auth decorator
├── static/
│ └── style.css
└── templates/
├── events.html
├── event.html
└── payloads.html
document.cookieCharges utiles :

Résultat :

Détail du résultat :

.env ne doit jamais être commité dans le contrôle de version.