GHSA-r9gp-7f88-9r54MediumCVSS 4.8

Lemur: JWT verifier honors attacker-supplied alg, enabling ATO

Published
June 25, 2026
Last Modified
June 25, 2026

🔗 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

Lemur-jwt-alg-hardening.zip

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

🔗 References (3)