En resumen, no hay una solución fácil. Tengo una sugerencia para una solución "fácil" en la parte inferior, pero tenga en cuenta que tiene muchas advertencias, que discutiré aquí. Sin embargo, primero, empecemos por el panorama general y avancemos hacia abajo.
En mi experiencia (después de haber trabajado con muchos sistemas heredados), "la seguridad no ha sido una prioridad durante mucho tiempo" significa que es probable que tenga varios problemas de seguridad ocultos en su sistema. XSS es solo un problema, estoy seguro. Así que, a menos que sepa que alguien ya está encima de estos, me preocuparía:
- contraseña de seguridad. Dudo que esté haciendo hash de acuerdo con los estándares de seguridad modernos, y este es un problema crítico que, por lo demás, se pasa por alto fácilmente.
- Seguridad de la tarjeta de crédito. Espero que usted sea compatible con PCI y no esté almacenando tarjetas de crédito en el sitio. He visto muchos sistemas heredados que almacenan tarjetas de crédito, aunque no se supone que debas hacerlo.
- SQLi es probablemente un problema real, y es especialmente peligroso si almacena las contraseñas de forma insegura o las tarjetas de crédito en su base de datos.
- Vulnerabilidades XSS!
Los números no tienen la intención de dar prioridad: todos son prioridades principales.
El punto de partida
Lo más importante es arreglar esto "institucionalmente". Esto va a ser lo más difícil de hacer, pero también es lo más crítico. Si pasa algunas semanas arreglando todas sus vulnerabilidades de XSS, pero la seguridad sigue siendo una prioridad de nivel inferior, el problema volverá a aparecer la próxima vez que un desarrollador envíe datos sin filtrar al navegador.
La mejor protección contra las vulnerabilidades de XSS es hacer que los desarrolladores sepan que deben tomarse en serio la seguridad y usar un motor de plantillas que maneje adecuadamente el escape de XSS por usted. La clave para recordar es que con XSS debe filtrar en la salida, no en la entrada. Es fácil ver esto como un problema de una sola manera: "Limpie los datos del usuario cuando entren en la entrada, y luego estará bien". Pero esto no protege contra todos los vectores de ataque, especialmente XSS agregado a través de SQLi. Sin embargo, en general, si la protección XSS es algo que sus desarrolladores deben hacer, recuerde que debe hacer todo el tiempo, terminará siendo olvidado. Es por eso que lo mejor que puede hacer es tener esa protección XSS incorporada en su sistema. Aquí es donde entra en juego un motor de plantillas. Cualquier sistema de plantillas competente aplica automáticamente el filtro XSS de forma predeterminada, y se debe informar específicamente si es necesario no filtrar por XSS.
Estoy seguro de que la refactorización de su sistema para incluir un motor de plantillas específicamente para ocuparse de las vulnerabilidades de XSS probablemente no va a suceder, pero también es importante entender que si no hace algo para solucionar el problema institucional Eso permitió que esto sucediera en primer lugar, el problema simplemente volverá y las semanas que demore en solucionarlo se perderán.
Primeros pasos prácticos
@Anders tiene algunos puntos de partida excelentes en su respuesta. Un CSP y el encabezado XSS funcionan de la misma manera: al indicar al navegador que habilite el lado del cliente de protección XSS. Tenga en cuenta (como mencionaron @Anders) que estos son dependientes del navegador y, especialmente para los navegadores más antiguos, es posible que no sean compatibles en absoluto. En particular, el soporte de IE para la CSP es muy mínimo, incluso hasta IE11 ( enlace )
El resultado es que, si bien estos pasos son buenos puntos de partida, definitivamente no puede confiar en ellos como su seguridad principal: todavía tiene que solucionar el problema. Obtener una buena herramienta de escaneo automatizada es definitivamente la mejor manera de comenzar. Le conseguirá algunos elementos de acción inmediata.
Una solución parcial
Otra opción que puede tener es colocar el filtro XSS en la pizarra en su aplicación. Normalmente no recomiendo esto, pero creo que la mejor opción para usted es una respuesta de varios niveles. La idea aquí es que agregue algo de código al proceso de arranque de sus aplicaciones que verifica todos los datos entrantes del cliente (datos de URL, datos de POST, cookies, encabezados de SOLICITUD, etc.). A continuación, realiza un filtrado para detectar las cargas de XSS comunes y, si lo encuentra, rechace la solicitud por completo.
El problema con el filtrado de listas negras es que puede ser muy poco confiable. Si lees la hoja informativa de evasión del filtro OWASP XSS obtendrás una buena idea de lo difícil que puede Ser confiable filtrar las vulnerabilidades XSS. Sin embargo, es una forma rápida de protegerse en cada solicitud, por lo que puede valer la pena en su caso. Sin embargo, un aspecto importante a tener en cuenta es que esto generalmente impedirá que los editores WYSIWYG funcionen. Eso puede o no ser un problema para usted.