更新日:2026年10月6日

9分で読めます

AIコーディングエージェントDeepSeek-Reasonixに設定ファイル汚染によるコマンド実行の脆弱性

GitLabの脅威リサーチグループは、ファイルの差分を表示しただけで攻撃者のコードが動く脆弱性ConfigPoisoningをDeepSeek-Reasonixで発見しました。

GitLabの脅威リサーチグループは、AIコーディングアシスタントとのペア作業を想定したデスクトップGitクライアント「DeepSeek-Reasonix Studio」に、コマンド実行の脆弱性(GHSA-grg2-7gc6-36m6、CVE-2026-102437)を発見しました。ConfigPoisoningと名付けたこの脆弱性では、デベロッパーがファイルの差分を表示した時点で、攻撃者が用意したコードが実行されるおそれがあります。対処するには、DeepSeek-Reasonix Studio 2.21.0、またはDeepSeek Reasonix npm 1.39.3へアップデートしてください。

これはDeepSeek-Reasonix固有の問題ではありません。GitLabの脅威リサーチグループの調査では、広く使われている複数のコーディングエージェントが同じ種類の脆弱性を抱えていました。いずれも、リポジトリ自身の.git/configや.gitattributesから、攻撃者が指定したコマンドが動いてしまうというものです。全容を公開するのは、このDeepSeek-Reasonixが最初の事例になります。

注記:GitLab上でホストされているGitリポジトリは、この脆弱性の影響を受けません。HTTPSやSSH経由のクローンでは、ローカルの設定ファイルが転送されないためです。

要点

  • 深刻な脆弱性 GitLabの脅威リサーチグループは、AI支援開発向けのデスクトップGitクライアントDeepSeek-Reasonix Studioに、深刻なコマンド実行の脆弱性を発見しました。特定のリポジトリ設定の条件下で、デベロッパーがファイルの差分を表示すると、攻撃者が用意したコードが動くおそれがあります。
  • 根本原因 DeepSeek-Reasonix独自のgitラッパーは、いくつかのgit設定キーをコマンドインジェクションから保護しています。しかし塞ぎきれていない穴が1つあり、それをコード内のコメントがみずから名指ししていました。filter.<driver>.cleanです。このキーは固定の設定キーではなく、.gitattributesを通じてgitがファイルごとに選択します。
  • 当面の推奨事項 DeepSeek-Reasonix Studio 2.21.0、またはDeepSeek Reasonix npm 1.39.3へアップデートしてください。gitを外部実行するツールを開発している場合は、脆弱なキーを1つ塞いで終わりにしないこと。呼び出しのたびに関連するキーをすべて上書きするか、gitのfilterおよびtextconvの仕組み(コミットや差分の生成前にファイル内容を変換するためのフック)の呼び出し自体を避けてください。

コーディングエージェントのアタックサーフェスが特殊な理由

コーディングエージェントは、デベロッパーが開いたディレクトリであれば、どこに対してもgitを実行します。そのとき読み込まれる.git/configと.gitattributesを書いたのは、リポジトリを開いたデベロッパーではなく、そのリポジトリを作った人物。gitの設定キーのうち、core.fsmonitor, core.hooksPath、diff.external、filter.<driver>.cleanといったものは、通常のgit操作の一部として、指定されたコマンドを実行します。素のgitクライアントについても、すでにこの点を扱ったアドバイザリーが出ています。

コーディングエージェントはそれぞれ独自の方法でgitをラップしているため、直近のインシデントの原因になったプリミティブだけを塞いで終わりにしがちです。DeepSeek-Reasonixのinternal/gitcmdも、呼び出しのたびに4つのプリミティブを塞いでいました。塞がれずに残った1つは、コード内のコメントが自分で名指ししていたものです。

脆弱性の仕組み

internal/gitcmdは、呼び出しのたびにcore.fsmonitorとmaintenance.autoを無効化し、差分の取得時には--no-ext-diffと--no-textconvを付与しますが、filter.<driver>.cleanには一切手を触れていません。このキーは固定のリストから選ばれるものではなく、.gitattributesがファイルごとに指定するため、ほかのキーと同じようにdeny-listで塞ぐ、という手が使えません。

実際の呼び出しは、desktop/workspace_changes.goの次の箇所です。

      args := []string{"-C", base, "diff", "--no-ext-diff", "--no-textconv", "--relative", "HEAD", "--", filepath.FromSlash(rel)}

    

それでもcleanフィルターはここで動きます。差分の比較に必要なblobを生成する処理であり、この工程には上記のフラグがまったく効きません。

呼び出しチェーンの全体像

呼び出しの流れを順に追ってみます。

  1. 仕込み secret.binには、pwnという名前のフィルタードライバーを割り当てる.gitattributesのエントリーが付いています。そしてリポジトリの.git/configが、そのドライバーのcleanコマンドとして攻撃者の選んだスクリプトを定義します。
  2. 差分ビューが開かれる デベロッパーが、DeepSeek-Reasonixのデスクトップアプリでそのファイルの差分を開きます。コミットしていない変更があるファイルなら、ごく普通の操作です。
  3. DeepSeek-Reasonixが堅牢化済みのコマンドを実行する desktop/workspace_changes.goがgit -c core.fsmonitor=false -c maintenance.auto=false -C <repo> diff --no-ext-diff --no-textconv -- secret.binを発行します。既存の堅牢化フラグはすべて揃った状態です。
  4. それでもcleanフィルターが動く gitは比較用のblobを作るためにfilter.pwn.cleanを呼び出しますが、これはどのフラグも及ばない工程です。攻撃者のコマンドは、差分の両側に対して1回ずつ実行されます。

堅牢化済みのコマンドを再現したところ、ペイロードは2回実行されました。diffは比較の両側についてcleanフィルターを通したblobを作るため、フィルターが片側ごとに1回ずつ発火します。一方git statusが確認するのは、どのファイルが変更されたかという点だけ。blobを作らないので、フィルターにも触れません。つまりこの不具合は差分の描画に限定されており、DeepSeek-Reasonixの実際のコードパスとも一致します。

影響範囲

.gitattributesはクローンしても残りますが、.git/configは残りません。攻撃を届けるには、アーカイブ、同期フォルダー、CIキャッシュ、devcontainerのビルドといった経路が必要になります。検証はコミットea28602と、プレリリースのタグstudio-v2.9.0で実施しました。影響はデスクトップアプリとnpmパッケージの両方に及びます。

ただし、エージェント型ツールに固有の、より直接的な経路もあります。デベロッパーのマシンですでに動いているコーディングエージェントが、不正なものだったり、侵害されていたり、プロンプトインジェクションを受けていたりすれば、そのエージェントはデベロッパー自身と同じファイルシステムへのアクセス権を持ちます。ごく普通にクローンしただけのリポジトリに、汚染された.git/configを直接書き込めてしまう。アーカイブも同期フォルダーもCIキャッシュも要りません。

新しいツールが古いバグを引き継ぐ理由

ここまでの話は、DeepSeek-Reasonixに限りません。

  • リポジトリの設定が、ツール自身の設定として扱われてしまう コーディングエージェントは.git/configや.gitattributesを自分の設定であるかのように読み込みますが、その中身を決めているのはリポジトリの作者です。これらのファイルはコードのすぐ隣に置かれ、見た目にもコードの一部のように思えるため、この区別は見落とされがちです。
  • 同じ信頼の崩れを、別のファイルですでに見ている 今年の初めにも、GitLabの脅威リサーチグループはSerenaで同じパターンを発見しました。別のAIコーディングツールであるSerenaは、デベロッパーがリポジトリを開いた際に、プロジェクト自身の設定ファイル.serena/project.ymlから攻撃者のコードを実行していました。どちらの事例も、リポジトリの作者が中身を決められるファイルをツールが信頼してしまったという点で共通しています。同じ誤りは、ほかのエージェント型ツールでも見つかるとみています。

今、何をすべきか

DeepSeek-Reasonixを利用している場合

Studio 2.21.0、またはDeepSeek Reasonix npm 1.39.3へアップデートしてください。それ以前のバージョンを使い続ける場合は、自分で直接クローンしたのではないリポジトリの差分を開かないようにしてください。

Gitをラップするツールを開発している場合

ここからの推奨事項は、自分の管理下にないディレクトリに対してgitを外部実行するすべてのツールに当てはまります。

  • バイト単位の内容だけが必要なら、git cat-fileやgit showでblobを読み、diff in-processを使ってください。
  • どうしても外部実行が必要なら、呼び出しのたびに関連するキーをすべて上書きします。対象はcore.fsmonitor、core.pager、core.editor、core.hooksPath、diff.external、core.sshCommand、そして.gitattributes、.git/info/attributes、グローバルおよびシステムの設定ファイルに現れるすべてのドライバー名に対するfilter.<driver>.cleanとsmudgeです。
  • あるフラグが別のフラグを兼ねることはありません。--no-ext-diffが効くのはdiff.externalに対してのみ。core.sshCommandには何の効果もありません。
  • 汚染された設定がリポジトリと一緒に届くとは限りません。デベロッパー本人と同じ権限で動いている別のエージェントや拡張機能、プロセスが、クローン済みのリポジトリへ直接書き込むこともできます。
  • 出荷前に、意図的に敵対的な設定の組み合わせを用意してテストしてください。

セキュリティチームを率いている場合

デベロッパーのマシン上でgitを外部実行するツールは、そのデベロッパーが持つ権限のすべてを使って動きます。ベンダーに確認すべきは、信頼できないリモートへの対処だけではありません。リポジトリローカルの設定をどう無効化しているかも、あわせて尋ねてください。

開示タイムライン

日付内容
2026-08-27esengineとアドバイザリーを起票
2026-09-29esengineが一時的な非公開フォークを作成し、報告を受理
2026-09-30修正版をリリース(Studio 2.21.0 / npm 1.39.3)。アドバイザリーを公開(GHSA-grg2-7gc6-36m6)
2026-09-30CVE-2026-102437を採番

報告を受け入れ、修正版をリリースしてくださったDeepSeek-Reasonixのメンテナーの皆様に感謝いたします。

GitLabにできること

自分のコードベースに同じパターンがないかを調べるなら、GitLab Duo Agent Platformのセキュリティ分析エージェントが役立ちます。まずは次のように問いかけてみてください。

      「このコードは、自分の管理下にないディレクトリに対してgitを外部実行していないか。また、実行前に `core.hooksPath, filter.*.clean`、`diff.external` を無効化しているか」

    

エージェントが、自社環境への影響を評価します。

今後の展望

リスクを知っていることと、それを塞ぐことは、必ずしも同じではありません。きちんと記録され、正直に認識されていたセキュリティ上の穴であっても、そのまま出荷されてしまう。今回のDeepSeek-Reasonixの経緯は、その事実をあらためて思い出させてくれます。同じパターンは、広く使われているほかのエージェント型ツールにも存在しており、現在は協調的な開示の手続きを進めている段階。修正が用意でき次第、それぞれの詳細を公開します。

GitLabの脅威リサーチグループによるセキュリティリサーチの記事をさらに読む

ご意見をお寄せください

このブログ記事を楽しんでいただけましたか?ご質問やフィードバックがあればお知らせください。GitLabコミュニティフォーラムで新しいトピックを作成してあなたの声を届けましょう。

フィードバックを共有する

今すぐ開発をスピードアップ

DevSecOpsに特化したインテリジェントオーケストレーションプラットフォームで実現できることをご確認ください。