鳩丸ぐろっさり (用語集)

bakera.jp > 鳩丸ぐろっさり (用語集) > OSコマンドインジェクション

用語「OSコマンドインジェクション」について

OSコマンドインジェクション (おーえすこまんどいんじぇくしょん)

話題 : セキュリティ

外部から任意の OS コマンドを実行することです。また、それが可能になっている状態のことを指すこともあります。

何らかの事情で、ユーザの入力がそのままシェルにコマンドとして渡せるようになっているとこのような事態が発生します。たとえば、以下のような Perl スクリプトによる CGI には OS コマンドインジェクションの危険性があります。

use CGI;
my $cgi = new CGI;
my $filename = $cgi->param('filename');
open(IN, "$filename.txt");
print qq{Content-Type: text/plain\n\n};
while(<IN>){
    print;
}
exit;

このスクリプトは、URL 引数の filename= の値を見て読み込むファイルを変えるようになっています。filename=test となっていれば、test.txt からデータを読み込みます。

普通は、テキストファイルの内容を表示するだけです。

ところが、ここで filename の値として "%7cdir%20c:%5c%3b" のような値が与えられるとどうなるかというと……。

なんと dir c:\ が実行され、サーバ内のファイルリストが表示されてしまいます。

%7cdir%20c:%5c%3b を URL デコードすると、"|dir c:\;" となります。Perl の open 関数は、| を渡されるとその後の文字列を OS コマンドとして実行するのです。

※例はサーバが Windows の場合を想定していますが、Unix 系のサーバでも "|ls -la /" などを与えれば同じような結果が得られます。

この動作自体は仕様です。CGI では、この機能は sendmail にメールの内容を渡したりするのによく使われます。

問題なのは、ユーザが自由にこの機能を使って、任意のコマンドを実行できてしまう点にあります。例では dir ですのでサーバ内の情報が引き出されるという結果になりましたが、ファイルを削除するようなコマンドを実行されればサーバのデータが破壊されてしまいます。

この例の場合、対処としては open ではなく sysopen を使う、ファイル名として危険な文字をサニタイズする、という方法が考えられます。

当然のことながら、perl の open 関数以外にも OS コマンドインジェクションの原因となり得るものがありますので注意が必要です。

最近の日記

関わった本など