¿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.