2026年9月6日 日曜日
AI時短ラボ
検証· 約17

コーディングエージェントのコンテナからCVEを99%消す──Echo×NanoClawの舞台裏を読む

コンテナセキュリティ企業Echoが、個人向けAIエージェントツールNanoClawとの提携で行ったCVE削減の手順を公式ブログで公開した。Trivy・Grype・Wizによる多重スキャン、安全なバージョンアップ、そして`expat`ライブラリのCVE-2025-59375のような『バックポートが極めて難しい』脆弱性の修正過程を、ブログ本文の記述に沿って追う。

コーディングエージェントのコンテナからCVEを99%消す──Echo×NanoClawの舞台裏を読む
執筆・編集:
目次

コンテナイメージのセキュリティを専門とする企業Echoが、個人向けAIエージェントツール「NanoClaw」との提携で行ったコンテナ内CVE(既知の脆弱性)削減の手順を、公式ブログで詳細に公開した。ブログ本文によれば、対象のコンテナイメージから約1,400件のCVEを削減し、その削減率はおよそ99%だったという。

3行まとめ

  • EchoがNanoClawのコンテナイメージからCVEを約1,400件、削減率にしておよそ99%削減したと公式ブログで報告
  • 手順はTrivy・Grype・Wizによる多重スキャン→安全なバージョンアップ→バックポート(新版のパッチを旧版へ移植)→自動ミラーリングの4段階。バックポート作業自体はEchoの「Backporter agent」が適用・ビルド・テスト・診断・修正を自動で繰り返し、人間のエンジニアは最終レビューと承認のみを行う
  • NanoClawはAnthropicのAgents SDK上で直接動く、WhatsApp・Telegram・Slack・Discord・Gmail等に接続するコンテナ実行のエージェントツールで、GitHubで30,643スター(確認時点)を集めている

何をやったか——4段階のCVE削減プロセス

ブログはこう始まる。

Last week we announced Echo's partnership with NanoClaw, designed to extend the vision and security of the open source project. In this post, we want to pull back the curtain and show you exactly how Echo's agentic hardening process works.

(先週、私たちはNanoClawとの提携を発表した。このオープンソースプロジェクトのビジョンとセキュリティを拡張することを目的としたものだ。この記事では、Echoのエージェント的ハードニングプロセスが実際にどう動いているか、舞台裏を見せたい)

手順は大きく4段階に分かれる。

ステップ1:安全にバージョンを上げられるものから片付ける。TrivyとGrypeとWizという独立した3つのスキャナーでNanoClawの純正コンテナイメージをスキャンし、後方互換性の高いことが知られているChromiumなどは安心してバンプする。ブログによれば、Chromium関連のCVEを除いても、まだ約600件の脆弱性が残ったという。

ステップ2:本当のリサーチが必要なバンプ。メジャーバージョンの飛び越えが必要な更新は、そのままでは動かないことが多い。ブログは@Hono/node-serverの例を挙げ、スキャナーが「大きなメジャージャンプが必要」と判定したケースでも、実際にソースコードを調べたところ、より近いバージョン(1.19.14)で既に修正されていたことが分かった、というエピソードを紹介している。この発見はEcho自身がアップストリームのアドバイザリに反映したという。

ステップ3:パッチとバックポート。ディストリビューションのメンテナーがメジャーバージョンでしか修正しない、いわゆる「won't fix」判定のCVEについては、Echoが直接ソースコードにパッチを当てる。ブログはこの作業を3つの課題のバランスと表現している。

Finding the right fix - understanding where the bug is, tracing the fixing commit, and confirming the fix is genuinely safe and complete […] Applying it without breaking anything […] Validating - compatibility, functionality and that the CVE was truly resolved.

(正しい修正を見つけること――バグの所在を理解し、修正コミットを追跡し、その修正が本当に安全かつ完全であることを確認する。〔中略〕何も壊さずに適用すること。〔中略〕検証――互換性、機能性、そしてCVEが本当に解決されたことの確認)

ステップ4:ミラーリングと同期。ファクトリーが結果を検証し、利用可能なアップストリームの修正がすべて適用されたことを確認すると、イメージはEcho storeへビルド・プッシュされ、NanoClaw側のレジストリへ数分以内に自動同期される。ブログはEchoのポリシーについてこう明言している。

Echo only implements official fixes. We don't create custom patches to ensure application compatibility and safety, minimal drift from upstream, and a trustworthy process for devs using Echo OS.

(Echoは公式の修正のみを実装する。独自のカスタムパッチは作らない。それがアプリケーションの互換性と安全性、アップストリームからの乖離の最小化、そしてEcho OSを使う開発者にとって信頼できるプロセスを保証する)

最も難しい例——XMLパーサーのメモリ増幅攻撃CVE-2025-59375

ブログがバックポートの難しさを示す具体例として選んだのが、expat(XMLパーサー)のCVE-2025-59375だ。選んだ理由をブログはこう説明する。

It's the hardest kind of backport there is - a security fix that isn't a bounds check but a new subsystem threaded through the middle of the library, carried from a newer upstream release down into the older version we ship, and one where the upstream maintainer explicitly warned distributors not to attempt a partial cherry-pick.

(これはあり得る中で最も難しい種類のバックポートだ。境界チェックの追加ではなく、ライブラリの中枢を貫く新しいサブシステムであり、新しいアップストリームリリースから私たちが提供する旧バージョンへと持ち込む必要があり、しかもアップストリームのメンテナー自身が「部分的なチェリーピックを試みるな」と明示的に警告していたものだ)

脆弱性の中身は、整形式の小さなXML文書が異常に大きなヒープ確保を引き起こすというものだ。

An attacker sends a small, entirely well-formed XML document and the parser allocates a wildly disproportionate amount of heap. Upstream's own figure: a ~250 KiB document caused roughly 800 MiB of allocation - an amplification factor of about 3,300.

(攻撃者は小さく、完全に整形式なXML文書を送るだけで、パーサーは著しく不釣り合いな量のヒープを確保してしまう。アップストリーム自身の数字によれば、約250KiBの文書がおよそ800MiBの確保を引き起こす――およそ3,300倍の増幅率だ)

expatには既に「billion-laughs」対策(出力が8MiBを超えると100倍制限をかける)があったが、この対策はパースされた出力バイト数だけを見ており、パーサー内部のハッシュテーブルや文字列プール、DTDの足場構造といった実際のヒープ使用量は見ていなかった。修正には、すべての内部確保をexpat_malloc/expat_free/expat_realloc経由にして各ブロックにサイズ情報を持たせる、parserCreateに親パーサー引数を追加して外部エンティティの子パーサーがルートパーサーの予算を消費するようにする、といった侵襲的な変更が必要だったとブログは説明している。

ブログには、この作業がどう決着したかも記されている。アップストリームの修正は17ファイルにまたがるが、Echoが提供する旧バージョンでは事情が異なるため、参照パッチはそのまま適用できず、Echoは9ファイルに触れる形でこれを移植した。ここでもEchoは「適用(apply)」ではなく「リベース」として扱うアプローチを取り、自社のバックポートエージェントに「適用→ビルド→アップストリームのテストスイート全体を実行→失敗を分類→専用のフィクサーに渡す→合格するまで繰り返す」というループを丸ごと任せたという。

このパッチ固有で解決が必要だった技術的な課題として、ブログは3点を挙げている。

課題 内容
ビルドガードの改名 修正は#ifdef XML_DTDでトラッカーを囲むが、Echo側のバージョンではこのマクロが2.6.0でXML_GEに改名済み。旧名のままだとプリプロセッサが修正全体を静かに無効化し、ビルドは通りテストも通り、スキャナーは「パッチ適用済み」と判定するのに、脆弱性は実際には残るという、この作業全体で最も危険な失敗モードになる
テストスイートの再編 アップストリームは単一のruntests.cを分割済みで、パッチのテスト変更をalloc_tests.cnsalloc_tests.cに振り分け直す必要があった。参照パッチが8ファイルなのに対しEcho側が9ファイルになる理由はこれ
修正が正しいために壊れるテスト 一部の既存テストは「realloc失敗が一定回数起きてもパースは生き残る」ことを前提にしていたが、修正後は前提が変わり、テストの調整が必要だった。テスト修正エージェントには「CVEパッチ自体以外は変更しない」「テストを弱める・スキップ・無効化しない」という厳格なルールを課したという

(出典:Echo公式ブログ本文)

最終的なパッチは9ファイル・64ハンク・追加786行/削除112行で、アップストリームのテストスイート全体が通過する形に収まった、とブログは報告している。

結果——「残った少数は監視を続ける」

ブログの結果セクションはこうまとめている。

We eliminated roughly 99% of the CVEs. The handful that remain are going to keep being monitored by our factory and resolved as soon as its possible.

(私たちはCVEのおよそ99%を削減した。残ったわずかな数は、私たちのファクトリーが監視を続け、可能になり次第解決していく)

FAQセクションでも同様の数字が繰り返されている。

Echo eliminates roughly 99% of CVEs versus the hundreds or thousands found in comparable runtimes. The handful that remain are vulnerabilities with no available upstream fix, patch, or bump.

(Echoは、比較対象となる他のランタイムで見つかる数百〜数千件のCVEに対して、およそ99%を削減する。残るわずかな脆弱性は、アップストリームの修正・パッチ・バンプが利用できないものだ)

タイトルにある「1,400件」という数字は、記事タイトル自体("How we eliminated 1,400 CVEs in NanoClaw's container images")に由来する。本文中では「99%」という削減率の記述が中心で、削減前後の絶対件数を示す比較グラフ(スキャン結果の画像)はブログに掲載されているが、画像内の具体的な数値をテキストとして読み取ることは今回の取得方法(HTML本文の抽出)ではできていない。

CVE-2025-59375を公式アドバイザリで裏取りする

Echoのブログが挙げるCVE-2025-59375について、GitHub Security Advisory(GHSA-vjqp-pjp6-xcxx)を確認したところ、ブログの記述と食い違わない内容が確認できた。

"libexpat in Expat before 2.7.2 allows attackers to trigger large dynamic memory allocations via a small document that is submitted for parsing."

(訳:Expat 2.7.2より前のlibexpatは、パース対象として提出された小さな文書によって、攻撃者が大規模な動的メモリ確保を引き起こすことを許してしまう)

深刻度は「high」、CVSS v3スコアは7.5(AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)、該当するCWEは「CWE-770(Allocation of Resources Without Limits or Throttling=制限のないリソース割り当て)」と分類されている。公開日は2025年9月15日。

さらに、アドバイザリが参照している修正元のプルリクエストlibexpat/libexpat#1034(タイトル「[CVE-2025-59375] Start tracking and limiting use of dynamic memory (fixes #1018)」)をGitHub APIで確認したところ、変更ファイル数17・追加899行・削除110行で、2025年9月15日にマージされていた。ブログ本文にあった「アップストリームの修正は17ファイルにまたがる」という記述は、この公式プルリクエストのchanged_filesの値と一致することを確認できた(Echo側の移植が9ファイルで済んだ、という数字自体はブログの記述のみに基づいており、Echo側の実際のパッチファイルを本記事で直接確認したわけではない)。

画像内のスキャン結果グラフの具体的な数字は読み取れていない

ブログ本文を再取得したことで、expatバックポートの結末(9ファイル・64ハンク・+786/-112行)と、NanoClaw自体の説明(Anthropic Agents SDK上で動く、WhatsApp・Telegram・Slack・Discord・Gmailなどに接続するコンテナ実行のエージェントツール、GitHubで30,643スター)は判明した。一方、ブログには「Scan results comparison」というスキャン結果比較の画像が掲載されているが、画像内の数値はテキスト抽出の対象外であり、本記事では文章として明記されている「約600件」「約99%」「1,400件(タイトルより)」「Hermes・OpenClawとの比較」といった数字・記述のみを扱っている。expatバックポートの「アップストリームの変更が17ファイル」「参照パッチが8ファイル」「Echo側が9ファイル」という3つの数字はブログの説明通りに記載しており、このうち「17ファイル」についてはGitHub上の公式プルリクエスト(libexpat/libexpat#1034)のchanged_filesと一致することを確認した。ただし「参照パッチが8ファイル」というブログ側の記述、およびEcho側の実際のパッチファイル(9ファイル)そのものは、Echo社内の非公開リポジトリにあるとみられ、本記事では直接確認できていない。この記事を書いている自分自身は、NanoClawもEcho OSも実際に導入して動かした経験がなく、CVE削減率の妥当性を独自に検証したわけではない。ブログが示す数字と手順の紹介にとどまる。

関連記事: Docker SandboxesとYOLOモード / AI検出ツールは「両方向に壊れている」

感想・指摘はコメント欄へ。

シェア: ポスト はてブ

出典・参照資料

AIニュースの解説を動画でも

YouTubeでは注目ニュースの背景を解説し、Xでは新着記事をお知らせしています。

コメント

まだコメントはありません。最初のコメントを書いてみませんか?

AIについて聞きたいことはありますか?

質問箱で無料で受け付けています。回答は公開され、他の方の参考にもなります。

質問箱を見る →

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

AIの新しい発表を、出典付きで整理して届けます。

関連記事