コンテンツにスキップ

セキュリティ

報告

脆弱性と思われるものは、公開の issue ではなく、このリポジトリの GitHub の非公開脆弱性報告(Security → Report a vulnerability)から知らせてほしい。

何をして、何が起き、何を期待していたかを書いてもらえれば十分である。再現手順があると 助かるが、必須ではない。動くトークンは貼らないこと——必要なのは、どこから漏れたかの 説明のほうである。

ここで重いと考えるもの

このサーバは、言語モデルと、公開された研究成果を持つリポジトリとのあいだに立つ。 その位置が、報告の重さを決める。

  • keycloak モードで、交換を経ずにトークンが InvenioRDM へ届くこと。 受け取る トークンは本サーバ宛であり、それを転送するのは MCP 仕様が禁じる confused deputy に あたる。下流のサービスに、持たせるつもりの無かった資格情報を渡すことになる。
  • 別の audience 宛に発行されたトークンが通ること。 aud を本サーバの canonical URI に対して検証しているのは、まさに他所で得たトークンを持ち込めないようにするためである。
  • scope を持たないまま書き込み・取り下げ・復元が行えること。 ツールを共有しつつ 入口を共有しない /mcp-auth 経由も含む。
  • トークンがログの行・エラー文・ツールの結果に入ること。 監査ログは subazpscope を意図して載せており、トークンは載せない。
  • 要求に応じてサーバに URL を取りに行かせられることupload_file_from_url の範囲を 超えて)。それは SSRF の形をしており、InvenioRDM v14 が transfer 種別 F を システム処理に限っているのも同じ理由による。

既知の運用上の危うさ

次は欠陥ではなく設定の性質なので、直すのではなく書いておく。

  • PAT モードに audience による分離は無い。 受け取るトークンが InvenioRDM の トークンである以上、構造的にそうなる(交換する先が無い)。同時にそれは、サーバが リポジトリに直接効く資格情報を持つということでもある。そこが問題になるなら keycloak モードを使う。
  • MCP_TLS_INSECURE=1 は証明書検証を切る(InvenioRDM と Keycloak の両方)。 自己署名の開発用インスタンスのために在る。正しい手順は、CA をシステムの束に足すこと。
  • mcp-remote--allow-http はトークンを平文で送る。 信頼できる経路に限ること。
  • compose のスタックは .env の秘密を平文で読む。 出発点であって、配備物ではない。
  • stdio 版の add_file(source_path=...) は、そのプロセスが読めるファイルを何でも 読んで送る。 これは設計どおりで、サーバは利用者本人として動くのだから、本人が 読めるものには届く。問題になるのは呼び出す側が言語モデルだからである。レコードの 本文、ファイル名、要約を頼んだ Web ページ——そのどれもが、~/.ssh/id_rsa を読んで 公開レコードに添付するよう仕向けようとしうる。クライアントはツール呼び出しごとに 承認を求めるので、自分で選んでいない source_path を承認しないこと。 HTTP 版はこの引数をそもそも公開していない。

範囲

最終的な権限判定は InvenioRDM のものである。「admin トークンならレコードを消せる」と いう報告は、InvenioRDM が設計どおり動いていることの説明であって、ここの脆弱性ではない。