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
terrapod-PoC — PoC — falta de autorización en el almacén de anclas de confianza GPG de toda la plataforma en Terrapod (GHSA-6qrc-597p-mrp9, CVE-2026-87006, CVSS 6.5). | Kitploit
Herramientas/GitHubGitHub/squeeze440/terrapod-poc
Autenticación y AutorizaciónAnálisis de VulnerabilidadesExplotaciónSeguridad WebPruebas de PenetraciónSeguridad de Cadena de SuministroPapers e Investigación
GitHubsqueeze440/terrapod-poc

terrapod-PoC

PoC — falta de autorización en el almacén de anclas de confianza GPG de toda la plataforma en Terrapod (GHSA-6qrc-597p-mrp9, CVE-2026-87006, CVSS 6.5).

Ver Repositorio
hace 7 díasAú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

Terrapod: aviso de seguridad

Estado del CVE: solicitado, pendiente de asignación. Este hallazgo se publica como GHSA-6qrc-597p-mrp9. Tras la asignación del CVE, este repositorio se renombra CVE-YYYY-NNNNN-terrapod-PoC y este banner se reemplaza con el enlace del CVE.

InvestigadorDostxodjayev Abdullox (@squeeze440)
AvisoGHSA-6qrc-597p-mrp9
CVSS 3.16.5 (Medio)
DebilidadCWE-862, CWE-284

Resumen

La falta de autorización en la API de gestión de claves GPG de Terrapod (main @ b36d953, posterior a v1.3.1) permite a cualquier principal autenticado —incluido un usuario con solo el rol integrado everyone y sin ninguna concesión de capacidades, o un token de runner con alcance limitado— crear y eliminar entradas en el almacén de anclas de confianza GPG de toda la plataforma, utilizado para verificar las firmas de todos los proveedores publicados en el registro privado, a través de POST /api/terrapod/v1/gpg-keys y DELETE /api/terrapod/v1/gpg-keys/{key_id}.

Producto

Terrapod (mattrobinsonsre/terrapod) — reemplazo autoalojado de Terraform Enterprise / HCP Terraform.

Versión probada

Commit b36d9535dedc31d85a02093d78f04da748492a2d (main), 10 commits por delante de la etiqueta de versión más cercana v1.3.1. (v1.3.2 existe como etiqueta pero se encuentra en la rama release/v1.3 y aún no se ha fusionado en main; el error está presente en ambas.)

CVSS v3.1 estimado

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N — 6.4 (Medio)

PR:L (no N): toda solicitud sigue necesitando una credencial válida —una sesión, un token de API o incluso un token de runner con alcance de ejecución runtok:—, solo que no una privilegiada. I:H/C:N/A:N: el error permite a un llamador sin privilegios corromper la integridad del almacén compartido de claves de firma del registro (eliminar claves legítimas, insertar las propias), pero no revela por sí mismo material de clave secreta (las claves privadas nunca se serializan en ninguna respuesta) ni deja el servicio fuera de línea.

Detalles

services/terrapod/api/routers/gpg_keys.py implementa el CRUD de las filas GPGKey —las claves públicas con armadura ASCII que Terrapod confía para verificar la firma separada SHA256SUMS.sig en cada versión de proveedor publicada en el registro privado (services/terrapod/services/registry_provider_service.py:191-201, _verify_and_store_shasums_signature). Todas las rutas del router están protegidas únicamente por Depends(get_current_user) —es decir, "algún principal autenticado"— sin ninguna comprobación de rol o capacidad:

  • create_gpg_key_endpoint — services/terrapod/api/routers/gpg_keys.py:104-130
  • list_gpg_keys_endpoint — gpg_keys.py:133-146
  • show_gpg_key_endpoint — gpg_keys.py:149-166
  • revoke_gpg_key_endpoint — gpg_keys.py:168-193
  • delete_gpg_key_endpoint — gpg_keys.py:195-213

Las funciones de servicio subyacentes (services/terrapod/services/gpg_key_service.py:144 create_gpg_key, :316 delete_gpg_key) no reciben ningún argumento de llamador/propiedad —GPGKey no tiene columna de espacio de nombres ni de propietario (_gpg_key_to_jsonapi codifica de forma fija "namespace": "default"; el campo namespace aceptado en la creación es analizado por el modelo de solicitud pero nunca se transmite). El conjunto de claves es una única lista global y compartida para toda la plataforma.

Compárese con todos los demás recursos de plataforma propiedad del administrador en el mismo código base —tokens.py, roles.py, vcs_connections.py, role_assignments.py—, que protegen todas las rutas mutadoras detrás de require_admin o de una comprobación explícita de propiedad bound_to == user.email or is_admin. gpg_keys.py es el único router en api/routers/ que gestiona un recurso crítico para la seguridad de toda la plataforma sin nada de eso.

Cadena de impacto: get_gpg_key_by_key_id() (registry_provider_service.py:195) realiza una búsqueda global y sin alcance —cualquier clave registrada alguna vez, por quien sea, es un ancla de confianza válida para cualquier publicación de proveedor (esto es por diseño para el registro de claves de publicador de autoservicio— el mensaje de error incluso dice add it via /api/terrapod/v1/gpg-keys first). Dado que el registro no tiene comprobación de autenticación, y la eliminación tampoco:

  1. Cualquier usuario autenticado (o un token de runner filtrado/observado, que require_non_runner existe específicamente para mantener fuera de los "endpoints de creación y gestión de recursos" según su propia docstring en services/terrapod/api/dependencies.py:387-400, pero que este router nunca utiliza) puede eliminar la clave de firma registrada de cualquier otro inquilino, rompiendo la verificación de firma de todas las versiones de proveedor que ese inquilino ya publicó —un ataque de integridad entre inquilinos que no requiere ninguna relación con el espacio de nombres objetivo.
  2. El mismo llamador puede registrar una nueva clave de confianza, ampliando el conjunto compartido de anclas de confianza de la plataforma sin más puerta que disponer de cualquier credencial.

La propia suite de pruebas del proyecto documenta esta laguna sin cuestionarla —services/tests/api/test_gpg_keys.py construye sus pruebas de camino feliz de creación/eliminación/revocación con AuthenticatedUser(roles=["everyone"], ...) (véase _user(), línea 23, usado en todo TestCreate/TestDelete/TestRevoke) y afirma 201/204 para ese usuario sin privilegios—, es decir, las pruebas afirman el comportamiento vulnerable como correcto, simplemente nunca se escribieron para preguntar "¿debería permitirse a everyone hacer esto?"

Prueba de concepto

Verificado dinámicamente contra la aplicación real (Postgres + Redis reales mediante el propio arnés de pruebas de integración docker-compose.test.yml del proyecto —sin mocks, sin modificaciones ajenas al código de la aplicación):

  1. Se escribió services/tests/integration/test_gpg_key_missing_authz_poc.py:
    • test_everyone_role_user_can_delete_admins_signing_key — un admin registra una clave pública PGP RSA-2048 real mediante POST /api/terrapod/v1/gpg-keys (201, confirmada presente en Postgres), luego un segundo usuario autenticado solo con roles=["everyone"] (sin admin, sin concesiones de capacidades) envía DELETE /api/terrapod/v1/gpg-keys/{key_id} y tiene éxito (204); se confirma después que la fila ha desaparecido de Postgres.
    • test_everyone_role_user_can_register_new_trusted_key — el mismo usuario sin privilegios registra una clave completamente nueva mediante POST /api/terrapod/v1/gpg-keys (201).
  2. Se construyó la imagen de prueba y se ejecutó contra infraestructura real:
    root@kitploit:~
    docker build -f docker/Dockerfile.test -t terrapod-test:local .
    docker compose -f docker-compose.test.yml run --rm test \
      pytest tests/integration/test_gpg_key_missing_authz_poc.py -v -m integration
    
    Resultado: — ambas afirmaciones (la eliminación no autorizada con éxito y la desaparición real de la fila de la base de datos real) se cumplieron. Captura de pantalla: .

Impacto

Cualquier usuario autenticado de una instancia de Terrapod —independientemente de su rol, acceso al workspace o permisos de registro, hasta el rol integrado sin privilegios everyone o el token de runner con alcance de una sola ejecución— puede manipular el almacén compartido de anclas de confianza GPG de la plataforma: eliminar la clave de firma registrada de otro equipo (rompiendo la verificación de firma de terraform init para todas las versiones de proveedor que ya publicó, en toda la plataforma) y/o añadir nuevas claves al conjunto de confianza. Esto socava la garantía de cadena de suministro de "registro privado de módulos + proveedores firmados con GPG" que el proyecto anuncia como característica destacada, sin requerir ningún privilegio de workspace o registro por parte del atacante.

Debilidades

  • CWE-862: Falta de autorización
  • CWE-284: Control de acceso inadecuado

Remediación

Añadir una puerta de capacidad/rol a las rutas mutadoras en services/terrapod/api/routers/gpg_keys.py, siguiendo el patrón ya utilizado por tokens.py/roles.py/vcs_connections.py —por ejemplo, Depends(require_admin) en create_gpg_key_endpoint, delete_gpg_key_endpoint y revoke_gpg_key_endpoint (revoke está protegido por separado al requerir un certificado de autorrevocación válido, pero aun así no debería ser accesible por un llamador arbitrario para las claves de otros inquilinos). list/show tienen menor riesgo (los bloques con armadura son claves públicas por diseño), pero probablemente también deberían requerir al menos require_non_runner por coherencia. Considérese también introducir una columna de espacio de nombres/propietario en GPGKey si el modelo previsto son claves de publicador de autoservicio por espacio de nombres, de modo que el propietario de un espacio de nombres pueda gestionar solo su(s) propia(s) clave(s) en lugar de la única lista global.

Crédito: Dostxodjayev Abdullox

Canal de notificación: Según SECURITY.md, no abrir un issue público. Utilizar el informe privado de vulnerabilidades de GitHub: ir a https://github.com/mattrobinsonsre/terrapod/security/advisories/new, hacer clic en "Report a vulnerability" y rellenar la descripción, los pasos para reproducir y las versiones afectadas. (Si el PVR no está disponible, la política indica enviar un correo electrónico directamente al mantenedor).

Descargar herramienta
2 passed
evidence/gpg_key_authz_poc_run3.png