Shellshock(CVE-2014-6271)

環境変数に潜む1行でWebサーバーが乗っ取られた事故から、bashの関数定義パーサの欠陥と、環境変数を信頼境界にしない設計原則を最短で学べる。

応用ShellshockbashRCECGI環境変数脆弱性最終更新: 2026-07-29
3つの要点
TL;DR
  1. 2014年9月公開のCVE-2014-6271。bashは環境変数の値が関数定義に見えると自動でパースするが、定義の閉じ括弧の後ろに続けた任意コマンドまで即実行してしまう欠陥。CVSS v2は最大の10.0。
  2. CGIはリクエストのヘッダ等を環境変数にしてサブプロセスへ渡す。攻撃者がUser-Agent等に細工した値を入れbashが起動されるとRCEが成立。DHCPクライアントやSSHのForceCommandも経路になった。
  3. 修正は関数定義を通常の環境変数と別名前空間に隔離し、値を単純代入に閉じ込めた。教訓は、境界を越えて流れ込む環境変数を信頼された入力として扱わないこと。

何が起きたか(影響範囲・深刻度)

2014年9月24日、GNU bash に関数のエクスポート処理をめぐる欠陥 CVE-2014-6271(通称 Shellshock)が公開されました。発見者は Stéphane Chazelas。bash 1.03(1989年)まで遡る約25年分のバージョンが影響を受け、CVSS v2 基本値は上限の 10.0(AV:N/AC:L/Au:N/C:C/I:C/A:C)、すなわち認証不要・低難度・遠隔からの完全な機密性・完全性・可用性の喪失と評価されました。

深刻さの本質は「攻撃者の入力が環境変数に載り、その環境で bash が起動される」経路が至る所に存在した点にあります。当時の Web は Apache の mod_cgi などで CGI スクリプトを多用し、シェルスクリプトの CGI や、内部で bash を呼ぶ言語処理系が現役でした。修正版が出た後も、最初のパッチが不完全だったことが判明して CVE-2014-7169 が採番され、続く精査で CVE-2014-7186 / CVE-2014-7187 / CVE-2014-6277 / CVE-2014-6278 が相次いで報告されました。一連のパッチが安定するまで数日を要した、影響範囲・悪用容易性ともに歴史的な事案です。

脆弱性の原理(なぜ起きるか)

bash はシェル関数を子プロセスへ引き継ぐため、関数を環境変数として文字列化する独自機能を持っていました。関数 foo をエクスポートすると、子プロセスの環境には次の形の変数が入ります。

foo=() {  echo hello; }

新しい bash が起動すると、初期化時にすべての環境変数を走査し、値が () { で始まるものを「エクスポートされた関数定義」とみなして復元します。ここで bash は値の断片をシェルの構文解析器にそのまま食わせて再パースしていました。問題は、パーサが関数定義の終わり(閉じ括弧)で停止せず、その後ろに続くコマンドまで読んで実行してしまうことです。概念的には次の値が渡ると、

X=() { :; }; <ここに置かれたコマンド>

bash は空関数 X を定義した後、セミコロンに続く部分を通常のコマンドとして即座に実行します(: は何もしない組み込みコマンド)。関数を「登録するだけ」のはずの処理が、値の内容次第で任意コマンドの実行に化けるわけです。

核心はパースと実行の混同

本来なら「この変数は関数定義である」という宣言的なデータであるべきものを、bash は手続き的なスクリプトとして評価してしまいました。データを暗黙にコードとして解釈する設計は、注入(injection)脆弱性の典型的な温床です。

エクスプロイトの流れ(どう悪用されるか)

横にスクロール

環境変数の関数輸入が後続文字列まで命令として読んだ脆弱性の攻撃入力から影響と防御までを示す図
攻撃入力が信頼境界を越える概念的な連鎖と、優先する検知・緩和策を整理します。

鍵は「攻撃者が値を制御できる環境変数」と「その環境で bash が起動される」の二条件がそろう経路です。代表例が CGI でした。CGI の仕様では、Web サーバーは HTTP リクエストのメタ情報を環境変数にしてスクリプトへ渡します。たとえば User-Agent ヘッダは HTTP_USER_AGENT、リクエストの RefererHTTP_REFERER といった変数になります。

攻撃経路攻撃者が制御する環境変数bash が起動される契機
Web / CGIHTTP_USER_AGENT など各種ヘッダ由来の変数シェルCGIの起動、または system() 等でのシェル呼び出し
DHCP クライアントサーバー応答のオプション値を渡すフック変数リース取得時に実行される設定スクリプト
SSH forced commandSSH_ORIGINAL_COMMANDauthorized_keys の command= や ForceCommand 経由の bash

攻撃者は User-Agent などのヘッダに () { :; }; で始まる関数定義風の文字列を仕込みます。サーバーがそのヘッダを環境変数に写し、CGI として bash を起動した瞬間、後続に置かれた命令が Web サーバー権限で走ります。SSH では、鍵に紐づく強制コマンドで実行権限を絞っていても、bash が起動される際に攻撃者が送り込んだ SSH_ORIGINAL_COMMAND が解釈され、制限の外側でコマンドが実行され得ました。DHCP でも、悪意ある応答内のオプション文字列がフック用の環境変数に入り、リース処理スクリプト経由で root 実行につながる構図です。

制限をすり抜ける点が致命的

SSH の forced command は本来「この鍵ではこの操作だけ」を強制する仕組みですが、Shellshock は起動される bash 自体の初期化を突くため、許可コマンドの実行前に攻撃コードが動きました。防御境界の内側で発火する点が被害を大きくしました。

なお本稿はディフェンス目的の解説であり、そのまま実行できる完全なペイロードは示しません。要点は、任意入力が環境変数として bash 起動時のパースに到達すれば実行に至る、という因果です。

修正と対策

上流の修正は二段構えでした。第一に、関数定義を運ぶ環境変数の名前空間を通常の変数から分離しました。以降 bash は foo ではなく BASH_FUNC_foo%% のような接頭辞・接尾辞つきの特別な名前でのみ関数を輸入します。ふつうの HTTP_USER_AGENT のような変数名は関数として解釈されなくなり、CGI 由来の入力が関数定義の入口に届かなくなりました。第二に、値のパースを関数定義の1文としてのみ受理し、閉じ括弧の後ろに続くコードを実行しないよう構文評価を厳格化しました。

最初のパッチ(CVE-2014-6271 向け)はパーサの停止条件が甘く、細工次第でなおコマンドが漏れ出したため CVE-2014-7169 として追補され、さらに深いパーサの健全性問題(CVE-2014-7186 / 7187 など)にも順次対処されました。運用側の緩和策としては、パッチ適用が最優先で、それが即座に不可能な場合は、シェルCGIを別言語へ置換する、WAF で関数定義風の文字列(() { を含む値)を遮断する、CGI 実行ユーザーの権限を最小化して被害範囲を封じ込める、といった多層防御が併用されました。

教訓(一般化できる原則)

Shellshock の一般化された教訓は、プロセス境界を越えて流れ込む環境変数を、信頼された入力として扱わないことです。環境変数は一見「自分のプロセスの設定」ですが、CGI や SSH のように上流が値を注入する場面では、実体は外部からの未検証入力です。それを構文解析器へ暗黙に渡す設計が破綻を生みました。

設計原則

データとコードを混同しない。宣言的な設定であるべき値を、意味を持つスクリプトとして評価しない。境界を越える入力は、たとえ環境変数という「内側らしい」入れ物に入っていても外部入力として扱う。

  • 信頼境界を入れ物ではなく由来で引く: 変数名やチャネルではなく「誰がこの値を決めたか」で信頼度を判断します。
  • 最小権限で被害を封じる: 実行が漏れても root でなければ影響は限定されます。特権分離は事故の前提として設計します。
  • 暗黙のコード解釈を排除する: 入力をパーサやシェルに渡す箇所を洗い出し、宣言的データは宣言的に扱います。

投機実行の副作用を突く別系統の欠陥はSpectre と Meltdownを、注入・多層防御・最小権限の一般論はセキュリティ、シェルとプロセス環境の仕組みはOS、リクエストが環境変数へ写る CGI の経路はWebの各トピックも参照してください。

脆弱性の解剖の記事ガイド

Shellshock(CVE-2014-6271)を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

Shellshock

比較で見る軸

難易度: advanced / カテゴリ: 脆弱性の解剖 / タグ数: 6

導入後に効く点

CGIはリクエストのヘッダ等を環境変数にしてサブプロセスへ渡す。攻撃者がUser-Agent等に細工した値を入れbashが起動されるとRCEが成立。DHCPクライアントやSSHのForceCommandも経路になった。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
脆弱性の解剖
タグ数
6

判断チェックリスト

  • 自社の用途が「Shellshock / bash」に近いか確認する。
  • 強みである「2014年9月公開のCVE-2014-6271。bashは環境変数の値が関数定義に見えると自動でパースするが、定義の閉じ括弧の後ろに続けた任意コマンドまで即実行してしまう欠陥。CVSS v2は最大の10.0。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

ShellshockbashRCECGI環境変数
参考: 公式情報