Este dilema se puede tratar de diversas formas, pero en este caso te damos la que en nuestra opinión es la solución más completa.
Solución:
No hagas esto con expresiones regulares. Recuerde, no solo está protegiendo contra HTML válido; estás protegiendo contra el DOM que crean los navegadores web. Se puede engañar a los navegadores para que produzcan DOM válidos a partir de HTML no válido con bastante facilidad.
Por ejemplo, consulte esta lista de ataques XSS ofuscados. ¿Está preparado para adaptar una expresión regular para evitar este ataque del mundo real en Yahoo y Hotmail en IE6/7/8?
¿Qué tal este ataque que funciona en IE6?
¿Qué hay de los ataques que no están listados en este sitio? El problema con el enfoque de Jeff es que no es una lista blanca, como afirma. Como alguien en esa página señala hábilmente:
El problema con esto es que el html debe estar limpio. Hay casos en los que puede pasar html pirateado y no coincidirá, en cuyo caso devolverá el html pirateado string ya que no coincidirá con nada para reemplazar. Esto no es estrictamente una lista blanca.
Sugeriría una herramienta especialmente diseñada como AntiSamy. Funciona analizando el HTML y luego recorriendo el DOM y eliminando cualquier cosa que no esté en el configurable lista blanca. La principal diferencia es la capacidad de manejar correctamente HTML mal formado.
La mejor parte es que en realidad realiza pruebas unitarias para todos los ataques XSS en el sitio anterior. Además, qué podría ser más fácil que esta llamada a la API:
public String toSafeHtml(String html) throws ScanException, PolicyException
Policy policy = Policy.getInstance(POLICY_FILE);
AntiSamy antiSamy = new AntiSamy();
CleanResults cleanResults = antiSamy.scan(html, policy);
return cleanResults.getCleanHTML().trim();
Extraje del mejor complemento Anti-XSS de NoScript, aquí está su Regex: funciona sin problemas:
<[^w<>]*(?:[^<>"'s]*:)?[^w<>]*(?:W*sW*cW*rW*iW*pW*t|W*fW*oW*rW*m|W*sW*tW*yW*lW*e|W*sW*vW*g|W*mW*aW*rW*qW*uW*eW*e|(?:W*lW*iW*nW*k|W*oW*bW*jW*eW*cW*t|W*eW*mW*bW*eW*d|W*aW*pW*pW*lW*eW*t|W*pW*aW*rW*aW*m|W*i?W*fW*rW*aW*mW*e|W*bW*aW*sW*e|W*bW*oW*dW*y|W*mW*eW*tW*a|W*iW*mW*a?W*gW*e?|W*vW*iW*dW*eW*o|W*aW*uW*dW*iW*o|W*bW*iW*nW*dW*iW*nW*gW*s|W*sW*eW*t|W*iW*sW*iW*nW*dW*eW*x|W*aW*nW*iW*mW*aW*tW*e)[^>w])|(?: