Ogni script di terze parti presente nelle pagine di checkout, login o amministrazione viene eseguito con gli stessi privilegi dell'utente che l'ha caricato. Se l'host che serve quello script viene compromesso, anche l'attaccante ottiene quei privilegi, in modo analogo a quanto accade con una XSS. La soluzione parte dal sapere quali script vengono caricati, per poi rimuovere ciò che è possibile e fissare (pin) o limitare il resto.
Sapere cosa viene eseguito sulle pagine sensibili
La cheat sheet OWASP sul JavaScript di terze parti indica tre rischi: la perdita di controllo sulle modifiche all'applicazione client, l'esecuzione di codice arbitrario sui sistemi dei client e la fuga di informazioni sensibili verso terzi. Tra gli esempi citati figurano l'incidente Ticketmaster del 2018 e l'indagine di ClearSky su Magecart e il furto di dati di pagamento.
Costruisca l'inventario pagina per pagina, partendo da checkout, login e amministrazione. Per ogni script annoti l'URL, il responsabile di business, il motivo per cui è presente e il modo in cui arriva. OWASP descrive tre vie di consegna: codice del fornitore incollato nella pagina, un <script src> che punta al fornitore e una richiesta indiretta tramite un tag manager.
Il tag manager è la via meno visibile. Può restituire script di più fornitori e il personale può cambiare ciò che restituisce tramite un'interfaccia web, senza toccare il Suo codice. Le modifiche vanno online al caricamento successivo della pagina e il codice è di solito offuscato.
Il sorgente HTML non mostrerà questi script. Apra gli strumenti per sviluppatori, passi alla scheda Network, percorra checkout e login ed elenchi ogni host che serve uno script.
Prima rimuovere, poi ospitare in locale
Chieda al responsabile di ciascuna voce se serva davvero su quella pagina. Un tag di marketing in una pagina di login o in un pannello di amministrazione raramente ha una buona risposta.
Per gli script che restano, OWASP indica come difesa il mirroring interno. Lei ospita direttamente una copia verificata, così una terza parte non può alterarla e il fornitore non riceve più l'indirizzo IP, il referrer o i cookie del visitatore. Il prezzo è la manutenzione: una copia in mirroring non include le correzioni del fornitore, quindi qualcuno deve occuparsi di riesaminarla e aggiornarla.
I fornitori abbandonati sono un problema a parte. Se il dominio che ospita uno script scade perché il fornitore è fallito o ha abbandonato il progetto, qualcuno può registrarlo di nuovo e pubblicare codice malevolo. Un fornitore ormai defunto presente nel Suo inventario è già di per sé un finding.
Fissare ciò che resta con Subresource Integrity
Subresource Integrity (SRI) consente alla pagina di dichiarare l'hash a cui un file deve corrispondere. Il browser confronta il file scaricato con quell'hash prima di eseguire uno script o applicare un foglio di stile e, se non coincidono, restituisce un errore di rete. La guida MDN a SRI indica il comando per generarlo:
cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A
Faccia precedere l'output da sha384- e lo inserisca nell'elemento:
<script src="https://cdn.example.com/script.js"
integrity="sha384-..."
crossorigin="anonymous"></script>
Il markup ha alcuni requisiti:
- L'attributo
crossoriginè obbligatorio. Il browser rifiuta SRI sulle richiesteno-cors, quindi un tag privo dell'attributo fallirà sempre. - La CDN deve inviare l'header
Access-Control-Allow-Origin. Molte inviano*. - È possibile indicare più hash. Il browser usa solo quelli dell'algoritmo più forte presente (SHA-256, SHA-384, SHA-512 in ordine crescente) e accetta il file se almeno uno corrisponde, il che consente di ammettere due versioni durante un aggiornamento. La specifica W3C descrive lo stesso comportamento.
SRI è adatto ai file che restano invariati finché non li modifica Lei. Uno script che il fornitore modifica a piacimento non supera il controllo dopo ogni modifica, e il container di un tag manager è proprio uno script di questo tipo. Limiti chi può pubblicarvi contenuti e lo tenga lontano dalle Sue pagine più sensibili.
Limitare con Content Security Policy
SRI stabilisce cosa deve contenere un determinato file. Una Content Security Policy (CSP) stabilisce da dove possono provenire gli script. La guida MDN a CSP raccomanda di consegnarla nell'header Content-Security-Policy su tutte le risposte, non solo sul documento principale.
Un punto di partenza per una pagina sensibile elenca gli host effettivamente utilizzati:
Content-Security-Policy: script-src 'self' cdn.example.com; object-src 'none'
Quando esiste una direttiva script-src o default-src, il JavaScript inline viene bloccato a meno che Lei non lo abiliti. MDN consiglia di evitare 'unsafe-inline', perché vanifica buona parte dello scopo di una CSP. Dove servono script inline, usi un nonce: generato a ogni risposta, imprevedibile, inserito da un template. Per le pagine statiche MDN suggerisce invece gli hash, e in tal caso anche gli script esterni richiedono l'attributo integrity.
OWASP afferma esplicitamente che un data layer non è una sandbox, perché i container dei tag manager possono eseguire JavaScript e HTML personalizzati. Limiti l'accesso alla pubblicazione e riesamini le modifiche come se fossero codice applicativo.
Individuare le lacune senza rompere il sito
L'header Integrity-Policy fa sì che il browser blocchi gli script privi dell'attributo integrity o caricati in modalità no-cors. Si parte dalla versione report-only:
Integrity-Policy-Report-Only: blocked-destinations=(script), endpoints=(integrity-endpoint)
L'endpoint richiede un header Reporting-Endpoints corrispondente. Le violazioni arrivano come report di tipo integrity-violation, che indicano l'URL bloccato. Gli script già fissati con hash scompaiono dai report, quindi questi ultimi non costituiscono un inventario completo degli script.
Quando non arrivano più report, secondo MDN si può attivare il blocco senza disservizi visibili agli utenti. Il container di un tag manager che non si può fissare continua a generare report, perciò le pagine che ne caricano uno restano in report-only. Può ispezionare gli header inviati dalle Sue pagine con il nostro strumento di verifica degli header HTTP.
Da dove cominciare
- Costruisca l'inventario di checkout, login e pagine di amministrazione a partire dalla scheda Network, annotando per ogni script responsabile, scopo e via di consegna.
- Rimuova le voci che nessuno sa giustificare, soprattutto nelle pagine di login e amministrazione, e segnali ogni fornitore il cui dominio sembri abbandonato.
- Ospiti in locale i file che è disposto a mantenere e a riesaminare. Fissi ogni script che conserva: generi hash SHA-384, aggiunga
integrityecrossorigin="anonymous"e collaudi in staging. - Attivi
Integrity-Policy-Report-Onlyper gli script e legga i report. ImpongaIntegrity-Policysolo quando ogni script della pagina ha un attributointegritye lasci in report-only le pagine con tag manager. - Collaudi in staging una
Content-Security-Policyconscript-srceobject-src 'none', dato che blocca gli script inline. Limiti chi può pubblicare nel Suo tag manager. Per una verifica esterna, un penetration test può includere queste pagine.
