MCP Objauthz Lab
M

MCP Objauthz Lab

2ポイント
5.8K

インストール

以下のコマンドをクライアントにコピーして設定
注意:あなたのキーは機密情報です。誰とも共有しないでください。

🤖 MCP オブジェクト認可ラボ

小規模でセルフホスト可能な 設計上脆弱 (vulnerable-by-design) な MCP サーバー。Model Context Protocol のツール群において オブジェクトレベル/クロステナント認可 の脆弱性(BOLA / IDOR — CWE-639, CWE-862)がどのように現れるか、そしてそれをどう発見するかを学ぶための教材です。

マルチテナント構成のノートサーバーで、6 つの MCP ツールを公開しています。うち 5 つは正しく認可されていますが、ちょうど 1 つだけ アクセスチェックが欠落しているため、ある組織の呼び出し元が別の組織のデータに到達できてしまいます。このバグは意図的に巧妙に仕込まれています。壊れているツールは兄弟ツールと見た目が同じで、欠けているのはたった 1 行です。それを見つけ、ローカルで悪用し、スイッチを 1 つ切り替えて修正される様子を確認してください。

🎯 このラボの目的

MCP のセキュリティは主に プロンプトインジェクション やツールポイズニングに注目が集まりがちです。オブジェクトレベル認可はより静かで、まったく別の種類の問題であり、一般的なプロンプトインジェクションのテストスイートやスキャナーでは 発見できません。MCP サーバーがマルチテナントである場合、クライアント供給の id からオブジェクトを解決するすべてのツールは、呼び出し元が その オブジェクトに触れる権限があるかを検証しなければなりません。1 つのツールでこのチェックを怠ると、クロステナントの読み取り・書き込み・削除が可能になります — プロンプトインジェクション対策がどれほど優れていても関係ありません。これを見つけるには 各ツールの認可を読み解く ことが必要であり、まさにこのラボが鍛えるスキルです。

🚀 クイックスタート(5 分以内)

要件:Node.js ≥ 20

npm install
npm run poc

期待される出力:

MCP object-level authorization lab — two-way gate

  BUILD  ACTION                                 OUTCOME  EXPECT   OK
  vuln   note_get   cross-tenant (Bob → Acme)   DENIED   DENIED   ✓
  vuln   note_delete cross-tenant (Bob → Acme)  DELETED  DELETED  ✓
  fixed  note_delete cross-tenant (Bob → Acme)  DENIED   DENIED   ✓
  fixed  note_delete same-tenant (Bob → Globex) DELETED  DELETED  ✓

  Two-way gate: PASS (vuln exploits, fix blocks the cross-tenant delete and still allows the same-tenant one).

この PoC は実際の MCP クライアントです。stdio 経由でサーバーを起動し(ローカルのみ — ネットワークも第三者もなし)、Bob(所属組織 Globex)として認証し、Acme が所有するノートに到達しようと試みます。いわゆる 双方向ゲート (two-way gate) を実行します:

  • vuln ビルドでは、クロステナント削除が 成功 する一方で、正しくスコープされた note_get は依然として拒否される — これはサーバーが 1 つだけ 壊れたツールを持ち、全体的にチェックが欠けているわけではないことを証明します。
  • fixed ビルドでは、同じクロステナント削除が ブロック され、Bob が 自分の 組織のノートを削除する操作は依然として 成功 する — これは修正が過剰ブロック(偽陽性)を引き起こしていないことを証明します。

🧩 チャレンジ

src/ を読む前に:このサーバーは 6 つのノートツールを公開しています — note_list、note_get、note_create、note_update、note_delete、note_search。ちょうど 1 つ が、ある組織の呼び出し元に別の組織のノートを操作させてしまいます。どれで、他のツールと何が違うのでしょうか?

ヒント

3 つのツールがクライアント供給の id を受け取ります(note_get、note_update、note_delete)。そのうち 2 つは、解決されたオブジェクトが自分の組織に属するかをチェックしています。1 つはチェックしていません。

答え

note_delete です。クライアント供給の id からノートを解決する点は note_get や note_update とまったく同じですが、(LAB_MODE=vuln の場合)requireOrgAccess(session, note) を一切呼び出していません。修正はその 1 行 — 兄弟ツールがすでに実行しているのと同じチェックです。 にある note_delete の上のコメントブロックを参照してください。

🏗️ アーキテクチャ

ファイル 役割
インメモリのマルチテナントシードデータ:組織 Acme(Alice)と Globex(Bob)、それぞれいくつかのノート。
resolveSession(token) → サーバー信頼の { user, org };requireOrgAccess(session, object) — オブジェクトレベルのチェック。
6 つのツール。note_delete が仕込まれた外れ値。
stdio MCP サーバー。LAB_MODE を読み取る(vuln がデフォルト / fixed)。
上記の双方向ゲートを実行する MCP クライアント。

アイデンティティモデル(意図的な簡略化)。 各ツールは bearer token を受け取り、サーバーがそれを固定のユーザーと組織に解決します。呼び出し元が自身の組織を主張することはなく、トークンを提示するだけです。本番の MCP サーバーでは、このアイデンティティは呼び出しごとの引数ではなく、トランスポート/OAuth レイヤーから取得されます。ラボでは、単一プロセスに留め、認可ロジックを明示的で読みやすく保つために、呼び出しごとに渡しています。

🔀 脆弱版と修正版

環境変数 1 つで仕込まれたバグを切り替えられるため、自分の MCP ホストでどちらのビルドでも実行できます:

# vulnerable (default)
npm start
# or: LAB_MODE=vuln npm start

# fixed
LAB_MODE=fixed npm start

Windows PowerShell の場合:

$env:LAB_MODE = 'fixed'; npm start

両ビルドの 唯一 の違いは、note_delete 内の // <-- THE FIX とマークされた 1 行だけです。

✅ 監査チェックリスト — MCP におけるオブジェクトレベル認可

実際のマルチテナント MCP サーバー(自分が所有するか、テストを許可されているもの)を監査する際に使用してください。このバグクラスは「サーバーは あなたが誰か を認証するが、あなたがこのオブジェクトに触れてよいか をチェックし忘れる」というものです:

  • [ ] クライアント供給のスコープを認可として信頼している。 ツールが org_id / project_id / tenant_id / account_id 引数を受け取り、それを 呼び出し元のメンバーシップと照合する のではなく クエリのスコープ指定 に使ってしまっている。
  • [ ] メンバーシップチェックがオブジェクト解決から分離している。 ツールは呼び出し元が何らかの組織/プロジェクトに属することを検証するが、オブジェクトを 別の id(オブジェクト自身の id)で読み込み、そのオブジェクトがそのメンバーシップの下に存在することを確認していない。(これから返す/変更するオブジェクトを認可すること — その隣にあるパラメータではなく。)
  • [ ] 一貫性のない認可 — 唯一の外れ値。 ほとんどのオブジェクト操作ツールはチェックしているが、1 つか 2 つがしていない。サンプルではなく、id でオブジェクトを解決する すべての ツールを読むこと。忘れられがちなのは、たいてい地味な動詞(delete、update、archive、export、"cover"/"make-default" などのサイドアクション)です。
  • [ ] 読み取りは守られているが変更は守られていない。 get/list はスコープされているのに update/delete/transfer がすり抜けている — あるいはその逆。
  • [ ] ワイルドカード/センチネルによるショートサーキット。 特別な値('all'、'*'、空、0、null)がスコープフィルタを完全にスキップする。
  • [ ] ロール/トークンタイプによるバイパス。 "internal"、"service"、"admin"、または代替 JWT タイプのコードパスが、オブジェクトごとのチェックをスキップする。
  • [ ] list → get の非対称性。 list は自分の組織のオブジェクトのみを返すため、id が「プライベート」に感じられる — しかし get/delete は 任意の id を受け付け、その id は推測可能または列挙可能である。
  • [ ] create/update が外部の親を受け入れる。 create(parent_id=…) や update での再親子付けが、呼び出し元がメンバーでない親を受け入れ、別のテナントにオブジェクトを注入してしまう。

攻撃のプリミティブは常に同じです:テナント B として認証し、テナント A に属するオブジェクト id で容疑ツールを呼び出し、A のデータを取得できるか(または変更できるか)を確認します。修正の確認も、この PoC と同じ方法で行ってください — 双方向 で:クロステナント呼び出しがブロックされ、かつ 正当な同一テナント呼び出しが依然として成功する必要があります。

🛡️ 安全性/スコープ

  • 設計上脆弱。 到達可能なネットワーク上にデプロイしたり、実際のコードの出発点として使用したり しないでください。学習目的でのみローカルで実行してください。
  • 合成データ。 すべての組織、ユーザー、ノート、トークンは架空のものです。実データも実ターゲットも存在せず、PoC はネットワークリクエストを一切行いません — ローカルサーバープロセスを起動するだけです。

📄 ライセンス

MIT.

代替品

G
Gmail MCP Server
Claude Desktop用に設計されたGmail自動認証MCPサーバーで、自然言語でのやり取りによるGmailの管理をサポートし、メール送信、ラベル管理、一括操作などの完全な機能を備えています。
TypeScript
30.1K
4.5ポイント
E
Edgeone Pages MCP Server
EdgeOne Pages MCPは、MCPプロトコルを通じてHTMLコンテンツをEdgeOne Pagesに迅速にデプロイし、公開URLを取得するサービスです。
TypeScript
38.2K
4.8ポイント
C
Context7
Context7 MCPは、AIプログラミングアシスタントにリアルタイムのバージョン固有のドキュメントとコード例を提供するサービスで、Model Context Protocolを通じてプロンプトに直接統合され、LLMが古い情報を使用する問題を解決します。
TypeScript
114.8K
4.7ポイント
B
Baidu Map
認証済み
百度マップMCPサーバーは国内初のMCPプロトコルに対応した地図サービスで、地理コーディング、ルート計画など10個の標準化されたAPIインターフェースを提供し、PythonとTypescriptでの迅速な接続をサポートし、エージェントに地図関連の機能を実現させます。
Python
60.5K
4.5ポイント
G
Gitlab MCP Server
認証済み
GitLab MCPサーバーは、Model Context Protocolに基づくプロジェクトで、GitLabアカウントとのやり取りに必要な包括的なツールセットを提供します。コードレビュー、マージリクエスト管理、CI/CD設定などの機能が含まれます。
TypeScript
35.4K
4.3ポイント
U
Unity
認証済み
UnityMCPはUnityエディターのプラグインで、モデルコンテキストプロトコル (MCP) を実装し、UnityとAIアシスタントのシームレスな統合を提供します。リアルタイムの状態監視、リモートコマンドの実行、ログ機能が含まれます。
C#
45.1K
5ポイント
M
Magic MCP
Magic Component Platform (MCP) はAI駆動のUIコンポーネント生成ツールで、自然言語での記述を通じて、開発者が迅速に現代的なUIコンポーネントを作成するのを支援し、複数のIDEとの統合をサポートします。
JavaScript
30.2K
5ポイント
S
Sequential Thinking MCP Server
MCPプロトコルに基づく構造化思考サーバーで、思考段階を定義することで複雑な問題を分解し要約を生成するのに役立ちます。
Python
41.5K
4.5ポイント
AIBase
智啓未来、あなたの人工知能ソリューションシンクタンク
© 2026AIBase