Introduzione alla scrittura trasversale (XSS) e alla difesa JavaScript

Lo scripting cross-site (XSS) è una delle vulnerabilità di sicurezza web più prevalenti, costantemente classificato nella OWASP Top 10. Un attacco XSS permette ad un attaccante di iniettare script lato client maligni nelle pagine web visualizzate da altri utenti.Questi script possono rubare i token di sessione, reindirizzare gli utenti a phishing siti, deface pages, o installare malware.

Comprendere i Tre Tipi di XSS

Prima di immergersi nella prevenzione, è essenziale capire le tre categorie principali di XSS: memorizzate, riflesse e basate su DOM, ognuna delle quali richiede un approccio di rilevazione e prevenzione leggermente diverso.

XSS memorizzato

Conservato (persistente) XSS si verifica quando l'ingresso maligno viene memorizzato permanentemente sul server (ad esempio, in un database, post del forum o commento) e successivamente servito agli utenti senza una corretta sanificazione.

Riferito XSS

Il dispositivo di attacco fa scattare una vittima nel fare clic su un link creato e il codice iniettato viene eseguito immediatamente.

XSS basato su DOM

Il payload di attacco modifica l'ambiente DOM nel browser della vittima. Il codice dannoso non tocca mai il server; proviene da JavaScript lato client che gestisce in modo non sicuro l'ingresso dell'utente (ad esempio, la lettura da , ], o ]]).

Rilevamento degli attacchi XSS con JavaScript

La rilevazione riguarda l'identificazione di attività sospette prima che si verifichi un danno. JavaScript può monitorare gli input degli utenti, monitorare le mutazioni DOM e convalidare i dati nei punti di entrata. Mentre il rilevamento lato client non può catturare tutti gli attacchi (soprattutto se l'attaccante effettua le richieste direttamente al server), fornisce una prima linea di difesa preziosa.

Validazione dell'ingresso e Sanitizzazione

Utilizzare ] invece di per prevenire l'esecuzione dello script. La seguente funzione rimuove i caratteri pericolosi da una stringa:

function sanitizeInput(input) {
 const div = document.createElement('div');
 div.textContent = input;
 return div.innerHTML;
}

Questo funziona perché l'impostazione ] non interpreta i tag HTML; tratta tutto come testo semplice. Il risultato [[] contiene versioni sfuggite di qualsiasi caratteri speciali HTML (ad esempio, , [, []]]]).

Monitoraggio delle Mutazioni DOM per gli Elementi Sospetti

Gli aggressori spesso iniettano tag o gestori di eventi ([[], []) nel DOM. Utilizzando l'API , è possibile guardare per inaspettate inserzioni di elementi.

const observer = new MutationObserver((mutations) => {
 mutations.forEach((mutation) => {
 mutation.addedNodes.forEach((node) => {
 if (node.nodeType === 1) { // element node
 if (node.tagName === 'SCRIPT') {
 console.warn('Potential XSS: a script element was injected via DOM.');
 node.remove(); // or log and analyze
 }
 // Check for dangerous attributes
 if (node.hasAttribute('onerror') || node.hasAttribute('onload')) {
 console.warn('Suspicious event handler attribute detected.');
 }
 }
 });
 });
});
observer.observe(document.body, { childList: true, subtree: true });

Cauzione:[] Gli script di blocco tramite [ possono essere bypassati da aggressori intelligenti e possono rompere le funzionalità legittime.

Convalida URL e parametri Hash

Per XSS basato su DOM, leggere i componenti URL in modo sicuro utilizzando [ ed evitare di inserire direttamente i valori in HTML.

const params = new URLSearchParams(window.location.search);
const userParam = params.get('name');
if (userParam && /[<>"'\/]/.test(userParam)) {
 console.warn('Potential XSS in parameter: ' + userParam);
 // Do not use this value in the DOM without encoding
}

Prevenire attacchi XSS con JavaScript

La prevenzione richiede un approccio multistrato. JavaScript da solo non può garantire completamente un'applicazione, ma quando combinato con una corretta sanificazione backend e [ Politica di sicurezza dei contenuti (CSP)[], riduce drasticamente il rischio.

codificare tutti i dati controllati dall'utente prima di inserire in DOM

La regola d'oro: non inserire mai dati non attendibili direttamente nel DOM. Utilizzare metodi DOM sicuri invece di interniHTML.

Usa o

const userInput = getUserInput();
const safeText = document.createTextNode(userInput);
document.getElementById('output').appendChild(safeText);

Quando devi usare , Saniti con una libreria

Se è assolutamente necessario rendere HTML (ad esempio, da un editor di testo ricco), si affida a una libreria di sanificazione di fiducia come [[ DOPMPurify[]. DOMPurify è una libreria ampiamente utilizzata, testata in battaglia che rimuove il codice dannoso preservando l'HTML sicuro.

// Example with DOMPurify (install via npm or CDN)
const dirty = '<img src=x onerror="alert(1)">';
const clean = DOMPurify.sanitize(dirty);
document.getElementById('content').innerHTML = clean;

DOMPurify funziona analizzando l'ingresso, stripping tag e attributi pericolosi, e restituire solo elementi consentiti. Visualizza DOMPurify su GitHub.

Evitare le funzioni JavaScript pericolose

Alcuni metodi e proprietà JavaScript sono noti per consentire XSS. Evitare o controllare rigorosamente:

  • ][]] – utilizzare [] o correttamente igienizzarsi.
  • , []] — stessa regola.
  • ][] – mai usare con l'ingresso dell'utente.
  • ][]]] – può essere sfruttata se qualsiasi input viene concatenato.
  • ] / [] con codice string[[[]] — evitare; utilizzare i riferimenti funzione invece.
  • []] costruttore[]] — analogo a .

Politica di sicurezza (CSP) tramite JavaScript? Non Raccomandato

CSP è un meccanismo del browser che limita i script in esecuzione. tipicamente è impostato tramite intestazioni HTTP, ma è anche possibile impostarlo utilizzando un [] tag o tramite JavaScript creando dinamicamente un elemento. Tuttavia, l'impostazione CSP in JavaScript è meno sicuro perché un attaccante che già ha un certo controllo potrebbe disabilitarlo.

const meta = document.createElement('meta');
meta.httpEquiv = 'Content-Security-Policy';
meta.content = "default-src 'self'; script-src 'self' 'unsafe-inline'"; // Be very careful with 'unsafe-inline'
document.head.appendChild(meta);

Per la produzione, configurare CSP nel server web o inverso proxy. [ La documentazione CSP MDN[ fornisce una guida completa.

Misure di sicurezza aggiuntive

Oltre a tattiche specifiche per JavaScript, una strategia completa di prevenzione XSS include queste misure critiche:

  • Sempre validare sul lato server.[ La convalida lato client può essere bypassata.
  • Usare le intestazioni di risposta HTTP appropriate. , , e soprattutto .
  • Esegui codifica ogni volta che rendi i dati dell'utente.[] Questioni di contesto: codificare per le entità HTML, codifica URL, codifica stringa JavaScript, ecc.
  • Le dipendenze sono aggiornate. Le librerie di JavaScript (ad esempio, le versioni precedenti di jQuery) sono un vettore XSS comune.
  • Utilizzare i framework con protezione XSS integrata. Reagire, Angular e Vue automaticamente evadere l'output per impostazione predefinita. Ancora, essere cauti con o .
  • Implementa un CSP rigoroso.] Evitare [ e se possibile.

Esempio di Real-World: Rendering di Commento sicuro

Considera un sistema di commento del blog in cui gli utenti inviano messaggi che vengono visualizzati ad altri. Un attaccante potrebbe provare a inserire [. Ecco un approccio JavaScript che si integra con il backend:

  1. Invio di seguito:[ Sanitize usando [] prima di inviare al server (ma il server deve ancora sanitizzare).
  2. Il server restituisce i dati:[ Il backend dovrebbe codificare il testo del commento in HTML.
  3. Realizzazione dei parametri:[]] Usa o un motore di template sicuro.
function renderComment(comment) {
 const item = document.createElement('div');
 item.className = 'comment';
 const body = document.createElement('p');
 body.textContent = comment.body; // escaped by browser
 item.appendChild(body);
 document.getElementById('comments').appendChild(item);
}

Testare le tue difese

Dopo aver implementato la prevenzione, testare l'applicazione utilizzando scanner automatizzati e carichi di pagamento manuali.

Utilizzare strumenti di sviluppo del browser per esaminare il DOM e garantire che i carichi di pagamento siano evasi. Inoltre, testare l'applicazione CSP controllando la console per i rapporti di violazione.

Conclusioni

Lo scripting cross-site rimane una minaccia seria, ma JavaScript offre strumenti potenti per il rilevamento e la prevenzione. Con la convalida degli input, il monitoraggio delle modifiche DOM, la fuga dell'output e l'integrazione con librerie robuste come DOMPurify, è possibile indurire significativamente la sicurezza del cliente. Ricorda che le misure lato client non sono un proiettile d'argento; completano una strategia di difesa-in-profondità che include la sanificazione del server-side, CSP headers, CSP e la sicurezza regolare.

Per ulteriori informazioni, consultare la pagina OWASP XSS[ e la OWASP XSS Prevention Cheat Sheet[.