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?

Sentryキー2,388件の露出から、Claude Codeを守るsandbox設定

0
Posted at

はじめに

Sentryの「公開DSN」(認証不要のエラー送信キー)を1つ悪用するだけで、Claude Code・Cursor・OpenAI Codexといった主要なAIコーディングエージェントを乗っ取れることが、セキュリティ企業Tenet Securityの調査チームTenet Threat Labsの調査で明らかになりました1。この記事では攻撃の仕組みを整理したうえで、Claude Code公式ドキュメントに実在する設定キーだけを使い、実際に手元の settings.json で塞ぐところまで解説します。

この記事で学べること

  • 「Agentjacking」と呼ばれる攻撃の仕組みと、なぜ現行のAIエージェントがほぼ確実に騙されるのか
  • Claude Codeの sandbox / permissions 設定で、攻撃の実害(認証情報の窃取)を防ぐ具体的な設定
  • 自分の settings.json が対策済みかを機械的にチェックするスクリプト

対象読者

  • Claude Code・Cursor・Codex等のAIコーディングエージェントを業務で使っている方
  • MCP連携(Sentry・GitHub等の外部サービス)をエージェントに組み込んでいる方

TL;DR

  • 攻撃者は認証不要の公開Sentry DSNに偽のエラーをPOSTし、「解決策」欄にマルウェア実行コマンドを仕込める
  • 開発者がエージェントに「このエラーを直して」と頼むと、エージェントは偽の解決策を鵜呑みにしてコマンドを実行してしまう
  • Claude Codeのsandboxは既定では ~/.aws/credentials 等の認証情報を読めてしまう。sandbox.credentials で明示的に塞ぐ必要がある

Agentjacking攻撃の仕組み

Tenet Threat Labsが2026年6月17日に公開した調査によると、攻撃は次の流れで成立します1

  1. 公開DSNへの偽エラー送信: Sentryの公開DSN(Webアプリのフロントエンドに埋め込まれる、送信専用の認証不要キー)に対し、攻撃者が任意の内容でエラーレポートをPOSTする
  2. 「解決策」への命令の埋め込み: エラーの「Resolution(解決策)」欄に、正規のトラブルシューティング手順を装って npx <malicious-package> のようなコマンド実行指示を紛れ込ませる
  3. 開発者による起動: 開発者がClaude CodeやCursorに「このSentryエラーを直して」と依頼すると、エージェントはSentry連携(MCP経由やSentry API経由)でエラー内容を取得し、埋め込まれた指示を「修正手順」として実行してしまう
  4. 認証情報の収集・送信: 実行されたコマンドが環境変数・AWS認証情報・SSH鍵・Dockerの設定などを収集し、攻撃者が管理する外部サーバーへ送信する

調査では、受動的な偵察(Censysによるインデックス調査・コード検索・CDN配信スクリプトの抽出)だけで 2,388組織 の有効な注入可能DSNが見つかり、うち71組織はTranco top-1M(アクセス数上位100万ドメイン)にランクインしていました1。検証用に用意した100件以上のAIエージェント実行環境(Claude Code・Cursor・Codexを含む4系統以上)に対して注入したところ、sandbox環境・クラウド・GCEコンテナ・WSLを問わず 85%の確率で攻撃が成功 したと報告されています1

なぜエージェントは騙されるのか

根本原因は、AIエージェントが「読むべき情報(データ)」と「実行すべき指示(コマンド)」を構造的に区別できない点にあります。これは典型的なプロンプトインジェクションの一種で、Microsoftも同時期に類似の問題(MCPツールのメタデータ書き換えによるエージェント誘導)を注意喚起しています2

Sentryのケースが特に強力なのは、開発者自身が「このエラーを直して」と 自発的に エージェントへ調査・修正を依頼する点です。攻撃者が何かを送りつけて実行させるのではなく、開発者の正当なワークフロー(バグ修正)そのものが攻撃の起点になるため、不審な操作という自覚が生まれにくくなっています。

Claude Codeで実際に塞ぐ設定

Tenet Securityはこの攻撃クラス向けに、Cursor・Claude Code向けのhardening configを公開しています(tenet-security/agent-jackstop3。ここでは同リポジトリの防御方針を踏まえつつ、Claude Code公式ドキュメントに実在するキーだけで構成した設定を示します4

防御の要点は「エージェントに攻撃コマンドを実行させないこと」と「万一実行されても認証情報を読ませないこと」の二段構えです。

// .claude/settings.json(プロジェクト単位。組織全体で強制するなら managed-settings.json へ)
{
  "permissions": {
    "ask": [
      "Bash(npx *)",
      "Bash(npm exec *)",
      "Bash(curl *)",
      "Bash(wget *)",
      "Bash(aws *)",
      "Bash(gcloud *)",
      "Bash(gh auth *)"
    ]
  },
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "denyRead": ["~/.ssh", "~/.aws", "~/.config/gcloud", "~/.docker/config.json"]
    },
    "credentials": {
      "files": [
        { "path": "~/.aws/credentials", "mode": "deny" },
        { "path": "~/.ssh", "mode": "deny" }
      ],
      "envVars": [
        { "name": "GITHUB_TOKEN", "mode": "deny" },
        { "name": "NPM_TOKEN", "mode": "deny" }
      ]
    },
    "network": {
      "allowedDomains": ["registry.npmjs.org", "*.npmjs.org", "pypi.org"]
    }
  }
}

各設定の役割は次のとおりです。

設定キー 役割
permissions.ask npxcurl 等、Sentryの「解決策」に仕込まれやすいコマンドを実行前に必ず確認させる
sandbox.filesystem.denyRead サンドボックス化されたBashコマンドから認証情報ディレクトリの読み取りを禁止する
sandbox.credentials 認証情報ファイル・環境変数を個別に保護し、コマンドが実行されても資格情報自体を渡さない
sandbox.network.allowedDomains 攻撃者が指定する未知のドメインへの通信(データ持ち出し)を既定で拒否する

組織全体に強制したい場合は、managed-settings.jsonsandbox.enabled: truesandbox.allowUnsandboxedCommands: false を設定し、開発者が緩めることができないようにします4

著者視点の発見ポイント

今回リサーチしていて意外だったのは、Claude Code公式ドキュメントに書かれているsandboxの既定動作でした。sandboxを有効化しただけでは、~/.aws/credentials~/.ssh はデフォルトで読み取り可能なままです4。sandboxのファイルシステム隔離は「書き込み」を現在の作業ディレクトリに制限するのが既定動作であり、「読み取り」はホームディレクトリの認証情報を含めてほぼ全体が対象になります。「sandboxを有効にしたから安全」という思い込みは、sandbox.credentialsfilesystem.denyRead を明示しない限り成立しません。

もうひとつの発見は、sandboxが制御するのはBashツールの子プロセスのみで、MCPツール呼び出し自体は別の権限系統(permissions)で管理されている点です4。Sentry連携がMCP経由かAPI直結かに関わらず、実際の被害は「取得した指示をBashで実行する」段階で発生します。つまりAgentjacking対策の本丸は「MCPを塞ぐこと」ではなく「取得した情報をコマンドとして実行させないこと」にあり、上記の permissions.asksandbox.credentials の組み合わせがその防御ラインになります。

設定を確認するチェックスクリプト

以下のスクリプトは、プロジェクトの .claude/settings.json に上記の主要な対策が含まれているかを機械的に確認します。git clone せずとも手元の設定ファイルにそのまま使えます。

#!/usr/bin/env python3
"""Claude Code settings.json の Agentjacking 対策チェック"""
import json
import sys
from pathlib import Path

REQUIRED_ASK_PATTERNS = ["Bash(npx", "Bash(curl", "Bash(aws"]
REQUIRED_DENY_PATHS = [".ssh", ".aws"]


def check(settings_path: str) -> int:
    data = json.loads(Path(settings_path).read_text())
    ask = data.get("permissions", {}).get("ask", [])
    sandbox = data.get("sandbox", {})
    deny_read = sandbox.get("filesystem", {}).get("denyRead", [])
    cred_files = [c.get("path", "") for c in sandbox.get("credentials", {}).get("files", [])]

    missing = []
    if not sandbox.get("enabled"):
        missing.append("sandbox.enabled が true になっていません")
    for pattern in REQUIRED_ASK_PATTERNS:
        if not any(pattern in a for a in ask):
            missing.append(f"permissions.ask に {pattern}...) がありません")
    for path in REQUIRED_DENY_PATHS:
        if not any(path in d for d in deny_read) and not any(path in c for c in cred_files):
            missing.append(f"{path} を denyRead / credentials で保護していません")

    if missing:
        print("NG:")
        for m in missing:
            print(f"  - {m}")
        return 1
    print("OK: Agentjacking向けの主要設定が揃っています")
    return 0


if __name__ == "__main__":
    target = sys.argv[1] if len(sys.argv) > 1 else ".claude/settings.json"
    sys.exit(check(target))

python3 check_agentjacking_defense.py .claude/settings.json のように実行すると、上記4項目(sandbox有効化・危険コマンドのask化・SSH/AWS認証情報の保護)が欠けている箇所を一覧できます。

まとめ

  • Agentjackingは「開発者自身がエージェントに調査・修正を依頼する」正当な操作を起点にするため、既存の異常検知では気付きにくい
  • Claude Codeのsandboxは既定で認証情報ディレクトリを読めてしまうため、sandbox.credentials / filesystem.denyRead の明示設定が必須
  • permissions.asknpx / curl 等の実行前確認を挟むだけでも、被害の連鎖を大きく断ち切れる

Sentry連携に限らず、外部サービスから取得したテキストを「指示」として実行しうる構成全般に同じリスクがあります。エージェントに外部データを読ませる連携を追加するたびに、今回の設定を振り返ることをおすすめします。

参考リンク

  1. Agentjacking: Coding Agents with Fake Sentry Errors — Tenet Threat Labs(2026-06-17、Ron Bobrov, Barak Sternberg, Nevo Poran) 2 3 4

  2. Securing AI agents: When AI tools move from reading to acting — Microsoft Security Blog(2026-06-30)

  3. tenet-security/agent-jackstop — GitHub

  4. Configure the sandboxed Bash tool — Claude Code Docs 2 3 4

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?