¿Cuál es la mejor manera de sanear las opiniones de los usuarios en PHP?

28

¿Cuál es la mejor manera de sanear las opiniones de los usuarios?

Estas son cosas que hago cuando los usuarios envían datos:

  1. substr si se encuentran más de valores limitados.
  2. htmlspecialchars() + ent_quotes + UTF-8
  3. str_replace '<' '>' entrada de los usuarios

¿Qué más cosas hay que hacer?

    
pregunta user2615947 16.09.2013 - 17:08
fuente

4 respuestas

45

"Sanitización" es un término inútil y engañoso. Aquí hay dos animales diferentes:

  1. Salida de escape. Esta es una preocupación de la etapa de salida . Cuando toma cadenas variables y las inyecta en una cadena más grande que tiene una sintaxis circundante, debe procesar la cadena inyectada para que se ajuste a los requisitos de esa sintaxis. Lo que exactamente es ese procesamiento depende del contexto: si está colocando texto en HTML, debe huir de ese texto en el punto de creación del HTML. Si está colocando texto en consultas SQL, debe eliminar el texto en el punto de creación de la consulta. (*)

  2. Validación de entrada. Esta es una preocupación de la etapa de entrada , asegurándose de que la entrada del usuario esté dentro de los valores posibles aceptados para un elemento de datos. Esto es principalmente una cuestión de reglas de negocio, que deben considerarse campo por campo, aunque hay algunos tipos de validación que tiene sentido hacer con casi todos los campos de entrada (principalmente para verificar los caracteres de control).

La validación de entrada tiene un impacto en la seguridad, ya que puede mitigar el daño cuando se ha cometido un error con el escape de la salida. Pero no es suficiente confiar en la validación de entrada como su única medida de manejo de texto, ya que siempre tendrá que permitir que el usuario use algunos caracteres que son especiales en la sintaxis de alguna u otra. Vas a querer poder tener una página web sobre fish & chips y un cliente en tu base de datos llamada O'Reilly .

“Desinfección” confunde estos dos conceptos y lo alienta a abordarlos en la misma etapa, que nunca puede funcionar de manera consistente. Un anti-patrón común es html-escape de todas sus entradas. Pero no sabe si cada elemento de entrada se enviará a HTML (y solo a HTML) en esa fase de procesamiento de entrada. Si haces esto:

  • terminas con material codificado en HTML en la base de datos, que no se puede cortar y procesar sin que las referencias de la entidad se interpongan en el camino;

  • si necesita crear contenido a partir de esos datos que no son HTML, como enviar un correo electrónico o escribir algún CSV, tiene un texto muy sucio;

  • si obtiene contenido en su base de datos de cualquier otra fuente, es posible que no se escape de HTML y, por lo tanto, enviarlo directamente a la página aún le brinda vulnerabilidades de XSS.

El concepto de "desinfección" debe ser destruido por el fuego, luego ahogado, cortado en trozos pequeños y destruido por un poco más de fuego nuevamente.

(*: en ambos casos es más inteligente elegir un método que realice el procesamiento por usted de manera implícita para que no se equivoque: use un lenguaje de plantillas HTML que se escape de la salida de manera predeterminada, y una capa de acceso a datos que use Consultas parametrizadas o mapeo relacional de objetos. De manera similar para otros tipos de escape: prefiera un serializador XML que cumpla con los estándares al escape XML manual, use un serializador JSON estándar para pasar datos a JavaScript, etc.)

  

substr si sobre valores limitados encontrados.

¿Quiere decir truncar cadenas de entrada demasiado largas? Eso está bien como una forma de validación de entrada donde las reglas de su negocio tienen una razón válida para limitar la longitud de una entrada. Pero es posible que prefiera devolver un error al usuario si tiene una cadena de entrada demasiado larga, ya que, dependiendo del campo, puede que no sea apropiado descartar los datos de forma silenciosa.

  

htmlspecialchars () + ent_quotes + UTF-8

Esta es la salida de escape. Hágalo en los valores en el punto en que los coloque en HTML, no en la entrada. Si está usando plantillas nativas de PHP, le gustaría definirse un atajo para que sea más rápido de escribir, por ejemplo:

function h($s) {
    echo htmlspecialchars($s, ENT_QUOTES, 'utf-8')l
}
...

<p>Hello, <?php h($user['name']); ?>!</p>
  

entrada de usuarios de str_replace < >

¿Para qué? Si se está escapando de HTML correctamente, estos caracteres están perfectamente bien, y a menos que las reglas de su negocio digan lo contrario, puede ser bastante válido incluirlos en un campo, así como ambos caracteres son válidos para que yo escriba este cuadro de comentarios para SO.

Por supuesto, es posible que desee no permitirlos en la validación de entrada para campos específicos, no los querría en un número de teléfono.

    
respondido por el bobince 16.09.2013 - 22:11
fuente
11

Yo uso los filtros PHP OWASP. Son realmente simples de usar y efectivos.

enlace

El código fuente es altamente legible. Hay muchas lecciones dolorosas allí.

    
respondido por el mgjk 23.09.2014 - 15:34
fuente
2

Dado que se trata de un problema de hace algunos años, algunas cosas cambian y los enlaces externos generalmente se pliegan, ya que los sitios no mantienen o abordan los enlaces que pueden existir en otros sitios.

Pasando a continuación, PHP se ha movido un poco y mucha gente pregunta acerca de las entradas de desinfección, pero hasta ahora, el uso de filter_var es escaso en el terreno, aunque no es perfecto, es mi lectura, seguro binario.

Así que obtienes una dirección de correo electrónico, bueno, a menos que no uses HTML5 cuando deberías usarlo junto con PHP filter_var , tu sitio será más seguro que alguien que escribe una rutina para sanear una entrada que no lo hace. t utilizar entradas HTML5. Escribir código para compatibilidad con versiones anteriores para navegadores que no son compatibles con HTML5 es completamente inútil y una pérdida de tiempo y recursos.

El otro problema de la seguridad es que los valores de $ _GET y $ _POST son volátiles y pueden cambiarse o cambiarse externamente de datos buenos a datos incorrectos, por lo tanto, cualquier rutina de desinfección que los use y les devuelva las entradas limpias es simplemente maduro para los problemas ... $ _REQUEST La matriz es más segura, una vez que se establece en su matriz segura, no se puede cambiar, por lo tanto, rellene su matriz segura tomando entradas y amp; filter_varlos en la matriz segura.

La forma en que desinfecto las entradas es algo como lo que sigue ...

$someSafeArray = array(
        "thefield"=>FILTER_SANITIZE_STRING,
        "theNumberfield"=>FILTER_SANITIZE_NUMBER,
        "theEmailfield"=>FILTER_SANITIZE_EMAIL
        );
foreach( $someSafeArray as $fld=>&$val)
    $val = filter_var( trim( $_REQUEST[$fld] ), $val );

Así que esto devolverá todos los campos (de las claves) y las entradas saneadas se colocarán en los valores de esas claves en la matriz segura.

Esto significa que uso las teclas de una lista blanca (matriz) para tomar SOLAMENTE las entradas que designo como campos válidos. Demasiada gente que he visto ofreciendo procesadores de formularios "dinámicos" que aceptan CUALQUIER entrada, ¡NO! Solo debe aceptar flujos de datos que su código / formulario está diseñado para manejar.

SALTE su página con un valor que su formulario de recepción pueda volver a calcular el hashing correcto para verificar que el servidor haya emitido su formulario, campos VACÍOS. Incluyo al menos un firld en blanco que es solo de lectura, oculto como campos de hashing pero la intención es para determinar si el formulario se está enviando o no, un bot llenará todos los campos con datos para intentar abrir la página.

SO Baiting tu página con un par de campos ficticios como ...

<input name="userlogin" type="hidden" value="" readonly />
<input name="empty" type="hidden" value="" readonly />

Si el formulario llegó a su servidor con algo en el campo de valor de cualquiera de las entradas, también puede detener el procesamiento de formularios y registrar la IP del usuario y bloquearlos, ya que son un bot o un pirata informático.

La inyección no es solo un problema de SQL, es un problema de la página PHP, así que tenga cuidado con los campos que acepta, con qué salt y bait de su formulario y opera una lista blanca.

DEJE DE USAR GET para pasar los parámetros de control, USE una cookie de sesión, ya que esto reduce las entradas en el script. Si utilizo una URL de tipo GET, entonces es solo para una táctica subversiva y permite el monitoreo de las variables que ingresan los usuarios en la URL. Y otras cosas para tratar de hackear.

He estado usando un proceso como este desde antes de que se introdujera la función filter_var, estaba sacando páginas sin la necesidad de una base de datos para validar las páginas entrantes y fue algo que los llamados profesionales me dijeron repetidamente que no era posible Bueno, lo único que tengo que decir es que "es si puedes pensar fuera de la placa de la caldera. (caja)" y lo suficientemente simple como para frustrar los intentos de pirateo, asegurar las páginas de formularios.

    
respondido por el Mark Giblin 13.11.2015 - 16:14
fuente
1

Yo, personalmente, nunca aparecería en < y > , solo etiquetas de tira , html caracteres especiales , codificación de entidades html , < a href="http://php.net/mysql_real_escape_string"> mysql_real_escape_string etc. en la entrada del usuario.

Lo que debe tener en cuenta es cómo se representarán los datos.

  • ¿Se emitirá en el extremo frontal?
  • ¿Va a entrar en la base de datos?
  • ¿Se va a utilizar en Javascript en la parte frontal?
  • ¿Qué tal en la inclusión de archivos?

Si va por el extremo frontal, entonces debes htmlentities it y strip_tags imo, de esta forma puedes estar seguro de que no están intentando ejecutar ningún código no deseado.

Además, eliminar las barras es una consideración bastante importante, recientemente detecté un XSS en el plugin WP Platinum SEO que puedes ejecutar código javascript a través del parámetro $ _GET ['s'] codificando todo en código hexadecimal escapado (\ \ x41 = A).

Si está ingresando datos en la base de datos, eche un vistazo a las consultas preparadas para DOP , así como a mysql_real_escape_string . Esto debería asegurar las entradas de su base de datos bastante bien.

Si está utilizando la entrada del usuario para solicitar archivos, asegúrese de que no sea susceptible de ataques de Poison Null Byte y En mi opinión, siempre elimine todas las barras inclinadas en el archivo incluido para asegurarse de que no puedan acceder a la ubicación deseada. También recomendaría desactivar allow_url_include / allow_url_fopen en su php.ini archivo.

Espero que esto ayude!

    
respondido por el DarkMantis 16.09.2013 - 17:20
fuente

Lea otras preguntas en las etiquetas