Aikido

コンテナセキュリティは困難です — Aikido Container AutoFixで容易に

執筆者
マッケンジー・ジャクソン

コンテナセキュリティはベースイメージから始まります。
しかし、ここに落とし穴があります。

  • 単純にベースイメージの「最新」バージョンにアップグレードするだけでは、アプリケーションが動作しなくなる可能性があります。
  • 既知の脆弱性を抱えたままリリースするか、互換性の問題を修正するために何日も費やすかのどちらかを選択せざるを得ません。
  • そして多くの場合、アップグレードする価値があるのかさえ不明です。

本稿では、ベースイメージの更新がなぜ見かけよりも難しいのかを探り、実際の事例を挙げながら、アプリケーションを壊すことなく安全かつインテリジェントなアップグレードを自動化する方法をご紹介します。

問題点:「ベースイメージを更新するだけ」— 言うは易く行うは難し

本稿を読んでいる方は、おそらく「コンテナを安全にする方法」のようなキーワードで検索されたことがあるでしょう。そして、AIが生成したあらゆる記事で最初に目にするのは、ベースイメージを更新するというものです。簡単そうに見えますよね?しかし、そう簡単ではありません。 

ベースイメージはセキュリティの中心点です。ベースイメージに脆弱性が含まれている場合、アプリケーションもその脆弱性を抱えることになります。このシナリオを考えてみましょう。 

コンテナイメージに対してスキャンを実行すると、高深刻度のCVEが発見されました。役立つ推奨事項は、ベースイメージをアップグレードすることです。素晴らしい、ランチ前には完了するでしょう。 

⚠️ CVE-2023-37920ubuntu:20.04 で発見
深刻度: 高
修正済み: 22.04
推奨事項: ベースイメージのアップグレード

…しかし問題が発覚します。 

から安易にアップグレードすると ubuntu:20.04 to ubuntu:22.04、アプリケーションは機能しなくなります。

ベースイメージを更新する際のいくつかの例と、実際に何が起こるかを見てみましょう。 

例1: アップグレード後に動作しなくなるDockerfile

初期Dockerfile:

FROM python:3.8-buster‍
RUN apt-get update && apt-get install -y libpq-dev
RUN pip install psycopg2==2.8.6 flask==1.1.2
COPY . /appCMD ["python", "app.py"]

チームは以下にアップグレードします:

FROM python:3.11-bookworm‍
RUN apt-get update && apt-get install -y libpq-dev
RUN pip install psycopg2==2.8.6 flask==1.1.2COPY . /appCMD ["python", "app.py"]

結果:

  • psycopg2==2.8.6 より新しいバージョンに対するコンパイルが失敗します libpq ヘッダーで bookworm.
  • flask==1.1.2 サポートしていません Python 3.11 ランタイム機能(非推奨のAPIが動作しなくなります)。
  • CIでビルドが失敗します。
  • 開発チームは不満を抱き、ランチも台無しになります。 

例2:微妙なランタイムバグを引き起こすベースイメージのアップグレード

オリジナル:

FROM node:14-busterCOPY . /app
RUN npm ci
CMD ["node", "server.js"]

アップグレード先:

FROM node:20-bullseye
COPY . /app
RUN npm ci
CMD ["node", "server.js"]

ランタイムの問題:

  • node:20 より新しい OpenSSL バージョンを使用しており、厳格なTLS検証により古いaxiosの設定が機能しなくなります。
  • アプリは UNABLE_TO_VERIFY_LEAF_SIGNATURE ランタイム時にエラーを HTTP レガシーサービスへの呼び出しでスローします。

「latest」がなぜ落とし穴なのか

Dockerエコシステムでは、最新のタグやトップラインリリースを使用することが推奨されています。しかし、これは月曜日に動作していたアプリケーションが火曜日に突然失敗する、という事態を招くことがよくあります。これは、バグ修正に時間を費やすことで、頭痛の種、停止、開発の遅延を引き起こす罠となることがよくあります。 

テスト済みのマイナーバージョンに固定することが解決策だと考えられがちですが、そう簡単ではありません。これは、常に新たなCVEを発見し続け、脆弱な状態に陥る可能性がある「セキュリティのモグラ叩き」ゲームに足を踏み入れることになります。 

意思決定の麻痺:アップグレードすべきか否か?

セキュリティチームはアップグレードを推進します。
開発者は安定性を理由に難色を示します。

どちらが正しいのでしょうか? 状況によります。

しかし、その意思決定を理解するためには、すべての選択肢を検討する必要があります。これは、すべてのバージョン、セキュリティリスク、安定性リスク、および可用性を網羅した膨大なスプレッドシートを作成することを意味します。 

それがどのようなものか見てみましょう。 

バージョンタグ 存在するCVE(高・クリティカル) 互換性リスク(1-5) 主要な破壊的変更 / 機能リスク エコシステムのバイナリサポート(Wheels/NPMバイナリ)
node:14-buster(現在) - CVE-2022-35256 (OpenSSLバッファオーバーフロー)
- CVE-2022-25883 (node-fetch SSRF)
- CVE-2021-32803 (object-pathにおけるプロトタイプ汚染)
1(安定しているが古くなっている) レガシーTLS、安全でない依存関係が組み込まれている 完全にサポートされているがEOL(メンテナンスは2023年4月に終了)
node:14-bullseye - 上記と同じCVE + 軽微な追加のOpenSSL問題 1 軽微なglibcの変更
Dockerランタイムレイヤーの互換性に関する潜在的な変更
安定;wheelおよびNPMエコシステムは引き続きサポート
node:16-buster - CVE-2023-30581 (libuv OOB書き込み)
- CVE-2022-35256 (OpenSSLオーバーフロー)
- CVE-2022-25883 (node-fetch SSRF)
2 Buffer()コンストラクタの非推奨警告
レガシーHTTPライブラリは厳格な警告を発する
広くサポートされている
node:16-bullseye - 上記と同様 + 軽微なOpenSSLのアップデート 2 DNSリゾルバの動作が若干異なります
内部ネットワーク呼び出しのテストカバレッジが必要です
サポート対象
node:18-bullseye - CVE-2022-45195 (古いビルドにおけるTLS脆弱性)
- CVE-2023-30581 (libuv OOB書き込み)
3 デフォルトでTLS厳格モード
レガシーなAxiosおよび古いリクエストライブラリは、厳格な証明書では失敗します
エコシステムは中程度の成熟度。一部のモジュールはアップグレードが必要です
node:18-alpine - 上記と同様。Alpineのglibcミスマッチのリスクがあります 4 Alpineのmuslは、bcryptのような特定のネイティブモジュールを破損させる可能性があります
ソースからのビルドのフォールバックに問題があります
ネイティブバイナリのリビルドが必要です
node:20-bullseye - 高度なCVEは0件(現在の安定版) 4 Breaking DNS resolver changes
Default ESM loader changes
axios < 1.3.2 breaks
積極的にサポートされています。エコシステムも追従しています
node:20-bookworm(最新版) - 高度なCVEは0件(2024年3月現在) 5 主な変更点:
TLSの厳格化
DNSの変更
ESMの強制適用
古いNPMプラグインの失敗
一部のニッチなモジュールはまだ追従中。最新のnode-gypが必要です

これにより、複雑で、質の悪い、不可能な選択肢が残されます 

  1. 古いイメージに留まり、脆弱性を受け入れる
  2. アップグレードしてアプリケーションを破損させ、本番環境のダウンタイムのリスクを負う
  3. 手動での互換性テストを試みる — 数日間の作業

手動アップグレードのワークフロー:

これを手作業で行う場合、以下のようになります:

  • CVEを確認: trivy image python:3.8-buster
  • 各CVEを調査します。アプリケーションのコンテキストで到達可能ですか?
  • アップグレード候補を決定します 
  • 新しいイメージをテストします:
    • ビルド
    • 単体テストを実行します
    • 結合テストを実行します
  • 失敗した場合は、コードをパッチするか、ライブラリをアップグレードしてみてください。
  • すべてのコンテナで繰り返します。

これは非常に手間がかかります。

現状維持のコスト

「壊れていなければ直すな」と考えるかもしれません。

しかし、パッチが適用されていないコンテナのCVEは、セキュリティ侵害の大きな要因です。「本番環境で稼働しているコンテナイメージの87%に、少なくとも1つのクリティカルまたは高深刻度の脆弱性がありました。」出典 

人気のあるベースイメージには、既知の多くのエクスプロイトも存在します。 

  • Unzipパス・トラバーサル脆弱性(CVE-2020-27350)は、何百万ものコンテナに何年も存在していました。
  • Heartbleed (CVE-2014-0160)は、公式の修正がリリースされた後も、レガシーコンテナに長く残っていました。
  • PHP-FPM RCE (CVE-2019-11043)は、細工されたHTTPリクエストを介してリモート攻撃者が任意のコードを実行することを可能にし、以下のコンテナベースイメージで非常に一般的でした。 pre-installed PHP-FPM パッチが適用される前は

AI AutoFix機能がどのように役立つか

この正確なシナリオを解決するため、Aikido Securityはコンテナの自動修正機能を展開しました。私たち自身もこの課題に直面しているからです。 

この機能は次のように動作します。Aikidoはコンテナの脆弱性をスキャンします。脆弱性が発見された場合(または、より可能性が高いのは発見された時)、いつものようにアラートを発し、ベースイメージを更新するよう促す代わりに、複数の選択肢を提供します。どのベースイメージのバージョンがどのCVEを解決するかを示す表を作成します。これにより、マイナーバージョンアップで高リスクのCVEのすべてまたは大部分が解消され、ベースイメージの適切なアップグレードであることが非常に迅速に確認できます。 

アップグレードがマイナーな変更である場合、バージョンを上げるためのプルリクエストを自動的に作成できます。 

これにより、何時間もの作業が削減されます

結論:

  • コンテナのベースイメージのアップグレードは本当に困難です。
  • 「ただアップグレードするだけ」というアドバイスは、複雑でリスクを伴うプロセスを過度に単純化しています。
  • チームが慎重になるのは当然ですが、セキュリティと安定性のどちらかを選択する必要はありません。
  • Aikidoのコンテナ自動修正は、お客様に代わって難しい作業を行うため、情報に基づいた意思決定が可能です。 
  • 次にベースイメージの脆弱性アラートを見たとき、パニックになることはありません。プルリクエストを受け取るでしょう。
共有:

https://www.aikido.dev/blog/why-updating-container-base-images-is-so-hard-and-how-to-make-it-easier

脅威ニュースをサブスクライブ

今日から無料で始めましょう。

無料で始める
CC不要

今すぐ、安全な環境へ。

コード、クラウド、ランタイムを1つの中央システムでセキュアに。
脆弱性を迅速に発見し、自動的に修正。

クレジットカードは不要です | スキャン結果は32秒で表示されます。