Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/squeeze440/terrapod-poc
Authentification et AutorisationAnalyse des VulnérabilitésExploitationSécurité WebTests d'IntrusionSécurité de la Chaîne LogistiqueArticles et Recherche
GitHubsqueeze440/terrapod-poc

terrapod-PoC

PoC — autorisation manquante sur le magasin d'ancres de confiance GPG à l'échelle de la plateforme dans Terrapod (GHSA-6qrc-597p-mrp9, CVE-2026-87006, CVSS 6.5).

Voir le dépôt
il y a 7 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Terrapod : avis de sécurité

Statut CVE : demandé, en attente d'attribution. Cette découverte est publiée sous GHSA-6qrc-597p-mrp9. À l'attribution de la CVE, ce dépôt est renommé CVE-YYYY-NNNNN-terrapod-PoC et cette bannière est remplacée par le lien CVE.

ChercheurDostxodjayev Abdullox (@squeeze440)
AvisGHSA-6qrc-597p-mrp9
CVSS 3.16.5 (Moyen)
FaiblesseCWE-862, CWE-284

Résumé

L'absence d'autorisation dans l'API de gestion des clés GPG de Terrapod (main @ b36d953, post-v1.3.1) permet à tout principal authentifié — y compris un utilisateur disposant uniquement du rôle intégré everyone et d'aucune attribution de capacité, ou un jeton de runner à portée limitée — de créer et supprimer des entrées dans le magasin d'ancres de confiance GPG à l'échelle de la plateforme, utilisé pour vérifier les signatures de chaque fournisseur publié dans le registre privé, via POST /api/terrapod/v1/gpg-keys et DELETE /api/terrapod/v1/gpg-keys/{key_id}.

Produit

Terrapod (mattrobinsonsre/terrapod) — remplacement auto-hébergé de Terraform Enterprise / HCP Terraform.

Version testée

Commit b36d9535dedc31d85a02093d78f04da748492a2d (main), 10 commits en avance sur le tag de version le plus proche v1.3.1. (v1.3.2 existe en tant que tag mais se situe sur la branche release/v1.3 et n'est pas encore fusionné dans main ; le bug est présent sur les deux.)

CVSS v3.1 estimé

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

PR:L (et non N) : chaque requête nécessite toujours un identifiant valide — une session, un jeton d'API, ou même un jeton de runner à portée d'exécution runtok: — mais pas un identifiant privilégié. I:H/C:N/A:N : le bug permet à un appelant non privilégié de corrompre l'intégrité du magasin d'ancres de confiance partagé du registre (supprimer des clés légitimes, insérer les siennes), mais ne divulgue pas en soi de matériel de clé secrète (les clés privées ne sont jamais sérialisées dans aucune réponse) et ne met pas le service hors ligne.

Détails

services/terrapod/api/routers/gpg_keys.py implémente le CRUD pour les lignes GPGKey — les clés publiques au format ASCII-armored que Terrapod considère comme fiables pour vérifier la signature détachée SHA256SUMS.sig sur chaque version de fournisseur publiée dans le registre privé (services/terrapod/services/registry_provider_service.py:191-201, _verify_and_store_shasums_signature). Chaque route du routeur n'est protégée que par Depends(get_current_user) — c'est-à-dire « un principal authentifié quelconque » — sans aucune vérification de rôle ou de capacité :

  • 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

Les fonctions de service sous-jacentes (services/terrapod/services/gpg_key_service.py:144 create_gpg_key, :316 delete_gpg_key) ne prennent aucun argument d'appelant ou de propriété — GPGKey n'a ni colonne de namespace ni de propriétaire (_gpg_key_to_jsonapi code en dur "namespace": "default" ; le champ namespace accepté à la création est analysé par le modèle de requête mais jamais transmis). L'ensemble des clés est une liste globale et partagée pour toute la plateforme.

Comparez cela avec toutes les autres ressources de plateforme détenues par l'administrateur dans le même codebase — tokens.py, roles.py, vcs_connections.py, role_assignments.py — qui protègent toutes les routes de mutation derrière require_admin ou une vérification explicite de propriété bound_to == user.email or is_admin. gpg_keys.py est le seul routeur dans api/routers/ qui gère une ressource critique pour la sécurité à l'échelle de la plateforme sans rien de tout cela.

Chaîne d'impact : get_gpg_key_by_key_id() (registry_provider_service.py:195) effectue une recherche globale et non délimitée — toute clé jamais enregistrée, par n'importe qui, est une ancre de confiance valide pour n'importe quelle publication de fournisseur (c'est intentionnel pour l'enregistrement en libre-service des clés de publication — le message d'erreur indique même add it via /api/terrapod/v1/gpg-keys first). Comme l'enregistrement n'a aucune vérification d'authentification, et que la suppression n'en a aucune non plus :

  1. Tout utilisateur authentifié (ou un jeton de runner divulgué/observé, que require_non_runner existe spécifiquement pour tenir à l'écart des « resource creation and management endpoints » selon sa propre docstring dans services/terrapod/api/dependencies.py:387-400, mais que ce routeur n'utilise jamais) peut supprimer la clé de signature enregistrée de tout autre locataire, brisant la vérification de signature pour chaque version de fournisseur que ce locataire a déjà publiée — une attaque d'intégrité inter-locataires sans aucune relation requise avec le namespace cible.
  2. Le même appelant peut enregistrer une nouvelle clé de confiance, élargissant l'ensemble partagé d'ancres de confiance de la plateforme sans autre barrière que de posséder un identifiant quelconque.

La propre suite de tests du projet documente cette lacune sans la remettre en question — services/tests/api/test_gpg_keys.py construit ses tests de chemin heureux create/delete/revoke avec AuthenticatedUser(roles=["everyone"], ...) (voir _user(), ligne 23, utilisé partout dans TestCreate/TestDelete/TestRevoke) et affirme 201/204 pour cet utilisateur non privilégié — c'est-à-dire que les tests affirment le comportement vulnérable comme correct, ils n'ont simplement jamais été écrits pour demander « everyone devrait-il être autorisé à faire cela ? »

Preuve de concept

Vérifié dynamiquement contre l'application réelle (vrai Postgres + Redis via le propre harnais de tests d'intégration docker-compose.test.yml du projet — aucun mock, aucune modification non liée au code de l'application) :

  1. Écrit services/tests/integration/test_gpg_key_missing_authz_poc.py :
    • test_everyone_role_user_can_delete_admins_signing_key — un admin enregistre une vraie clé publique PGP RSA-2048 via POST /api/terrapod/v1/gpg-keys (201, présence confirmée dans Postgres), puis un second utilisateur authentifié avec roles=["everyone"] uniquement (pas d'admin, aucune attribution de capacité) envoie DELETE /api/terrapod/v1/gpg-keys/{key_id} et cela réussit (204) ; la ligne est confirmée absente de Postgres par la suite.
    • test_everyone_role_user_can_register_new_trusted_key — le même utilisateur non privilégié enregistre une toute nouvelle clé via POST /api/terrapod/v1/gpg-keys (201).
  2. Construit l'image de test et l'a exécutée contre l'infrastructure réelle :
    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
    
    Résultat : — les deux assertions (la suppression non autorisée réussissant, et la ligne disparaissant réellement de la base de données réelle) ont tenu. Capture d'écran : .

Impact

Tout utilisateur authentifié d'une instance Terrapod — quel que soit son rôle, son accès aux workspaces ou ses permissions de registre, jusqu'au rôle intégré non privilégié everyone ou au jeton de runner à portée d'une seule exécution — peut altérer le magasin partagé d'ancres de confiance GPG de la plateforme : supprimer la clé de signature enregistrée d'une autre équipe (brisant la vérification de signature terraform init pour chaque version de fournisseur qu'elle a déjà publiée, à l'échelle de la plateforme) et/ou ajouter de nouvelles clés à l'ensemble de confiance. Cela compromet la garantie de chaîne d'approvisionnement « registre privé de modules + fournisseurs signés GPG » que le projet présente comme une fonctionnalité phare, sans exiger de privilège de workspace ou de registre de la part de l'attaquant.

Faiblesses

  • CWE-862 : Autorisation manquante
  • CWE-284 : Contrôle d'accès inapproprié

Remédiation

Ajouter une barrière de capacité/rôle aux routes de mutation dans services/terrapod/api/routers/gpg_keys.py, en suivant le modèle déjà utilisé par tokens.py/roles.py/vcs_connections.py — par exemple Depends(require_admin) sur create_gpg_key_endpoint, delete_gpg_key_endpoint et revoke_gpg_key_endpoint (revoke est protégé séparément en exigeant un certificat d'auto-révocation valide, mais ne devrait toujours pas être accessible à un appelant arbitraire pour les clés d'autres locataires). list/show présentent un risque moindre (les blocs armor sont des clés publiques par conception) mais devraient probablement aussi exiger au moins require_non_runner par cohérence. Envisager également d'introduire une colonne de namespace/propriétaire sur GPGKey si des clés de publication en libre-service par namespace constituent le modèle prévu, afin qu'un propriétaire de namespace puisse gérer uniquement sa ou ses propres clés plutôt que la liste globale unique.

Crédit : Dostxodjayev Abdullox

Canal de signalement : Conformément à SECURITY.md, ne pas ouvrir d'issue publique. Utiliser le signalement privé de vulnérabilité de GitHub : rendez-vous sur https://github.com/mattrobinsonsre/terrapod/security/advisories/new, cliquez sur « Report a vulnerability », et remplissez la description, les étapes de reproduction et les versions affectées. (Si le PVR n'est pas disponible, la politique indique d'envoyer un courriel directement au mainteneur.)

Télécharger l’outil
2 passed
evidence/gpg_key_authz_poc_run3.png