Output
Cuando una salida de Unicode se traduce a un conjunto de caracteres de 8 bits, a veces se realiza con una conversión de "mejores esfuerzos". Los caracteres que no tienen una coincidencia exacta se convierten en algo similar, por lo que tal vez "a con circunflejo" se convierta en "a". Esto puede ser extremadamente peligroso para la seguridad. Hay un carácter de Unicode "medio ancho menos que signo". Los navegadores no reconocen esto como el inicio de una etiqueta, por lo que generalmente no se escapa. Sin embargo, en una conversión de los mejores esfuerzos, se puede traducir a un formato regular < y esto puede causar un defecto XSS. Esto no es solo una preocupación teórica; He visto esto en la naturaleza. Alguna información aquí .
En la mayoría de los casos, la mejor solución es utilizar utf-8 en todas partes. Si esto no es posible, debe hacer una conversión estricta, en lugar de realizar los mejores esfuerzos. Y si eso no es posible, entonces debes hacer el mejor esfuerzo de conversión ANTES de escapar.
Input
Hay una regla muy simple para evitar problemas: descodificar antes de validar . Independientemente del conjunto de caracteres que obtenga (o la codificación de la URL, etc.), descodifíquelo completamente antes de validar o realizar cualquier operación en los datos. Si sigues esta regla, deberías ser bueno, incluso si hay fallas en tu decodificación (por ejemplo, aceptar secuencias de utf-8 demasiado largas).