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('/', '/', $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.
Asegúrese de usar declaraciones preparadas para evitar la inyección SQL. http://php.net/manual/en/pdo.prepared-statements.php –