Pues ese tema de los filtros es muy muy extenso, pero si te puedo dar algunos tips.
¿Cómo google chrome, Internet explorer e IIS saben que deben detener un XSS y no un falso positivo?, utilizan dos técnicas:
* El filtrado
* Comparación I/O
Esto quiere decir que existen dos capas antes de llegar al bloqueo, el filtrado es cuando detectan que tu solicitud http ya sea en el request o en el body de la petición viene una mezcla de carácteres inseguros (payload), como por ejemplo etiquetas html, para esto la mayoría usan expresiones regulares, chrome es un poco mas complejo ya que usa otro tipo de filtrado donde evalua caso a caso los caracteres. Ahora, que detecte un contenido HTML no quiere decir que necesariamente sea un ataque por lo cual viene una segunda capa que es la comprobación I/O, o sea input de entrada v/s output de salida, si el contenido que retorna el sitio WEB contiene parte del contenido malicioso detectado por el primer filtro (o sea, si pongo un <script> en la url y aparece en el código devuelto por el sitio web) entonces ahi recién detiene la carga del sitio y alerta de un posible ataque de tipo XSS.
Ahora, con respecto a esto, donde la mayoría de las personas erran es intentar bypasear la primera capa la cual está lleno de reglas fuertes, bypaseables pero fuertes en ves de buscar bypasear la segunda capa y ahi es donde viene lo entretenido.
Por ejemplo, supongamos un escenario de un sistema que me tocó ver el mes pasado: Existe una compañía donde por norma de Active Directory todos los usuarios de la organización que usan windows solo pueden utilizar Google Chrome para mitigar los ataques de tipo XSS utilizando el filtro nativo pero tienen un portal WEB con un XSS y nos tocó comprobar que esa capa de protección de Google Chrome no era suficiente. El problema consistía en que el sitio WEB vulnerable tenía un XSS en una sección donde se podian guardar comentarios de páginas, el proceso era el siguiente:
Estabas en el sitio web y querias postear un comentario -> Este comentario era enviado por Ajax/javascript al servidor a traves de una petición post, el servidor solo devolvía un mensaje "OK", -> luego javascript al saber que el servidor retornó ese OK refrescaba el contenido de los comentarios apareciendo el comentario insertado. Bueno, esto era vulnerable a un XSS persistente.
[ Usuario envía comentario ]
↓
[ javascript: HTTP/POST ]
↓
[ Detección Google Chrome: Input: positivo ] <-
↓
[ Solicitud HTTP ]
↓
[ Respuesta WEB: "OK" text/plaintext ]
↓
[ Detección Google Chrome: Output: negativo ] <- !!
¿Donde estaba el problema? que Google Chrome perdió la segunda capa de validación debido a que el sistema WEB no retorna el contenido enviado, por lo cual para el navegador no hay ataque y tampoco tiene como saber que el contenido HTML que aparecerá después en un comentario fue el ingresado en la solicitud HTTP/POST.
Explotación: se ćreó un formulario html oculto dentro de una página de pruebas y al momento de ingresar este se enviaba al sitio web con el contenido HTML a insertar en el comentario (XSS), el sitio web original al solo responder un "OK" imposibilitó a Google Chrome entender si se trataba de un ataque o no por lo cual no lo detuvo, luego de esto el mismo sitio web de pruebas redireccionó al usuario hacia la página de comentarios para que le apareciese el XSS y listo!
Como ves, el filtro anti XSS no sirvió de nada porque para detener ataques de debe cumplir todo un flujo y puedes interrumpirlo en diferentes partes no solo bypaseando reglas.
Por otro lado si colocas un caracter que el contenido HTML no imprime entonces tampoco lo detecta, por ejemplo: <script>/*%01*/alert(0);</script> ya que el filtro esperará a que aparezca toda la cadena no solo una parte de ella y en la mayoría de los servidores webs estos caracteres no se interpretan como por ejemplo .net sobre IIS., también es posible crear un bypass utilizando filtros de eliminación de caracteres nativo como un censurador de palabras, por ejemplo si te censuran "f
uck" entonces escribes: <scrif
uckpt>alert(0)</script>, entonces el filtro esperará a que la etiqueta completa aparezca en el contenido HTML para detectar si realmente fue un ataque pero como el sistema WEB eliminó la palabra censurada dejó al descubierto la etiqueta script.
Y de esta manera hay muchas maneras de bypasear filtros, otra manera es creando etiquetas personalizadas no estandarizadas pero si interpretables abusando de la tecnología que vienen en todos los navegadores WEBs sobre la "tolerancia a errores", por ejemplo: <x style="position:absolute;left:0;width:100%;height:100%;background-image:url(http://...phishing.jpg)"> ya que la etiqueta x no existe, por lo general tanto google chrome como internet explorer y mas del 90% de los waf solo buscan etiquetas conocidas ya que se apegan mucho al estandard de la w3c, pero no funcionan como un navegador web el cual interpreta contenido, los navegadores no funcionan de manera tan estricta como un waf y ahi es donde es posible aprovecharse para realizar un bypass.
En fin, podría estar todo el día sobre como bypasear filtros anti xss, aunque tampoco quiero decir que sean un desperdicio, respeto mucho a la gente que hace estos tipos de filtros porque se requiere mucho conocimiento y dedicación, a demás si frena ataques básicos, pero nunca será algo efectivo como para depositar la confianza en ellos.
Artículos sobre esto? pues no conozco muchos, he visto uno o dos en pdf escritos en ingles y la verdad es que entiendo poco porque no me gusta el inglés. Pero deben haber muchos dando vuelta por internet, basta buscar sobre "xss filter bypass", hay algunos de defcon y otros de whitehat.
No conozco tu interés en conocer del tema pero si buscas como atacar averigua más, pero si buscas como solucionar entonces no pierdas tu tiempo y enfócate en como aumentar la productividad y seguridad en los aplicativos con buenas prácticas.
Saludos.