¿Cuáles son algunos conceptos importantes para enseñar a los desarrolladores acerca de los scripts entre sitios (XSS)?

41

Estoy ayudando con una capacitación de una hora para desarrolladores (aproximadamente 100 de ellos) en scripts entre sitios. ¿Cuáles son algunos conceptos que crees que son indispensables para llegar a ellos? Ahora mismo tenemos:

  • Diferencia entre reflejado y almacenado
  • Capas de defensa ( WAFs , defensas del navegador, encabezados de servidor y codificación segura)
  • Codificación segura y contexto de los parámetros de codificación

Y, sobre todo, el impacto potencial de las vulnerabilidades.

    
pregunta mcgyver5 31.08.2016 - 20:56
fuente

7 respuestas

77

Desde la perspectiva de un desarrollador, los dos primeros puntos que tiene no son muy relevantes. Los XSS almacenados y reflejados tienen la misma mitigación: evite adecuadamente las cosas que emita de acuerdo con su contexto. Es probable que las capas de defensa solo se vean como una excusa para implementar pobremente esta mitigación: "La WAF lo atrapará por mí".

En su lugar, enfóquese en estas prácticas de higiene de códigos:

  • Valide, no escape, en la entrada. La validación de entrada debe ser solo para garantizar que la entrada tenga sentido, no que sea "segura". Es imposible saber en este momento si es seguro, ya que no conoce todos los lugares donde se utilizará.
  • Suponga que todos los datos no son seguros. Nunca asuma que se han escapado algunos datos, o que no incluye etiquetas, citas, entidades o lo que sea. Comprenda que la entrada insegura puede provenir de cualquier parte: encabezados HTTP, cookies, parámetros de URL, datos de importación masiva, etc.
  • Escape en el punto de uso. Escape los datos para el contexto en el que se usa, cuando se usa. ¿Solo quieres escapar una vez para mejorar el rendimiento? Asigne un nombre a la variable de destino según sea seguro usar: jsstringsafeEmail , htmlattrsafeColor , htmltextsafeFullName , etc.
respondido por el bonsaiviking 31.08.2016 - 21:22
fuente
19
  

¿Cuáles son algunos de los conceptos que crees que son indispensables para comunicarles?

  • Diferencia entre reflejado y almacenado: realmente no me importa.
  • Capas de defensa - Sí. Muchos desarrolladores no entienden la "defensa en profundidad". Suponga que cualquier otra mitigación ha fallado y su código es lo último que se encuentra entre el atacante y el recurso vulnerable. ¿Qué puedes hacer para mitigar el ataque?
  • Codificación segura y contexto de los parámetros de codificación: absolutamente.
  • y, sobre todo, el impacto potencial de las vulnerabilidades. - absolutamente

¿Qué más? Lo importante que falta en su lista es: hay muchas herramientas y técnicas que se pueden utilizar para mitigar estas posibles vulnerabilidades; La defensa en profundidad sugiere que usemos tantos como sea posible.

  • Sea seguro por diseño, seguro por defecto. Piense en las vulnerabilidades en todas las etapas de diseño e implementación. Asegúrese de que está optando por salir de estar seguro cuando sea necesario, y no optar por entrar cuando sea necesario.
  • Haz modelos formales de amenaza. ¿Dónde pueden ingresar datos hostiles a un sistema y dónde pueden irse? ¿Qué subsistemas se confían entre sí y cuáles no? Si no sabes dónde están los límites, es difícil endurecerlos contra ataques.
  • Las cadenas son el enemigo. Los datos deben fluir en objetos inteligentes que se pueden componer de manera inteligente, no en cadenas que pueden ser concatenadas y divididas.
  • Si está utilizando un idioma que tiene un sistema de tipo, capture si los datos están contaminados o no se contaminan en el sistema de tipo. Haga que el compilador le diga que está asignando datos contaminados a un contexto que espera datos no contaminados.
  • Si no tiene un compilador que encuentre sus errores, emule un sistema de tipos en su disciplina de nombres. Si una variable contiene datos contaminados, haga que se haya "contaminado" en alguna parte de su nombre. Si asigna un valor contaminado a una variable que no tiene "contaminada" en su nombre, acaba de detectar un problema en el momento de revisar el código en lugar de cuando el atacante tiene éxito.
  • Use herramientas de análisis estático diseñadas por profesionales de la seguridad para encontrar este tipo de problemas; Preste especial atención a la salida, incluso falsos positivos . Un falso positivo es una indicación de que un analizador no pudo ver el código correcto; eso significa que probablemente tampoco puede ser visto como correcto por un humano. Arregle el código para que la herramienta ya no encuentre el falso positivo.
  • Prueba todo como un atacante, no un usuario. Si hay un código que sanea la entrada, pídale a un miembro de su equipo que lo ataque. Los errores de desinfección son una fuente común de vulnerabilidades difíciles de detectar.
  • Haga pruebas para detectar errores de configuración en la producción. Las vulnerabilidades de XSS pueden deberse a la desactivación accidental de alguna validación o desinfección con fines de depuración o prueba, y al olvidarse de volver a encenderla, llevar la configuración incorrecta a producción, y así sucesivamente.
  • Y así sucesivamente.
respondido por el Eric Lippert 31.08.2016 - 23:28
fuente
9

Cubriste la mayoría de los conceptos básicos. Para ampliar un poco sus puntos (algunos de estos parecerán obvios para la mayoría de los lectores aquí, pero no necesariamente serán obvios para todos los desarrolladores):

  • XSS puede ocurrir a través de GET y POST.
  • XSS también es un problema en los backends de administración.
  • El XSS basado en DOM existe.
  • Existen defensas del navegador, pero no se debe confiar en no . Lo mismo ocurre con los WAF y los encabezados de servidor.
  • La codificación debe ocurrir al imprimir, no cuando se recibe una entrada.
  • El contexto es realmente importante. La codificación HTML no es suficiente en algunas situaciones.
  • JavaScript y CSS de escape / codificación son difíciles. Se recomienda usar una biblioteca existente.
  • Todos los parámetros deben estar codificados. No es un buen método para codificar solo los parámetros que parecen inseguros.
  • Se recomienda encarecidamente el filtrado de entrada adicional (por ejemplo, si necesita un número entero, verifique que en realidad sea un número entero, idealmente localizado en alguna clase de entrada), pero nunca debe ser la única línea de defensa.

Pero el punto más importante en mi opinión: La codificación HTML debería ocurrir de forma predeterminada , mediante el uso de un motor de plantillas que codifique todos los parámetros de forma predeterminada.

Si la codificación ocurre en todo el lugar, es muy fácil olvidarlo solo una vez. Por supuesto, todavía es importante cuidar de todas las situaciones en las que la codificación HTML no es suficiente, pero la mayoría de las vulnerabilidades de XSS se evitarán con la codificación predeterminada.

    
respondido por el tim 31.08.2016 - 21:18
fuente
6

Creo que las dos lecciones más importantes para enseñar son estas:

  1. Si está generando un marcado o cualquier otra representación textual estructurada (por ejemplo, JSON, SQL, cadenas de consulta de URL) de manera ad hoc mediante la concatenación de cadenas, entonces detenga lo que está haciendo inmediatamente , y busque o cree una biblioteca centralizada y segura para marcado o generación DOM.
  2. No confíe en las estrategias de prevención XSS que requieren que realice alguna de las siguientes acciones:
    • Adivina qué intentará el atacante o, de lo contrario, intentará ser más astuto que el atacante. En particular, los filtros del lado de entrada tienen un historial de ser engañados por los atacantes, y deben considerarse con sospecha.
    • Identifique, una y otra vez en diferentes contextos, qué variables son entradas "no confiables" que luego debe tratar excepcionalmente. (Más bien, todas las entradas no deben ser confiables de forma predeterminada; debe excluirse de la protección XSS, no habilitarla).

En mi primer punto: casi todos los problemas de inyección surgen al trabajar en el nivel de abstracción incorrecto : los programadores están concatenando cadenas en situaciones en las que deberían estar utilizando operaciones de nivel superior que se abstraen de la Manera correcta de hacer las cosas. Y esto significa que:

  1. Los programadores terminan resolviendo exactamente el mismo problema complicado una y otra vez (escape correcto de los valores de cadena en el contexto en el que se insertan). Incluso si lo hicieron bien todas las veces (¡no es probable!), Las soluciones nunca se reutilizarán.
  2. Dado que la responsabilidad de escapar correctamente de los valores de cadena se difunde por todo el código base en lugar de concentrarse en un punto, auditar el código de seguridad y solucionar los problemas se vuelve un poco más difícil.

En el segundo punto: una buena lección sobre los peligros de confiar en el filtrado del lado de entrada sería examinar el XSS de OWASP Hoja de trucos para evadir el filtro . Piense que esa página documenta un intento fallido tras otro y otro para resolver XSS a través del filtrado del lado de entrada, y la inteligencia que los atacantes pudieron usar para sortearlo.

También suele ver muchos consejos que hablan sobre entradas "no confiables" y sobre cómo procesarlas, lo cual está lleno de peligros porque:

  • Averiguar en qué entradas se puede confiar es mucho trabajo, especialmente cuando tienes que hacerlo una y otra vez;
  • Podría juzgar incorrectamente qué entradas son confiables;
  • Las entradas en las que se puede confiar hoy pueden no ser confiables mañana.

XSS Prevention Cheat Sheet de OWASP es otro documento excelente que sigue a mis dos puntos. Se centra en cómo de forma segura insertar arbitrary cadenas en documentos HTML, CSS y Javascript generados dinámicamente. Si resuelve ese problema en un solo lugar (ya sea en una biblioteca de terceros o en su base de código) y aplica esa solución de manera consistente, lo hará muy bien: tendrá que "cortar la yugular" de las vulnerabilidades de XSS.

    
respondido por el Luis Casillas 31.08.2016 - 21:38
fuente
1

Ya ha enumerado algunos de los conceptos más importantes, lo único que agregaría es la ubicuidad y la facilidad de las pruebas para detectar vulnerabilidades de XSS. XSS es a menudo la primera vulnerabilidad que se enseña, y después de la inyección de SQL es posiblemente la más famosa. También es trivial de escanear, y muchos escáneres de aplicaciones como burp y w3af podrán detectar XSS automáticamente.

Comprender esto es importante porque explica por qué xss todavía existe: prácticamente todos los sitios tienen algún tipo de protecciones xss en su lugar, pero aún son vulnerables cuando un probador inteligente o un escáner es capaz de encontrar información del usuario que el desarrollador ha olvidado. Para desarrollar software libre de xss de forma segura, los desarrolladores deben estar conscientes de que los atacantes utilizan vectores impares para enviar cargas útiles, por ejemplo. Encabezados HTTP, menús desplegables, cualquier cosa que se pueda editar en un proxy HTTP.

    
respondido por el Buffalo5ix 31.08.2016 - 21:30
fuente
1

El punto más importante a destacar, en mi humilde opinión, es que debes saber qué contiene una variable (o campo de base de datos). Debe saber si es texto (y qué conjunto de caracteres / codificación es, en ese caso), o si es HTML (o un atributo HTML, que es otro tipo de datos), o SQL, etc.

Luego, debe aplicar a las conversiones adecuadas cuando necesite pasar de una a otra.

El gran problema es que en muchos casos, la representación de un fragmento de texto (probablemente el tipo más común de datos que puede manipular) es la misma ya sea de texto, HTML, SQL, etc. (el texto "abc" es el mismo que el HTML abc o el SQL 'abc' ) y por esta razón las personas tienden a concatenar bits sin ninguna conversión.

Pero eso se romperá tan pronto como se encuentre con cualquier personaje que tenga un significado especial en uno de los contextos. Esto no solo conduce a problemas de seguridad (inyecciones de XSS y de SQL), sino también a problemas de formato (todos hemos visto sitios que comienzan a mostrar entidades HTML como &lt; cuando deberían mostrar < ), ya que la gente olvida La conversión, o hacerlo varias veces.

Es bastante raro que realmente necesite permitir la entrada de HTML real. En la mayoría de los casos, desea texto. Solo mantén el texto como está, manipulalo tal como es. Pero una vez que desee mostrarlo (en una página HTML), conviértalo a HTML (utilizando bibliotecas / marcos estándar y probados , no su búsqueda y reemplazo improvisados basados en expresiones regulares).

Del mismo modo, lo convierte cuando desea compilar una solicitud de SQL (utilizando consultas parametrizadas, de preferencia). Pero todavía lo guardas exactamente como está.

Muchos marcos agregarán capas de abstracción que "ocultarán" todo esto si realmente los usas. Pero todos sabemos que, incluso con las mejores herramientas, siempre terminará con alguien que intente crear un poco de HTML, por lo que necesitan saber qué se debe hacer si lo hacen.

Si desea / necesita manipular el HTML real, ingrese una dimensión completamente diferente en términos de problemas de XSS. Tenga en cuenta que se puede cubrir en una hora ...

    
respondido por el jcaron 01.09.2016 - 16:13
fuente
0

XSS es grave

Realice una demostración de XSS para demostrar que tiene un impacto en el mundo real, más allá de alert('xss') .

XSS nos afecta

Proporciona algunas estadísticas, por ejemplo. Durante el año pasado, se identificaron 17 fallas de XSS en nuestros productos en las pruebas de penetración.

La solución está escapando

Muéstrales la diferencia entre el código que no se escapa y es vulnerable, y el código que se escapa. Intente de nuevo la demostración y vea cómo falla.

Buenas prácticas de codificación

Muéstreles buenas maneras de escapar con los lenguajes y marcos que usa su empresa. Lo ideal es un motor de plantillas que realice el escape automático. Si tiene un solo idioma / marco en toda la empresa, esto es más fácil. De lo contrario, muestre un ejemplo y dígales que lean el marco particular que están utilizando.

Errores comunes

Contexto de la página. Incluso si tiene un motor de plantillas de escape, los datos no confiables dentro de una etiqueta <script> pueden causar XSS.

¿Qué datos no son de confianza? Por ejemplo, si obtiene una fuente RSS de un sitio externo, sigue siendo un riesgo XSS, aunque no sea una entrada directa del usuario.

DOM XSS: el uso de JavaScript eval y document.write puede causar XSS.

Defensa en profundidad

CSP es una excelente defensa en profundidad, pero puede ser difícil de implementar.

Las opciones de cookies y la validación de solicitudes se pueden implementar fácilmente, pero son solo defensas parciales.

Pide ayuda

Cuando haga algo difícil, como permitir que los usuarios utilicen etiquetas HTML limitadas en los comentarios, pida ayuda a un especialista en seguridad.

    
respondido por el paj28 02.09.2016 - 09:44
fuente

Lea otras preguntas en las etiquetas