flawopen.com/Teardowns/cve-2026-87913-aws-security-agent-mcp-s3-bucket-ownership
CVE-2026-87913:AWS MCP の S3 情報漏えい
AWS Security Agent の予測可能な S3 バケットに、非公開のソーススキャン用アーカイブが別アカウントへ送信される可能性がありました。0.2.0 へ更新し、実際のバケット所有者を確認してください。[1], [2], [4]
配達員が住所に建物があるかだけを確認し、所有者を調べない状況を想像してください。別の人が先に住所を登録して荷物を受け取れます。修正では S3 に確認時とアップロード時の両方で所有者を検証させます。[2], [1]
主要な概念と専門用語
MCP サーバー- AI アシスタント向けに操作をツールとして提供するローカルサービス。サーバープロセスの権限で動きます。[3]
フレームワーク対応
- このガイドで説明する弱点の CWE 参照: CWE-283 CWE-341
- OWASP GenAI 2025 — LLM06:2025 過剰なエージェンシー
根本原因の分析 (Root Cause)
AWS Security Agent MCP サーバーは、顧客の AWS アカウント ID とリージョンからスキャン用バケット名 security-agent-scans-<account-id>-<region> を生成します。AWS とメンテナーの通知によると、脆弱版はバケットの存在を確認しましたが、顧客アカウントの所有物かは検証していませんでした。S3 名はグローバルに一意で、アカウント ID は公開情報です。第三者が予測可能な名前を先に登録すると、サーバーがアップロードする非公開アーカイブを受け取る可能性があり、ソース、認証情報、インフラ状態が含まれ得ます。これはクラウド資源の所有確認不足と予測可能な名前の問題で、AIモデルのプロンプトインジェクションではありません。対象は 0.1.0〜0.1.5、0.2.0 は S3 操作に ExpectedBucketOwner を加え、不一致時に失敗します。更新しても既登録の名前は解放されません。実際の所有者を確認し、第三者所有ならスキャンを再開しないでください。
バケット名だけでは所有者を確認できない
| 境界 | 文書化された条件 | 運用担当者の対応 |
|---|---|---|
| 影響を受けるバージョン | awslabs.security-agent-mcp-server 0.1.0〜0.1.5 が影響を受け、0.2.0 で所有者確認が追加された。 | 0.2.0 以降へアップグレードし、実行中のパッケージバージョンを確認する。 |
| 予測可能なバケット名 | スキャン用バケット名はアカウント ID とリージョンから生成され、別の AWS アカウントが先に登録できる。 | 一致する名前はアドレスとして扱い、所有権の証明とはみなさない。 |
| アカウント間アップロード | 脆弱なサーバーは所有者を確認せず名前だけでバケットを受け入れ、非公開のスキャンアーカイブをアップロードする可能性があった。 | スキャンまたはアップロードの前に、バケットが想定アカウントの所有物であることを確認する。 |
| 修正された所有権境界 | ExpectedBucketOwner により、S3 は所有権確認時とアップロード時の両方で所有者を照合する。 | 更新後に実際の所有者を確認する。第三者が名前を所有している場合はスキャンを停止する。アップグレードでバケットは移転しない。 |
ステップ・バイ・ステップの攻撃フロー
ソースコード比較:脆弱 vs 堅牢化
以下は模式例であり、逐語的なソースではありません。存在確認だけでは不十分です。S3 は確認時と書き込み時に期待所有者を照合する必要があります。認証済み AWS ID から期待値を取得し、不一致なら中断します。更新後も所有者を別途確認してください。登録済みの名前は更新だけでは譲渡・解放されません。 AWSの資料ではHeadBucketとPutObjectの両方でExpectedBucketOwnerがサポートされ、所有者が一致しない場合は403で失敗します。fail-closedのガードとして使えますが、バケットが他者所有だと判断する前に、認可された所有者確認経路でアクセス拒否エラーを調査してください。[2], [8], [9]
ソース抜粋: アドバイザリに基づくAWS SDKの例であり、逐語的なソース差分ではありません。
# 脆弱な処理の簡略例:名前は確認しますが、所有者は確認しません。
s3.head_bucket(Bucket=bucket_name)
s3.put_object(
Bucket=bucket_name,
Key=object_key,
Body=archive_bytes,
)
# 各操作を想定するバケット所有者のアカウントに紐付けます。
expected_owner = sts.get_caller_identity()["Account"]
s3.head_bucket(
Bucket=bucket_name,
ExpectedBucketOwner=expected_owner,
)
s3.put_object(
Bucket=bucket_name,
Key=object_key,
Body=archive_bytes,
ExpectedBucketOwner=expected_owner,
)
エンジニアリング&システム堅牢化チェックリスト
- ✓
awslabs.security-agent-mcp-serverを 0.2.0 以降へ更新し、プラグイン、CI イメージ、フォークの実行版も確認する。[2], [4] - ✓スキャン前に派生バケットが想定アカウント所有か確認する。名前が見つかるだけでは証明にならない。[1], [2]
- ✓アップロードを含むすべての S3 操作に期待アカウントを
ExpectedBucketOwnerとして指定する。[8], [9] - ✓所有者不一致時は停止する。第三者が所有する場合はスキャンを止め AWS に相談する。[1]
- ✓可能なら初回利用前に顧客アカウントでバケットを作成し、最小権限と暗号化を適用する。[3], [1]
- ✓脆弱版で実行したスキャンを調べ、秘密情報が含まれる可能性があれば認証情報を更新する。[2], [1]
参考資料
- AWS Security Bulletin 2026-105-AWS — CVE-2026-87913
- Maintainer GHSA-3jxw-vj8m-8x77
- AWS Security Agent IDE integration and scan bucket workflow
- awslabs.security-agent-mcp-server 0.2.0 release
- NVD — CVE-2026-87913
- MITRE CWE-283 — Unverified Ownership
- MITRE CWE-341 — Predictable from Observable State
- Boto3 HeadBucket — ExpectedBucketOwner
- Boto3 PutObject — ExpectedBucketOwner
- 同じパッケージの関連する別の脆弱性:AWS MCP Git引数インジェクション(CVE-2026-97662)