docker cp は、コンテナからビルド成果物・テスト結果・ログ・調査用の証拠を取り出すために、CI・開発機・インシデント対応で日常的に使われる。その「取り出す」操作が、実はホストを乗っ取る書き込みプリミティブになり得た——それが CopyEscapeCVE-2026-17106)だ。Imperva Red Teamが発見したこの脆弱性は、悪意あるコンテナが docker cp の宛先ディレクトリの外へ任意ファイルを書き込める「destination escape(宛先エスケープ)」で、条件次第でホスト上のroot実行に至る。

本記事では、copyescape の仕組み・影響範囲・修正版・実際に動かして確認した自システム確認コマンド、そして紛らわしい別脆弱性 Copy Fail(CVE-2026-31431)との違いを、一次ソース(GitHub Advisory・moby issue・Docker公式ブログ)に絞って整理する。当サイトの他のコンテナ/開発ツール脆弱性はサプライチェーンセキュリティ2026|攻撃手法・防御ツール・実践チェックリストも参照してほしい。

CopyEscapeの仕組み。悪意あるコンテナがtarにsymlinkを仕込む→デーモンがtar生成→CLIがローカル展開しOSがリンク解決→宛先dstの外へ書き込み(destination escape)→runc等を上書きしroot実行
CopyEscape(copy-out)の流れ。tarに仕込まれたリンクを展開時にOSが解決し、宛先の外へ書き込む。特権実行時はruncの上書き等でroot実行に至る(出典: GHSA-hfg8-hc9c-6c3h + Imperva報告を基に作図)。
30秒でわかる CopyEscape(2026年8月時点)
  • 正体docker cp / sbx cp のtar展開の欠陥(CVE-2026-17106・GHSA-hfg8-hc9c-6c3h)。CVSS 4.0で7.1(High)、CWE-22+CWE-59。
  • 何が起きる:悪意あるコンテナが宛先の外へ任意ファイルを書き込み、特権実行時はrunc上書き等でroot実行
  • 誰が危険:CI・開発者端末・特権自動化・インシデント調査・AIエージェントのSandbox(sbx cp)。
  • 修正版:Engine&CLI 29.7.2/Desktop 4.86.0/Sandboxes 0.38.0(29.7.0は退行あり=29.7.2以降が完全修正)。
  • 注意:名前が似た Copy Fail(CVE-2026-31431)は別物(カーネルの権限昇格)。混同禁物。

CopyEscape(CVE-2026-17106)とは——docker cpのdestination escape

一言でいえば、悪意あるコンテナが docker cp のコンテナ→ホストコピー時に、指定した宛先の外へファイルを作成・上書きできる脆弱性だ。公式のGitHub Advisory(GHSA-hfg8-hc9c-6c3h)は原因をこう記述する。「The extractor decides where each archive entry lands using lexical string checks and then performs the filesystem operation on a path that is resolved by the OS, so a links introduced by the archive can be followed out of the destination directory.」——展開器は各エントリの配置先を字句的な文字列チェックで決めるが、実際のファイル操作はOSが解決したパスに対して行うため、アーカイブに仕込まれたリンクをたどって宛先ディレクトリの外へ出られる(原文ママ)。分類はCWE-22(パストラバーサル、path traversal)+CWE-59(リンク追跡、link following)、CVSS 4.0の基本値は7.1(High)、ベクトルは CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:A/VC:H/VI:H/VA:H/... だ。数値の出所を明確にしておくと、この 7.1 とベクトル・CWEは公式のGitHub Advisory(GHSA-hfg8-hc9c-6c3h)から直接確認した一次情報である。もしNVDや二次報道が別のスコアを示していても、まずは一次のGHSAを優先して読むのが安全だ。

ベクトルの読み方が実態をよく表している。AV:L(ローカル)・AT:P(特定の前提条件が必要)・PR:N(権限不要)・UI:A(操作者が実際にコピーを実行する必要がある)——つまり「オペレーターが悪意あるコンテナに対して docker cp を実行する」という、ごくありふれた操作が引き金になる。

CopyEscapeの怖さは「特殊な攻撃」ではなく「日常的な docker cp が、相手のコンテナ次第でホスト書き込みに化ける」点にある。取り出す側が無防備なら、コンテナが罠を仕込める。

この docker cp 脆弱性は、厳密には「コンテナ内部から外へ抜け出す」古典的なコンテナエスケープとは向きが逆だ。コンテナ内で権限昇格して脱獄するのではなく、ホスト側の docker cp という操作を利用して、コンテナが用意した罠をホストに展開させる。つまり攻撃の主導権はコンテナのファイル内容にあり、発火のトリガーはホスト側オペレーターの「取り出し」操作になる。結果として得られるのは実質的なコンテナエスケープ(ホストへの任意書き込み)だが、経路が docker cp である点が新しい。

読者の3つの問いへの答え
何ができる(攻撃者視点):悪意あるコンテナが `docker cp` の宛先の外へ任意ファイルを書き込み、特権実行時はroot実行に至る。
何を解決する(防御視点):29.7.2 以降への Docker アップデートで根本修正。更新前は信頼できないコンテナへの `docker cp` を避ける。
何を確認する:`docker version` でEngineが 29.7.2 未満か、`sbx version` で 0.38.0 未満かを点検する。

仕組み:copy-out がなぜホスト書き込みになるのか

鍵は「docker cp はバイト単位の直接コピーをしていない」ことだ。コンテナ→ホストのコピー docker cp container:/path ./dst では、デーモンが要求されたコンテナ内パスを走査してtarアーカイブを組み立て、それをCLIへストリームし、CLIがローカルで展開する。ここで問題なのは、tarの中身はコンテナ側が完全に制御できる点だ。コンテナは、ターゲットが宛先ディレクトリの外(たとえば /usr/bin/runc~/.ssh/authorized_keys)を指すシンボリックリンク/ハードリンクのエントリをtarに埋め込める。CLIの展開処理がそのリンクをOS上で解決して書き込むと、書き込みは ./dst の外へ逃げる——これがdestination escapeだ。

flowchart TD A["悪意あるコンテナ
tarにsymlinkエントリを仕込む"] --> B["dockerデーモン
コンテナ内パスを走査しtar生成"] B --> C["docker CLI(ホスト側)
tarをローカル展開"] C --> D{"リンクをOSが解決"} D -->|"宛先dst内"| E["正常なコピー"] D -->|"宛先dstの外を指す"| F["ホストの任意パスへ書込
例: runc / rcファイル / SSH設定"] F --> G["特権実行なら
次回Docker起動時にroot実行"]

なぜ「字句チェックだけでは防げない」のかは、シンボリックリンクの性質を思い出すと腑に落ちる。展開器は各エントリのパス文字列を見て「./dst の内側だな」と判断するが、実際に open() して書き込む段では、途中のパス要素がシンボリックリンクならOSがそれを別の場所へ解決する。つまり「文字列としては内側」でも「解決後の実体は外側」というズレが生まれる。TOCTOU(判定と操作の間の状態差)にも似た、リンクを介した古典的な陥穽だ。tarのようなアーカイブは任意のリンクエントリを表現できるため、コンテナ側がこのズレを意図的に作り込める。

影響を受けるのは基盤ライブラリ moby/go-archive の展開系関数(UnpackUnpackLayerUntar/UntarUncompressedApplyLayer)で、0.2.2未満が脆弱、0.3.0で修正されている。これらの関数は docker cp だけでなくイメージのレイヤ適用など複数の経路で使われるため、修正はライブラリ層でまとめて行われた。書き込みは docker cp(や sbx cp)を実行したユーザー/自動化プロセスの権限で行われる。だからこそ、sudo docker cp やroot権限のCIジョブのような特権実行が最も危険だ。Impervaの報告では、書き込みプリミティブで runc バイナリを上書きし、次にDockerがそれを呼んだ瞬間にroot実行へ至る経路が具体的に示されている。

影響範囲:docker cp / sbx cp とAIエージェントSandbox

影響を受けるコマンドは2つある。通常の docker cp と、Docker Sandboxes の sbx cp(AIコーディングエージェントのワークフロー向け)だ。後者が本サイトの読者に直結する。AIエージェントに任意コードを書かせ、その成果物をホストへ取り出す——この「取り出し」に sbx cp を使うため、信頼できない/侵害されたエージェントSandbox内で作られた成果物が、同じdestination escapeでホストを危険にさらし得る。エージェント実行基盤の安全性を、モデルの振る舞いだけでなく「成果物の取り出し経路」まで含めて考える必要がある、という警鐘だ。

影響を受けるバージョンと安全な状態を整理する。

対象 影響を受けるバージョン 安全な状態
Docker Engine & CLI 29.7.2 未満(29.7.0は退行あり) 29.7.2 以降
Docker Desktop 4.86.0 未満 4.86.0 以降(Engine 29.7.2 同梱)
Docker Sandboxes(sbx) 0.38.0 未満 0.38.0 以降
基盤ライブラリ moby/go-archive 0.2.2 未満 0.3.0 以降

最も影響を受ける役割は、CIシステム、開発者端末、特権を持つ自動化、インシデント対応で疑わしいコンテナからデータを取り出す作業、そしてAIエージェントのSandboxだ。とりわけ調査・フォレンジックの現場は「疑わしいコンテナ」を相手にする前提なので、無防備な docker cp は自らを危険に置く。

CIが危険な理由をもう少し具体化すると、CIジョブは往々にして特権(root、あるいはDockerソケットへのフルアクセス)で動き、ビルドやテストのために信頼境界の外から来たイメージ/コンテナを扱う。プルリクエスト起点のビルドで外部貢献者のDockerfileをそのまま動かし、その成果物を docker cp で取り出す——という一見普通のパイプラインが、CopyEscapeの理想的な発火条件を満たしてしまう。攻撃者は悪意あるイメージをPRに紛れ込ませ、CIが成果物を取り出す瞬間にホスト(CIランナー)へ書き込む。ランナーが握るクラウド資格情報やパブリッシュトークンを考えれば、これは前半で述べたサプライチェーン侵害の入口とも地続きだ。「取り出す」操作の無防備さが、そのまま供給チェーンの穴になる。

AIエージェントのSandbox(sbx cp)についても同じ構図が当てはまる。エージェントに自由にコードを書かせ・実行させる設計では、Sandbox内のファイルは実質「信頼できない入力」だ。その成果物をホストへ sbx cp で回収する経路が destination escape を許せば、エージェントが生成物に罠を仕込むだけでホスト側へ手が届く。エージェント実行基盤を評価するときは、隔離の強さ(どれだけ閉じ込められるか)だけでなく、隔離を越えてデータを出す経路の安全性まで見る必要がある——CopyEscapeはその盲点を突いた事例だ。

タイムライン:開示から29.7.2までの経緯

修正が一度で決まらなかった点が、この脆弱性の実務的な要注意ポイントだ。以下のタイムラインは moby のリリース・issueの実データと各社報告に基づく。

日付(2026年) 出来事
約4月 協調的開示が開始(初期修正の退行により複数回延長)
6月24日 再現報告 issue #52948 が公開(ricardobranco777、PoC参照)
7月24日 Docker が CVE-2026-17106 を割当、8月初旬の協調公開を計画
7月30日 go-archive v0.3.0 + Engine/CLI 29.7.0 が展開修正を出荷(ただし機能退行
7月31日 ハードニングによる重大な機能退行が報告される
8月6日 Engine/CLI 29.7.2 と Docker Sandboxes 0.38.0 を公開(退行解消の完全修正)
8月10日 Docker Desktop 4.86.0 公開・一般公開(disclosure)

教訓は明確だ。「29.7.0で直った」と早合点しないこと。29.7.0は絶対パスのハードリンクを持つイメージを弾く、古いLinuxカーネルで docker cp やイメージpullが失敗する、といった退行を招いた。完全な修正は 29.7.2 であり、安全な下限はここだ。この「セキュリティ修正が機能退行を生み、追加リリースで解消される」パターンは珍しくない。パッチ適用の運用では、最初のセキュリティリリースに飛びつくより、退行報告が落ち着いた次のパッチまで見て適用版を選ぶほうが、結果的に安定することもある(ただし公開済みPoCがある本件では、退行に注意しつつ29.7.2へ速やかに上げるのが正解だ)。なお、公開済みのPoCbikini/exploitarium 内)が存在するため、攻撃の再現ハードルは低い。パッチ適用の緊急度は高いと考えるべきだ(本記事はPoCの内容には触れない)。

CopyEscapeの自システム確認コマンド(実測)+緩和策

まず自分のDockerが影響を受けるかを確認する。以下は当環境(Docker 29.3.1)で実際に実行し、挙動を確認したコマンドだ。

# クライアント/サーバ(Engine)の版数を確認
docker version --format 'Client:   Server: '
docker --version

# Engineだけ取り出して比較(29.7.2 未満なら影響あり)
docker version --format ''

# Docker Sandboxes を使う場合(0.38.0 未満なら影響あり)
sbx version 2>/dev/null || echo "sbx未導入(AIエージェントSandboxを使う場合のみ対象)"

当環境では Client: 29.3.1 が返り、29.7.2 未満のため「影響あり(要アップデート)」と判定できた(sbx は未導入)。Docker Desktop 利用者は Settings → About で 4.86.0 以降かを確認する。判定は単純で、Engine/CLIが 29.7.2未満・Desktopが 4.86.0未満・Sandboxesが 0.38.0未満、または moby/go-archive 0.2.2未満 をベンダリングしていれば脆弱だ。

見落としがちなのは、Docker CLIを内部でベンダリングしている周辺ツールだ。CI用のオーケストレーター、独自のコンテナ実行基盤、moby/go-archive を直接依存に持つGo製ツールなどは、ホストのDockerを29.7.2に上げても、そのツール内蔵の古いライブラリが残っていれば脆弱なままになり得る。自組織のツールチェーンで go-archive のバージョンを go list -m all | grep go-archive のように棚卸しし、0.3.0以降であることを確認しておくと安心だ。バージョン確認は「ホストのDocker」だけで終わらせず、tar展開を行う全ての経路に広げるのが定石になる。

緩和策(すぐに更新できない場合)
最善は Engine/CLI 29.7.2 以降・Docker Desktop 4.86.0 以降・Docker Sandboxes 0.38.0 以降への更新です。直ちに更新できない場合の回避策(Imperva/Docker報告より):
信頼できない/稼働中のコンテナに対して `docker cp` を実行しない
・コピー前にコンテナを停止する
`sudo docker cp`(sudo経由のコピー)を排除し、CIでは最小権限を徹底する
・疑わしい/フォレンジック用データは、使い捨ての隔離環境(VMや使い捨てアカウント)でのみ取り出す

Copy Fail(CVE-2026-31431)との違い——混同注意

名前が似た別の脆弱性があるので、はっきり区別する。両者は同じ2026年・同じDocker界隈で「Copy…」という似た名前だが、層もCVEも修正も違う。

項目 CopyEscape Copy Fail
CVE CVE-2026-17106 CVE-2026-31431
ユーザー空間(docker cp / sbx cp のtar展開) Linuxカーネル(AF_ALG暗号サブシステム algif_aead
何が起きる 宛先エスケープでホストファイル上書き→root実行 ページキャッシュ経由でsetuidバイナリ破壊→ホストroot昇格
docker cpとの関係 まさにdocker cpの脆弱性 docker cpとは無関係
主な対処 Engine 29.7.2 等へ更新 Engine v29.4.3+(seccomp/AppArmor で AF_ALG を遮断)

Docker公式ブログもCopy Failについて「docker cp コマンドとは何の関係もない」と明言している。名前の類似で対処を取り違えないこと——CopyEscapeの対策(cp周りの運用見直し+29.7.2更新)と、Copy Failの対策(カーネル/seccomp側)は別物だ。

実務では、この2つを「Docker周りの2026年の“Copy系”脆弱性」とひとまとめに記憶してしまうと、片方だけ対処して安心する事故が起きやすい。チェックの粒度を分けておくとよい。CopyEscape側は「Docker Engine/CLI/Desktop/Sandboxes のバージョンと、tar展開を行う周辺ツールのgo-archiveバージョン」を見る。Copy Fail側は「Linuxカーネルのバージョンと、Docker Engineが AF_ALG を seccomp/AppArmor で遮断しているか(v29.4.3+ の既定プロファイル)」を見る。対象レイヤが違うので、点検リストも別々に持つのが安全だ。共通するのは「Dockerを新しめの安定版に保つ」ことだが、それだけで両方が塞がると誤解しないほうがよい。

まとめ

CopyEscape(CVE-2026-17106)は、docker cp / sbx cp のtar展開に潜む destination escape で、悪意あるコンテナがホスト上の任意ファイルを上書きし、特権実行時は runc上書き等でroot実行に至る(CVSS 7.1・High、CWE-22+59、go-archive 0.2.2未満が脆弱)。日常的な「コンテナからの取り出し」が攻撃面になる点、そして AIエージェントのSandbox(sbx cp) も対象である点が、本サイトの読者にとっての要注意ポイントだ。対処は明確で、Engine/CLI 29.7.2・Desktop 4.86.0・Sandboxes 0.38.0 以降へ更新(29.7.0は退行ありで不可)、更新できない間は信頼できないコンテナへの docker cpsudo docker cp を避ける。公開済みPoCがあるため緊急度は高い。名前が似た Copy Fail(CVE-2026-31431・カーネルの権限昇格)とは別物なので混同しないこと。関連するコンテナ脆弱性はDocker認可バイパスCVE-2026-34040、エージェント実行基盤の攻撃面はAnthropic MCP stdio RCE脆弱性も併せて参照してほしい。

参照ソース

GitHub Advisory GHSA-hfg8-hc9c-6c3h(CVE-2026-17106) — 原因記述・CVSS7.1・CWE-22/59・影響関数・go-archive 0.2.2未満/0.3.0の一次情報
moby/moby issue #52948 — 再現報告・PoC参照・対象バージョン
moby/moby releases(29.7.0/29.7.2) — 29.7.0の退行と29.7.2での完全修正
Docker公式ブログ Copy Fail(CVE-2026-31431) — CopyEscapeと別物であることの一次確認