aws-samples / aws-samples/sample-autonomous-cloud-coding-agents

registry: symlinked .mcp.json exfiltrates secret to a different tracked path + arbitrary-file-write (#665 B4 #1)

オープン
#758 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る
registry security
主要言語
TypeScript
スター
143
フォーク
46
平均マージ
3日 10時間
マージ済み PR(30日)
24

説明

**Source:** BLOCKING #1 from @scottschreckengaust's review of #665 — https://github.com/aws-samples/sample-autonomous-cloud-coding-agents/pull/665#pullrequestreview-4915535549 (`agent/src/registry/loader.py:190`)
**Parent:** #246 · **Sibling blockers:** the fail-open guard and the skip-worktree data-loss issues (linked below)

## Problem
`apply_mcp_assets` computes `mcp_path = os.path.join(repo_dir, ".mcp.json")` and opens it `"w"`. Python's `open(..., "w")` **follows symlinks**, so if the cloned repo ships `.mcp.json -> config/mcp.json` (both tracked — a normal shared-config layout), the resolved **unredacted** MCP runtime (bearer headers, `url?token=`, `--api-key` args) lands in `config/mcp.json`. The `_protect_mcp_json_from_commit` guard then flags only the *symlink's* index entry (`.mcp.json`), leaving `config/mcp.json` unguarded — so `post_hooks.ensure_committed` (`git add -u`) stages it and `ensure_pushed` pushes the secret into the PR's git history. Reproduced against the real loader at `0b06ff5`.

The same symlink-follow is an **arbitrary-file-write primitive**: `.mcp.json -> .github/workflows/ci.yml` overwrites the workflow (and `add -u` stages it); `.mcp.json -> .git/config` corrupts repo config so every later git call fails. Repo layout is attacker-controlled input — the agent clones untrusted repos / PR branches (`repo.py:299`).

## Fix
Refuse a non-regular target before writing:
```python
if os.path.islink(mcp_path):
raise RegistryAssetLoadError(f"refusing to write resolved MCP config through a symlink: {mcp_path}")
```
(`os.open(..., O_NOFOLLOW)` is the race-free variant.)

> Note: Scott's recommended durable fix — route registry MCP servers through the SDK in-process `mcp_servers` option instead of writing `.mcp.json` at all — closes this together with the sibling blockers. If that path is taken, this issue is subsumed.

## Acceptance
- A symlinked `.mcp.json` (pointing at a second tracked file, or into `.git`/`.github`) causes `apply_mcp_assets` to raise, not write-through
- Regression test: symlink `.mcp.json` at a second tracked file, assert raise + `git add -u && git diff --cached` empty

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

agent/src/registry/loader.py:190 から開始して apply_mcp_assets を追跡し、その後、信頼できない checkout のコンテキストについて repo.py:299 を確認します。別の追跡対象ファイルを指す symlink の .mcp.json を使った回帰テストを追加し、対象を変更せずに操作が例外を発生させることを検証します。関連する registry テストを実行し、git add -u && git diff --cached が引き続き空であることを確認します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
git, python
領域
backend, security
issue の種類
バグ
難易度
3/5
見積もり時間
1〜2日
活発さ
静か
明瞭さ
明確に書かれている
初心者へのやさしさ
72/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。