「Webアプリケーションの脆弱性診断で”OSコマンドインジェクション”が検出された」「入力フォームからサーバーを乗っ取られると聞いたが、具体的に何が起きるのか分からない」――こうした不安を感じたことはないでしょうか。
OSコマンドインジェクションは、SQLインジェクションやXSSと並んで古くから知られるWebアプリケーションの脆弱性です。しかし、攻撃が成功した場合の被害はこれらの中でも特に深刻で、サーバー全体の制御を奪われる可能性があります。IPA(情報処理推進機構)の「安全なウェブサイトの作り方」でも、重点的に対策すべき脆弱性として取り上げられています。
この記事では、OSコマンドインジェクションの仕組み・被害パターン・具体的な防御策について、現場で使えるレベルで解説します。「名前は聞いたことがあるが、どう対策すればいいのか分からない」という方にも理解できるようまとめました。

OSコマンドインジェクションとは?なぜ深刻なのか
OSコマンドインジェクション(OS Command Injection)とは、Webアプリケーションを経由して、サーバーのOS(オペレーティングシステム)上で不正なコマンドを実行させる攻撃手法です。
通常、Webアプリケーションがサーバー上で外部コマンドを呼び出す処理を持っている場合、ユーザーの入力値がそのコマンドの一部に組み込まれることがあります。ここに攻撃者が細工した入力を送り込むことで、開発者が意図していないOSコマンドが実行されてしまいます。
OSコマンドインジェクションが他の脆弱性よりも深刻とされる理由は、被害の範囲にあります。
・サーバー全体が影響を受ける: SQLインジェクションはデータベースが対象だが、OSコマンドインジェクションはサーバーOS上のあらゆる操作が対象になり得る
・権限次第で被害が拡大する: Webアプリケーションの実行ユーザーの権限でコマンドが動くため、権限設定が甘いとファイルの読み書き・削除、ネットワーク経由の攻撃拡大まで可能になる
・攻撃の痕跡を消される恐れがある: OSコマンドでログファイルを削除・改ざんされると、被害調査(フォレンジック)が困難になる
OWASP(Open Worldwide Application Security Project)が公表する「OWASP Top 10」でも、インジェクション系の脆弱性は常にトップクラスに位置しています。その中でもOSコマンドインジェクションは、成功した場合のインパクトが最大級の部類に入ります。
攻撃の仕組み ― どのように不正なコマンドが実行されるのか
OSコマンドインジェクションの仕組みを理解するには、Webアプリケーションが「なぜOSコマンドを呼び出すのか」を知る必要があります。
たとえば、ユーザーが入力したドメイン名に対してDNS検索を行う機能や、入力されたファイル名をサーバー上で処理する機能を持つWebアプリケーションがあるとします。内部では以下のような処理が行われています。
# Webアプリケーション内部の処理イメージ(概念的な擬似コード) # ユーザーが入力したドメイン名を変数に格納 # domain = ユーザーの入力値 # OSコマンドとして実行 # system("nslookup " + domain)
通常のユーザーが「example.com」と入力すれば、サーバー上では「nslookup example.com」が実行されるだけです。しかし、ここに問題があります。
1. メタ文字によるコマンドの連結
LinuxやWindowsのシェル(コマンドを解釈する仕組み)には、複数のコマンドを1行で実行するための特殊文字(メタ文字)があります。代表的なものはセミコロン(;)、パイプ(|)、アンパサンド(&&)などです。
攻撃者がドメイン名の入力欄に「example.com; cat /etc/passwd」のような文字列を入力すると、サーバー上では以下のように解釈されます。
# 攻撃時にサーバーで実行されるコマンドのイメージ # nslookup example.com; cat /etc/passwd # → nslookup example.com が実行された後、 # cat /etc/passwd も実行される
セミコロンの前後で2つの独立したコマンドとして処理されるため、攻撃者が追加した「cat /etc/passwd」(ユーザー情報ファイルの内容を表示するコマンド)もサーバー上で実行されてしまいます。
2. 攻撃が成功した場合に実行される操作
一度コマンドの注入に成功すると、攻撃者は以下のような操作を試みます。
・情報の窃取: 設定ファイルやデータベースの接続情報など、サーバー上の機密ファイルを読み取る
・バックドアの設置: 外部から継続的にアクセスできる裏口プログラムを仕掛ける
・マルウェアのダウンロード: 外部サーバーから不正プログラムを取得して実行する
・他のサーバーへの攻撃: 侵入したサーバーを踏み台にして、内部ネットワークの他のサーバーを攻撃する
・ログの改ざん・削除: 侵入の痕跡を消して、発見を遅らせる
3. 攻撃の入口になりやすい機能
以下のような機能を持つWebアプリケーションは、OSコマンドインジェクションのリスクが高くなります。
・ファイルのアップロード・変換処理(画像のリサイズ、PDFの変換など)
・メール送信機能(sendmailコマンドを内部で呼び出す場合)
・DNS検索・Ping・Whois検索などのネットワークツール機能
・外部プログラムの実行を伴うファイル処理
これらの機能が「ユーザーの入力値をそのままOSコマンドに渡している」場合、攻撃者にとっての入口になります。

具体的な防御手順
OSコマンドインジェクションの防御は、「ユーザーの入力をOSコマンドに直接渡さない」ことが大原則です。以下の対策を優先度の高い順に解説します。
1. OSコマンドの呼び出しをそもそもやめる
最も確実な対策は、OSコマンドの呼び出し自体を排除することです。多くの処理は、プログラミング言語の標準ライブラリや専用ライブラリで代替できます。
# 危険: OSコマンドを呼び出すパターン # system("nslookup " + domain) # system("convert " + input_file + " " + output_file) # 安全: ライブラリで代替するパターン # Python: socket.getaddrinfo(domain, None) でDNS解決 # Python: Pillowライブラリで画像変換 # PHP: gethostbyname($domain) でDNS解決
「本当にOSコマンドを呼び出す必要があるか?」をまず検討してください。大半のケースでは、ライブラリへの置き換えが可能です。
2. やむを得ない場合はシェルを経由しない実行方法を使う
どうしてもOSコマンドの実行が必要な場合は、シェルを経由せずにコマンドを直接実行する関数を使います。シェルを経由しなければ、メタ文字(;、|、&&等)が特殊文字として解釈されないため、コマンドの連結による攻撃が成立しません。
# Pythonの場合 # NG: シェル経由(shell=True) # subprocess.call("nslookup " + domain, shell=True) # OK: シェルを経由しない(引数をリストで渡す) # subprocess.call(["nslookup", domain]) # PHPの場合 # NG: シェル経由 # system("nslookup " . $domain); # OK: エスケープ関数を使用 # system("nslookup " . escapeshellarg($domain));
3. 入力値を厳格にバリデーション(検証)する
OSコマンドに渡す可能性のある入力値は、ホワイトリスト方式(許可する値を事前に定義)で厳格にチェックします。
・許可文字の限定: ドメイン名なら英数字・ハイフン・ドットのみ許可する
・長さの制限: 入力値の最大長を設定し、不自然に長い値を拒否する
・メタ文字の拒否: セミコロン(;)、パイプ(|)、アンパサンド(&)、バッククォート(`)、ドル記号($)、括弧等を含む入力を拒否する
・選択式UIの採用: 自由入力ではなくプルダウンやラジオボタンで値を選ばせる設計にする
# 入力値のバリデーション例(Pythonの擬似コード) # import re # ドメイン名として許可する文字パターン # pattern = r'^[a-zA-Z0-9][a-zA-Z0-9\-\.]+[a-zA-Z0-9]$' # if not re.match(pattern, user_input): # return "不正な入力です"
ただし、バリデーションだけで完全に防御できるわけではありません。あくまで「OSコマンドを呼ばない」「シェルを経由しない」といった根本対策の補助として位置づけてください。
4. 実行ユーザーの権限を最小化する
Webアプリケーションの実行ユーザーには、必要最小限の権限だけを付与します。万が一コマンドインジェクションが成功しても、被害の範囲を限定できます。
・Webサーバーのプロセスをroot権限で動かさない
・アプリケーション専用のユーザーを作成し、必要なディレクトリ以外への書き込み権限を与えない
・chrootやコンテナで実行環境を隔離する
# Linuxでの権限確認例 # Webサーバーの実行ユーザーを確認 ps aux | grep nginx ps aux | grep apache # 実行ユーザーの権限を確認 id www-data
5. WAF(Web Application Firewall)で多層防御する
WAFを導入することで、OSコマンドインジェクションの典型的な攻撃パターン(メタ文字を含む不審なリクエスト)を入口で検知・遮断できます。
ただし、WAFはあくまで「追加の防御層」です。WAFをすり抜ける巧妙な攻撃も存在するため、根本的な対策(OSコマンドを呼ばない設計、シェル非経由の実行)を置き換えるものではありません。
中小企業でも今日からできること
自社で開発したWebアプリケーションがなくても、OSコマンドインジェクションのリスクはゼロではありません。利用しているCMSやWebシステムの設定、外部委託で作られたシステムに潜む脆弱性に備える必要があります。
| 対策 | 内容 | コスト |
|---|---|---|
| CMS・プラグインの更新 | WordPress等のCMSとプラグインを最新版に保つ。OSコマンドインジェクションの修正パッチが含まれることがある | 無料 |
| 脆弱性診断の実施 | 外部の診断サービスで自社Webサイトをスキャンする。無料のオープンソースツールもある | 無料〜数十万円 |
| クラウド型WAFの導入 | サーバーの設定変更なしで導入できるクラウド型WAFで、既知の攻撃パターンを遮断する | 月額数千円〜 |
| サーバー権限の確認 | Webサーバーがroot権限で動いていないか、保守担当に確認する | 無料 |
| 開発会社への確認 | 自社WebシステムでOSコマンドの呼び出し箇所があるか、入力値の検証が適切に行われているかを確認する | 無料 |
まず着手すべきは「CMS・プラグインの更新」と「サーバー権限の確認」です。どちらもコストがかからず、すぐに実施できます。
自社開発のWebアプリケーションがある場合は、ソースコード中にsystem()、exec()、popen()などOSコマンドを実行する関数の呼び出しがないか確認してもらうことが重要です。呼び出しがある箇所は、ライブラリでの代替を検討してください。
よくある誤解と注意点
【注意】「入力値をエスケープすれば安全」は過信しない
OSコマンド用のエスケープ関数(PHPのescapeshellarg()やescapeshellcmd()など)を使えば一定の防御効果はあります。しかし、OSやシェルのバージョン、文字エンコーディングの違いによってエスケープが不完全になるケースが報告されています。エスケープはあくまで補助的な対策であり、「OSコマンドを呼ばない設計」や「シェルを経由しない実行」を優先してください。
【注意】「社内システムだから大丈夫」は危険な思い込み
インターネットに公開していない社内システムであっても、OSコマンドインジェクションのリスクはあります。標的型攻撃(特定の組織を狙った攻撃)では、まずフィッシングメールで社内PCに侵入し、そこから社内ネットワーク上のWebアプリケーションの脆弱性を突くという手順が使われます。社内システムであっても、外部公開システムと同じレベルのセキュアコーディングが求められます。
【注意】「SQLインジェクション対策をしていればOSコマンドインジェクションも防げる」は誤り
SQLインジェクションとOSコマンドインジェクションは、攻撃の対象と防御の方法がまったく異なります。SQLインジェクションはデータベースへの不正な命令を防ぐもので、プリペアドステートメントが有効です。一方、OSコマンドインジェクションはOSへの不正な命令を防ぐもので、OSコマンドの呼び出しを排除するか、シェルを経由しない実行方法が必要です。それぞれ個別に対策する必要があります。

本記事のまとめ
OSコマンドインジェクションは、Webアプリケーションを通じてサーバーのOS上で不正なコマンドを実行させる攻撃手法です。攻撃が成功した場合、サーバー全体の制御を奪われる可能性があり、インジェクション系の脆弱性の中でも被害のインパクトは最大級です。
防御の最優先事項は「OSコマンドの呼び出しをライブラリに置き換える」ことです。どうしても必要な場合はシェルを経由しない方法で実行し、入力値のバリデーション、権限の最小化、WAFの導入で多層防御を構築しましょう。
| 脅威 | 対策 | 優先度 |
|---|---|---|
| OSコマンドの不正実行 | OSコマンド呼び出しをライブラリで代替 | 最優先 |
| メタ文字によるコマンド連結 | シェルを経由しない実行方法の使用 | 最優先 |
| 不正な入力値 | ホワイトリスト方式のバリデーション | 高 |
| 被害範囲の拡大 | 実行ユーザーの権限最小化 | 高 |
| 既知の攻撃パターン | WAF導入(根本対策の補助として) | 中 |
Linuxサーバーの権限管理やプロセス実行ユーザーの設定については、姉妹サイトLinuxMaster.JPで詳しく解説しています。OSレベルの権限設定を適切に行うことで、万が一の攻撃成功時にも被害を最小限に抑えられます。
Webアプリケーションの脆弱性対策、見落としはありませんか?
OSコマンドインジェクションをはじめとするWebアプリケーションの脆弱性は、正しい知識と適切な設計で防御力を大きく高められます。
正しいセキュリティ知識を体系的に身につけたい方へ、メルマガで実践的なセキュリティ対策ノウハウをお届けしています。


コメント