Media

Lemur: Sub-CA creation never checks `AuthorityPermission` on the parent authority

  • Publicada: 18.08.2026
  • Actualizado: 11.10.2026 14:19

Summary

Repo under test: https://github.com/Netflix/lemur

When ADMIN_ONLY_AUTHORITY_CREATION=False (an explicitly supported and documented configuration), POST /api/1/authorities with type=subca never verifies that the caller holds AuthorityPermission on the supplied parent authority. The parent field is resolved by AssociatedAuthoritySchema via a raw fetch_objects(Authority, data) lookup, then passed straight through service.create → mint → cryptography-issuer.create_authority, which loads options["parent"].authority_certificate.private_key and signs a brand-new intermediate CA on the caller's behalf.

Any authenticated non-read-only user can therefore mint a sub-CA chained to any internal root whose private key Lemur holds — including roots they hold no role on — attach a role they already belong to, and immediately issue or offline-sign trusted leaf certificates for arbitrary names.

Affected route

POST /api/1/authorities (with type=subca)

Affected code

Impact

In deployments that set ADMIN_ONLY_AUTHORITY_CREATION=False to enable self-service CA creation, any authenticated non-read-only user — with zero permission on a given internal root CA — can obtain a working intermediate CA chained to that root. They can then:

  • Issue TLS certificates for arbitrary names trusted by every relying party that trusts the internal root, bypassing LEMUR_ALLOWED_DOMAINS, sensitive-domain flags, and the per-user domain-authorization plugin.
  • Export the sub-CA private key and sign end-entity certificates entirely outside Lemur, defeating all in-product issuance controls.

This converts "can create a self-contained test CA" into "can mint trusted certs under any internal PKI root in the organisation". The ADMIN_ONLY_AUTHORITY_CREATION documentation does not warn operators of this consequence.

Root cause

AuthoritiesList.post evaluates AuthorityCreatorPermission (a global "may create authorities" flag) and StrictRolePermission, but never evaluates AuthorityPermission(parent.id, parent.roles) against the caller-supplied parent. AssociatedAuthoritySchema is a pure lookup schema with no authz hook, and neither authorities.service.create nor mint re-check before invoking issuer_plugin.create_authority(options). The bundled cryptography-issuer then uses the parent's stored private key directly.

Validated evidence

Static trace, confirmed by code inspection (validation status: CONFIRMED):

  • parent is loaded via AssociatedAuthoritySchema (raw fetch_objects), passed unchecked through views.post → service.create → mint → plugin.create_authority → issue_certificate, where the parent authority's stored private key is read and used to sign the new intermediate.
  • No call to AuthorityPermission(parent.id, ...) exists anywhere on this path.
  • Precondition ADMIN_ONLY_AUTHORITY_CREATION=False is an explicitly supported config (docs/administration.rst:517).

Proof of concept / reproducer

Status: reconstructed from source report (static control-flow trace; not executed against a live CA).

Preconditions: ADMIN_ONLY_AUTHORITY_CREATION=False; attacker is an authenticated Lemur user holding any role other than read-only; <PARENT_AUTHORITY_ID> is any internal cryptography-issuer root CA the attacker holds no role on; <ATTACKER_ROLE> is any role the attacker already belongs to.

bash
curl -sS -X POST "<TARGET_BASE_URL>/api/1/authorities" \
  -H "Authorization: Bearer <AUTH_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "attacker-subca",
        "owner": "attacker@example.com",
        "description": "poc",
        "type": "subca",
        "parent": {"id": <PARENT_AUTHORITY_ID>},
        "plugin": {"slug": "cryptography-issuer"},
        "roles": [{"name": "<ATTACKER_ROLE>"}],
        "commonName": "attacker-intermediate",
        "validityYears": 1
      }'

The response contains a new authority whose authority_certificate is signed by <PARENT_AUTHORITY_ID>'s private key. The caller is recorded as creator and holds <ATTACKER_ROLE> on it, so POST /api/1/certificates against the new authority succeeds (and skips allowed_issuance_for_domain because is_private_authority is true).

Static-trace validation command from the source report:

bash
grep -n 'parent' lemur/authorities/schemas.py lemur/authorities/views.py lemur/authorities/service.py \
  && sed -n '37,55p' lemur/plugins/lemur_cryptography/plugin.py

Source artifact: audit/harnesses/public-repo-threat-model-harness/results/netflix-lemur-100run-mythos-20260627T051129Z/findings.jsonl (run_022, finding cluster lemur-subca-parent-authz, 5/100 runs).

Suggested fix

In AuthoritiesList.post (or authorities.service.create), when data.get('parent') is present, enforce AuthorityPermission(parent.id, [r.name for r in parent.roles]).can() before invoking the issuer plugin, regardless of ADMIN_ONLY_AUTHORITY_CREATION. Additionally, update the ADMIN_ONLY_AUTHORITY_CREATION documentation to state that disabling it currently grants every authenticated user the ability to chain sub-CAs off any internal root whose private key Lemur holds. Consider also requiring admin (or an explicit per-parent capability) for any type=subca creation independent of the global flag.

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Python (PyPI) lemur < 1.9.3 1.9.3

Referencias

Puntuación CVSS 6.5/10
Vector CVSS
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N
Debilidad (CWE)
CWE-862
Plataforma
Python (PyPI)
Paquete
lemur
Publicada
18.08.2026
Actualizado
11.10.2026 14:19

Fuentes y licencias

OSV / GitHub Advisory Database - PYSEC-2026-3677 - PyPA Advisory Database; CC BY 4.0

OSV / GitHub Advisory Database - GHSA-g7p5-89mh-248h - CC BY 4.0

Historial de vulnerabilidades: lemur

Todas las vulnerabilidades publicadas de este paquete (Python (PyPI)), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (18) en el archivo
Entradas en total
18
Primera → última
08.2017 08.2026
Sin corrección
0
Explotada en ataques
0

Distribución por gravedad

  • Crítica 1
  • Alta 9
  • Media 8

Divulgaciones por año

  1. 2017: 1
  2. 2018: 0
  3. 2019: 0
  4. 2020: 0
  5. 2021: 0
  6. 2022: 0
  7. 2023: 1
  8. 2024: 0
  9. 2025: 0
  10. 2026: 16
Gravedad:
  1. Lemur: Sub-CA creation never checks `AuthorityPermission` on the parent authority esta entrada
    Media · 6.5 CVE-2026-71317 < 1.9.3 1.9.3
  2. Alta · 7.5 CVE-2023-30797 < 1.3.2 1.3.2
  3. Alta · 7.5 CVE-2015-7764 < 0.1.5 0.1.5

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.