Webapp de chat. Los clientes (es decir, los navegadores web) envían mensajes al servidor, que el servidor transmite a todos los clientes conectados. El código del lado del cliente se ve así:
let p = document.createElement('p')
p.appendChild(document.createTextNode(message))
document.getElementById('chatbox').appendChild(p)
Donde message
es la cadena recibida del servidor.
El problema aquí es que se recomienda encarecidamente para sanear los datos no confiables del lado del servidor antes de insertarlos en el cuerpo del documento, eliminando los caracteres especiales ( <
, >
, "
, etc.) y reemplazándolos con las entidades HTML apropiadas. Me dijeron que el código anterior era vulnerable a XSS si esto no se hace .
Sin embargo, tal desinfección parece llevar a una visualización incorrecta de los mensajes si se usa document.createTextNode
. A diferencia de innerHTML
, document.createTextNode
muestra caracteres especiales verbatim y no los interpreta como HTML . Por lo tanto, el saneamiento del lado del servidor que cambia los caracteres antes mencionados a las entidades HTML hará que los clientes muestren las entidades, no los caracteres que se supone que los entes representan .
Como tal, no creo que dicha validación sea necesaria ni correcta cuando se usa document.createTextNode()
.
Sin embargo, me dijeron que, sin embargo, siempre es necesario desinfectar las cadenas no confiables del lado del servidor. Me dijeron que escapar de estos caracteres del lado del servidor era siempre necesario. En ese caso, ¿se supone que debo dejar de usar document.createTextNode()
y comenzar a usar innerHTML
en su lugar? Me parece extraño porque siempre he pensado que innerHTML
es una de las menos características seguras de JavaScript, que no debe usarse con contenido no confiable.