- Fixed missing authorization check (
GHSA-4h97-p9wq-chqj_) onPOST /certificates/<id>/exportfor plugins
withrequires_key = False(e.g.java-truststore-jks). The ownership check was previously skipped
entirely for these plugins with no compensating control. Since such plugins never receive the real private
key, any authenticated user may still use them regardless of ownership; plugins withrequires_key = True
continue to require ownership and log akey_viewaudit event, and only they are passedcert.private_key. - Fixed missing authorization on the
replacesfield (GHSA-cfh6-pv5c-38jv_), where any authenticated
caller could reference an arbitrary certificate by ID on certificate create, upload, and edit requests,
silencing its expiration notifications and retargeting its rotation without the owning team's knowledge.
authorize_certificate_replacementnow requires the caller to own or hold a role on every certificate
named inreplaces, consistent with the existing check for direct revoke/edit. Enforcement can be
disabled viaENFORCE_REPLACES_AUTHORIZATION(defaults toTrue) for deployments that need to
temporarily preserve the old behavior while they grant the appropriate role to affected workflows. - Fixed plaintext credential exposure via the destinations API (
GHSA-6c8m-q6g9-vrw3_). Sensitive
destination plugin options (e.g. SFTP password and private key passphrase) were returned in plaintext
to any authenticated caller viaGET /destinations,GET /destinations/<id>, and
GET /certificates/<id>/destinations. Sensitive option values are now redacted for non-admin
callers; admins retain the ability to view and edit them. - Fixed incomplete fix for ACME
acme_urlSSRF (GHSA-v5rc-cpwc-cfpr). The 1.9.2 fix for
GHSA-v2wp-frmc-5q3vvalidatedacme_urlagainstACME_DIRECTORY_HOST_ALLOWLISTonly at
authority creation time. Any user with a role on an existing ACME authority could still overwrite
its storedacme_urlwith an internal/IMDS address viaPUT /api/1/authorities/<id>, since the
update path storedoptionsverbatim with no re-validation. The next certificate issuance via that
authority would then cause Lemur's backend to fetch the attacker-controlled URL.acme_urlis now
also validated against the allowlist on authority update. - Fixed SSRF via ACME client following server-controlled URLs (
GHSA-xpmj-wjcp-6pww_). In addition to
theacme_urlallowlist check above, the ACME client itself no longer trusts hostnames supplied by
the directory/order/authorization/finalize responses returned by the ACME server; outbound requests are
now pinned to the configured, allowlisted directory host, closing a second SSRF vector where a malicious
or compromised ACME server could redirect Lemur's backend to arbitrary internal URLs mid-issuance. - Fixed missing authorization check on sub-CA creation (
GHSA-g7p5-89mh-248h_). When
ADMIN_ONLY_AUTHORITY_CREATIONis disabled,POST /api/1/authoritieswith
type=subcanever verified that the caller holdsAuthorityPermissionon the
supplied parent authority, letting any authenticated non-read-only user mint a sub-CA
chained off any internal root Lemur holds the private key for and issue trusted leaf
certs under it.AuthoritiesList.postnow enforcesAuthorityPermissionon the
parent authority before delegating to the issuer plugin, matching the check already
used when updating an existing authority. - Fixed arbitrary certificate revocation at the CA (
GHSA-pxmc-2ffp-8j67_). Certificate identity was tracked
only by Lemur's internal database row, not by the actual CA-side certificate. Any authenticated user could
upload a duplicate record for a certificate they didn't own (matching an existingauthority_idand
serial) and then revoke it viaPUT /api/1/certificates/<id>/revoke, causing the CA to revoke the
real certificate belonging to another user.POST /api/1/certificates/uploadnow requires
AuthorityPermissionon the specified authority, and rejects uploads whose(authority_id, serial)
pair already matches an existing certificate with a409response.PUT /api/1/certificates/<id>/revoke
now also checks authorization and endpoint attachment against every certificate row sharing
(authority_id, serial)with the one being revoked, not just the row named in the request, closing the
gap for any duplicate rows that already exist.
.. _GHSA-4h97-p9wq-chqj: GHSA-4h97-p9wq-chqj
.. _GHSA-cfh6-pv5c-38jv: GHSA-cfh6-pv5c-38jv
.. _GHSA-6c8m-q6g9-vrw3: GHSA-6c8m-q6g9-vrw3
.. _GHSA-v5rc-cpwc-cfpr: GHSA-v5rc-cpwc-cfpr
.. _GHSA-v2wp-frmc-5q3v: GHSA-v2wp-frmc-5q3v
.. _GHSA-xpmj-wjcp-6pww: GHSA-xpmj-wjcp-6pww
.. _GHSA-g7p5-89mh-248h: GHSA-g7p5-89mh-248h
.. _GHSA-pxmc-2ffp-8j67: GHSA-pxmc-2ffp-8j67