CVE-2026-71303: Lemur ACME Authority Update SSRF (Incomplete Fix)
Lemur's certificate authority update endpoint lets any user with an authority role silently replace the ACME directory URL with an internal address, causing the server to make outbound requests to…

The problem
Lemur 1.9.2 added _validate_acme_url() to block non-allowlisted ACME directory URLs, but only wired that check into the authority creation path (POST). The authority update endpoint (PUT /api/1/authorities/<id>) accepted and stored the options field verbatim, with no allowlist check at all.
Any authenticated user who has been granted membership in an ACME authority's role group (a routine operational grant that lets them issue certificates) can call the PUT endpoint to overwrite acme_url with an arbitrary URL. On the next certificate issuance via that authority, Lemur's celery worker reads the stored URL and issues an outbound HTTP request to it, achieving SSRF.
In cloud deployments this reaches AWS IMDSv1, GCP metadata, or Azure IMDS, and can yield IAM credentials.
Proof of concept
A working proof-of-concept for CVE-2026-71303 in lemur, with the exact payload below.
PUT /api/1/authorities/1 HTTP/1.1
Host: lemur.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"owner": "security@example.com",
"description": "Let's Encrypt Production",
"active": true,
"roles": [{"id": 5}, {"id": 6}, {"id": 7}],
"options": "[{\"name\": \"acme_url\", \"value\": \"http://169.254.169.254/latest/meta-data/\"}]"
}The root cause is a missing call to _validate_acme_url() in the PUT code path. In lemur/authorities/service.py, the update() function writes options straight to the database when it is non-empty, with no inspection of individual option names or values.
The sink is in lemur/plugins/lemur_acme/acme_handlers.py, where setup_acme_client() reads acme_url from the stored JSON and passes it directly to ClientV2.get_directory(directory_url, net), an outbound HTTP call.
The patch (commit edca0390) closes the gap by calling _validate_acme_url() whenever options is provided on an update, mirroring the check that already existed on the POST creation path. CWE-918 (SSRF) applies because the application makes server-side network requests to a URL that a non-privileged user can fully control.
The fix
Upgrade to Lemur 1.9.3 (commit edca0390f930344d65ff4ca37a669c2320e3dfad). The patch adds an acme_url allowlist check inside the authority update path so that _validate_acme_url() is enforced on both POST and PUT. As a short-term workaround, set ACME_DIRECTORY_HOST_ALLOWLIST explicitly and restrict authority role membership to trusted operators only.
Related research
- high · 7.4CVE-2026-70666CVE-2026-70666: Lemur ACME Client Server-Side Request Forgery via Server-Controlled URLs
- CRITICAL · 9.9CVE-2026-55166CVE-2026-55166: Lemur ACME SSRF + Creator IDOR leads to AWS IAM and PKI key compromise
- high · 7.7CVE-2026-71307CVE-2026-71307: Lemur Authenticated Plaintext Destination Credential Exposure
- high · 8.1CVE-2026-71308CVE-2026-71308: Lemur Unauthorized Certificate Hijack via Unchecked replaces Field