この記事では、node.jsを使用してシステムコマンドを正しく呼び出して、一般的なコマンドラインインジェクションの脆弱性を回避する方法を学びます。
コマンドを呼び出すためによく使用する方法は、最も単純なchild_process.execです。非常にシンプルな使用パターンがあります。文字列コマンドを渡し、コールバック関数にエラーまたはコマンド処理の結果を渡します。
Child_Process.execを介した呼び出しシステムコマンドの非常に典型的な例を次に示します。
コードコピーは次のとおりです。
child_process.exec( 'ls'、function(err、data){
console.log(data);
});
ただし、ユーザーが入力したパラメーターをコマンドに追加する必要がある場合はどうなりますか?明らかな解決策は、ユーザー入力をコマンドに直接貼り付けることです。しかし、私の長年の経験は私に言っています:あるシステムから別のシステムに接続された文字列を送ると、いつか問題があります。
コードコピーは次のとおりです。
var path = "user input";
child_process.exec( 'ls -l' + path、function(err、data){
console.log(data);
});
接続文字列に問題があるのはなぜですか?
まあ、child_process.execエンジンの下では、「/bin/sh」の実行が呼び出されます。ターゲットプログラムではありません。送信コマンドは、シェルを実行するために新しい「/bin/sh」プロセスに渡されます。Child_Process.execの名前はやや誤解を招くものです。これはプログラムではなく、バッシュインタープリターです。
コードコピーは次のとおりです。
[PID 25170] execve( "/bin/sh"、["/bin/sh"、 "-c"、 "ls -l user input"]、[/ * 16 vars */]
たとえば、攻撃者はセミコロンを使用できます ";"コマンドを終了して新しいコールを開始すると、バックテックまたは$()を使用してサブコマンドを実行できます。潜在的な虐待も多くあります。
それで、それを呼ぶ正しい方法は何ですか?
execfile / spawn
SPAWNとEXECFILE追加配列パラメーターを使用します。これは、他のコマンドを実行でき、追加のコマンドを実行しないシェル環境ではありません。
ExecFileとSpawnを使用して、前の例を変更して、システム呼び出しがどのように異なるか、なぜコマンドインジェクションの影響を受けない理由を確認しましょう。
child_process.execfile
コードコピーは次のとおりです。
var child_process = require( 'child_process');
var path = "。"
child_process.execfile( '/bin/ls'、['-l'、path]、function(err、result){
console.log(結果)
});
システムコールを実行します
コードコピーは次のとおりです。
[PID 25565] execve( "/bin/ls"、["/bin/ls"、 "-l"、 "]、"]、[/ * 16 vars */]
child_process.spawn
スポーン交換の使用例は非常に似ています。
コードコピーは次のとおりです。
var child_process = require( 'child_process');
var path = "。"
var ls = child_process.spawn( '/bin/ls'、['-l'、path])
ls.stdout.on( 'data'、function(data){
console.log(data.toString());
});
システムコールを実行します
コードコピーは次のとおりです。
[PID 26883] execve( "/bin/ls"、["/bin/ls"、 "-l"、 "。"]、[/ * 16 vars */
SpawnまたはExecFileを使用する場合、私たちの目標は1つのコマンド(パラメーター)のみを実行することです。これは、 /bin /lsがバックティックまたはパイプを処理する方法を知らないため、ユーザーが挿入コマンドを実行できないことを意味します。 /bin /bashが説明するのは、それらのコマンドのパラメーターです。パラメーターを使用してパラメーターをSQLクエリに渡すことに似ています。
しかし、警告もあります。スポーンまたはexecfileを使用することは必ずしも安全ではありません。たとえば、ユーザー入力パラメーターを実行している /ビン /検索と渡すと、システムがトラップされる可能性があります。 Findコマンドには、任意のファイルの読み取り/書き込みを許可するいくつかのオプションがあります。
したがって、ここにnode.js実行システムコマンドに関するいくつかのガイダンスがあります:
特にユーザーが入力したパラメーターを含める必要がある場合は、child_process.execの使用を避けてください。覚えておいてください。
ユーザーにパラメーターを渡さないようにしてください。選択の使用は、ユーザーに文字列を直接入力させるよりもはるかに優れています。
ユーザーがパラメーターを入力できるようにする必要がある場合は、コマンドのパラメーターを広範囲に参照し、安全なオプションを決定し、ホワイトリストを作成します。