テック技報最新号へ →
セキュリティ

メールアドレスもシェルに渡せば命令になる:GNU Savannah の GPG 鍵テストからの侵入

外部コマンドに利用者の入力を渡すときは、文字列を連結してシェルに渡さず、引数の配列として渡す。メールアドレスのような「形式が決まっていそうな値」も例外にしない。

@MalwareBibleJP · 2026-11-02
#command-injection#secure-coding#php#shell#supply-chain

何が起きたか

  • GNU の開発基盤 Savannah(PHP 製の Savane)で、GPG 鍵のテスト時にメールアドレスをコマンド文字列に連結し、PHP の proc_open でシェルへ渡していた。アドレス内の特殊文字がシェルに解釈され、登録ユーザーがコマンドを実行できた。
  • Hacktron の研究者は AI 監査ツールでこれを見つけ、DB 認証情報の読み取り、管理者への昇格、Bash メンテナーの鍵登録画面の編集が可能だったと報告。古いカーネルの OverlayFS 欠陥で root も取得したとしている。
  • FSF は、アドレスを命令の一部ではなくデータとして GPG へ渡すよう修正し、供給網の侵害はなかったとの見解を示している。

防ぎ方

  1. シェルを経由しない: PHP なら proc_open に文字列ではなく配列を渡す(PHP 7.4 以降は配列を渡すとシェルを通さず直接実行する)。Node.js は execFile / spawn(shell: false)、Python は subprocess.run([...]) を使う。
  2. オプションと値の区切りを入れる: 値が - で始まるとオプションとして解釈される。対応するコマンドでは -- を挟んでから値を渡す。
  3. 入力検証は補助と考える: メールアドレスの正規表現チェックは、RFC 上許される ' や $ などを通しうる。エスケープ関数や検証に頼らず、まずシェルを使わない構造にする。
  4. ライブラリがあればそれを使う: GPG なら外部コマンドを組み立てるより、GPGME などの API バインディングで値を渡すほうが安全。

被害を広げないための教訓

  • Web サーバー権限で DB 認証情報が読めたことが、管理者昇格につながった。Web アプリの実行ユーザーから読める設定ファイルの範囲を最小にする。
  • 古いカーネルの既知の権限昇格で root まで届いた。基盤サーバーのカーネル更新を後回しにしない。

出典

X の元の投稿を開く