Es strip tags () vulnerable a los ataques de scripting?


¿Hay un XSS conocido u otro ataque que lo hace más allá de un

$content = "some HTML code";
$content = strip_tags($content);

echo $content;

?

El manual tiene una advertencia:

Esta función no modifica ningún atributo en las etiquetas que permite usar allowable_tags, incluidos los atributos style y onmouseover que un usuario travieso puede abusar al publicar texto que se mostrará a otros usuarios.

Pero eso está relacionado con el uso del parámetro allowable_tags solamente.

Sin etiquetas permitidas set , ¿es strip_tags() vulnerable a cualquier ataque?

Chris Shiflett parece decir que es seguro:

Utilizar Soluciones Maduras

Cuando sea posible, use soluciones maduras y existentes en lugar de intentar crear las suyas propias. Funciones como strip_tags() y htmlentities() son buenas opciones.

Es esto correcto? Por favor, si es posible, citar fuentes.

Sé acerca de HTML purifier, htmlspecialchars() etc.- Estoy no buscando el mejor método para desinfectar HTML. Sólo quiero saber sobre este tema específico. Esta es una pregunta teórica que surgió aquí.

Referencia: strip_tags() implementación en el código fuente PHP

Author: Community, 2011-04-26

4 answers

Como su nombre puede sugerir, strip_tags debería eliminar todas las etiquetas HTML. La única forma en que podemos probarlo es analizando el código fuente. El siguiente análisis se aplica a una llamada strip_tags('...'), sin un segundo argumento para las etiquetas de la lista blanca.

En primer lugar, alguna teoría sobre las etiquetas HTML: una etiqueta comienza con un < seguido de caracteres que no son espacios en blanco. Si esta cadena comienza con un ?, no debe ser analizada. Si esta cadena comienza con un !--, se considera un comentario y lo siguiente el texto tampoco debe ser analizado. Un comentario termina con un -->, dentro de dicho comentario, se permiten caracteres como < y >. Los atributos pueden aparecer en etiquetas, sus valores pueden estar opcionalmente rodeados por un carácter de comilla (' o "). Si existe tal comilla, debe estar cerrada, de lo contrario si se encuentra un >, la etiqueta no está cerrada.

El código <a href="example>xxx</a><a href="second">text</a> se interpreta en Firefox como:

<a href="http://example.com%3Exxx%3C/a%3E%3Ca%20href=" second"="">text</a>

La función PHP strip_tags se hace referencia en línea 4036 de ext / standard / string.c . Esa función llama a la función interna php_strip_tags_ex.

Existen dos buffers, uno para la salida, el otro para "etiquetas HTML internas". Un contador llamado depth contiene el número de corchetes angulares abiertos (<).
La variable in_q contiene el carácter de comilla (' o ") si existe, y 0 si no. El último carácter se almacena en la variable lc.

Las funciones tienen cinco estados, tres se mencionan en el descripción sobre la función. Sobre la base de esta información y el cuerpo de la función, se pueden derivar los siguientes estados:

  • El estado 0 es el estado de salida (no en ninguna etiqueta)
  • El estado 1 significa que estamos dentro de una etiqueta html normal (el búfer de etiquetas contiene <)
  • El estado 2 significa que estamos dentro de una etiqueta php
  • Estado 3: venimos del estado de salida y encontramos los caracteres < y ! (el búfer de etiquetas contiene <!)
  • Estado 4: dentro de HTML comentario

Solo necesitamos tener cuidado de que no se pueda insertar ninguna etiqueta. Es decir, < seguido de un carácter sin espacios en blanco. La línea 4326 comprueba un caso con el carácter < que se describe a continuación:

  • Si está entre comillas (por ejemplo, <a href="inside quotes">), el carácter < se ignora (se elimina de la salida).
  • Si el siguiente carácter es un carácter de espacio en blanco, < se añade al búfer de salida .
  • si está fuera de una etiqueta HTML, el estado se convierte en 1 ("dentro de la etiqueta HTML") y el último carácter lc se establece en <
  • De lo contrario, si está dentro de la etiqueta HTML a, el contador llamado depth se incrementa y el carácter se ignora.

Si > se cumple mientras la etiqueta está abierta (state == 1), in_q se convierte en 0 ("no en una cita") y state se convierte en 0 ("no en una etiqueta"). Se descarta el buffer de etiquetas.

Las comprobaciones de atributos (para caracteres como ' y ") se realizan en el búfer de etiquetas que se descarta. Así que la conclusión es:

Strip_tags sin una etiqueta lista blanca es seguro para la inclusión fuera de las etiquetas, no se permitirá ninguna etiqueta.

Por "etiquetas externas", quiero decir no en etiquetas como en <a href="in tag">outside tag</a>. Sin embargo, el texto puede contener < y >, como en >< a>>. Sin embargo, el resultado no es HTML válido, <, > y & todavía necesita ser escapado, especialmente el &. Que se puede hacer con htmlspecialchars().

La descripción para strip_tags sin un argumento de lista blanca sería be:

Se asegura de que no exista ninguna etiqueta HTML en la cadena devuelta.

 45
Author: Lekensteyn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-29 19:42:25

No puedo predecir futuros exploits, especialmente porque no he mirado el código fuente de PHP para esto. Sin embargo, ha habido exploits en el pasado debido a que los navegadores aceptan etiquetas aparentemente inválidas (como <s\0cript>). Por lo tanto, es posible que en el futuro alguien pueda explotar el comportamiento extraño del navegador.

Aparte de eso, enviar la salida directamente al navegador como un bloque completo de HTML nunca debería ser inseguro:

echo '<div>'.strip_tags($foo).'</div>'

Sin embargo, esto no es seguro:

echo '<input value="'.strip_tags($foo).'" />';

Porque uno podría terminar fácilmente la cita a través de " e insertar un controlador de script.

Creo que es mucho más seguro convertir siempre stray < en &lt; (y lo mismo con las comillas).

 10
Author: Matthew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-26 16:54:11

Strip tags es perfectamente seguro - si todo lo que está haciendo es enviar el texto al cuerpo html.

No es necesariamente seguro ponerlo en atributos mysql o url.

 2
Author: kemus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-26 10:08:48

De acuerdo con esta herramienta en línea , esta cadena se escapará "perfectamente", pero el resultado es otro malicioso!

<<a>script>alert('ciao');<</a>/script>

En la cadena las etiquetas "reales" son <a> y </a>, ya que < y script> por sí solas no son etiquetas.

Espero estar equivocado o que sea solo por una versión antigua de PHP, pero es mejor comprobar en su entorno.

 2
Author: Ludovico Grossi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-02 20:53:19