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
alibi — Recoupez les vues de votre surface d'attaque et identifiez les points de terminaison qui ne peuvent pas se corroborer mutuellement. | Kitploit
Outils/GitHubGitHub/owasp-noir/alibi
Outils DéfensifsReconnaissanceAnalyse StatiqueAnalyse des VulnérabilitésAnalyse de CodeAudit de ConfigurationCollecte d'InformationsSécurité WebDevSecOpsSécurité des API
GitHubowasp-noir/alibi

alibi

1012il y a 2 joursPas encore vérifié

Recoupez les vues de votre surface d'attaque et identifiez les points de terminaison qui ne peuvent pas se corroborer mutuellement.

Voir le dépôt

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

alibi

Recoupez les vues de votre surface d'attaque et trouvez les endpoints qui ne peuvent pas se corroborer mutuellement.

Un endpoint devrait pouvoir rendre compte de lui-même. Il est dans le code, donc un contrat devrait le décrire. Il est dans le contrat, donc quelque chose devrait l'implémenter. Il reçoit du trafic réel, donc il ferait mieux d'exister quelque part. Quand une vue connaît un endpoint et que les autres non, cet écart est le constat.

alibi exécute OWASP noir, lit son JSON et compare les vues entre elles.

Pourquoi c'est un outil séparé

Noir lit déjà cinq vues indépendantes de la même surface :

VueLue depuis
codeplus de 200 analyseurs couvrant 33 langages
docOpenAPI, RAML, WSDL, GraphQL SDL, AsyncAPI, gRPC, Smithy, TypeSpec, OData, OpenRPC
trafficHAR, mitmproxy, Burp, Caido, ZAP, Postman, Insomnia, Bruno, .http
gatewaynginx, Apache, Envoy, Kong, Traefik, APISIX, Caddy, Istio, Kubernetes Ingress et Gateway API
infraTerraform, CloudFormation, CDK, Serverless, Vercel, Netlify, Wrangler, Azure Functions, Kamal

Ce qu'il ne fait pas, c'est les comparer. C'est tout le travail ici, et cela ne nécessite aucune modification de noir — alibi l'exécute une fois par vue et joint les résultats.

La partie par vue est importante. Noir déduplique par (method, url) à travers tous les analyseurs, donc une route Flask et un chemin OpenAPI orthographiés identiquement fusionnent en un seul endpoint portant une seule technologie. C'est correct pour un outil de découverte — c'est un seul endpoint — mais cela efface la corroboration que cet outil est conçu pour mesurer, et l'efface dans la pire direction possible : mieux deux vues s'accordent, plus elles disparaissent. Casdoor se scanne comme 372 endpoints de code et 9 documentés ; scannez son répertoire swagger/ seul et la spécification en compte 235.

--only-techs restreint le pool de détecteurs, donc un scan par vue garde chacune entière. Quelle technologie parle pour quelle vue, c'est views.yml ; quelles technologies existent, c'est ce que rapporte noir list techs.

alibi ne parse aucun format d'API par lui-même. Sa seule entrée est le JSON de noir.

Installation

Nécessite noir 1.0.0 ou plus récent dans le PATH — c'est la version où noir list techs est devenu une sous-commande, et ce catalogue est ce qui assigne chaque technologie à une vue. Le développement suit la version actuelle de noir. Un binaire plus ancien est refusé par son nom plutôt que laissé échouer à sa première lecture de catalogue.

root@kitploit:~
$ uv tool install noir-alibi     # or: pipx install noir-alibi
$ alibi scan ./my-service

Utilisation

root@kitploit:~
$ alibi scan                                      # the working directory
$ alibi scan ./service ./contracts ./prod.har     # or wherever the views live

Chaque chemin est une source, scannée une fois par vue. Pointez-le vers ce que vous avez — une arborescence de sources, un répertoire de spécifications, un seul fichier de capture — et les vues qui vous manquent désactivent leurs règles plutôt que d'inonder le rapport.

root@kitploit:~
alibi  ·  1 source  ·  377 endpoints

  code 372   doc 235

  230 corroborated -- vouched for by more than one view

  19 endpoints nearly matched another view -- these may be matching failures, not real gaps

SHADOW  Shadow API -- Implemented, but no contract describes it
  134 findings  ·  4 critical, 57 high, 62 medium, 11 low

  critical POST    /api/upload-groups        router.go:87
           upload paths carry more consequence than reads
  critical POST    /api/upload-permissions   router.go:208
  ...
  ... and 122 more (SHADOW in full: -f json)

TWO SURFACES?
  The doc view is 97% under /api, and 37 of these findings are outside it.
  If that is a separate surface the contract never covered, narrow the scan:
    alibi scan <paths> --ignore '^/(?!api(/|$))'
  If it is the same surface left undocumented, they are the findings that matter most.

Les groupes s'arrêtent à douze — l'ordre va du pire au meilleur, donc la queue est la partie la moins informative, et -f json contient tout.

En CI

root@kitploit:~
- run: alibi scan . ./contracts -f sarif > alibi.sarif
- uses: github/codeql-action/upload-sarif@v3
  with: { sarif_file: alibi.sarif }

Voir ce que chaque vue contenait

Le rapport dit que les vues divergent ; --endpoints dit ce que chacune d'elles contenait.

root@kitploit:~
$ alibi scan ./repo -f json --endpoints

Chaque vue obtient une liste : la clé, quelles vues l'ont corroborée, les technologies derrière elle, les fichiers, et l'orthographe avant normalisation — ce qui est là où la différence se trouve toujours quand deux lignes auraient dû correspondre et ne l'ont pas fait. C'est trois à quatre fois le reste de la charge utile, donc c'est un flag plutôt que le comportement par défaut.

Ou filtrez directement : alibi scan . ./contracts --fail-on high sort avec un code non nul quand un constat atteint cette sévérité. Un scan que noir n'a pas pu lire entièrement rapporte executionSuccessful: false, donc une exécution dégradée ne passe pas pour une exécution propre.

Comment les endpoints sont mis en correspondance

Noir conserve la syntaxe de route propre à chaque framework plutôt que d'en inventer une commune, donc le même endpoint arrive orthographié de plusieurs façons :

root@kitploit:~
python_flask   /api/users/<int:user_id>
aiohttp        /users/{id}
java_spring    /api/catalog/{id}
oas3           /v1/pets/{petId}
rails          /posts/:id
nginx          /admin/.*

La règle qui les rend comparables : le nom d'un paramètre de chemin ne fait pas partie de son identité. {petId} et <int:user_id> décrivent le même emplacement ; seuls sa position et le fait qu'il couvre ou non un / importent. Les noms sont conservés comme preuve et rapportés, mais n'atteignent jamais la clé.

Les constats indiquent comment la correspondance a été faite :

GradeSignification
G1les orthographes concordaient déjà
G2elles concordent une fois la syntaxe des paramètres normalisée
G0une seule vue le possède — rien n'a été mis en correspondance

Ce qui le garde honnête

Un outil comme celui-ci meurt en rapportant des centaines de constats à sa première exécution, ou en rapportant des progrès que personne n'a faits. Six choses s'y opposent :

Les règles ne se déclenchent pas sans les deux vues. Scannez une base de code sans aucun contrat nulle part et chaque endpoint se qualifie techniquement comme une shadow API non documentée. Ces constats ne disent rien d'autre que le fait que vous n'avez fourni aucune documentation, donc une règle ne s'exécute que quand chaque vue sur laquelle elle raisonne était réellement dans le scan. Le rapport nomme les règles qui sont restées à l'écart.

Les quasi-correspondances sont rapportées comme un doute, pas comme des constats. « Dans le code, pas dans la doc » est indiscernable de « dans les deux, mais alibi a échoué à les aligner ». Donc un endpoint qui atterrit dans une vue est vérifié contre les autres pour une quasi- correspondance — même chemin avec un verbe différent, ou à un segment près là où un côté a un paramètre et l'autre un littéral. Les constats portant une quasi-correspondance sont rétrogradés et signalés pour revue. Ce compte se trouve à côté des totaux, parce que chaque constat n'est fiable que dans la mesure où il est petit.

Des vues qui ne se sont jamais rencontrées sont un diagnostic, pas des centaines de constats. Argo CD enregistre /api en Go et documente 198 chemins en dessous, donc son code et sa spécification ne partagent pas un seul endpoint. Lu littéralement, cela fait 58 shadow APIs et 198 contrats fantômes, aucun d'entre eux réel. Zéro corroboration entre deux vues peuplées signifie que la comparaison n'a pas fonctionné — un point de montage qui tient lieu des routes en dessous, ou une stack que noir n'a pas pu lire — donc les règles sont retenues et la raison est imprimée à la place. Les chemins qui s'avèrent avoir de nombreux endpoints d'autres vues en dessous sont étiquetés comme points de montage probables.

Quand les deux vues s'alignent une fois qu'un préfixe constant est retiré de l'une d'elles, le diagnostic le dit et nomme le préfixe. La spécification générée de Gitea déclare basePath: /GITEA-API-APP-SUBURL/api/v1 tandis que son routeur Go monte /api/v1 ; les vues ne partagent rien, mais 154 des 535 chemins documentés correspondent à un chemin de code une fois ces trois segments retirés. C'est un basePath de spec, un servers[].url, ou un point de montage que le lecteur de code a abandonné — et c'est rapporté, jamais appliqué, parce que réaligner les chemins masquerait le bug qu'il a trouvé.

Un flot qui est en réalité un seul sous-arbre manquant est nommé comme tel : 207 des 354 contrats fantômes de NodeBB se trouvent sous /api/v3, où la vue code ne contient rien du tout.

Une vue manquante et une vue vide signifient des choses opposées. Noir rapporte ce qu'il n'a pas pu lire, et alibi l'imprime au-dessus des constats. NetBox livre un document OpenAPI de 12,35 Mo avec 308 chemins ; noir l'ignore pour dépassement de sa limite de taille de fichier, et sans ce rapport alibi déclare que le projet ne documente rien — pas simplement incomplet, mais la mauvaise réponse énoncée avec assurance.

Une règle qui a cessé de s'exécuter n'a rien résolu. Enregistrer des scans et les comparer réintroduit la même erreur à distance : oubliez le répertoire de contrats lors d'une exécution et SHADOW n'évalue rien, ce qui pour une différence naïve ressemble exactement à la fermeture de toutes les shadow APIs. Sur le fixture à cinq vues, retirer un argument a transformé sept constats persistants en « résolus ». Les instantanés enregistrent quelles règles ont été évaluées, les différences ne considèrent que les règles qui se sont exécutées dans les deux scans, et le reste est nommé sous NOT COMPARED.

Une absence n'est une preuve que quand le signal existe. Les tagueurs d'auth de Noir couvrent les frameworks qu'ils connaissent. Dans une stack qu'ils ne couvrent pas, rien ne porte de tag d'auth, et traiter cela comme « non authentifié » promeut chaque constat et vide la colonne de sévérité de son sens. Les ajustements qui se déclenchent sur un tag manquant exigent que ce tag apparaisse quelque part dans le scan au préalable.

Règles

RègleConditionSévérité
ORPHANreçoit de vraies requêtes, absent du codehigh
LIVE_UNDOCreçoit de vraies requêtes, décrit par aucun contrathigh
SHADOWdans le code, dans aucun contratmedium
DANGLINGune règle de gateway qui n'atteint rien d'implémentémedium
DRIFTdéclaré pour le déploiement, absent du codemedium
PHANTOMdans un contrat, pas dans le codelow
UNEXPOSEDimplémenté, mais aucune règle de gateway ne l'atteintlow
COLDimplémenté, jamais vu recevant une requêteinfo

La sévérité évolue ensuite selon ce que les tagueurs de noir ont trouvé : données personnelles, uploads de fichiers, aucun signe d'authentification, ou une méthode qui change l'état.

La carte des vues (views.yml) et les règles (rules.yml) sont des données, pas du code.

Les gateways ne sont pas des listes d'endpoints

Un seul location /api/ représente tout ce qui se trouve en dessous, donc les règles de gateway et d'infrastructure répondent à est-ce que ceci atteint cet endpoint plutôt qu'à est-ce que ceci le contient. Comparées comme des ensembles, chaque règle de préfixe ressemble à une route que personne n'a implémentée et chaque route implémentée semble inatteignable.

La couverture est délibérément généreuse. Noir rapporte le chemin qu'une règle correspond mais pas si elle correspond comme préfixe ou exactement (location = /x, un Ingress pathType: Exact), donc l'exactitude ne peut pas être récupérée — et traiter chaque règle comme un préfixe supprime des constats plutôt que d'en inventer.

Le rapport indique quelle proportion du code chaque vue de routage atteint, parce que savoir si « 34 endpoints qu'aucun gateway n'atteint » est réel dépend de si cette config est celle qui front le service. Aucun seuil ne sépare cela honnêtement : le fixture de test e2e d'Argo CD atteint 39 % de son code et la vraie config de NetBox atteint 100 %.

Un catch-all — location /, un Ingress à /, un RewriteRule ^(.*)$ — n'est pas une preuve dans un sens ou dans l'autre. Il route tout ou rien, pareil pour chaque endpoint, donc il compte comme n'en atteignant aucun. Une vue gateway ne contenant rien d'autre n'a aucun signal à offrir, et UNEXPOSED reste à l'écart et le dit plutôt que de rapporter chaque endpoint comme inatteignable. Le chart Helm de Casdoor est exactement cela : une règle Ingress à /, qui lue comme preuve a produit 365 constats.

Le trafic doit avoir été observé

Une capture HAR enregistre des requêtes qui ont eu lieu. Une collection Postman enregistre des requêtes que quelqu'un avait l'intention de faire. ORPHAN, LIVE_UNDOC et COLD raisonnent tous sur ce qui s'est exécuté, donc ils exigent une vue que quelqu'un a réellement observée et le disent quand ils restent à l'écart.

La surface non-web reste dehors

Noir rapporte les arguments CLI, les topics Kafka et les deep links mobiles dans la même liste. cli://gitops-engine/agent aplati en HTTP devient /agent — il entre en collision avec toute route web de ce nom et on lui demande si un gateway route vers lui. Le protocole fait partie de l'identité de l'endpoint ; http et https sont un seul espace et tout le reste garde le sien.

Suppression

Certains écarts sont l'état voulu. Placez un .alibi.yml à côté de la source :

root@kitploit:~
ignore:
  - path: "^/internal/"
    why: internal-only admin surface
  - rule: UNEXPOSED
    path: "^/debug/"
    why: not fronted by the gateway in this repo

Ou passez --ignore REGEX pour un cas ponctuel. Les constats supprimés sont comptés et le compte est imprimé — un outil qui abandonne discrètement des constats est pire qu'un qui en imprime trop, parce qu'il n'y a plus aucun moyen de savoir ce qu'il a retenu.

Statut

Précoce, mais les cinq vues sont comparées.

Mesuré sur cinq dépôts :

Dépôtcodedoccorroboréconstatscode↔doc
casdoor372235230 (98%)139comparé
netbox11461193796 (67%)746comparé
argo-cd59198131retenu
authentik23111931192retenu
flipt24200retenu

Casdoor est le cas le plus propre : 230 de ses 235 endpoints documentés correspondaient au code, sans aucun échec de normalisation de chemin. Les 19 quasi-correspondances étaient le même chemin sous un verbe différent — noir enregistrant chaque méthode sur un handler catch-all Go, pas un problème de correspondance.

NetBox est le cas instructif. Il contient deux surfaces dans un seul dépôt : une interface web rendue côté serveur et une API REST DRF-router que seule la seconde est documentée. Scanné en entier, il rapporte 746 constats, la plupart étant l'observation vraie mais inutile qu'une interface web n'est pas dans une spécification d'API. Restreint à la surface que le contrat décrit, il se réduit à ce qui valait réellement la peine d'être dit :

root@kitploit:~
$ alibi scan ./netbox --ignore '^/(?!api(/|$))'

→ 3 shadow APIs : /api/plugins, /api/schema/redoc, /api/schema/swagger-ui, toutes les trois réellement servies et réellement absentes du schéma. Les 397 fantômes qui restent sont les opérations en masse que la propre sous-classe de routeur de NetBox ajoute à chaque endpoint de liste, que nul parcours d'urlconf ne peut voir.

Les trois autres sont retenus, chacun pour une raison qui vaut la peine d'être connue :

  • Argo CD enregistre /api en Go et documente 198 chemins en dessous — la même surface à deux granularités.
  • authentik assemble son URLconf à l'exécution en important le module urls de chaque application installée, ce qu'aucun lecteur statique ne peut suivre.
  • flipt monte un gateway gRPC ; sa source Go contient une seule route. Sa surface HTTP est implémentée dans des annotations .proto, c'est pourquoi grpc parle pour la vue code : classé là, 36 de ses 36 chemins documentés se corroborent.

Ce qui est le plafond de cet outil, dit clairement : il compare ce que noir peut lire, et une vue lue à la mauvaise granularité est pire qu'une vue pas lue du tout. La plupart de la machinerie ci-dessus existe pour distinguer ces cas plutôt que pour les rapporter comme des défauts.

Licence

MIT

Télécharger l’outil