2

システムにアクセスして、PHP インターフェイス (または PHP ライブラリ) を持たないコマンド ライン プログラムにアクセスする必要がある PHP ライブラリを作成しています。そのため、システムにアクセスして CLI プログラムから出力を取得するための最良の (そして最も安全な方法) は何だろうと考えていました。と の両方を調べましたが、このような状況でどちらsystem()exec()使用するのが最適かはまだわかりません。

ライブラリは、ユーザーが渡したテキストの文字列を取得し、それをコマンド ラインに送信して、別のテキストの文字列を取得します。明らかに、ユーザー提供のデータを CLI に渡すときに、実行可能データが渡されないことを確認するための検証を行います。

4

2 に答える 2

2

ととshell_exec()一緒に提案します。escapeshellcmd()escapeshellarg()


明確にするために(この回答を最初に投稿したとき、私は外出していました):シェルコマンドを保護する正しい方法は次のとおりです。

$exe = 'cat';
$args = array('/etc/passwd');

$args = array_map('escapeshellarg', $args);

$escaped = escapeshellcmd($exe . ' ' . implode(' ', $args));

これは、上記のコードの正当なデモ(悪質なデモも) です。

もちろん、上記は単なるダミーの例です。ただし、主な考え方は、各引数に適用してから、コマンド文字列全体 (実行可能ファイルへのパスと以前にエスケープされた引数を含む) をescapeshellarg()呼び出すことです。escapeshellcmd()これは、任意のコマンドでは重要です。

: secureとは、、、などの特別な意味を持つ文字 (ウィキペディアのリンクを参照) をエスケープすることにより、シェル インジェクション攻撃を実行できないようにすると同時に、スペースやその他の特別な意味を持つ可能性のある文字を適切に引用することを意味します。シェルによる解釈。><&&|

それはさておき、許可されているすべてのコマンドをすでにホワイトリストに登録している場合は、すでに可能な限り最高のセキュリティを備えており、上記の機能は必要ありません (とにかく使用しても害はありません)。


実際の呼び出し関数に関しては、いくつかの癖がありますが、ほとんど同じことを行います。個人的にはshell_exec()、戻り値がより用途が広いため、私は好みます (このページから):

  • exec() : コマンドからの出力の最後の行を返し、何もフラッシュしません。
  • shell_exec() : コマンドからの出力全体を返し、何もフラッシュしません。
  • system() : コマンドからの出力の最後の行を返し、出力の各行の後に出力バッファーをフラッシュしようとします。
  • passthru() : 何も返さず、ブラウザに干渉することなく結果の出力を渡します。特に、出力がバイナリ形式の場合に役立ちます。

system()終了戻りコードを除いて、戻り値が の他のすべての関数の動作を模倣できますshell_exec()。ただし、逆に実行するのは難しいか、不可能です。

これで問題が解決することを願っています。

于 2012-11-10T08:02:44.827 に答える
1

理想的にはpassthru()、事前に定義された可能な入力のリストから使用します(ユーザーが入力のサニタイズを心配せずinput == 'operation_a'にできるように)。{ passthru('operation_a'); }それ以外の場合は、passthru()入力のいくつかの深刻な衛生状態で使用してください。passthru()コマンドの出力をキャプチャし、一括してブラウザに戻すことができます。この関数は、バイナリ出力が必要な場合 (画像生成など) に特に役立ちます。

于 2012-11-10T03:36:05.720 に答える