Releases: Netflix/lemur
Release list
v1.9.3
- 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
v1.9.2
- Fixed ACME
acme_urlSSRF (GHSA-v2wp-frmc-5q3v_) where a user-supplied directory URL was fetched
server-side with no validation, allowing IMDS and internal network access.acme_urlis now validated
againstACME_DIRECTORY_HOST_ALLOWLISTat authority creation time. Default allowlist covers Let's Encrypt
prod/staging and GTS; operators extend it via config for internal or additional ACME CAs. - Enhanced private key export audit log (
GHSA-v2wp-frmc-5q3v_) to recordaccess_via(creator vs. rbac),
creator_id, andcurrent_owneron every/certificates/<id>/keyfetch, making post-ownership-transfer
creator access visible in the audit trail. - Fixed JWT algorithm confusion vulnerability (
GHSA-r9gp-7f88-9r54_) where the JWT verifier accepted the
algorithm name from the unverified token header instead of pinning it server-side. The server now reads
the accepted algorithm list fromLEMUR_TOKEN_ALGORITHMS(defaults to["HS256"], which is the only
algorithm Lemur has ever used to issue tokens). Deployments that have not changed the default are fully
backward-compatible with no config change required. - Fixed post-authentication SSRF (
GHSA-54vg-pfh7-jq95_) where CRL Distribution Point and OCSP responder URLs
extracted from uploaded certificate extensions were used as network destinations without validation. Both
crl_verifyandocsp_verifynow reject RFC1918, loopback, and link-local destinations before issuing
outbound requests. Operators may optionally configureLEMUR_TRUSTED_CRL_HOSTSandLEMUR_TRUSTED_OCSP_HOSTS
allowlists. The module-levelcrl_cacheis now bounded to 1000 entries to prevent unbounded cache growth. - Fixed plaintext password storage vulnerability (
GHSA-q437-g7fv-2jvv_) where
users.service.update()wrote new passwords to the database without hashing. The
before_updateSQLAlchemy event listener was missing, so the bcrypt hash applied
on insert was bypassed on every admin-driven password reset viaPUT /api/1/users/<id>.
Passwords are now hashed before update. Any reset password should be treated
as compromised and rotated. Runlemur rehash_passwordsafter upgrading to
detect and re-hash any cleartext passwords already in the database. - Fixed privilege escalation (
GHSA-x3vf-mgxj-7785_) where any member of a role could rewrite that role's membership
list, rename the role, or add arbitrary users viaPUT /api/1/roles/<id>. The endpoint now requires admin
permission, consistent with the existingDELETE /api/1/roles/<id>handler. - Corrected the GHSA-qcqw-jwxc-2hqg fix from 1.9.1. The original fix changed
LEMUR_STRICT_ROLE_ENFORCEMENTto
defaultTrue, which broke normal user operations (certificate issuance, notification management, etc.) for
any deployment where users are assigned custom group roles rather than the built-inadminoroperator
roles. By design, Lemur allows any authenticated user to perform write operations; theread-onlyrole is an
explicit opt-in restriction for users who should only have read access. The correct fix targets only that case:
StrictRolePermissionnow explicitly denies identities carrying theread-onlyrole, regardless of the flag
value, while permitting all other authenticated users.LEMUR_STRICT_ROLE_ENFORCEMENTis reverted to default
False; setting it toTruerestricts write access toadminandoperatoronly, as before.
ADMIN_ONLY_AUTHORITY_CREATIONremainsTrue(authority creation is an admin action).
Note that by design, any authenticated user (not assignedread-only) retains write access
to notifications, certificate upload, and domain management. Operators in higher-risk environments
should evaluateLEMUR_STRICT_ROLE_ENFORCEMENT = Trueto restrict these operations toadmin
andoperatorusers. See theLEMUR_STRICT_ROLE_ENFORCEMENTdocumentation for details.
.. _GHSA-v2wp-frmc-5q3v: GHSA-v2wp-frmc-5q3v
.. _GHSA-54vg-pfh7-jq95: GHSA-54vg-pfh7-jq95
.. _GHSA-r9gp-7f88-9r54: GHSA-r9gp-7f88-9r54
.. _GHSA-q437-g7fv-2jvv: GHSA-q437-g7fv-2jvv
.. _GHSA-x3vf-mgxj-7785: GHSA-x3vf-mgxj-7785
v1.9.1
- Fixed authorization bypass (GHSA-qcqw-jwxc-2hqg) where
StrictRolePermissionandAuthorityCreatorPermission
granted access to any authenticated user on default Lemur installs. BothLEMUR_STRICT_ROLE_ENFORCEMENTand
ADMIN_ONLY_AUTHORITY_CREATIONnow default toTrue(fail-closed). Existing installs that explicitly set
either flag toFalseare unaffected.
v1.9.0
This release contains fixes for two security vulnerabilities (GHSA-3r34-vq8m-39gh, GHSA-vr7c-r5gj-j3w5).
- Fixed a bug where the old certificate was not removed from an endpoint after rotation.
- Added GcsDestinationPlugin, which allows uploading certificates to Google Cloud Storage.
- Fixed a bug where rotation notifications did not include endpoint context.
- Fixed AttributeError when running lemur CLI commands without a config file.
- Added ENABLE_AUTOROTATION_FILTER: a configurable, plugin-independent callback that can be used to skip enabling autorotate based on your specific business logic. For example, you could disallow enabling autorotate on certs with notifications disabled.
- Added REISSUE_FILTER: a configurable, plugin-independent callback that can be used to reject reissuance requests based on your specific business logic. For example, you could disallow reissuing certs on abandoned ELBs.
- Added AWS_ELB_IGNORE_TAGS to allow multiple ELB tags to be ignored.
- Added support for ignoring CloudFront distributions and IAM certificates via the AWS_CLOUDFRONT_IGNORE_TAGS and AWS_IAM_IGNORE_TAGS config options.
- Added ENABLE_AUTO_ROTATE_ALL_AUTHORITIES configuration to allow all authorities to be considered for destination autorotate task.
- Added CERTIFICATE_UPDATE_REQUEST_VALIDATION: a configurable, plugin-independent callback that can be used to reject requests based on your specific business logic. For example, you could disallow certs with rotate set and no destinations to reduce volume of unused certs.
- Added CERTIFICATE_CREATE_REQUEST_VALIDATION: a configurable, plugin-independent callback that can be used to reject requests based on your specific business logic. For example, you could disallow certs with rotate set and no destinations to reduce volume of unused certs.
- Added CERTIFICATE_EXPORT_KEY_REQUEST_VALIDATION: a configurable, plugin-independent callback that can be used to reject private key export requests based on your specific business logic. For example, you could block specific API keys from exporting private keys for migrated certificates.
- Added the disable_autorotate_without_endpoint celery task, along with a customizable DISABLE_AUTOROTATION_FILTER function you can use to determine when to disable autorotate. By default, nothing will be changed by this task when scheduled.
- Added a new API endpoint /certificates/{certificate_id}/description for updating just the description field of a certificate, avoiding the need to provide the full certificate object for simple description updates.
- Removed support for Postgres 12, Postgres 15, Python 3.9, and Ubuntu 20.04. Added support for Postgres 16.
v1.8.2
What's Changed
- Bump requests from 2.31.0 to 2.32.0 by @dependabot in #4858
- Correct publishing workflow by @jtschladen in #4857
- Correct Route53 DNS zone bug by @jtschladen in #4859
- Bump types-paramiko from 3.4.0.20240311 to 3.4.0.20240423 by @dependabot in #4865
- Bump freezegun from 1.5.0 to 1.5.1 by @dependabot in #4860
- Bump flask-mail from 0.9.1 to 0.10.0 by @dependabot in #4863
- Bump flask-limiter from 3.6.0 to 3.7.0 by @dependabot in #4864
- Bump actions/upload-artifact from 3 to 4 by @dependabot in #4862
- Bump actions/download-artifact from 3 to 4 by @dependabot in #4861
- Bump faker from 25.0.1 to 25.4.0 by @dependabot in #4866
- Better default for CIS create authority endpoint by @jmcrawford45 in #4869
- Bump pre-commit from 3.7.0 to 3.7.1 by @dependabot in #4870
- Bump certifi from 2024.2.2 to 2024.6.2 by @dependabot in #4871
- Bump boto3 from 1.34.84 to 1.34.122 by @dependabot in #4874
- Bump acme from 2.10.0 to 2.11.0 by @dependabot in #4873
- Bump validators from 0.28.1 to 0.28.3 by @dependabot in #4867
- Prep release by @jmcrawford45 in #4875
Full Changelog: v1.8.1...v1.8.2
v1.8.1 Release
See the CHANGELOG for more details.
v1.8.0 Release
See the CHANGELOG for more details.
v 1.7.0 release
See the CHANGELOG for more details.
v 1.6.0 release
See the CHANGELOG for more details.
v1.5.0 Release
See the CHANGELOG for more details.