¿Se deben sanear las cadenas no confiables del lado del servidor si se insertan en el cuerpo del documento mediante document.createTextNode?

1

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.

    
pregunta gaazkam 26.08.2018 - 00:53
fuente

1 respuesta

1

La entrada a createTextNode , textContent y el no estándar innerText toman cadenas de JavaScript simples. No necesita ni debe codificar esa entrada como HTML, todo lo que necesita son simples cadenas JS.

Dicho esto, todavía es necesario codificar correctamente el mensaje del servidor. Si está generando el texto como HTML, lo codificaría con entidades HTML. Si está enviando el mensaje como JavaScript o JSON, normalmente lo codificará con un codificador JSON. La codificación correcta depende del contexto en que se imprime y no siempre es HTML.

    
respondido por el Alexander O'Mara 26.08.2018 - 03:18
fuente

Lea otras preguntas en las etiquetas