Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
alibi — 攻撃対象領域の見解を相互検証し、互いに裏付けが取れないエンドポイントを見つけ出します。 | Kitploit
ツール/GitHubGitHub/owasp-noir/alibi
防御ツール偵察静的分析脆弱性分析コード分析構成監査情報収集ウェブセキュリティDevSecOpsAPIセキュリティ
GitHubowasp-noir/alibi

alibi

攻撃対象領域の見解を相互検証し、互いに裏付けが取れないエンドポイントを見つけ出します。

10122日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
リポジトリを見る

alibi

攻撃対象面の見え方を相互検証し、互いに裏付けの取れないエンドポイントを見つけ出す。

エンドポイントは自己を説明できるべきである。コードに存在するなら、契約がそれを記述しているはずだ。契約に存在するなら、何かがそれを実装しているはずだ。実際のトラフィックを受けているなら、どこかに存在しているはずだ。ある見え方がエンドポイントを認識しているのに、他の見え方が認識していないとき、そのギャップが発見事項である。

alibi は OWASP noir を実行し、その JSON を読み、各見え方を相互に比較する。

なぜこれが別のツールなのか

Noir はすでに同じ対象面の5つの独立した見え方を読み取る:

見え方読み取り元
code33言語にわたる200以上のアナライザー
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 および Gateway API
infraTerraform、CloudFormation、CDK、Serverless、Vercel、Netlify、Wrangler、Azure Functions、Kamal

それがやらないのは、それらを比較することだ。ここでの仕事はまさにそれであり、noir への変更は一切不要である — alibi は見え方ごとに一度実行し、結果を結合する。

見え方ごとの部分が重要である。Noir はすべてのアナライザーにわたって (method, url) で重複排除するため、同一に綴られた Flask ルートと OpenAPI パスは、1つの技術を持つ1つのエンドポイントに collapse する。これは発見ツールとしては正しい — それは1つのエンドポイントである — が、このツールが測定するために作られた裏付けを消し去り、しかも最悪の方向に消し去る: 2つの見え方が一致するほど、より多くが消えるのだ。Casdoor は372のコードエンドポイントと9の文書化されたエンドポイントとしてスキャンされる; その swagger/ ディレクトリだけをスキャンすると、仕様には235ある。

--only-techs は検出器プールを制限するので、見え方ごとに1回のスキャンでそれぞれを完全に保つことができる。どの技術がどの見え方を代表するかは views.yml であり、どの技術が存在するかは noir list techs が報告するものである。

alibi は独自の API フォーマットを一切パースしない。その唯一の入力は noir の JSON である。

インストール

PATH 上に noir 1.0.0 以降が必要である — これは noir list techs がサブコマンドになったリリースであり、そのカタログがすべての技術をある見え方に割り当てるものである。開発は現在の noir リリースを追跡している。古いバイナリは、最初のカタログ読み取りで失敗させるのではなく、名前を挙げて拒否される。

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

使い方

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

すべてのパスはソースであり、見え方ごとに一度スキャンされる。手持ちのもの — ソースツリー、仕様ディレクトリ、単一のキャプチャファイル — を指定すれば、欠けている見え方はレポートを溢れさせるのではなく、そのルールをオフにする。

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.

グループは12で止まる — 順序は最悪が先なので、末尾は最も情報量の少ない部分であり、-f json にはすべてが含まれる。

CI での利用

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

各見え方が何を保持していたかを見る

レポートは見え方が不一致だと述べる; --endpoints はそれぞれが何を含んでいたかを述べる。

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

すべての見え方がリストを得る: キー、それを裏付けた見え方、その背後の技術、ファイル、そして正規化前の綴り — 2つの行が一致すべきなのに一致しなかったとき、違いは常にそこにある。これはペイロードの残りの3〜4倍の大きさなので、デフォルトではなくフラグである。

あるいは直接ゲートする: alibi scan . ./contracts --fail-on high は、発見事項がその重大度に達したときに非ゼロで終了する。noir が完全に読み取れなかったスキャンは executionSuccessful: false を報告するので、劣化した実行がクリーンなものとして通ることはない。

エンドポイントのマッチング方法

Noir は共通のものを発明するのではなく、各フレームワーク自身のルート構文を保持するため、同じエンドポイントがいくつかの綴りで到着する:

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/.*

これらを比較可能にするルール: パスパラメータの名前はその同一性の一部ではない。 {petId} と <int:user_id> は同じスロットを記述する; 重要なのはその位置と、/ にまたがるかどうかだけである。名前は証拠として保持され報告されるが、キーには決して到達しない。

発見事項はマッチがどのように行われたかを述べる:

グレード意味
G1綴りがすでに一致していた
G2パラメータ構文が正規化されると一致する
G01つの見え方だけが持っている — 何もマッチしなかった

何がこれを誠実に保つか

このようなツールは、初回実行で何百もの発見事項を報告するか、誰も達成していない進捗を報告することで死ぬ。6つのことが反論する:

両方の見え方がなければルールは発火しない。 どこにも契約がないコードベースをスキャンすると、すべてのエンドポイントが技術的には文書化されていないシャドウ API に該当する。それらの発見事項は、あなたが文書を何も提供しなかったこと以外何も述べていないので、ルールはそれが推論するすべての見え方が実際にスキャンに含まれていたときにのみ実行される。レポートは参加しなかったルールを名指しする。

ニアミスは発見事項ではなく疑いとして報告される。 「コードにあるが、ドキュメントにない」は「両方にあるが、alibi がそれらを並べるのに失敗した」と区別がつかない。そこで、ある見え方に落ちたエンドポイントは、他の見え方に対してニアミスがないかチェックされる — 異なる動詞を持つ同じパス、または一方がパラメータで他方がリテラルである1セグメント違い。ニアミスを伴う発見事項は降格され、レビューのためにフラグが立てられる。その数は合計の隣に位置する、なぜならすべての発見事項はそれが小さいほど信頼できるからである。

決して出会わなかった見え方は、何百もの発見事項ではなく1つの診断である。 Argo CD は Go で /api を登録し、その下に198のパスを文書化しているので、そのコードとその仕様は1つのエンドポイントも共有していない。文字通りに読めば、それは58のシャドウ API と198のファントム契約であり、どれも本物ではない。2つの populated な見え方の間のゼロの裏付けは、比較が機能しなかったことを意味する — その下のルートの代わりに立つマウントポイント、または noir が読み取れなかったスタック — なので、ルールは保留され、代わりに理由が出力される。他の見え方からの多くのエンドポイントがその下にあることが判明したパスは、推定マウントとしてラベル付けされる。

2つの見え方が、一方から定数プレフィックスを取り除くと整列するとき、診断はそう述べ、そのプレフィックスを名指しする。Gitea の生成された仕様は basePath: /GITEA-API-APP-SUBURL/api/v1 を宣言する一方、その Go ルーターは /api/v1 をマウントする; 見え方は何も共有しないが、535の文書化されたパスのうち154が、それら3つのセグメントを取り除くとコードパスに一致する。それは仕様の basePath、servers[].url、またはコードリーダーが落としたマウントである — そしてそれは報告され、決して適用されない、なぜならパスを再整列させるとそれが見つけたバグを隠してしまうからである。

本当に1つの欠落したサブツリーである flood は、1つとして名指しされる: NodeBB の354のファントム契約のうち207が /api/v3 の下にあり、そこではコードの見え方は何も保持していない。

欠落した見え方と空の見え方は反対のことを意味する。 Noir は読み取れなかったものを報告し、alibi はそれを発見事項の上に出力する。NetBox は308のパスを持つ12.35MBの OpenAPI ドキュメントを同梱している; noir はファイルサイズ上限を超えたためそれをスキップし、その報告がなければ alibi はプロジェクトが何も文書化していないと述べる — 単に不完全なだけでなく、自信を持って述べられた誤った答えである。

実行を止めたルールは何も解決していない。 スキャンを記録して比較することは、距離を置いて同じ過ちを再導入する: ある実行で contracts ディレクトリを忘れると SHADOW は何も評価しない、それは素朴な差分にはすべてのシャドウ API が閉じられたのと全く同じに見える。5つの見え方のフィクスチャで、1つの引数を落とすと7つの standing な発見事項が「解決済み」になった。スナップショットはどのルールが評価されたかを記録し、差分は両方のスキャンで実行されたルールのみを考慮し、残りは NOT COMPARED の下に名指しされる。

不在は、シグナルが存在するときにのみ証拠となる。 Noir の auth タガーは、それが知っているフレームワークをカバーする。それがカバーしないスタックでは、何も auth タグを持たず、それを「未認証」として扱うとすべての発見事項を昇格させ、重大度の列から意味を排出してしまう。欠落したタグで発火する調整は、そのタグがまずスキャンのどこかに現れることを要求する。

ルール

重大度はその後、noir のタガーが見つけたものに応じて変動する: 個人データ、ファイルアップロード、認証の兆候なし、または状態を変更するメソッド。

見え方マップ (views.yml) とルール (rules.yml) はどちらもコードではなくデータである。

ゲートウェイはエンドポイントリストではない

1つの location /api/ はその下のすべてを代表するので、ゲートウェイとインフラのルールは これがそのエンドポイントに到達するか に答え、これがそれを含むか には答えない。集合として比較すると、すべてのプレフィックスルールは誰も実装していないルートに見え、すべての実装されたルートは到達不能に見える。

カバレッジは意図的に寛容である。Noir はルールがマッチするパスを報告するが、それがプレフィックスとしてマッチするのか正確にマッチするのか (location = /x、Ingress の pathType: Exact) は報告しないので、正確性は回復できない — そしてすべてのルールをプレフィックスとして扱うことは、発見事項を捏造するのではなく抑制する。

レポートは各ルーティング見え方がコードのどれだけに到達するかを述べる、なぜなら「どのゲートウェイも到達しない34のエンドポイント」が本物かどうかは、その設定がサービスを front しているものかどうかに依存するからである。それを誠実に分ける閾値は存在しない: Argo CD の e2e テストフィクスチャはそのコードの39%に到達し、NetBox の実際の設定は100%に到達する。

catch-all — location /、/ の Ingress、RewriteRule ^(.*)$ — はどちらの証拠でもない。それはすべてをルーティングするか何もルーティングしないかで、すべてのエンドポイントに対して同じなので、それらのどれにも到達しないものとして数えられる。他に何も保持しないゲートウェイの見え方は提供できるシグナルを持たず、UNEXPOSED は参加を控えてそう述べる、すべてのエンドポイントを到達不能として報告するのではなく。Casdoor の Helm チャートはまさにそれである: / の1つの Ingress ルールで、証拠として読むと365の発見事項を生み出した。

トラフィックは監視されていなければならない

HAR キャプチャは発生したリクエストを記録する。Postman コレクションは誰かが行おうとしたリクエストを記録する。ORPHAN、LIVE_UNDOC、COLD はすべて何が実行されたかを推論するので、誰かが実際に監視した見え方を要求し、参加を控えるときはそう述べる。

非 Web の対象面は除外される

Noir は CLI 引数、Kafka トピック、モバイルディープリンクを同じリストで報告する。cli://gitops-engine/agent を HTTP に平坦化すると /agent になり — その名前の任意の Web ルートと衝突し、ゲートウェイがそこにルーティングするかどうかを問われる。プロトコルはエンドポイントの同一性に属する; http と https は1つの空間であり、それ以外はすべて独自のものを保つ。

抑制

一部のギャップは意図された状態である。ソースの隣に .alibi.yml を置く:

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

または一度限りなら --ignore REGEX を渡す。抑制された発見事項はカウントされ、その数が出力される — 発見事項を静かに落とすツールは、多すぎるものを出力するツールよりも悪い、なぜなら何を保留したかを知る方法がもはやないからである。

ステータス

初期段階だが、5つの見え方すべてが比較されている。

5つのリポジトリに対して測定:

Casdoor は最もクリーンなケースである: その235の文書化されたエンドポイントのうち230がコードに一致し、パス正規化の失敗は一切なかった。 19のニアミスはすべて異なる動詞の下の同じパスだった — noir が Go の catch-all ハンドラーですべてのメソッドを登録しているのであり、マッチングの問題ではない。

NetBox は教訓的なものである。それは1つのリポジトリに2つの対象面を保持する: サーバーレンダリングの Web UI と、2番目のものだけが文書化されている DRF ルーター REST API。全体をスキャンすると746の発見事項を報告し、そのほとんどは Web UI が API 仕様にないという真実だが役に立たない観察である。契約が記述する対象面にスコープを絞ると、実際に言う価値のあるものに collapse する:

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

→ 3つのシャドウ API: /api/plugins、/api/schema/redoc、/api/schema/swagger-ui、3つとも本当に提供され、本当にスキーマに存在しない。残る397のファントムは、NetBox 自身のルーターサブクラスがすべてのリストエンドポイントに追加する一括操作であり、どの urlconf ウォークも見ることができない。

他の3つは保留されている、それぞれ知る価値のある理由で:

  • Argo CD は Go で /api を登録し、その下に198のパスを文書化している — 2つの粒度での同じ対象面。
  • authentik はインストールされたすべてのアプリの urls モジュールをインポートすることで実行時に URLconf を組み立てる、それはどの静的リーダーも追跡できない。
  • flipt は gRPC ゲートウェイをマウントする; その Go ソースは1つのルートを保持する。その HTTP 対象面は .proto アノテーションで実装されており、それが grpc がコードの見え方を代表する理由である: そこにファイルされると、その36の文書化されたパスのうち36が裏付けられる。

これがこのツールの天井であり、率直に述べると: それは noir が読み取れるものを比較し、間違った粒度で読まれた見え方は全く読まれないものよりも悪い。上記の機構のほとんどは、それらを欠陥として報告するのではなく、それらを見分けるために存在する。

ライセンス

MIT

ツールをダウンロード
ルール条件重大度
ORPHAN実際のリクエストを受けているが、コードに存在しないhigh
LIVE_UNDOC実際のリクエストを受けているが、どの契約にも記述されていないhigh
SHADOWコードにあるが、どの契約にもないmedium
DANGLING実装された何にも到達しないゲートウェイルールmedium
DRIFTデプロイのために宣言されているが、コードに欠けているmedium
PHANTOM契約にあるが、コードにないlow
UNEXPOSED実装されているが、どのゲートウェイルールも到達しないlow
COLD実装されているが、リクエストを受けているのを一度も見られていないinfo
リポジトリcodedoccorroboratedfindingscode↔doc
casdoor372235230 (98%)139compared
netbox11461193796 (67%)746compared
argo-cd59198131held back
authentik23111931192held back
flipt24200held back