inyección de sql, exec y preg_replace filter

2

Se me ha informado que no es seguro usar esto con respecto a la inyección de SQL:

preg_replace("/[\"'%()@$.!&?_: #\/-]/","", mysql_real_escape_string($_GET['var']));

¿Cuál sería la diferencia en el siguiente cambio?

mysql_real_escape_string(preg_replace("/[\"'%()@$.!&?_: #\/-]/","", $_GET['var']));

¿qué tal si no se realizó una conexión a la base de datos, por ejemplo, se llamó a exec, cómo podría evitarse esto? ejemplo de trabajo? ¿Una mejor manera de protegerse contra la inyección?

$theVar = preg_replace("/[\"'%()@$.!&?_: #\/-]/","", mysql_real_escape_string($_GET['var']));
exec("zip -r archived.zip ./".$theVar."/");
    
pregunta quick_learner42 13.05.2013 - 04:57
fuente

3 respuestas

1

Todo depende del contexto en el que se insertan los datos proporcionados por el usuario.

En caso de que no sea un literal de cadena SQL, mysql_real_escape_string sería inútil ya que no hay una cadena que el atacante tenga que romper de y algo así como UNION SELECT … con ciertos caracteres de espacio en blanco en lugar del espacio filtrado todavía sería posible.

Explotar el ejemplo de exec es aún más fácil:

var=;+evil+command;+cd+

Esto resultaría en:

zip -r archived.zip ./; evil command; cd /

Aquí escapeshellarg sería la función de escape adecuada:

exec("zip -r archived.zip ".escapeshellarg("./".$theVar."/"));

Sin embargo, aún tendrías que validar $_GET['var'] aunque estés usando escapeshellarg para asegurarte de que el valor ingresado es lo que esperas, por ejemplo, una ruta de acceso válida al sistema de archivos.

Espero que veas que no hay una función universal de escape o filtrado. Siempre debe tener en cuenta el contexto en el que se insertarán los datos proporcionados por el usuario. Cada contexto puede tener sus propias reglas, caracteres especiales y secuencias de escape que deben tratarse por separado. Incluso encontrará múltiples niveles de contextos que todos deben manejarse por separado y en el orden correcto.

    
respondido por el Gumbo 13.05.2013 - 07:18
fuente
1

La única forma segura de protegerse contra la inyección de SQL es mediante consultas parametrizadas. Vea: Hoja de referencia de prevención de inyección SQL por OWASP .

    
respondido por el Ayrx 13.05.2013 - 05:41
fuente
1

Esto no es una inyección SQL en absoluto; no está pasando $theVar a un servidor SQL, sino a un comando de shell. Por lo tanto, mysql_real_escape_string es inútil.

Debes emplear escapeshellarg , que aplica el mismo concepto a una cadena de shell.

En este ejemplo,

$theVar = preg_replace("/[\"'%()@$.!&?_: #\/-]/","",  mysql_real_escape_string($_GET['var']));
exec("zip -r archived.zip ./".$theVar."/");

no está escapando a los caracteres de redirección < y & gt ;. Entonces (por ejemplo) es posible sobrescribir cualquier archivo al que tenga acceso el proceso que ejecuta zip .

Peor aún, no estás escapando del carácter separador de comando; . Por lo tanto, es posible agregar comandos adicionales (en la medida en que no usen ninguno de los caracteres prohibidos) que también se ejecutarán.

Un mejor enfoque sería ver qué caracteres están permitidos en un nombre de archivo, y solo aceptarlos, rechazar cualquier cadena que contenga caracteres prohibidos. Si permite caracteres comodín (parece que lo hace), expándalos usted mismo con glob() para obtener una lista de archivos, y verifique que los archivos tengan permisos y ubicaciones al traducir cada ruta a una ruta canónica única usando realpath() .

Mejor aún, no permitir comodines. En ese momento, también sería fácil verificar si el archivo solicitado existe realmente. Los comandos de Shell en su mayoría serían inválidos o inexistentes como nombres de archivos, y serían rechazados automáticamente sin costo adicional.

    
respondido por el LSerni 13.05.2013 - 08:50
fuente

Lea otras preguntas en las etiquetas