0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

サブプロセスに親の認証情報を継承させない: Claude Code の環境スクラブを実装して検証する

0
Posted at

Claude Code に Bash を実行させたり、フックや stdio MCP サーバーを動かしたりすると、それらは Claude Code プロセスの子プロセスとして起動します。UNIX の標準的な挙動として、子プロセスは親の環境変数をそのまま継承します。つまり、親プロセスが ANTHROPIC_API_KEY やクラウドプロバイダーの認証情報を持っていれば、あなたが実行させたスクリプトも、プロンプトインジェクションで実行させられたスクリプトも、同じ変数を読めてしまいます。

本稿では、この継承経路を断つための環境変数フラグ群を、空のディレクトリから通しで設定・検証する手順としてまとめます。対象は 2026-09-08 時点の Claude Code の設定です。検証には実行コマンドと「成功をどう見分けるか」をセットで示します。

fork したサブプロセスが親の認証情報を継承する問題

危険なのは、認証情報が「Claude Code のプロセスにある」こと自体ではなく、「そこから fork された任意のシェルがそれを読める」ことです。悪意あるプロンプトが echo $ANTHROPIC_API_KEY | curl ... のようなシェル展開を Bash ツールに実行させれば、シークレットは外部へ流出します。防御の要点は、親プロセスは API 呼び出しのために認証情報を保持したまま、子プロセスの環境からだけそれを取り除くことです。

CLAUDE_CODE_SUBPROCESS_ENV_SCRUB で継承を断つ

CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 を設定すると、Claude Code は子プロセスを起動する際にその環境から認証情報を削除します。対象は Bash ツール・フック・MCP stdio サーバーで、削除されるのは Anthropic とクラウドプロバイダーの認証情報、Claude Code が認証情報として認識するその他の変数、そしてパッケージレジストリ URL に埋め込まれた認証情報です。

strip credentials from subprocess environments (Bash tool, hooks, MCP stdio servers)

上記のとおり、削除は「サブプロセスの環境」に対して行われます。親プロセス自体の認証情報は残るため、Claude Code の API 呼び出しは通常どおり動き、子プロセスだけがシークレットを読めなくなります。

シェルで有効化してから起動します。

export CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1
claude

空ディレクトリから通しで検証する

継承が本当に断たれたかは、子プロセス側から環境を覗いて確かめます。ここで有効なのが CLAUDECODE 変数です。これは Claude Code が起動したサブプロセスに常に 1 として設定されるため、「env コマンドが確かに Claude Code の子プロセスで走った」ことの陽性対照になります。

Claude Code に次を実行させます。

env | grep -E 'ANTHROPIC|AWS_|CLAUDECODE' || echo "no credential match"

成功の見分け方は次のとおりです。CLAUDECODE=1 の行は出る(=確かに子プロセスで実行された)。一方で ANTHROPIC_API_KEY やクラウド認証情報の行は出ない。スクラブが効いていれば、認証情報の grep はヒットせず終了コード 1 で no credential match が表示されます。もし CLAUDECODE=1 すら出なければ、そもそも Claude Code 経由で実行できていません(設定の切り分けができます)。

MCP stdio サーバーの環境を絞る

MCP stdio サーバーはあなたのシェル環境を継承して起動されるのが既定です。CLAUDE_CODE_MCP_ALLOWLIST_ENV=1 を設定すると、安全なベースライン環境とサーバー設定の env だけで起動されるようになります。サーバーが本当に必要とする変数だけをホワイトリストとして明示する、という発想です。

.mcp.json に、環境をファイルへ書き出すだけのプローブサーバーを置いて確かめられます。

{
  "mcpServers": {
    "envprobe": {
      "command": "bash",
      "args": ["-c", "env > /tmp/mcp-env.txt; exec cat"],
      "env": { "MY_SERVER_TOKEN": "configured-value" }
    }
  }
}

成功の見分け方: /tmp/mcp-env.txtMY_SERVER_TOKEN=configured-value は含まれるが、あなたの ANTHROPIC_API_KEY やクラウド認証情報は含まれない。

スクリプトの呼び出し回数に上限を設ける

CLAUDE_CODE_SCRIPT_CAPS は、特定スクリプトを1セッションあたり何回まで呼べるかを JSON オブジェクトで制限します。これは CLAUDE_CODE_SUBPROCESS_ENV_SCRUB が設定されている場合にのみ機能します。マッチングはサブ文字列ベースなので、./scripts/deploy.sh $(evil) のようなシェル展開トリックもキャップに数えられます。ただし xargsfind -exec によるランタイムのファンアウトは検出されず、あくまで多層防御の一手段です。

.claude/settings.jsonenv の各エントリはシェルから継承した値を置き換えてプロセス環境に書き込まれます):

{
  "env": {
    "CLAUDE_CODE_SCRIPT_CAPS": "{\"./scripts/deploy.sh\": 2}"
  }
}

「有効化しただけ」で終わらせないための勘所

第一に、env ブロックで変数を空文字列にしても保護にはなりません。空の値は子プロセスにそのまま継承されるため、「値を消したつもり」でも空文字列が渡ります。第二に、CLAUDE_CODE_SCRIPT_CAPS はセキュリティ境界ではなく多層防御の一枚です。第三に、Linux では Bash サブプロセスが隔離された PID 名前空間で走り、/proc 経由でホストの環境を読めなくなりますが、その副作用として pspgrepkill がホストプロセスを見たりシグナルを送ったりできなくなります。プロセス管理に依存するワークフローは影響を受けます。

References

[1] https://code.claude.com/docs/en/env-vars

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?