Luego de ver los diferentes tipos de ataques utilizando XSS y
convencerlos (espero) de que es extremadamente peligroso cuando es
explotado por alguien que sabe, es hora de dar algunas recomendaciones
para evitar al máximo este tipo de ataques.
En un principio pensaba
dar recomendaciones de programador, pero también es interesante la parte
de como defendernos siendo usuarios finales de una página, dado que no
podemos confiar en la mayoría de los "programadores" que andan dando
vueltas, porque no conocen ni medio de seguridad (es una lástima, pero
es así). Arranquemos así con lo que podemos hacer desde nuestra posición
de usuarios web.
Trust no oneNunca
mejor aplicada esta frase de X-Files, cuando se trata de navegar por la
Web, no podemos confiar en nadie, ni siquiera en nuestros amigos. Por
esto, lo mejor es estar prevenidos y tener en cuenta algunos consejos
para no ser víctimas del XSS. Estos consejos se aplican a ataques en
general, aunque en me esté focalizando en XSS.
El primer paso a
dar es utilizar un browser decente. La mayoría de la gente sigue
utilizando damn vulnerable Internet Explorer, incluso versiones
extremadamente vulnerables como la 6 que no proveen mucha ayuda al pobre
navegante. Es verdad que Microsoft ha mejorado mucho con su browser en
los últimos años, no leo sobre muchos exploits para la versión 8, pero
las versiones 6 y 7 siguen siendo grandes víctimas y tienen gran
presencia en la web. Por supuesto que no sólo IE es un gran problema,
todos los browsers cuentan con su lista negra de errores, las versiones 1
y 2 de Firefox no ayudan mucho en cuanto a prevenir XSS. Por supuesto
que Opera, Safari y Chrome también arrastran sus problemas.
Mi
elección es utilizar Firefox 3+ con algunos complementos que nos ayuden a
distinguir XSS. Chrome tiene un gran futuro, pero creo que todavía está
bastante verde.
Los agregados pueden darnos una buena mano para
prevenir ataques. NoScript para Firefox es un excelente ejemplo. Este
agregado bloquea contenido JavaScript, Flash, Java y otros,
permitiéndonos elegir qué páginas tienen permitido ejecutar qué. Además
reconoce diferentes ataques y los bloquea, reportándolos al usuario.
Internet Explorer 8 cuenta con filtros XSS
que intentan acercarse a la funcionalidad de NoScript, aunque por ahora
parecen estar basados solamente en listas negras con ataques conocidos.
Otro
add-on interesante es Netcraft Anti-Phishing Toolbar disponible para
Firefox e Internet Explorer que nos permite identificar sites que
intentan robarnos información. Actualmente tanto Firefox como IE
incorporaron una funcionalidad muy similar, así que tal vez no es tan
útil como hace un tiempo.
El siguiente paso sería desactivar toda
feature que no utilicemos. Existen múltiples formas de ejecutar ataques
a través de tecnologías que muchas veces no utilizamos. Entre las más
conocidas podemos encontrar JavaScript, ActiveX, Flash, Java, etc. La
regla del pulgar nos dice, si no lo usamos, desactivemoslo. Es verdad
que muchas páginas pueden no funcionar, pero al menos deberíamos poder
bloquear selectivamente por página. NoScript nos da una gran mano para
realizar esta tarea.
No clickear a lo tonto en todo lo que nos
mandan. El comportamiento por defecto debería ser, desconfiar de todo
link recibido por mail, foro, blog, red social, etc. Si la URL es muy
larga, ya es algo muy sospechoso, y si incluye las palabras script o
hacen referencia a algún script, es algo mucho más sospechoso. También
son sospechosas las direcciones codificadas usando url, decimal o hexa
encoding.
Tampoco deberíamos seguir links codificados con tinyurl o
algún otro servicio de acortamiento de urls. Estos links podrían
llevarnos a cualquier lado sin que nos enteremos. Existen algunos sites
que nos permiten decodificar estas URLs pequeñas y ver de qué tratan
realmente. Algunos ejemplos son
http://longurl.org/ o
http://kiserai.net/turl.plProgramación Web SeguraLuego
de tirar algunos consejos sobre cómo actuar al navegar por la red, nos
metemos con la programación Web segura o "lo que diferencia un buen
programador de uno mediocre". Si bien en un principio parece fácil
solucionar este problema, existen más vueltas de las que uno se imagina.
Por suerte, como cité en el primer artículo, existen algunas páginas
con ejemplos para probar e imaginarnos cómo un atacante puede
"encontrarle la vuelta" y vulnerar nuestro site.
El principio
básico para evitar el XSS es el bien conocido "validar la entrada y
filtrar la salida". Este principio que se aplica a todos los problemas
de programación se usa poco y sin embargo nos salva de mucho. En el caso
del XSS puede elegirse "validar la entrada" o bien "filtrar la salida",
cada uno con sus ventajas y desventajas. Validar la entrada implica
revisar todo lo ingresado por el usuario, mientras que filtrar la salida
implica revisar sólo lo que se expone en la página, osea, si no todo se
expone en la página, solo se debe filtrar una parte de todo lo
ingresado. El problema con filtrar la salida es que quedan almacenados
datos mal formados en bases de datos o archivos, algo que puede
afectarnos si va cambiando la política de filtrado en la programación,
pero los datos quedan intactos en los servers.
El consenso general es
validar la entrada y evitarnos problemas futuros, además, filtrar la
salida implica analizar los datos cada vez que se van a mostrar,
mientras que validarlos a la entrada hace que el trabajo se realice una
sola vez.
La mayor ventaja del filtrado de salida es que en esta
etapa se sabe dónde se van a incluir los datos, es decir, no es lo mismo
incluir los datos en el HTML que en una porción de código JavaScript,
el tipo de filtrado puede cambiar en ambos casos. Por otro lado, qué
sucede si el sistema que valida la entrada tiene un agujero en la
validación y permite que algunos ataques pasen? una vez que los datos se
almacenaron, quedan ahí... por más que parchemos el validador, los
datos que ya pasaron seguirán estando y el ataque persistirá. Si por el
contrario, usamos filtado de la salida y se descubre un bug en los
filtros, una vez que lo parchamos, estamos salvados.
Leyendo todo
esto, uno puede creer que lo mejor es implementar ambos controles, a la
entrada y a la salida. Bueno, eso es cierto, sería ideal que el
encargado de mostrar los datos no confíe para nada en los datos que
tiene, y que el validador de la entrada haga su mejor esfuerzo pora que
no pasen porquerías al almacenamiento. El problema, como siempre, es el
agregado de procesamiento, algo que en un sistema con mucho tráfico
nunca es deseado.
Una vez que tenemos decidido si validar la entrada o filtrar la salida, o ambos, debemos poner manos a la obra.
Escapando caracteres clavesLo
primero que viene a la mente cuando hablamos de inyección XSS es evitar
los benditos delimitadores de tag "<" y ">", además de comillas
simples y comillas dobles, que permiten ciertos trucos. Hay dos opciones
para hacer esto, eliminamos estos caracteres o los codificamos de forma
que el browser los interprete como texto. Existen varias formas de
codificar estos caracteres para que el browser los interprete como texto
y no como parte del HTML. Veamos cómo codificar los 5 caracteres más
relevantes (llamados "big 5" en algunos lugares) y la barra hacia
delante (usada para cerrar tags):
| Caracter | Codificacion HTML | Codificación Hexa | Codificación Decimal |
| & | & | & | & |
| " | " | " | " |
| ' | ' | ' | ' |
| < | < | < | < |
| > | > | > | > |
| / | | / | / |
Esto
quiere decir que si el usuario ingresa un >, nosotros deberíamos
colocar un > (o & o &) en su lugar, para que no
se interprete como código HTML. Por lo que he leído, algunas
codificaciones en hexa o decimal pueden verse distintas en algunos
browsers según la codificación de caracteres utilizada (UTF-8, ISO
8859-1, etc), así que recomendaría utilizar la codificación HTML.
Piensen ahora en alguno de los ejemplos anteriores, si antes el resultado de una inyección era:
Usuario: <B><SCRIPT>alert('XSS');</SCRIPT></B>
escapando los tags obtendremos:
Usuario: <B><SCRIPT>alert('XSS');</SCRIPT></B>
Como se ve, el código actual no ejecutaría ningún alert, sino que mostraría el código en la pantalla (como debería ser).
En
muchos lenguajes existen funciones implementadas para realizar el
trabajo de cambiar un caracter por su equivalente HTML, o bien para
eliminar estos caracteres. A continuación les dejo algunos ejemplos:
PHP
-
htmlentities nos ayuda a codificar los caracteres citados (utilizar la
opción ENT_QUOTES para codificar comillas simples también).
- strip_tags nos permite eliminar tags de un dado string.
ASP.NET
- HttpUtility.HtmlEncode nos da una mano codificando HTML.
- No encontré una función para eliminar tags, pero si una solución interesante en el foro http://forums.asp.net/t/901364.aspx:
System.Web.UI.HtmlControls.HtmlGenericControl htmlDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
htmlDiv.InnerHtml = htmlString;
String plainText = htmlDiv.InnerText;
- ASP también cuenta con un parámetro seteable en el Web.config (o
incluso en Machine.config) que valida la entrada y nos arroja una
excepción cada vez que un parámetro contiene entidades HTML. Este
parámetro se llama validateRequest. Si está en false, no se valida nada,
pero si está en true ASP hace su magia. Eso sí, después capturen la
excepción, porque vi varios ejemplos donde la página arroja un error
horrible que el usuario no debería ver...
Pueden leer un poco más sobre validateRequest en http://www.asp.net/(S(ywiyuluxr3qb2dfva1z5lgeg))/learn/whitepapers/request-validation/
JSP
Al
parecer a la gente de Sun no le resultó interesante incorporar una
función para codificar caracteres especiales (ni para eliminar tags),
así que Java no incluye entre sus librerías default una función que haga
el trabajo. Por suerte en una entrada de la página de OWASP encontramos una función que haga el trabajo.
Como
se pueden imaginar, si no contamos con funciones empaquetadas con el
lenguaje (como el caso de java) siempre podemos construir nuestra
función para codificar o eliminar tags. Eso si, hay que tener cuidado en
la forma en que armamos expresiones regulares para eliminar tags, dado
que algunas pueden no ser muy efectivas.
Escapando lo anterior estamos salvados?Muchos
autores han dicho (y muchos siguen diciendo) que si escapamos los "big
5" estamos a salvo del XSS... bueno, me apena decirles "WRONG!".
Dependiendo
la situación en la que nos encontremos, no es estrictamente necesario
utilizar los caracteres antes citados. En muchos casos nos basta con
utilizar un event handler (manejador de eventos) como onClick, onError,
onMouseOver, etc (existen casi 100 manejadores de eventos). Consideren
un ejemplo donde el usuario decidió no cumplir con el estándar HTML y
armó el siguiente código en php:
<INPUT TYPE=TEXT
SIZE=30 NAME=search VALUE=<?php if(isset($_GET['user'])) print
"<B>".$_GET['search']."</B>" ?> />
este
es el clásico ejemplo del buscador (ja, ya parece nombre de ejemplo de
libro de sistemas operativos). Como ven, el usuario no usó ninguna
comilla, pero aún así, el código es válido para la mayoría de los
browsers. Ahora, el usuario malo, podría ingresar lo siguiente en el
campo de búsqueda: "nada
onMouseOver=alert(String.fromCharCode(88,83,83))" (sin las comillas). El
resultado HTML de la ejecución del código php será:
<INPUT TYPE=TEXT SIZE=30 NAME=search VALUE=nada onMouseOver=alert(String.fromCharCode(88,83,83)) />
ahora, cuando el usuario coloque el mouse sobre el campo de búsqueda, saltará el alert.
Observaron
algo en el ejemplo? para el exploit no utilicé ninguno de los "big
5"!!! Tal vez se preguntan qué es la función String.fromCharCode. Esta
función se encarga de obtener un caracter a partir del código ascii en
decimal, el 88 representa la X y el 83 la S. De esta forma, no
necesitamos incluir la comilla simple para el alert. Otra forma que
también funciona es colocar "nada
onMouseOver=alert("XSS")" donde usamos las comillas
HTML codificadas.
Otro ejemplo es el de programadores totalmente
kamikazes que se encargan de meter datos ingresados por un usuario en
una función JavaScript! Si bien este código no debe estar necesariamente
HTML escapeado, debería estar JavaScript escapado para no ejecutar
código ingresado por el usuario. Un ejemplo rápido que se me ocurre, es
el caso que queremos cambiar el color de una opción seleccionada por el
usuario (tal vez un menú con varias opciones), por ejemplo:
<input type="button" id="home" value="home" onClick="window.location.href='test.php?opcion=home'" />
<input type="button" id="guest" value="guest" onClick="window.location.href='test.php?opcion=guest'" />
<?php echo $_GET['opcion']; ?>
<script>
var opcion = '<?php echo $_GET['opcion']; ?>';
if (opcion == "home")
{
document.getElementById('home').style.backgroundColor = "green";
document.getElementById('guest').style.backgroundColor = "red";
}
else if( opcion == "guest")
{
document.getElementById('home').style.backgroundColor = "red";
document.getElementById('guest').style.backgroundColor = "green";
}
</script>
El código anterior simplemente cambia el color de fondo del botón apretado, basándose en la opción seleccionada, la cual obtenemos de la URL. Ahora, que pasa si en la variable opción colocamos lo siguiente: "la'; alert('XSS'); //" el resultado en la variable anterior será:
var opcion = 'la'; alert('XSS'); //';
es decir, cerramos la asignación a la variable opción, luego ejecutamos un alert y comentamos el resto. Esto sin usar los delimitadores de tags, ni comillas dobles, ni ampersand, aunque sí comillas simples, pero si tenemos en cuenta que htmlentities por defecto no codifica comillas simples, podríamos correr riesgos aún usando esa función.
Vale aclarar que si tenemos habilitado el atributo magic_quotes de php, éste agregará back slash ("\") a las comillas y puede que el ejemplo no funcione. Igualmente existen formas para escapar los escapadores.
Y si quiero texto enriquecido?Aca es donde empiezan los problemas mayores...
En muchos casos deseamos que el usuario pueda ingresar texto con formato, así que tal vez nos gustaría que puedan usar los tags <b> (negrita), <i> (cursiva), <a href> (links), <img> (imágenes), etc. Para este tipo de aplicaciones, no podemos utilizar una función que nos elimine todos los tags, sino que debemos hacer una eliminación/codificación selectiva...
Las cosas se pueden poner realmente feas dependiendo de lo que deseamos permitir. Recuerden que prácticamente ningún tag está a salvo de scripting, por ejemplo, en IE el código <B STYLE="xss:expression(alert('XSS'))"></B> les mostrará un alert...
Para arrancar, la política default debe ser: escapar/borrar todo tag a menos que esté explícitamente permitido (whitelist). Ahora, de los tags permitidos, debe hacerse un examen en busca de código potencialmente malicioso, o bien tener un formato predefinido de tag. Por ejemplo, si lo único que queremos permitir es el tag <B>, no deberíamos permitir cosas como <B STYLE="xss:expression(alert('XSS'))">. Hay que tener especial cuidado con el tag <IMG>, como pueden observar en la
lista de RSnake, las cosas que se pueden hacer son muchas. Incluso armando expresiones regulares para buscar cosas como la palabra javascript en el código puede ser difícil. Por ejemplo, tal vez deseamos evitar que alguien ingrese lo siguiente:
<IMG SRC="javascript:alert('XSS');">
pero también deberemos escapar cosas como:
<IMG SRC="jav ascript:alert('XSS');">
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>
o cosas más oscuras como:
<IMG SRC=javascript:alert('XSS')>
<IMG SRC=javascript:alert('XSS')>
Los ejemplos anteriores funcionan solamente en IE 6 y Opera 9, pero hay que tener en cuenta la cantidad de usuarios (me animaría a decir millones?) que todavía utilizan IE 6...
Una buena recomendación es armar el texto resultante a partir de un formato fijo según lo ingresado por el usuario, y no dejar directamente lo que el usuario ingresó. Por ejemplo, si el formato de salida será <IMG SRC="http://algo">, no importa que el usuario ingrese <IMG SRC="http://algo" width="0" height="0" style="width:100px; height: 100px;" alt="">, el resultado será siempre <IMG SRC="http://algo">. También debería verificarse que el argumento SRC sea válido, esto es, que sea una referencia a una imagen y no un script.
Como se irán dando una idea, habilitar algunos tags trae varios dolores de cabeza. Por suerte existen algunas librerías creadas para tal fin. Una interesante es
PHP Input Filter que ha sido premiada por su labor. Otros esfuerzos interesantes son el proyecto
OWASP ESAPI que soporta los lenguajes Java, .NET, PHP, Classic ASP, Cold Fusion, Python, and Haskell, y
AntiXSS para ASP.NET.
6 reglas de oro by OWASPLa OWASP nos provee 6 reglas (http://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet) para evitar ataques del tipo XSS. El artículo trata el problema de forma general y no ofrese una solución concreta para un lenguaje en particular, de eso deberá encargarse el programador. Estas reglas están muy bien pensadas y cubren todo lo que he tratado hasta aquí, si es que se implementan correctamente... claro.
A continuación les traduzco los principios básicos de cada regla, para la información completa diríganse a la fuente original:
Regla #0 - Nunca insertar datos no confiables excepto en lugares permitidosLa regla cero nos dice, negar todo!, es decir, no colocar ningún dato ingresado por el usuario en el HTML a menos que esté incluído en alguna de las reglas #1 a #5. Esta regla sirve como complemento a todas las demás, es decir, si no está incluido en las otras reglas, entonces no lo incluyas en tu HTML!
<script>...NUNCA PONER DATOS NO CONFIABLES AQUI...</script> directamente en un script
<!--...NUNCA PONER DATOS NO CONFIABLES AQUI...--> dentro de un comentario HTML
<div ...NUNCA PONER DATOS NO CONFIABLES AQUI...=test /> en el nombre de un atributo
<...NUNCA PONER DATOS NO CONFIABLES AQUI... href="/test" /> en el tag de un nombre
Regla #1 - Escapear HTML antes de insertar datos no confiables en el contenido de un elemento HTMLEsta regla sirve para cuando queremos poner datos no confiables directamente en algún lugar del cuerpo HTML. Esto incluye dentro de todos los tags conocidos como div, p, b, td, etc.
<body>...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...</body>
<div>...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...</div>
aplicar para cualquier otro elemento HTML.
Para escapar los datos no confiables, aplicar lo que expliqué en la sección "Escapando caracteres claves".
Regla #2 - Escapear atributos antes de insertar datos no confiables en atributos HTML comunesEsta regla se utiliza para colocar datos no confiables dentro de atributos como width, name, value, etc. Esto no debería usarse para atributos complejos como href, src, style, o cualquiera de los even handlers como onMouseOver. Es extremadamente importante que para los even handlers se siga la regla #3.
<div attr=...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...>contenido</div> dentro de atributos sin comillas
<div attr='...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...'>contenido</div> dentro de atributos con comillas
<div attr="...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...">contenido</div> dentro de atributos con comillas dobles
Excepto los caracteres alfanuméricos, escapar todo caracter con valores ASCII menores a 256, con el formato #xHH (es decir, valor hexa) para evitar el problema de salirse de los atributos (como el ejemplo citado en "Escapando lo anterior estamos salvados?").
Regla #3 - Escapear JavaScript antes de insertar datos no confiables en datos JavaScriptComo tercer regla tenemos la concerniente a los event handlers de JavaScript que pueden ser especificados en varios elementos HTML. El único lugar seguro para poner datos no confiables es dentro de comillas.
<script>alert('..ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...')</script> dentro de un string entre comillas
<script>x='...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...'</script> a un lado de una expresión entre comillas
<div onmouseover='...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...'</div> dentro de un event handler entre comillas
Excepto los caracteres alfanuméricos, escapar todo caracter con valores ASCII menores a 256, con el formato #xHH (es decir, valor hexa) para evitar el problema de cambiar del contexto de datos al contexto script o en otro atributo. No utilizar escapeadores como la barra invertida porque los caracteres como las comillas serán reemplazados por su codificación HTML correspondiente.
Regla #4 - Escapear CSS antes de insertar datos no confiables en propiedades HTML de estiloEsta regla existe para los casos en que se desee colocar datos no confiables en una hoja de estilo o en un tag de estilo. Debido al poder de CSS para realizar ataques, es importante que sólo se coloquen datos no confiables dentro del valor de una propiedad y no en otros lugares de los datos de estilo. Sobre todo debe tenerse mucho cuidado de no colocar datos no confiables en propiedades como url, behaviour, y custom. Lo mismo se aplica a las expresiones de propiedad de IE, las cuales permiten JavaScript.
<style>selector { property : ...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...; } </style> valor de propiedad
<span style=property : ...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...;>text</style> valor de propiedad
Excepto los caracteres alfanuméricos, escapar todo caracter con valores ASCII menores a 256, con el formato #xHH. No utilizar escapeadores como la barra invertida porque los caracteres como las comillas serán reemplazados por su codificación HTML correspondiente.
Regla #5 - Escapear URL antes de insertar datos no confiables en atributos URLLa última regla de esta lista se utiliza para los casos en que deseamos colocar datos no confiables en un link que apunta a otro lugar. Esto incluye a los atributos href y src. Existen otros atributos de locación, pero no es recomendable colocar datos no confiables en ellos. Algo importante de remarcar es que resulta muy mala idea colocar datos no confiables en URLs javascript:, pero de ser necesario se puede utilizar la regla #3 para ello.
<a href=http://...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...>link</a > un link normal
<img src='http://...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI...' /> fuente de una imagen
<script src="http://...ESCAPEAR DATOS NO CONFIABLES ANTES DE COLOCARLOS AQUI..." /> archivo script
Excepto los caracteres alfanuméricos, escapar todo caracter con valores ASCII menores a 256, con el formato #xHH. Incluir datos no confiables en URLs data: no debería estar permitido, debido a que no hay una buena forma de deshabilitar ataques con escapeado para prevenir el salirse de la URL.
Fumata finalComo pudieron ver a lo largo del artículo, la prevención de XSS no es la pavada que puede parecer al principio. Agregar editores de texto enriquecido (osea, aceptar código HTML ingresado por el usuario) complica considerablemente las cosas. Hay que tener mucho cuidado de codificar todo lo ingresado por el usuario, y evitar, siempre que se pueda, colocar datos no confiables en lugares peligrosos como dentro de un script.
Nunca se debe confiar en el browser del cliente. Distintos motores renderizan las cosas a su gusto y muchas veces de forma peligrosa. Por ejemplo, los browsers aceptan tags mal formados como <script (sin el > que cierra). Como pueden leer en las referencias, IE puede hacer cosas locas al intentar decifrar la codificación de caracteres o el contenido de un documento... Firefox también tiene problemas como el uso de la directiva moz-binding para incluir XML.
En fin, la vida del programador no es para nada fácil, pero es importante que al menos tengan noción de los peligros que enfrentan, y tratar de aplicar las 6 reglas que propone OWASP para minimizar riesgos.
Recomiendo altamente la lectura del documento ArticlesXSS de la sección Web Security de los HOWTO de google. También es una exelente lectura el libro XSS Attacks, pero este es pago y tal ves no puedan obtenerlo. Por supuesto que es indispensable leer los artículos de la OWASP para programar de forma segura.
La realización de este artículo me llevó mucho más tiempo que la de los dos anteriores, encontré mucho material y traté de incluir todo lo más relevante. Espero que les sea de utilidad, tanto para programadores como para entusiastas o simples aprendices =)
Si bien con esto cerraría la parte más grosa de XSS, espero poder escribir antes de terminar diciembre algunos complementos más, como el de ataques relacionados, o el de herramientas para detección de XSS. Como siempre, si tienen material para agregar, dejen referencias en los comentarios y tal vez lo incluya en un artículo versión "Lost Chapters" =)
Referencias- XSS Attacks - Cross Site Scripting Exploits and Defence (Jeremiah Grossman, Robert "RSnake" Hansen, Petko "pdp" D. Petkov, Anto Rager, Seth Fogie)
-
XSS (Cross Site Scripting) Prevention Cheat Sheet - OWASP-
ArticlesXSS - Web Security - Google-
How To: Prevent Cross-Site Scripting in ASP.NET-
XSS (Cross Site Scripting) Cheat Sheet (RSnake)-
Browser Security Handbook-
Data Validation - OWASP
Fuente: http://itfreekzone.blogspot.com/2009/12/combatiendo-el-cross-site-scripting.html