Mejores prácticas actuales para prevenir ataques XSS persistentes

5

Tengo un campo de texto que le permite al usuario escribir lo que quiera. Después de guardar, los resultados se muestran más tarde en la pantalla para potencialmente muchas personas.

XSS me parece un poco a la magia negra, por lo que me pregunto cuáles son las mejores prácticas actuales para manejar esta situación (desde formas específicas para desinfectar las entradas hasta formas específicas de codificar HTML para mostrar)     

pregunta Jarrod Everett 31.08.2012 - 00:39
fuente

7 respuestas

10

Escape las citas, filtre la palabra javascript, restrinja las letras permitidas, etc.

Es posible que solo quieras leer las Pautas de OWASP en XSS .

Esto

    
respondido por el Eric G 31.08.2012 - 02:14
fuente
10

Ya que quiere las mejores prácticas actuales y la última respuesta aquí es en agosto de 2012, pensé que también podría evaluar y actualizar esto.

Mejores prácticas para prevenir cualquier tipo de ataque XSS (persistente, reflejado, DOM, lo que sea).

  1. Valide estrictamente todas las entradas. Por ejemplo, si solicita un código postal del Reino Unido, asegúrese de que solo se permiten letras, números y el carácter de espacio. Haga esto en el servidor y, si la validación falla, muestre un mensaje al usuario para que pueda corregir su entrada. Haga esto para todas las variables fuera de su control, incluidas las cadenas de consulta, los datos POST, los encabezados y las cookies.
  2. Agregue algunos encabezados de seguridad . A saber
    • X-XSS-Protection: 1; mode=block para activar la protección del navegador XSS reflectante en modo de bloqueo en lugar de modo de filtrado. El modo de bloqueo detiene los ataques como este .
    • X-Content-Type-Options: nosniff para evitar la inserción de JavaScript en imágenes y otros tipos de contenido.
    • Content-Security-Policy: con script-src y style-src estrictos al menos. No permitir unsafe-inline o unsafe-eval . Este es el padre de los encabezados por matar a XSS.
  3. Sigue las reglas en OWASP XSS (Cross Site Scripting) Prevention Cheat Sheet al generar valores de , sin embargo, para la regla # 3 haría lo siguiente:
    • Use HTML atributos de datos para mostrar algo dinámico en la página.
    • por ejemplo %código%
    • Donde <body data-foo="@foo" /> generará una versión codificada en HTML de la variable. p.ej. @foo daría " />
    • Agarra estos valores usando JQuery o JavaScript: <body data-foo="&quot; &#x2F;&gt;" />
    • De esta manera, no tiene que preocuparse por ninguna codificación doble, a menos que su JavaScript más adelante se inserte como HTML, sin embargo, las cosas son aún más simples, ya que también se trata de la codificación en lugar de mezclarlas todas.
    • Use una función como la siguiente para codificar HTML si está usando var foo = $("body").data("foo"); , de lo contrario podría presentar una vulnerabilidad. Lo ideal es utilizar las funciones document.write o JQuery textContent y text() .

Aborda estos en orden inverso. Concéntrese en el # 3 ya que esta es la principal mitigación para XSS, el # 2 le dice al navegador que no ejecute nada que se deslice a través y el # 1 es una buena medida de defensa en profundidad (si no pueden ingresar caracteres especiales, pueden hacerlo) t salir). Sin embargo, el número 1 es más débil porque no todos los campos se pueden validar estrictamente y puede afectar la funcionalidad (imagine Stack Exchange sin la capacidad de permitir " attr() " como entrada).

function escapeHtml(str) {
    return String(str)
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;")
        .replace(/\//g, "&#x2F;")
}
    
respondido por el SilverlightFox 23.08.2016 - 20:34
fuente
4

Componga su HTML utilizando un lenguaje de plantillas de escape automático que, de forma predeterminada, escapa entradas no confiables para usted.

Por ejemplo, las plantillas de Django escapan a los caracteres especiales HTML :

  

Claramente, los datos enviados por el usuario no deben ser confiados a ciegas e insertados directamente en sus páginas web, ya que un usuario malintencionado podría usar este tipo de agujero para hacer cosas potencialmente malas. Este tipo de vulnerabilidad de seguridad se denomina ataque de secuencias de comandos entre sitios (XSS).

     

Para evitar este problema, tienes dos opciones:

     
  1. Puede asegurarse de ejecutar cada variable que no sea de confianza a través del filtro de escape, que convierte los caracteres HTML potencialmente dañinos en peligrosos. Esta fue la solución predeterminada en Django durante sus primeros años, pero el problema es que le incumbe a usted, el autor del desarrollador / plantilla, asegurarse de que está escapando de todo. Es fácil olvidarse de escapar de los datos.
  2.   
  3. Puedes aprovechar el escape HTML automático de Django. El resto de esta sección describe cómo funciona el escape automático.   De forma predeterminada en Django, cada plantilla se escapa automáticamente de la salida de cada etiqueta variable.
  4.   

También hay una variedad de plantillas de escape automático contextuales que son un poco más inteligentes y pueden prevenir XSS incluso cuando sus plantillas contienen JavaScript, CSS y URL incrustados.

Plantillas de cierre dice:

  

El autoescape contextual se realiza mediante el aumento de las plantillas de cierre para codificar correctamente cada valor dinámico según el contexto en el que aparece, defendiendo así las vulnerabilidades de XSS en valores controlados por un atacante.

El lenguaje de la plantilla de Go utiliza el ajuste automático de contexto:

  

Las plantillas HTML tratan los valores de los datos como texto simple que debe codificarse para que puedan incrustarse de forma segura en un documento HTML. El escape es contextual, por lo que las acciones pueden aparecer en contextos de JavaScript, CSS y URI.

    
respondido por el Mike Samuel 01.09.2012 - 01:56
fuente
2

La única práctica recomendada: controlar estrictamente el tipo y sanear sus datos.

Siempre use el método adecuado para generar datos según el tipo: nunca renderice lo que se ingresó como texto en HTML (es decir, asigne datos de texto ingresados por el usuario a la propiedad .data del nodo de texto en DOM, no a .innerHTML mágico). Nunca use la entrada en eval -como la construcción o como subcadena de la consulta de la base de datos: las herramientas adecuadas serían el analizador de expresiones y los marcadores de posición respectivamente.

Rechace o limpie todo lo que venga a su programa desde fuentes externas (incluidas sus propias bases de datos internas, ¡eso también podría verse comprometido!) a un conjunto estricto de patrones permitidos.

Utilice protocolos y serializadores establecidos y comprobados para el transporte de datos, preferiblemente uno que tenga implementación nativa tanto en el extremo de envío como en el de recepción (serializador JSON, protobuf, almacenable en Perl, etc.) en lugar de cotizaciones hechas en casa.

    
respondido por el Oleg V. Volkov 31.08.2012 - 14:19
fuente
0
  

Tengo un campo de texto que le permite al usuario escribir lo que sea   quiere . Después de guardar, los resultados se muestran más tarde en la pantalla para   potencialmente muchas personas.

Ese es el problema. Confíe NO en la entrada del usuario ... Para evitar XSS, debe desinfectar la entrada del usuario antes de almacenarla en la base de datos.

Algunas cosas que debes verificar:

  • No permitir etiquetas HTML. Una vez que haya prohibido todas las etiquetas, podría permitir algunas de ellas (como este sitio) como <hr> <b> etc. O crear su propio sistema de etiquetas, [img] [b] ...

  • No permitir " o ' , reemplácelos por su código HTML &quot; y &#39;

  • Si planea permitir hipervínculos, asegúrese de que la URL sea válida. En otras palabras, deben comenzar con http:// o https://

Probablemente, el lenguaje en el que está desarrollando la aplicación tiene funciones para verificar la mayoría de los puntos anteriores (al menos, verificar comillas y etiquetas HTML).

    
respondido por el eversor 31.08.2012 - 14:39
fuente
0

Si el servidor solo sirve entidades y valores (por lo que no sirve partes de DOM) y no genera HTML, los valores de codificación crean problemas de codificación porque la parte que integra estos valores en el DOM ya no debe confiar en su entradas, lo que resulta en problemas de codificación doble.

Creo que la función de un servidor de este tipo (que no construye DOM, sino que solo almacena y sirve datos) no es desinfectar las entradas. Sin embargo, aún puede validar las entradas antes y devolver una Solicitud incorrecta 400 si se detecta un patrón de ataque. De esta manera, el servidor contribuye a la protección contra XSS sin todos los problemas de modificación de datos debido a la desinfección.

Creo que la desinfección del lado del servidor debe reservarse para los servidores que crean el lado del servidor DOM: que sirven páginas HTML o partes de páginas HTML.

Pero si DOM se modifica en el lado del cliente, el código JS no debe confiar en su entrada y evitar las inyecciones de XSS.

El problema es: en Java, las bibliotecas de seguridad de OWASP ofrecen API para desinfectar HTML, pero no solo para validarlo. Para hacerlo, he encontrado la anotación de hibernación @SafeHtml que utiliza JSoup y se puede usar fácilmente en los campos DTO con @Valid anotación para habilitar la validación en una clase / método / parámetro.     

respondido por el Pleymor 19.09.2016 - 11:10
fuente
0

Disculpe si no estoy muy claro. El inglés no es mi lengua materna. La mejor manera de garantizar un gran nivel de seguridad en su producto es seguir la regla de oro: " Nunca confíe en las entradas del usuario "

Por lo tanto, siempre debe asumir que un usuario intentará enviar datos inesperados a su aplicación, que no seguirá los protocolos (es decir, que falsificará algunos campos, repetirá la solicitud, etc.) Y usted debe predecir su comportamiento.

Para el punto XSS debes

- > Valide la entrada del usuario (es decir, si espera obtener un nombre, debe bloquear todos los valores que contengan caracteres especiales como% o ", si espera un número de teléfono, debe bloquear los valores que contienen letras, y así sucesivamente)

- > Desinfecte la entrada del usuario (es decir, escape todos los caracteres que tienen una semántica específica para el intérprete en el backend. Para el XSS es usualmente html / javascript, por lo que debería preocuparse por ", & lt ;, > in prioridad)

Como hemos dicho a nuestros colegas, hay una gran guía hecha por OWASP con respecto a la prevención XSS: enlace

    
respondido por el Farewell 04.01.2018 - 15:48
fuente

Lea otras preguntas en las etiquetas