LASSIC Media らしくメディア
OSコマンドインジェクションとは|仕組みと対策
Webアプリケーションのなかには、利用者が入力した文字列をもとに、サーバのOSに対して命令(コマンド)を出す機能があります。たとえば「入力されたホスト名に対して疎通確認を行う」といった処理です。この命令の組み立て方に隙があると、利用者の入力に紛れ込ませた別の命令まで、サーバがそのまま実行してしまうことがあります。これがOSコマンドインジェクションです。
OSコマンドインジェクションは、アプリがOSのコマンドを呼び出す箇所を悪用し、攻撃者が仕込んだ任意のコマンドをサーバ上で実行させる攻撃です。数ある脆弱性のなかでも、サーバそのものを操作されてしまうため影響が大きい部類に入ります。この記事では、発注者やプロジェクトマネージャー、これからWeb開発に関わる方に向けて、OSコマンドインジェクションの仕組みと被害、そして開発・発注の現場でおさえておきたい対策を整理していきます。
OSコマンドインジェクションとは何か
OSコマンドインジェクションとは、アプリケーションがサーバのOSコマンドを呼び出す処理に対し、利用者の入力を通じて別のコマンドを紛れ込ませ、意図しない命令を実行させる攻撃です。「インジェクション(injection)」は「注入」を意味し、本来はデータであるべき入力欄に、命令を注入されてしまう点に名前の由来があります。
仕組みの根っこは、SQLインジェクションとよく似ています。SQLインジェクションがデータベースへの命令文(SQL)を狙うのに対し、OSコマンドインジェクションはOS、つまりサーバの土台そのものへの命令を狙います。実行される場所がデータベースかOSかという違いはあるものの、「本来はデータとして扱うべき入力が、命令の一部として解釈されてしまう」という構図は共通しているのです。
そして狙われるのがOSである以上、成立したときの影響は広い範囲に及びます。ファイルの読み書きやプログラムの起動など、サーバ上でできることの多くが攻撃者の手に渡ってしまう恐れもあるのです。だからこそ、情報処理推進機構(IPA)などでも、重大度の高い脆弱性として繰り返し注意が呼びかけられています。
この記事のポイント
- OSコマンドインジェクションは、入力を悪用してサーバ上で任意のコマンドを実行させる攻撃です。
- 入力を命令の一部として組み立てる処理が原因で、狙われるのがOSのため影響が大きくなりがちです。
- 対策の本筋は、OSコマンドの呼び出し自体を避け、言語の標準機能で代替することにあります。
なぜ起こるのか(仕組み)
OSコマンドインジェクションは、アプリが「利用者の入力」と「OSへの命令」をつなぎ合わせてコマンドを組み立てるときに生まれます。多くのOSでは、コマンドを解釈して実行する「シェル」という仕組みがあり、ここでは記号にそれぞれ特別な意味が与えられているのです。たとえばセミコロンは命令の区切りを表し、縦棒は前の結果を次へ渡す働きを持ちます。
問題は、こうした記号を含む入力を、そのままコマンドの文字列に埋め込んでしまう場合です。ホスト名を受け取って疎通確認を行う機能を例に、正常な入力と細工された入力を並べてみましょう。
正常な入力なら、ひとつの疎通確認の命令が動くだけです。ところが、区切り記号のあとに別の命令を書き足した入力を受け取ると、シェルはそれを二つの命令とみなし、後ろに付け足された命令まで実行してしまいます。攻撃者はこの隙を突き、ファイルの中身を読み出す命令や、外部と通信する命令などを送り込むわけです。アプリ側が入力を「ただのホスト名」と信じて組み立てているところに、落とし穴があります。
どんな被害につながるのか
OSコマンドインジェクションが成立すると、攻撃者はサーバ上でコマンドを実行できる立場を得ます。これはサーバの操作権限の一部を明け渡すに等しく、被害は多岐にわたるのです。代表的なものを整理しました。
| 被害の種類 | 起こりうること |
|---|---|
| 情報の窃取 | 設定ファイルや認証情報、個人データなどを読み出して外部へ持ち出す |
| 改ざん・破壊 | ファイルの書き換えや削除により、サービスの停止やデータ喪失を引き起こす |
| 侵入の足がかり | サーバを踏み台にし、社内ネットワークの他の機器へ攻撃を広げる |
| 不正プログラムの設置 | マルウェアや不正な常駐プログラムを仕込み、継続的に悪用する |
いずれも、アプリの内部にとどまらずサーバ全体、さらには周囲のネットワークへと波及しうる点が特徴です。個人データの漏えいが起きれば、個人情報保護法にもとづく報告や本人への通知が求められる場面も出てきます。単一の入力欄の見落としが、事業全体の信頼にかかわる事態へつながりかねないのです。
どう防ぐのか(対策)
OSコマンドインジェクションを防ぐ考え方の中心は、「そもそもOSコマンドを組み立てて呼び出す処理を、できるだけ使わない」ことにあります。呼び出さなければ、命令を注入される余地も生まれないからです。そのうえで、どうしても必要な場合の手立てを重ねていきます。
| 対策 | 内容 | 位置づけ |
|---|---|---|
| OSコマンドを避ける | ファイル操作や通信は、言語の標準ライブラリやAPIで代替する | 根本策。呼び出さないのが最も強い |
| シェルを介さず渡す | やむを得ず外部プログラムを呼ぶ際は、引数を分けて渡し、シェルに解釈させない | 記号が命令として働く余地を断つ |
| 入力の検証 | 許可する文字や形式を決め、それ以外を受け付けない(許可リスト方式) | 補強策。単独では取りこぼしも |
| 権限の最小化 | アプリの実行権限を絞り、万一のときの被害範囲を小さくする | 被害の軽減策 |
軸になるのは、上の二つ、すなわち「OSコマンドを呼ばない」「呼ぶとしてもシェルを介さない」という考え方です。多くのプログラミング言語には、外部プログラムを呼び出す際に、入力を命令ではなく引数として明確に分けて渡す仕組みが用意されています。この方式を使えば、区切り記号を含む入力が来ても、それは命令ではなく単なる文字列として扱われます。入力を文字ごとにエスケープするやり方もありますが、抜けが生じやすいため、まずは呼び出し方そのものを見直すのが堅実でしょう。
発注・開発でおさえる点
OSコマンドインジェクションは、外部コマンドを呼び出す一部の処理に潜むため、システム全体を俯瞰して対策を織り込む視点が求められます。発注や設計の段階で意識しておきたい点を挙げておきます。
外部コマンドの呼び出し箇所を洗い出す
まずは、システムのなかでOSコマンドや外部プログラムを呼んでいる処理がどこにあるのかを把握します。ファイル変換、帳票の生成、疎通確認、外部ツールとの連携などが典型的な箇所です。ここを一覧にしておくと、点検やレビューの的が絞りやすくなります。
セキュリティ要件に明記する
「利用者の入力を用いてOSコマンドを組み立てない」「外部プログラムはシェルを介さず引数を分けて呼ぶ」といった方針を、要件定義や設計書に書き入れておくと、実装の判断がぶれにくくなります。抽象的な「セキュリティに配慮する」ではなく、具体的な作法まで落とし込んでおくことがポイントでしょう。
コードレビューと診断を組み合わせる
実装後は、外部コマンドの呼び出し箇所を重点的にレビューし、あわせて脆弱性診断で実際に入力を試す確認も行います。人の目による確認と、ツールや外部診断による確認を組み合わせると、見落としを減らしやすくなります。リリース前の工程に組み込んでおくとよいでしょう。
よくある誤解と勘所
OSコマンドインジェクションは、SQLインジェクションほど話題に上らないぶん、対策の勘所が誤解されがちです。代表的なつまずきを表にまとめました。
| よくある誤解 | 実際のところ |
|---|---|
| 記号をエスケープすれば防げる | シェルの記号は多く、抜けが生じやすい。呼び出し方の見直しが本筋 |
| 社内向けシステムなら心配ない | 内部の利用者や、侵入後の横展開で悪用される余地は残る |
| 入力欄がなければ無関係 | ファイル名やヘッダ経由など、目立たない入力経路も対象になりうる |
| WAFを入れれば済む | WAFは補助。すり抜けもあり、実装側の対策とあわせてこそ活きる |
勘所をひとことでいえば、「入力を命令の材料にしない」ことに尽きます。エスケープで危ない記号をふさぐ発想は、いたちごっこになりがちです。それよりも、OSコマンドを呼ばずに済ませる、あるいは呼ぶにしても入力を引数として切り分けて渡す——という設計側の工夫が、根本からの解決につながります。この視点を持っておくと、レビューでどこを見るべきかも定まってくるでしょう。
まとめ
- OSコマンドインジェクションは、入力を悪用してサーバ上で任意のコマンドを実行させる攻撃である。
- 本来データであるべき入力が、シェルへの命令の一部として解釈されることで成立する。
- 狙われるのがOSのため影響が大きく、情報窃取・改ざん・侵入の足がかりなどにつながる。
- 対策の本筋は、OSコマンドを呼ばないこと、呼ぶ場合もシェルを介さず引数を分けて渡すこと。
- 入力検証や権限の最小化は補強策として重ね、外部コマンドの呼び出し箇所を洗い出しておく。
よくある質問
OSコマンドインジェクションとSQLインジェクションはどう違うのですか。
命令が実行される場所が異なります。SQLインジェクションは、データベースに送る命令文(SQL)に不正な内容を紛れ込ませる攻撃です。一方OSコマンドインジェクションは、サーバのOSに対する命令(コマンド)を狙います。どちらも「本来データであるべき入力が命令の一部として解釈される」という点は共通していますが、OSを狙うぶん、サーバ全体を操作されかねない広い影響につながりやすいという違いがあります。
入力をエスケープすれば防げるのではないですか。
エスケープも一定の効果はありますが、それだけに頼るのはおすすめできません。シェルが特別な意味を持たせる記号は数が多く、環境によっても異なるため、すべてを漏れなくふさぐのは難しいのが実情です。そのため、まずはOSコマンドの呼び出し自体を避け、どうしても必要なときはシェルを介さず入力を引数として分けて渡す方式を採るのが本筋になります。エスケープは、その上に重ねる補強と位置づけるとよいでしょう。
自社のシステムに脆弱性がないか、どう確認できますか。
まずは、システムのなかでOSコマンドや外部プログラムを呼び出している処理を洗い出すところから始めます。そのうえで、利用者の入力がその組み立てに使われていないかを、コードレビューで確認します。あわせて、脆弱性診断のツールや外部の診断サービスを使い、実際に細工した入力を試して反応を見る方法も有効です。人の目による確認と、診断による確認を組み合わせると、見落としを減らしやすくなります。
WAFを導入していれば対策は十分ですか。
WAFは有力な補助ですが、それだけで十分とはいえません。WAFは既知の攻撃パターンを検知して遮断しますが、巧妙に細工された入力にはすり抜けの余地が残るのです。あくまで防御の一枚と捉え、アプリケーション側でOSコマンドの呼び出しを避ける、入力を引数として分けて渡すといった実装の対策とあわせて用いることで、はじめて厚みのある守りになります。多層で守る発想が大切です。
著者:テレリモ総研編集部 鈴木 亮佑
LASSICでは、国内ニアショア開発体制を活かし、Webアプリケーションのセキュリティ要件の整理から設計・実装、公開済みシステムの点検・改修までを一貫して支援する体制です。要件定義の段階から実装、テスト、リリース後の運用・保守まで、工程を分けずに任せられる点も強みでしょう。OSコマンドインジェクションをはじめとする脆弱性への対策でお困りの際も、ご相談いただけます。
ご不明な点はお問い合わせフォームからもご連絡いただけます。