Aug 18, 2026·6 min read·45 visits
An authorization bypass in Netflix Lemur prior to v1.9.3 allows authenticated users to revoke arbitrary TLS certificates at the upstream CA. By uploading a duplicate metadata record of a victim's certificate, an attacker becomes the owner of that local record and can bypass safety checks to trigger CA-level revocation, resulting in immediate service disruption.
CVE-2026-71417 is an authorization bypass vulnerability (CWE-639) in Netflix Lemur, an open-source TLS certificate management framework. In versions prior to 1.9.3, a low-privileged authenticated user can bypass role and certificate-level permission boundaries to revoke arbitrary managed TLS certificates at the upstream Certificate Authority (CA). This vulnerability stems from an architectural issue where Lemur evaluates authorization against internal database row ownership rather than the unique, cryptographic identity of the certificate. An attacker can exploit this flaw by uploading a duplicate record of a target certificate and requesting its revocation, triggering a downstream CA-side revocation and a subsequent denial-of-service (DoS) condition for services relying on the target certificate.
Netflix Lemur functions as a centralized orchestration engine for managing the lifecycle of TLS certificates across large enterprise infrastructures. It interacts with upstream Certificate Authorities (such as DigiCert or Let's Encrypt) to automate issuance, renewal, and revocation. Because Lemur serves as a high-privilege gateway to external CA infrastructure, it maintains strict internal authorization controls. Users are typically organized into roles with specific 'AuthorityPermissions' and 'CertificatePermissions' to restrict access to sensitive keys and domains.
CVE-2026-71417 describes a critical flaw within Lemur's multi-tenant permission model. Specifically, the software fails to properly restrict manually uploaded certificate metadata and subsequently relies on database-row-level ownership check rather than cryptographic identity checks during revocation requests. This architectural decoupling allows any low-privileged, authenticated user to subvert the intended security controls.
The impact is categorized under CWE-639 (Authorization Bypass Through User-Controlled Key). Because the vulnerability results in the revocation of active production certificates at the upstream CA level, it carries a severe availability impact. Services utilizing the revoked certificates will immediately experience trust failures during client TLS handshakes, leading to wide-scale, enterprise-wide service outages.
The root cause of CVE-2026-71417 is a two-part failure involving unrestricted manual database entry and flawed authorization validation logic.
First, the certificate upload endpoint ('POST /api/1/certificates/upload') did not validate whether the uploading user possessed administrative or ownership privileges over the Certificate Authority associated with the certificate. Furthermore, the Lemur database schema did not enforce unique constraints on combinations of the authority identifier and the certificate serial number. Consequently, a malicious user could manually upload the public metadata of an active certificate owned by another team, associating it with any arbitrary CA configured in the system. Since the attacker uploaded the record, Lemur designated the attacker as the 'owner' of this newly created database row.
Second, the revocation endpoint ('PUT /api/1/certificates/<id>/revoke') relied on row-level authorization rather than global certificate identity. When the attacker requested revocation for their newly uploaded duplicate row, Lemur's access control check succeeded because the attacker was the registered owner of that specific database entry. Additionally, Lemur's built-in safeguard—which blocks the revocation of certificates currently mapped to active endpoints ('cert.endpoints')—failed. Because the attacker's newly uploaded duplicate record had no active endpoints associated with it in the Lemur tracking database, the safeguard query returned empty. The application then passed the revocation instruction to the upstream CA integration plugin, which executed the revocation using the certificate's shared cryptographic identifiers, invalidating the victim's production certificate.
An attacker with standard, authenticated API access to Lemur can execute this attack sequence with minimal complexity. The exploitation flow follows these steps:
Reconnaissance: The attacker queries the Lemur API to retrieve the public certificate metadata of the target certificate, capturing the public PEM certificate block and the associated authority identifier.
Database Shadowing: The attacker calls 'POST /api/1/certificates/upload' and submits the victim's public PEM certificate. The attacker specifies themselves as the owner and links the certificate to the target authority. Because no authority validation or uniqueness checks are performed, the application database inserts a new row (e.g., ID 9999) pointing to the same cryptographic identity as the victim's legitimate row (e.g., ID 1111).
Bypassing Safeguards & Requesting Revocation: The attacker targets their newly created row by issuing a 'PUT /api/1/certificates/9999/revoke' request. The backend verifies that the caller owns row 9999 (which is true) and that row 9999 has no deployed endpoints (which is also true).
CA-Side Execution: The issuer plugin processes the request and transmits the revocation instruction to the external CA using the serial number. The CA revokes the certificate, terminating its validity globally.
The vulnerability was resolved in commit 851389ae737a6d6bf16c1f9ca64a2ce56c1cc5c6. The patch implements validation at both the upload (ingestion) and revocation (action) boundaries.
At the ingestion boundary ('POST /api/1/certificates/upload'), the patch verifies that the user possesses permission to interact with the specified authority. It then parses the uploaded certificate body to extract the serial number and queries the database for existing records sharing the same 'authority_id' and 'serial' combination. If a matching record is found, the application rejects the upload with a '409 Conflict' error:
# lemur/certificates/views.py - Upload Fix
authority = data.get("authority")
if authority:
authority_roles = [x.name for x in authority.roles]
if not AuthorityPermission(authority.id, authority_roles).can():
return (
dict(message="You are not authorized to upload a certificate for the specified authority."),
403,
)
parsed_cert = utils.parse_certificate(data["body"])
serial = defaults.serial(parsed_cert)
existing = Certificate.query.filter(
Certificate.authority_id == authority.id,
Certificate.serial == str(serial),
).first()
if existing:
return (
dict(
message=f"A certificate with serial={serial} already exists for this authority "
f"(Certificate id={existing.id})."
),
409,
)At the action boundary ('PUT /api/1/certificates/<id>/revoke'), the patch modifies the authorization logic to query for all database rows sharing the target certificate's 'authority_id' and 'serial'. The handler then enforces ownership and endpoint checks across all retrieved records, preventing attackers from using a self-owned alias to bypass checks on a production certificate:
# lemur/certificates/views.py - Revocation Fix
related_certs = [cert]
if cert.authority_id and cert.serial:
related_certs = Certificate.query.filter(
Certificate.authority_id == cert.authority_id,
Certificate.serial == cert.serial,
).all()
for related in related_certs:
if g.current_user != related.user:
owner_role = role_service.get_by_name(related.owner)
permission = CertificatePermission(owner_role, [x.name for x in related.roles])
if not permission.can():
return dict(message="You are not authorized to revoke this certificate. Blocked by related row."), 403Although the patch successfully addresses the primary exploit vector, security teams should remain aware of specific implementation limits and risks.
First, the duplicate check during upload is performed at the application layer via an ORM query ('Certificate.query.filter(...)') rather than a unique constraint at the database layer. This introduces a Time-of-Check to Time-of-Use (TOCTOU) race condition. If an attacker submits concurrent duplicate upload requests, the database could potentially commit multiple matching rows before the application checks complete. However, the updated revocation endpoint mitigates the impact of this condition because it queries for all matching serials and authorities dynamically, meaning any subsequent revocation attempt will still be blocked by the original, legitimate record's permissions.
Second, the patch introduces a potential operational issue for legacy deployments containing pre-existing duplicate rows. If duplicate rows were inserted before applying the v1.9.3 upgrade, a legitimate owner attempting to revoke their certificate will be blocked. The updated revocation code will locate the legacy duplicate row owned by the other user and fail the authorization check. Administrators must clean up duplicate database rows during the upgrade process.
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:L/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Lemur Netflix | < 1.9.3 | 1.9.3 |
| Attribute | Detail |
|---|---|
| Vulnerability Type | CWE-639: Authorization Bypass Through User-Controlled Key |
| Attack Vector | Local API Access (Authenticated User Session) |
| CVSS v3.1 Base Score | 7.3 |
| EPSS Score | Not available |
| Exploit Status | Proof of Concept (PoC) available in official repository |
| CISA KEV Status | Not Listed |
| Scope Impact | Changed (S:C) - Lemur exploitation leads to external CA revocation |
The system fails to check if the user is authorized to perform the action on the referenced object by its key.
An open redirect vulnerability exists in Payload CMS within its Next.js-based authentication routing components. The sanitization utility fails to properly account for control characters and ambiguous encodings, allowing unauthenticated attackers to redirect users to external malicious domains after successful authentication.
A critical SQL Injection and access control bypass vulnerability was identified in Payload CMS database adapters (SQLite and PostgreSQL using Drizzle ORM internally). The vulnerability arises from case-sensitive logical operator checks during path validation and unvalidated sort queries. This allows remote attackers to bypass access control rules, execute unauthorized queries, and retrieve sensitive data through blind SQL injection side channels.
A critical prototype pollution vulnerability in the import-export plugin of Payload CMS allows unauthenticated remote attackers to bypass access controls and achieve remote code execution.
CVE-2026-105806 is an improper access control vulnerability within the Model Context Protocol (MCP) plugin for Payload CMS. Authenticated users with low privileges can manipulate API key creation and mapping to associate keys with arbitrary users, including administrators. This allows total session takeovers and privilege escalation via MCP-authenticated API requests.
An access control vulnerability in `@payloadcms/plugin-stripe` allows authenticated low-privilege users to bypass authorization boundaries and execute arbitrary, highly privileged operations on the connected Stripe platform via an exposed REST proxy.
A critical access control bypass vulnerability (CVE-2026-105851) in Payload CMS allows authenticated users to bypass field-level access controls during document duplication. By duplicating high-privilege documents, such as administrator accounts, standard users can inherit sensitive fields (e.g., role configurations or API keys), leading to privilege escalation.