¿Es seguro este método de desinfección?

4

He implementado esta solución de desinfección:

function san($str, $type="full") {
    switch ($type) {
        case "full":
            $str = preg_replace("/[^a-zA-Z0-9_\-]/i", "", $str);
        break;
        case "mid":
            $str = preg_replace("/</i", "&gt;", $str);
            $str = preg_replace("/>/i", "&lt;", $str);
        break;
        case "low":
            if ($str == "true" || $str == true)
                $str = true;
            else
                $str = false;
        break;
    }

Quiero dormir tranquilo, pero no soy un experto en seguridad. ¿Qué puede pasar por ese filtro? Sé cómo usar expresiones regulares, pero ¿es posible codificar str para omitir esta función?

El nivel mid está destinado a proteger contra XSS y el nivel full contra la inyección de comandos, como este:

$str = san($_REQUEST['cmd']);
$cmd = "cmd1 foo | cmd2 -arg=". $str; 
shell_exec($cmd); // is this secure?
    
pregunta David Sýkora 27.03.2016 - 18:00
fuente

1 respuesta

7

¿Es suficiente un filtro de entrada genérico?

No, el saneamiento de entrada no es la defensa adecuada contra cualquier ataque, por lo que solo porque tenga algunos filtros no es una razón para llamarlo un día.

Necesita defensas adecuadas contra ataques típicos en el lugar, por ejemplo, declaraciones preparadas para inyección SQL, codificación de variables en salida contra XSS, etc.

Dicho esto, el filtrado de entrada adicional es altamente recomendado como defensa en profundidad.

Usabilidad de su función

La usabilidad es importante. Si nadie sabe qué hace exactamente su función y cómo usarla adecuadamente, proporcionará menos seguridad ya que las personas, esto puede incluirlo en el futuro, lo usarán de manera incorrecta o lo cambiarán.

Sin embargo, tu función no es tan utilizable. Si veo san($x, "full") , no tengo idea de lo que está sucediendo. Lo mismo ocurre con mid y low como argumentos (y la denominación no parece tener sentido; se supone que el bajo es menos seguro, en contra de ... algo ... ¿que lleno o medio?). / p>

Un "completo" genérico también hace que sea muy fácil cambiar lo que hace el código. Tal vez pienses que necesitas ; en algún otro caso, ¿por qué no agregarlo? No parece hacer ningún daño, y aún coincide con la descripción "completa".

Sugeriría alguna clase genérica Input con métodos tales como getInt($name) , getAlphaNum($name) , getCleanHTML($name) , getRaw($name) , getFilter($name, $regex) , etc. Con nombres como estos, verá inmediatamente lo que obtiene , y si es apropiado para la entrada y la situación. También sabe que no debe cambiar la implementación ( getInt siempre debe devolver un entero, getAlphaNum siempre es alfanum).

Defensa contra la ejecución del código

Su ejemplo debería ser seguro. No puedo salir del contexto actual o agregar un nuevo comando, porque no tengo espacio ni punto y coma, ni ningún otro carácter que pueda usarse en diferentes shells para agregar nuevos comandos.

Aún así, como se sugirió anteriormente, lo reescribiría. Por lo que podría tener este aspecto:

$str = Input::getFilter("cmd", [^a-zA-Z0-9_\-]);
$cmd = "cmd1 foo | cmd2 -arg=". escapeshellarg($str); 
shell_exec($cmd); // is this secure?

Ahora está utilizando el enfoque recomendado (escapeshellarg), y tiene un filtro adicional, donde queda bastante claro lo que el filtro hace actualmente o podría hacer en el futuro.

Defensa contra XSS

Primero, tu código está fastidiado. < es $lt (por menos de).

En segundo lugar, esto defenderá contra XSS en algunos casos, pero no en todos. No se defenderá contra XSS si ya está en un contexto de etiqueta (por ejemplo, <img src="[USERINPUT]"> ), o en un contexto de JavaScript (por ejemplo, <script>var = "[USERINPUT]";</script> ).

Esta es también una de las razones por las que el filtrado de entrada no es suficiente para evitar XSS (excepto el filtrado muy estricto, por ejemplo, solo aceptar un entero). Necesitas conocer el contexto para defenderte adecuadamente contra él. En la mayoría de los contextos, htmlspecialchars con ENT_QUOTES es lo suficientemente bueno, vea esta guide para más información.

    
respondido por el tim 27.03.2016 - 20:21
fuente

Lea otras preguntas en las etiquetas