AIペンテスターが25分で見つけた3年前の管理者トークン

2023年のコンテナビルドに埋め込まれたGitHub認証情報が2026年7月まで有効だった — しかも公開レジストリに置かれたまま

|5分で読める0
Server racks in a data center - Baseten runs AI inference infrastructure, where a stale build credential granted admin rights on the repositories driving its clusters
Server racks in a data center - Baseten runs AI inference infrastructure, where a stale build credential granted admin rights on the repositories driving its clusters

あるセキュリティ企業が、推論基盤の提供元としてBasetenを評価する過程で、自律型スキャンエージェントを同社のドメインに向けた。認証情報もソースコードも与えていない。それから約25分後、エージェントの手元には内部リポジトリの管理者権限を持つGitHubトークンがあった。Strixは9月1日にこの脆弱性開示を公開した。Basetenが修正を終えてから7週間後のことだ。

要点

  • 問題の認証情報は2023年3月3日にコンテナイメージのビルド履歴へ書き込まれ、2026年7月の検証時点でも認証に成功した。
  • このトークンはrepoスコープを持ち、Basetenの主力製品リポジトリ、クラスタを動かすGitOpsリポジトリ、Homebrew tapに対して管理者権限とプッシュ権限を与えていた。
  • Basetenのセキュリティチームは報告からおよそ17時間でレジストリを非公開にし、トークンをローテーションした。

スキャンはどうやってそこに到達したか

作業はごく普通の偵察から始まった。ホストの列挙と証明書ログの調査を行うと、BasetenのサブドメインでHarborのコンテナレジストリが浮かび上がった。Harborはイメージをプロジェクト単位でまとめるが、このインスタンスではひとつのプロジェクトが公開状態だった。リポジトリ一覧の取得、匿名pullスコープの発行、マニフェストとblobのダウンロードに、トークンは一切必要なかった。その中にbaseten/baseten-appという名前のイメージがあった。

レジストリが露出していること自体は珍しくない。イメージを意図的に公開している企業は多い。問われるのは、そのイメージに何が入っているかだ。最初に見つかったAWSキーのペアは失効していた。読み取り専用のID確認リクエストを投げると、トークンが無効だというエラーが返ってきた。エージェントはそこで止まらずレイヤーを取得し、オープンソースのスキャナーTruffleHogを実行し、さらにファイルシステムだけでなくイメージのconfigまで読んだ。

認証情報はファイルではなくメタデータにあった

トークンはビルド履歴のcreated_byフィールドに残っていた。各レイヤーを生成したコマンドを記録する領域だ。該当の手順は、プライベートな依存関係をGit経由で取得するために、GITHUB_TOKENというビルド引数をRUN行へそのまま展開していた。Dockerはこの履歴をイメージのconfigに保存し、configはイメージと一緒にダウンロードされる。

持ち帰るべき要点はここだ。レイヤーから認証情報のファイルを削除しても、ビルド履歴に写しが残っていれば意味がない。ビルドが認証情報入りのリモートURLをグローバルのGit設定に書き込んでいれば、写しはもうひとつ増える。

GitHubへの読み取り専用リクエストは、basetenbotというアカウントについて200を返した。repoスコープを持ち、basetenlabs組織に所属するアカウントだった。リポジトリごとに確認すると、3つのリポジトリで管理者権限とプッシュ権限があり、顧客専用のものを含む他のプライベートリポジトリにも読み書き権限が及んでいた。Strixはそこで手を止めたという。クローンもプッシュも設定変更も行わず、開示のメールを送った。

対応は速かった

報告書のタイムラインは、この種のベンダー報告としては異例に短い。Strixが連絡したのは7月13日午後11時10分。翌朝にはHarborのプロジェクトが非公開になっていたが、トークン自体はまだ生きていた。7月14日午後4時34分、Basetenはこの問題をクリティカルと認め、トークンをローテーションしたと伝えたうえで、取得したイメージを安全に削除するよう求めた。研究者側は30分後に削除を確認している。残る指摘は7月17日に解消され、Basetenは公開前に記事の草稿を確認した。

古いイメージが事故を繰り返す理由

企業価値130億ドルのBasetenは、ツールや意識の面で遅れた企業ではない。開示文書も、同社がすでに独自のAIセキュリティツールを運用していると記している。失敗の本質は、2023年のビルド成果物が、周囲のコードが更新された後も攻撃面の一部として扱われなかった点にある。Dockerfileを直しても、誰かがすでにpullしたイメージには手が届かない。だから重要なのは修正ではなく失効処理だ。

推奨される対策は、認証情報が残らないようBuildKitのsecret mountを使い、そのうえでレイヤーと履歴の両方を点検することだ。ソフトウェアサプライチェーンで繰り返し表面化してきた問題と同じ系統であり、累計2億4500万ダウンロードのクレートで汚染されたリリースが86分間公開され続けた一件もそうだった。

この件にはもうひとつの物語がある。誰が見つけたかだ。AIエージェントが偵察、レジストリの列挙、行き止まりの認証情報、メタデータ検索、権限マッピングを自分でつないだ。Harborを探せとも、トークンを探せとも指示されていない。この能力は、契約前にBasetenを調査するベンダーだけのものではない。

よくある質問

顧客データにアクセスされましたか?

いいえ。Strixは読み取り専用のGitHubリクエストでトークンの権限範囲を確認し、そこで止めたと述べている。アクセス可能だった顧客リポジトリをクローンすることも、コードをプッシュすることも、設定を変更することもしていない。取得したコンテナイメージはBasetenの要請に応じて削除した。

ファイルは無害だったのに、なぜトークンが露出したのですか?

ファイルではなく、コンテナイメージのビルド履歴に記録されていたためだ。Dockerは各レイヤーを作ったコマンドをイメージのconfigに保存するが、このビルドはトークンの値をRUNコマンドへ直接埋め込んでいた。そのconfigはイメージと一緒にダウンロードされる。

ビルド用の認証情報はどう扱うべきですか?

BuildKitのsecret mountを使えば、ビルド中だけ認証情報を利用し、イメージやメタデータには残さずに済む。既存のイメージはレイヤーの中身とビルド履歴の両方を監査すべきだ。公開済みのイメージから見つかった認証情報は、削除で済ませず必ず失効させる必要がある。

この記事への反応を残してください!

SJ

ディスカッション

ログインして投稿
読み込み中...

関連記事