2012-05-04 2 views
2

私は誰かがsystem()からlibcからの呼び出しは安全ではないと言って聞いた。glibcのsystem()コールは安全ですか?

私が考えることができる理由の1つは、シェルユーティリティを起動することです。 /bin/bashで、system("rm -rf $input")が起動し、$ inputが墨塗りされていないユーザ入力であれば、$ input = "/"なら大惨事に陥る可能性があります。 その他の理由は何ですか?

+5

これで十分ではありませんか? – Mat

+0

@Mat入力が厳密に型付けされ、サニタイズされていない場合はありません。 – PnotNP

+1

@NulledPointer "サニタイズ"とは "ホワイトリスト"を意味します。そうでなければ...まあ、あなたが思うよりも難しいと言いましょう。 –

答えて

3

一般に、「安全」は、システムコールのファミリ(execve()が最も低いレベルの標準コールです)との比較によるものです。あなたが実行しているのはです。$IFSとなります(これは楽しいことです:誰かがあなたの上で$IFSを変更できる場合、シェルは解析しません)物事はあなたの期待通りに)。

+0

IFSは、実際にはほとんどの人が考えるよりもはるかに少ない効果しかありません。それは危険ですが、あなたが最初にそれを読んだときに聞こえるほど危険なほど危険なものではありません。他の問題ははるかに大きい.. –

+0

+1 IFSのために、念頭に置いておくべきである – PnotNP

0

"誰か"が何を持っていたかは分かりませんが、おそらくsystem()はシェルを介してコマンドを実行するので、最終的なコマンド実行が計画したものと異なる場合があります。たとえば、PATH環境変数が設定される場所と、他の変更可能なものが混在していることはわかりません。

execのバリエーションに固執しますが、それでもあなたがそれらに渡すものに非常に注意してください。

2

これは入力サニティチェックの一般的なケースです。あなたが扱う文字列には、エスケープシーケンスなどをフィルタリングするジェネリックパーサーが必要です。すべてのまともなPHPアプリケーションは、たとえば、SQLデータベースを呼び出す前にこれを行います。

この最初のケースは非常に明白です。誰かがあなたのシステムを破壊する可能性があります。もう1つは、あなたのコード内で命令/関数を上書きするバイナリコードを与えられ、あなたのプログラムがまったく違うことをしている場合です(つまり、脱獄/ルート攻撃の仕組みです)。この特定の脅威の詳細については、あなたはバッファオーバーフローやコードインジェクションの攻撃をよく読んでください。 http://en.wikipedia.org/wiki/Code_injection

また、ここではコードインジェクションを行う例があります:あなたも持っていません Understanding and doing Code Injection in C

+1

"すべてのまともなPHPアプリケーションは、これまでSQLデータベースを呼び出す前にこれを行う"実際にはまともなPHPアプリケーションは、 (または既存のエスケープ関数を使用して)任意のSQLをエスケープします。同様に、私はまともなアプリケーションが、システムを使用する代わりにexec-like関数を介してユーザー引数を渡し、引数を手で消毒することを期待しています。 – sepp2k

+0

合意。私は、一般的には、直接ユーザー入力を取ったものは、予期せぬもの(例えば、エスケープシーケンス、マシンコードなど)を削除するためにそれを浄化することを意味しています。 – DevNull

+0

@Dogbert安全であるように浄化に頼っているならば、上記sepp2kで提案されているプラ​​クティスに従えば、サニタイズは不要です。 –

3

rmを呼び出して悪意のある入力を行って、ハードドライブを消去します。 system("harmless_command $input")を実行し、$input; rm -rf /の場合、harmless_commandに続いてrm -rf /が実行されます。ですから、コマンドでユーザー入力を補間して悪質な入力が問題になる場合は、システムを使うのは悪い考えです。

セキュリティ上の問題に加えて、システムを使用するとバグが発生する可能性もあります。たとえば、system("some_command $filename")と$ filenameにスペース(または他のシェルのメタ文字)が含まれている場合、ファイル名を最初に正しくエスケープしない限り、コマンドは爆発します。

exec *ファミリの関数(シェルを通過する単一の文字列ではなく、コマンドの引数を含む配列または可変引数リストを使用する)を使用する場合、これらの問題はありません。コードは、ユーザーの権限を持つユーザーのコンピュータ上で実行する場合には


¹は、一つは悪質な入力が問題ではないことを主張することができます。ユーザーがハードドライブを消去する悪意のある入力を入力すると、それは実際にユーザー自身の過ちです。しかし、コードがリモートサーバー上で実行される場合や、拡張されたアクセス許可を使用してローカルで実行される場合は、別の問題です。

関連する問題