GHSA-r9gp-7f88-9r54MediumCVSS 4.8
Lemur: JWT verifier honors attacker-supplied alg, enabling ATO
🔗 CVE IDs covered (1)
📋 Description
Field | Value -- | -- Title | Lemur 1.9.0: JWT verifier trusts attacker-supplied alg from token header — defense-in-depth gap; chain-dependent ATO with secret disclosure Component | lemur/lemur/auth/service.py:130-137 CWE | CWE-347 (Improper Verification of Cryptographic Signature) Attack Prerequisite | Defense-in-depth gap on its own — no single-request exploit against PyJWT 2.x. Single-request ATO requires a separate disclosure issue that leaks LEMUR_TOKEN_SECRET, or a future migration to asymmetric signing without fixing this sink. Affected Versions | github.com/Netflix/lemur version = "1.9.0". Same code present in every prior release that has the auth/service.py:130 block.
Exploit Code & Lab Set-up
sequenceDiagram
participant Attacker
participant Lemur as Lemur API
participant Disclosure as Disclosure surface
participant Audit as Audit logging
Note over Attacker,Lemur: "Today: PyJWT 2.x mitigation holds for alg=none"
Attacker->>Lemur: "Bearer alg=none token with [payload]"
Lemur->>Lemur: "pyjwt.decode raises (alg=none + non-None key)"
Lemur-->>Attacker: "403 Forbidden"
Note over Disclosure,Lemur: "Chain step: separate disclosure leaks LEMUR_TOKEN_SECRET"
Attacker->>Disclosure: "trigger debug / SSRF / backup leak"
Disclosure-->>Attacker: "LEMUR_TOKEN_SECRET value"
Note over Attacker,Lemur: "Forge HS256 admin token with leaked secret"
Attacker->>Lemur: "Bearer alg=HS256 admin token signed with leaked secret"
Lemur->>Lemur: "algorithms=[HS256] (taken from header) — accepted"
Lemur-->>Attacker: "200 OK, role=admin"
Note over Audit: "alg=HS256 in audit log - no anomaly flag because attacker picks alg"
🎯 Affected products1
- pip/lemur:< 1.9.2