Vulnerabilidad XSS en función de filtrado en PHP

¿Alguien sabe de una buena función que hay para el filtrado de entrada genérico a partir de formas? Zend_Filter_input parece requieren un conocimiento previo de los contenidos de la entrada y me preocupa que el uso de algo como HTML Purifier tendrá un gran impacto en el rendimiento.

¿Qué pasa con algo como : http://snipplr.com/view/1848/php–sacar-xss/

Muchas gracias por la entrada.

  • HTMLPUrifier podría tomar algunos recursos, pero probablemente no tienen mucho contenido publicado ? (en comparación con lo consultado, por ejemplo) ;; si ejecuta HTMLPurifier al guardar los datos a la DB, y no cuando la lectura desde la DB, puede que esté bien…
InformationsquelleAutor codecowboy | 2009-08-26

10 Kommentare

  1. 80

    Forma sencilla? Uso strip_tags():

    $str = strip_tags($input);

    También puede utilizar filter_var() para que:

    $str = filter_var($input, FILTER_SANITIZE_STRING);

    La ventaja de filter_var() es que usted puede controlar el comportamiento de, por ejemplo, la extracción o la codificación de alta y baja de los personajes.

    Aquí está una lista de desinfección de los filtros.

    • gracias – no sabía acerca de filter_var()
    • Así es esta la mejor manera o HTML Purifier el mejor camino a seguir para lograr la máxima seguridad.
    • Mientras cletus en general, tiende a ser irregular, con el viejo y simple strip_tags() es un enorme y supervisión de un problema de seguridad. Por favor, lea lo siguiente para más detalles htmlpurifier.org/comparison#striptags
    • Yo lo he probado y es seguro contra inyecciones SQL demasiado!
    • El problema con strip_tags es que no validar atributos. Así como no permitir que ninguna de las etiquetas, que debería funcionar como un filtro XSS.
    • Este no protege contra algo como " onclick="alert('Why it is not blocked?')
    • A menos que usted desea tira de cada etiqueta, esto no es un seguro de filtro XSS. HTML Purifier (y similares) de las bibliotecas son el único medio eficaz para permitir que las etiquetas y razonables para proteger la seguridad del usuario, con datos proporcionados.

  2. 26

    Hay un número de maneras en que los hackers poner a utilizar para ataques XSS, PHP las funciones incorporadas de no responder a todo tipo de ataques XSS. Por lo tanto, las funciones tales como strip_tags, filter_var, mysql_real_escape_string, htmlentities, htmlspecialchars, etc, no nos protegen 100%. Usted necesita un mecanismo mejor, aquí es ¿cuál es la solución:

    function xss_clean($data)
    {
    //Fix &entity\n;
    $data = str_replace(array('&','<','>'), array('&','<','>'), $data);
    $data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
    $data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
    $data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');
    
    //Remove any attribute starting with "on" or xmlns
    $data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);
    
    //Remove javascript: and vbscript: protocols
    $data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
    $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
    $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);
    
    //Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
    $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
    $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
    $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);
    
    //Remove namespaced elements (we do not need them)
    $data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);
    
    do
    {
        //Remove really unwanted tags
        $old_data = $data;
        $data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
    }
    while ($old_data !== $data);
    
    //we are done...
    return $data;
    }
    • Hey @Sarfraz es su función realmente seguro?
    • también debe agregar urldecode delante de couse este script no funciona por ejemplo en %22%3E%3Cscript%3Ealert(‘try_xss’);%3C/script%3E
    • Hay una actualización de este código proporcionado por Christian Stocker: blog.liip.ch/archivo/2008/09/10/…
  3. 7

    la mejor y la forma segura es el uso de HTML Purifier. Siga este enlace para algunos consejos sobre su uso con Zend Framework.

    HTML Purifier con Zend Framework

    • Pero dammmmn es que la biblioteca de la hinchada.
    • Puede ser hinchado, pero cuando usted realmente necesita la opción nuclear para filtrar hacia fuera, es la mejor.
  4. 3

    Tengo un problema similar. Necesito que los usuarios enviar contenido html a una página de perfil con un gran editor WYSIWYG (Redactorjs!), me escribió la siguiente función para limpiar el presentado html:

        <?php function filterxss($str) {
    //Initialize DOM:
    $dom = new DOMDocument();
    //Load content and add UTF8 hint:
    $dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">'.$str);
    //Array holds allowed attributes and validation rules:
    $check = array('src'=>'#(http://[^\s]+(?=\.(jpe?g|png|gif)))#i','href'=>'|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i');
    //Loop all elements:
    foreach($dom->getElementsByTagName('*') as $node){
        for($i = $node->attributes->length -1; $i >= 0; $i--){
            //Get the attribute:
            $attribute = $node->attributes->item($i);
            //Check if attribute is allowed:
            if( in_array($attribute->name,array_keys($check))) {
                //Validate by regex:    
                if(!preg_match($check[$attribute->name],$attribute->value)) { 
                    //No match? Remove the attribute
                    $node->removeAttributeNode($attribute); 
                }
            }else{
                //Not allowed? Remove the attribute:
                $node->removeAttributeNode($attribute);
            }
        }
    }
    var_dump($dom->saveHTML()); } ?>

    La $echa matriz contiene todos los permitidos atributos y reglas de validación. Tal vez esto es útil para algunos de ustedes. Yo no lo he probado aún, así que los consejos son bienvenidos

  5. 2
    function clean($data){
        $data = rawurldecode($data);
        return filter_var($data, FILTER_SANITIZE_SPEC_CHARS);
    }
    • no funciona. pero $data = filter_var($_GET['data'], FILTER_SANITIZE_STRING); obras.
  6. 1

    htmlspecialchars() es perfectamente adecuado para el filtrado de la entrada de usuario que se muestra en los formularios html.

  7. 0

    De acuerdo a http://www.mcafeesecure.com Solución General en situación de vulnerabilidad de cross-site scripting (XSS) función de filtro puede ser:

    function xss_cleaner($input_str) {
        $return_str = str_replace( array('<','>',"'",'"',')','('), array('&lt;','&gt;','&apos;','&#x22;','&#x29;','&#x28;'), $input_str );
        $return_str = str_ireplace( '%3Cscript', '', $return_str );
        return $return_str;
    }
    • La aceptada previamente y altamente upvoted respuesta proporciona una limpias y cortas solución. ¿Qué hace su soulution añade a esa respuesta? Marque esta metaSO pregunta y Jon Skeet: Codificación Blog sobre el modo de dar una respuesta correcta.
  8. -1

    Trate de usar para la Limpieza de XSS

    xss_clean($data): "><script>alert(String.fromCharCode(74,111,104,116,111,32,82,111,98,98,105,101))</script>
  9. -1

    He encontrado una solución para mi problema con los posts con umlaut alemán. Para proveer de totalmente de limpieza (la muerte) de los posts, os codificar los datos entrantes:

        *$data = utf8_encode($data);
        ... function ...*

    Y en el último me decodificar la salida para llegar a corregir los signos:

        *$data = utf8_decode($data);*

    Ahora el post de ir a través de la función de filtro y me da un resultado correcto…

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea