2009-11-09 8 views
5

Tengo un campo de texto de formulario que acepta una url. Cuando se envía el formulario, inserto este campo en la base de datos con la inyección anti-sql adecuada. Mi pregunta es sobre xss.de entrada es URL, cómo protegerlo de xss

Este campo de entrada es una url y debo volver a mostrarlo en la página. ¿Cómo puedo protegerlo de xss en el camino a la base de datos (creo que no es necesario nada porque ya me he ocupado de la inyección SQL) y en el camino de la base de datos?

Imaginemos que lo tenemos así, lo estoy simplificando, y no se preocupe por la inyección sql. ¿A dónde voy desde aquí después de eso?

$url = $_POST['url']; 

Gracias

+1

Asegúrese de usar declaraciones preparadas para evitar la inyección SQL. http://php.net/manual/en/pdo.prepared-statements.php –

Respuesta

9

Suponiendo que esto va a ser puesto en el contenido HTML (por ejemplo, entre <body> y </body> o entre <div> y </div>), es necesario codificar los 5 caracteres XML especiales (&, <, >", '), y OWASP recomienda incluir barra (/) y la orden interna de PHP, htmlentities() va a hacer la primera parte para usted, y un simple str_replace() puede hacer la barra:.

function makeHTMLSafe($string) { 
    $string = htmlentities($string, ENT_QUOTES, 'UTF-8'); 
    $string = str_replace('/', '&#x2F;', $string); 
    return $string; 
} 

Si, sin embargo, va a poner el valor contaminado en un atributo HTML, como la cláusula href= de <a, deberá codificar un conjunto diferente de caracteres ([espacio]% * + , - /; < =>^y |) -y debe hacer doble cita de sus atributos HTML:

function makeHTMLAttributeSafe($string) { 
    $scaryCharacters = array(32, 37, 42, 43, 44, 45, 47, 59, 60, 61, 62, 94, 124); 
    $translationTable = array(); 
    foreach ($scaryCharacters as $num) { 
     $hex = str_pad(dechex($num), 2, '0', STR_PAD_LEFT); 
     $translationTable[chr($num)] = '&#x' . $hex . ';'; 
    } 

    $string = strtr($string, $translationTable); 
    return $string; 
} 

La última preocupación es ilegal caracteres UTF-8-cuando se entrega a algunos navegadores, una secuencia de bytes UTF-8-mal formada puede salir de una entidad HTML. Para protegerse contra esto, simplemente asegúrese de que todos los caracteres UTF-8 que recibe son válidas:

function assertValidUTF8($string) { 
    if (strlen($string) AND !preg_match('/^.{1}/us', $string)) { 
     die; 
    } 

    return $string; 
} 

El modificador u en esa expresión regular hace que sea una coincidencia de expresiones regulares Unicode. Al hacer coincidir un solo chararchter, ., estamos seguros de que toda la cadena es Unicode válida.

Como todo esto depende del contexto, es mejor hacer cualquiera de estas codificaciones en el último momento posible, justo antes de presentar la salida al usuario. Estar en esta práctica también hace que sea fácil ver los lugares que te has perdido.

OWASP proporciona una gran cantidad de información sobre su XSS prevention cheat sheet.

+0

Nunca escuché acerca de ninguna precaución especial que deba tomarse con los atributos html, contra elementos de texto. ¿Tienes alguna referencia/explicación para eso? – troelskn

+2

Ah ... Para responder a mi propia pregunta, OWASP recomienda esto porque es necesario * si los atributos no están entre comillas *. Yo recomendaría citar atributos en su lugar. – troelskn

+0

En cuanto a la codificación de caracteres para su inclusión en atributos HTML, OWASP dice (énfasis mío) "Los atributos sin comillas se pueden separar con muchos caracteres, ** incluyendo ** [espacio]% * +, - /; < = >^y |." . Entonces, solo codificar estos no debería ser suficiente ¿no? – Lode

1

Debe codificarlo con htmlspecialchars antes de mostrarlo a un usuario. Por lo general, esto es suficiente cuando se trata de datos fuera de <script> etiqueta y/o atributos de etiqueta HTML.

1

No mueva su propia protección XSS, hay demasiadas maneras en que algo puede pasar (ya no puedo encontrar el enlace a una cierta demografía XSS, pero la cantidad de posibilidades es asombrosa: IMG roto) etiquetas, atributos extraños, etc.).

Utilice una biblioteca existente como sseq-lib o extraiga una de un marco establecido.

Actualización: Aquí está the XSS-demopage.