Solución simple para XSS

2

Tengo una idea de cómo derrotar a XSS tan simple que puede funcionar y me preguntaba si alguien ya había hecho algo similar.

El objetivo aquí no es la eficiencia sino la seguridad. En otras palabras, no me importa intercambiar ancho de banda por seguridad. Mi idea sería servir a todos los caracteres dentro de etiquetas HTML simples.

Básicamente, si lo siguiente, por el motivo que fuera, sería un exploit XSS funcional: 0WNED!byXSS (que por cualquier motivo nadie lo hubiera detectado), se serviría como:

<i>0</i><i>W</i><i>N</i>E<i>D</i>!<i>by</i>X<i>S</i>S<i>

Básicamente, un bucle se aseguraría de hacer solo:

  • escribe <i>
  • escribe un solo carácter
  • escribe </i>

¿Podría funcionar algo así técnicamente (aparte de las interpretaciones y los problemas de ancho de banda) y se ha hecho algo así?

EDIT

Aquí hay un ejemplo (simplificado) de lo que estoy pensando.

En lugar de servir esto:

<html>
  <head>
    <title>Sample</title>
  </head>
  <body>
    <table>
      <tr>
        <td>Here goes user input</td>
        <td>potentially containing an XSS exploit</td>
      </tr>
    </table>
</table>
</body>
</html>

Yo serviría esto:

<html>
  <head>
    <title>Sample</title>
  </head>
  <body>
    <table>
      <tr>
        <td><i>H</i><i>e</i><i>r</i><i>e</i><i> </i><i>g</i><i>o</i><i>e</i><i>s</i><i> </i><i>u</i><i>s</i><i>e</i><i>r</i><i> </i><i>i</i><i>n</i><i>p</i><i>u</i><i>t</i></td>
        <td><i>p</i><i>o</i><i>t</i><i>e</i><i>n</i><i>t</i><i>i</i><i>a</i><i>l</i><i>l</i><i>y</i><i> </i><i>c</i><i>o</i><i>n</i><i>t</i><i>a</i><i>i</i><i>n</i><i>i</i><i>n</i><i>g</i><i> </i><i>a</i><i>n</i><i> </i><i>X</i><i>S</i><i>S</i><i> </i><i>e</i><i>x</i><i>p</i><i>l</i><i>o</i>it</td>
      </tr>
    </table>
</table>
</body>
</html>

La etiqueta <i> se eligió de manera arbitraria, cualquier etiqueta (preferiblemente de una letra) sería suficiente.

Varias funcionalidades del sistema operativo / navegador parecen seguir funcionando correctamente:

  • Puedo cortar y pegar correctamente en el portapapeles
  • Todavía puedo buscar texto ( por ejemplo puedo buscar "va" y, a pesar del hecho de que cada letra de "va" está envuelto por etiquetas que el navegador aún encuentra bien)

Supongo que el motor de búsqueda todavía analizaría / indexaría correctamente el contenido (no estoy muy seguro de lo que dice).

A mi parecer, es una forma bastante simple y efectiva de prevenir muchos ataques basados en las entradas maliciosas de los usuarios.

    
pregunta Cedric Martin 10.03.2013 - 16:26
fuente

5 respuestas

7

Esto parece una solución tonta para un problema ya resuelto:

  1. Use una biblioteca de purificadores HTML para permitir solo un subconjunto seguro, O
  2. Los caracteres de entrada cuestionables de escape HTML como <>'"& a sus equivalentes (por ejemplo, < va a &lt; ). Además, si necesita permitir algún formato (por ejemplo, los usuarios pueden enviar enlaces, insertar texto en negrita) use un subconjunto seguro de un lenguaje de marcado liviano para convertir las entradas de usuario como [google link](http://www.google.com) a enlace de google .

Si su esquema fue perfecto e insertó cada carácter de la entrada de usuario no confiable, carácter por carácter, entre su propia etiqueta como <i>h</i><i>e</i><i>l</i><i>l</i><i>o</i> , personalmente no veo que un atacante realice fácilmente un ataque XSS, aunque alguien más podría hacerlo. pensar en algo

Líneas de ataques que podrían funcionar:

  • tal vez puedan desordenar el DOM (insertando símbolos < > ) y algún navegador aleatorio intentará arreglarlo y corregirlo de alguna manera insegura.
  • tal vez algún navegador permita que un atacante inserte la tecla de retroceso (Unicode 08) y escape de sus etiquetas de alguna manera
  • o algún navegador optimiza internamente las etiquetas consecutivas, por ejemplo, las convierte en <i>hello</i> .
  • o su método de analizar el carácter de entrada del usuario por carácter es defectuoso y superado.

Además, con su método no veo cómo su esquema le permitiría hacer cualquier cosa que desee hacer; por ejemplo, permite a los usuarios dar formato a texto o publicar enlaces o cualquier cosa elegante. En este caso, es más simple simplemente prohibir los caracteres <>&'" que tienen un significado especial en HTML.

    
respondido por el dr jimbob 10.03.2013 - 18:54
fuente
5

¡Felicitaciones! He pensado un poco en esto y este es un sistema de escape bastante sólido. Aunque puede conducir a errores, no creo que esto sea muy útil para un atacante. La razón principal por la que una codificación de separación de caracteres es mejor que una codificación html tradicional es que causa problemas con la carga útil de un atacante.

Por ejemplo, los filtros XSS a veces no logran evitar que XSS dependa de dónde está escrito en la página. Si un filtro XSS toma en consideración el <> usual mientras ignora una doble cita, entonces este es un vector xss que usa la carga útil ";alert(1)// :

<script>
var j="";alert(1)//";
document.write(j);
</script>

Sin embargo, el uso de un método de codificación de separación de caracteres provocará un error de análisis de Java:

<script>
var j="<i>"</i><i>a</i><i>l/i><i>e</i><i>r</i><i>t</i><i>";
document.write(j);
</script>

¡La codificación HTML no es una panacea! El navegador descodifica automáticamente los valores dentro de una etiqueta HTML y esto puede llevar a xss en eventos DOM:

<a href="" onclick="alert('hi&#39;);alert(/xss/)//'">click</a>

En este caso, se mostrarán dos cuadros de alerta porque &#39; se descodificará automáticamente a una sola cita ' antes de que se evalúe como javascript. Sin embargo, si solo puede inyectar un solo carácter, obtendrá una excepción en la carga útil.

La codificación HTML es buena porque el navegador decodificará los valores HTML como <form value="o&#39;connel"> en el o'connell esperado antes de enviarlo como una solicitud. Si utiliza cualquier otro método de codificación xss, todos los valores entrantes deberán decodificarse, lo que podría causar problemas de filtrado o daños en los datos.

No creo que la sobrecarga adicional de este método de escape justifique la seguridad provista. Es preferible utilizar una codificación HTML tradicional. Un buen sistema de plantillas facilita la defensa contra xss.

    
respondido por el rook 10.03.2013 - 20:24
fuente
2

Si su carácter especial es <i> y </i> y los datos que está tratando de codificar o visualizar incluyen < , i o > , entonces deberá "escapar" de esos caracteres. (o el trío de 3 caracteres) Como son caracteres bastante comunes, creo que deberás asegurarte de que siempre estén codificados / descodificados correctamente.

Entonces, ahora lo que tenemos es una solución que requiere que el desarrollador garantice un escape adecuado, también debemos tener en cuenta que no todo se escapa en todos los casos. Es decir, la etiqueta <title> .

En un caso, un Título puede contener nombres de usuario, nombres de productos, etc. Si se usa esta función, el escape condicional de la entrada del usuario es una cosa más que el desarrollador deberá recordar. Lo siguiente a considerar es JSON y Javascript. Las cosas no son tan simples ahora.

La solución que está proponiendo es crear el mismo problema que intenta resolver, aunque de otra forma: Exigir al desarrollador que escape de forma condicional los caracteres en función del contexto del valor que se mostrará.

Para complicar aún más esto, es cualquier DHTML creado por javascript que también debe mostrarse en el navegador, o si se utiliza la entrada del usuario para descargar una imagen:

   <img src="http://example.com/hackedUserDisplayName.js">

Enesecaso,eldesarrolladorqueríausarlaentradadelusuarioparaincluirenlapágina,peronolalimpiócorrectamente.Elenfoquedeetiquetadonoseusaríaaquíyhabríarotolaurldelaimagensilofuera.

Lofelicitoporpensarenmedidasdeseguridadproactivasytratardeencontrarunenfoquedetallaúnica,pero debe probar sus ideas con los ejemplos de XSS enumerados en esta página.

Sigue intentándolo y haznos saber si eres capaz de inventar un enfoque más consistente para arreglar XSS. El resultado más probable es que estarás bien versado en XSS. Es un ganar / ganar.

    
respondido por el random65537 10.03.2013 - 19:38
fuente
1

XSS es un problema resuelto. El hecho de que se sigan encontrando vulnerabilidades de XSS no significa que no se haya resuelto. Simplemente significa que alguien de manera incorrecta, o no implementó una solución.

Esta solución que planteas aquí es interesante, pero no la usaría.

Por un lado, probablemente tendrías que usar elementos span en lugar de i elements. Eso es un <span> seguido de 1 carácter seguido de </span> . multiplicado por la cantidad de caracteres de entrada que permita su aplicación web. Imo, eso es una hinchazón innecesaria en los datos que se deben almacenar. Además, aún debe considerar una entrada errónea como los caracteres NULL, & lt ;, & gt ;,;, ', "y otros símbolos.

Además, es mejor desinfectar la entrada antes de almacenarla en una base de datos y nuevamente después de recuperarla de una base de datos. La solución que tiene aquí no haría nada por recopilar datos al recuperarlos de una base de datos; lo digo porque estoy seguro de que ambos estamos de acuerdo en que no sacarán un carácter de la base de datos y lo insertarán dentro de un espacio. etiqueta.

    
respondido por el cmt 10.03.2013 - 19:10
fuente
0

Si busca eliminar por completo las posibilidades de ser vulnerable a los ataques XSS, agregue esto a su script PHP. Cuando toma la entrada del usuario y la inserta en una variable, como esto: $input = $_POST['input']; , en lugar de eso (que es 100% vulnerable) vaya: $input = htmlspecialchars($_POST['input']); . O también puedes ir: htmlentities($input = $_POST['input']); .

    
respondido por el A Web Dude 08.04.2016 - 20:19
fuente

Lea otras preguntas en las etiquetas