In breve, non esiste una soluzione facile. Ho un suggerimento per una soluzione "facile" in fondo, ma tieni presente che contiene molti avvertimenti, che discuterò qui. Per prima cosa, iniziamo dal grande quadro e procediamo verso il basso.
Nella mia esperienza (avendo lavorato con molti sistemi legacy) "la sicurezza non è stata una priorità per un lungo periodo" significa che probabilmente nel tuo sistema ci sono molti problemi di sicurezza nascosti. XSS è solo un problema, ne sono sicuro. Quindi, a meno che tu non sappia che qualcuno è già in cima a questi, mi preoccuperei di:
- Sicurezza della password. Dubito che tu stia tagliando secondo i moderni standard di sicurezza, e questo è un problema critico che altrimenti viene facilmente trascurato.
- Sicurezza della carta di credito. Spero che tu sia conforme PCI e non stia conservando le carte di credito sul posto. Ho visto molti sistemi legacy che memorizzano le carte di credito anche se non dovresti.
- SQLi è probabilmente un problema reale ed è particolarmente pericoloso se memorizzi le password in modo non sicuro o le carte di credito nel tuo database.
- Vulnerabilità XSS!
I numeri non intendono implicare priorità: sono tutte priorità principali.
Il punto di partenza
La cosa più importante è risolvere questo "istituzionalmente". Questo sarà il più difficile da fare, ma è anche il più critico. Se passi qualche settimana a sistemare tutte le tue vulnerabilità XSS, ma la sicurezza continua a essere una priorità di livello inferiore, il problema tornerà la prossima volta che uno sviluppatore invierà dati non filtrati al browser.
Le migliori protezioni contro le vulnerabilità XSS sono gli sviluppatori che sanno prendere sul serio la sicurezza e utilizzare un motore di template che gestisca in modo appropriato l'escape di XSS. La chiave da ricordare è che con XSS devi filtrare in output, non in input. È facile vederlo come un problema a senso unico "Pulisci i dati utente quando entrano nell'input, e poi stai bene". Ma questo non protegge da tutti i vettori di attacco, in particolare XSS aggiunto tramite SQLi. In generale, però, se la protezione XSS è qualcosa che i tuoi sviluppatori devono fare per ricordarti di fare ogni volta, finirà per essere dimenticata. Ecco perché la soluzione migliore è quella di avere quella protezione XSS integrata nel tuo sistema. È qui che entra in gioco un motore di template. Qualsiasi sistema di template competente applica automaticamente il filtro XSS per impostazione predefinita e, in particolare, deve essere informato se è necessario il filtro not per XSS.
Sono certo che il refactoring del sistema per includere un motore di template specifico per occuparsi delle vulnerabilità XSS probabilmente non accadrà, ma è anche importante capire che se non si fa qualcosa per risolvere il problema istituzionale questo ha permesso che ciò accadesse, in primo luogo, il problema sta per tornare, e le settimane che ti occorreranno per risolvere questo problema saranno sprecate.
Primi passi pratici
@Anders ha alcuni ottimi punti di partenza nella sua risposta. Un CSP e l'intestazione XSS funzionano entrambi allo stesso modo: dicendo al browser di abilitare il lato client di protezione XSS. Tieni presente che, come menzionato da @Anders, questi sono dipendenti dal browser e, soprattutto per i browser meno recenti, potrebbero non essere supportati affatto. In particolare, il supporto di IE per CSP è minimo, anche fino a IE11 ( link )
Il risultato è che mentre questi passaggi sono buoni punti di partenza, non puoi sicuramente fare affidamento su di essi come la tua sicurezza principale: devi ancora risolvere il problema sulla tua estremità. Ottenere un buon strumento di scansione automatico è sicuramente il modo migliore per iniziare. Ti darà alcuni elementi di azione immediati.
Una soluzione parziale
Un'altra opzione che potresti avere consiste nel mettere il filtro XSS su tutta la linea della tua applicazione. Normalmente non lo consiglio, ma penso che la soluzione migliore per voi sia una risposta a più livelli. L'idea è di aggiungere del codice al processo di bootstrap delle applicazioni che controlla tutti i dati in arrivo dal client (dati url, dati POST, cookie, intestazioni REQUEST, ecc ...). Quindi esegui alcuni filtri per rilevare i payload XSS comuni e, se trovato, rifiuta la richiesta tutti insieme.
Il problema con il filtro della lista nera è che può essere molto inaffidabile. Se hai letto il foglio di evasioni del filtro OWASP XSS ti farai un'idea di quanto sia difficile essere affidabile filtrare le vulnerabilità XSS. Tuttavia, è un modo rapido per ottenere protezione su ogni richiesta, quindi potrebbe essere utile nel tuo caso. Un aspetto importante da tenere presente è che in genere questo impedirà agli editor WYSIWYG di funzionare. Questo potrebbe o non potrebbe essere un problema per te.