この記事で扱われているのは、2026年4月29日に公開された CVE-2026-31431、通称 Copy Fail です。
ざっくり言うと、ローカルの一般ユーザーが、公開された Python スクリプトを使うことで root shell を取れてしまう という話です。
ここでいう root shell は、すごく簡単に言えば「管理者権限のコマンド操作ができる状態」です。
普通のユーザーでは触れないファイルを読めたり、設定を変えたりできるので、かなり強い権限です。
この脆弱性が面白いのは、単に「Linux ホストで危ない」だけではなく、Linux container の攻撃にも転用できる点です。
コンテナは Web サービス、開発環境、CI(継続的インテグレーション)ジョブなど、かなり広く使われています。だから、こういう脆弱性は「一部の研究ネタ」ではなく、実運用に直撃しうる話だと思います。
筆者は、Docker から Podman に移行した理由のひとつとして、Podman のセキュリティ姿勢を挙げています。
特に重要なのが、rootless でコンテナを動かしやすいことです。
rootless は、その名の通り root じゃない一般ユーザーでコンテナを動かす方式 です。
たとえばユーザー bar(UID 1001)が自分で podman run を実行すると、コンテナの中で動くプロセスは、ホスト側から見ると bar が起動したプロセスになります。
Docker の典型的な構成だと、クライアントは一般ユーザーでも、裏で rootful daemon が動いていて、最終的に root がコンテナを起動することが多いです。ここが Podman と大きく違うところです。
この違い、地味に見えてかなり重要です。
個人的には、「誰が最終的にプロセスを生んでいるのか」 はセキュリティを考える上での核心だと思います。
記事では、bar という一般ユーザーを作り、そのユーザーで Podman を使って HTTP server コンテナを起動しています。
コンテナの中で動く python3 は、コンテナ内では root に見えます。
でもホスト側では、実際には bar のプロセスです。
ここで引っかかるのが、次の疑問です。
「コンテナ内で root って言われても、ホスト root とは違うのでは?」
その通りです。ここで出てくるのが user namespaces です。
user namespaces は、コンテナの中と外で UID/GID を別物として扱える仕組みです。
root に見えるbar に対応している記事では /etc/subuid にある設定も紹介されています。
これは「このユーザーに、どの UID 範囲を割り当ててよいか」を決めるものです。
要するに、コンテナ内の root は“見かけ上の root”であって、ホストの本物の root ではないということです。
この仕組みのおかげで、たとえコンテナ内で何か悪いことが起きても、ホスト全体に直結しにくくなります。
筆者は podman unshare を使って、namespace の中と外でホームディレクトリの所有者がどう見えるかを比較しています。
bar:barroot:rootこのズレが、まさに user namespace の本質です。
こういう実験は、言葉だけで説明されるよりずっと腑に落ちます。私もこういう「見え方の違い」を実際に確かめる説明は好きです。
ここで次のポイントが出てきます。
コンテナ内の root でも、ホストの root と同じではない。
さらに、コンテナ内の root ができることには、Linux capabilities という制限がかかります。
capabilities は、ざっくり言えば root の権限を細かく分割したものです。
昔の root は「全部できる」存在でしたが、capabilities を使うと、
chroot を使うなどの権限を、必要なものだけ渡せます。
記事では、apt install が動くときに複数の capabilities が与えられていることを確認しています。
これは、パッケージのインストールにいろいろな特権操作が必要だからです。
逆に、--cap-drop=all で全部の capability を消すと、apt が失敗します。
つまり、必要な権限を少しでも削りすぎると、コンテナは普通に壊れるわけです。ここがセキュリティの難しさでもあります。
個人的には、これはすごく現実的な話だと思います。
セキュリティは「全部禁止すれば勝ち」ではなく、何を許すと何が壊れるかを見極める作業なんですよね。
ここが記事の中心です。
結論として、Copy Fail は rootless container でも exploit でき、コンテナ内の root shell を取れると筆者は確認しています。
ただし重要なのは、その影響範囲です。
rootless Podman では、コンテナの root は ホストの unprivileged user が持てる範囲に制限されるため、被害はかなり限定されます。
つまり、
ということです。
これはかなり大事なポイントです。
「コンテナが壊れたら全部終わり」というわけではない。
でも同時に、「コンテナが壊れても大したことない」と軽く見るのも危険。
このバランス感覚が、この記事の価値だと思います。
記事の後半では、defence in depth、つまり 防御を何重にも積む話が出てきます。
これ、セキュリティでは本当に大事です。1枚の壁に頼ると、そこが破られた瞬間に全部終わるからです。
イメージを read-only にする考え方です。
書き込み可能な部分を減らせば、侵害後に勝手な変更をされにくくなります。
CPU やメモリ、プロセス数などに制限をかけることです。
暴走したコンテナがホストを食い尽くすのを防ぎます。
コンテナ内で使えるコマンドを絞る方法です。
攻撃者が使える道具が少なければ、それだけ悪用しにくくなります。
ネットワークの出入り口を制御することです。
コンテナが侵害されても、外部への通信や横展開をしにくくできます。
このへんは地味ですが、実務ではかなり効きます。
現実の攻撃って、派手なゼロデイだけでなく、「侵害された後に何ができるか」で被害が決まることが多いので。
この記事の一番おもしろいところは、単に「脆弱性があった」で終わらず、rootless container の防御効果を実地で確認している点です。
私の感想としては、Podman の rootless 設計はかなり筋がいいです。
コンテナ内で root を取られても、ホストの root に直結しにくい。これは安心材料として大きいです。
ただし、安心しすぎるのも危険です。
rootless でもコンテナは侵害されるし、侵害されたコンテナは次の攻撃の足場になりえます。
だからこそ、
という多層防御が必要なんだと思います。
Copy Fail は、コンテナの世界でも無視できない脆弱性です。
ただし Podman の rootless container は、ホスト全体への影響をかなり抑える設計になっています。
この記事を読んで強く感じるのは、「コンテナは便利だが、魔法ではない」ということです。
rootless、user namespaces、capabilities という仕組みは、地味だけど効く。
そして、その地味さこそが信頼できるセキュリティの土台なんだと思います。