Diventa Autore per CoreTech | Scopri di più
27/03/20 CoreTech Blog
Sei sicuro che il tuo sito web sia protetto dallo Scripting tra siti se la ricerca Google non è avvenuta per cinque mesi?
Il 26 settembre 2018, uno degli sviluppatori che lavorano alla libreria Open-source Closure (originariamente creata da Google e utilizzata in Ricerca Google) ha creato un commit che ha rimosso parte della sanificazione dell'input. Presumibilmente, questo perché hanno incontrato problemi con la progettazione dell'interfaccia utente. L'autore di questo commit e i suoi revisori non hanno notato che questa modifica ha introdotto una vulnerabilità XSS.
Nel febbraio 2019, un ricercatore di sicurezza Masato Kinugawa ha scoperto questa vulnerabilità e l’ha segnalata a Google. Google ha reagito immediatamente e la vulnerabilità è stata risolta il 22 febbraio 2019, ripristinando il commit originale che lo ha causato. L'intero caso è stato descritto in molti dettagli da un altro esperto di sicurezza, LiveOverflow.
La vulnerabilità nella libreria di chiusura era molto difficile da rilevare. Si basava su una tecnica raramente utilizzata chiamata mutazione XSS. Le vulnerabilità di mutazione XSS sono causate da differenze nel modo in cui i browser interpretano lo standard HTML.
A causa delle differenze del browser, è molto difficile sanificare l'input dell'utente sul server. Il server deve tenere conto di tutte le differenze non solo tra i browser, ma anche le loro versioni. Il modo più efficiente per sanificare l'input rispetto a XSS è quello di farlo lasciando che il browser interpreti l'input senza eseguirlo effettivamente.
Esiste un'eccellente libreria lato client per la sanificazione XSS: DOMPurify. Questa libreria viene utilizzata anche da Closure. Tuttavia, DOMPurify non è infallibile. In rari casi, è necessaria un'ulteriore sanificazione. Ed era esattamente quella sanificazione in più che è stata rimossa nel settembre 2018 con l'aggiornamento alla chiusura.
DOMPurify sanifica l'input dell'utente utilizzando l'elemento template. I browser elaborano la proprietà innerHtml dell'elemento div e la stessa proprietà dell'elemento template in modo diverso. Nel caso dell'elemento div innerHtml viene eseguito immediatamente dopo l'assegnazione di un valore. Nel caso dell'elemento template è possibile applicare la sanificazione prima dell'esecuzione.
L'idea alla base di DOMPurify è prendere l'input dell'utente, assegnarlo alla proprietà innerHtml dell'elemento template fare in modo che il browser lo interpreti (ma non lo esegua) e quindi sanificarsi per il potenziale XSS. Tuttavia, è la logica alla base di tale interpretazione che è la causa sottostante della mutazione XSS.
Per comprendere come i browser interpretano HTML non valido, crea un documento HTML con solo il contenuto seguente:
<div><script title="</div>">
Quando lo apri nel browser, vedrai che il codice viene interpretato come segue:
<html>
<head></head>
<body>
<div><script title="</div>">
</script>
</div>
</body>
</html>
A questo punto, provare a creare un documento HTML con il contenuto seguente:
<script><div title="</script>">
Il browser interpreta questo codice in modo diverso:
<html>
<head>
<script><div title="</script>
</head>
<body>
">
</body>
</html>
Questa differenza è dovuta al fatto che quando il browser rileva il tag <script> passa dal parser HTML al parser JavaScript fino a quando non viene trovato il tag di chiusura.
Nella maggior parte dei casi, il browser interpreterà lo stesso documento sempre nello stesso modo indipendentemente dalle circostanze. Tuttavia, c'è un caso in cui questo comportamento può essere diverso a causa di determinate circostanze lato client: il tag noscript
La specifica HTML indica che il tag noscript deve essere interpretato in modo diverso a seconda che JavaScript sia abilitato o meno nel browser. Questa differenza nel comportamento del browser è esattamente ciò che Masato Kinugawa ha usato per il suo attacco di prova di concetto XSS. Si scopre che il codice HTML non valido viene interpretato in modo diverso quando assegnato alla proprietà innerHtml dell'elemento template (come se JavaScript fosse disabilitato) e in modo diverso quando viene assegnato alla proprietà innerHtml dell'elemento div (come se JavaScript fosse abilitato).
Masato Kinugawa utilizzò il seguente carico utile per eseguire l'attacco proof-of-concept:
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
Se JavaScript è disabilitato (come per l'elemento template utilizzato da DOMPurify per la sanificazione XSS), il browser interpreta il payload nel modo seguente:
<noscript>
<p title="</noscript><img src=x onerror=alert(1)>"></p>
</noscript>
Il valore di "</noscript><img src=x onerror=alert(1)>" è il valore dell'argomento title Pertanto, DOMPurify non sanificare il contenuto di input perché non vi è alcun JavaScript, quindi non vi è alcun rischio XSS.
Tuttavia, se JavaScript è abilitato (come per l'elemento div utilizzato dal browser) il browser interpreta il payload nel modo seguente:
<noscript>
<p title="</noscript>
<img src="x" onerror="alert(1)">
"">
"
L'elemento noscript
termina presto e l'elemento img viene interpretato completamente, incluso il contenuto JavaScript dell'attributo onerror
E 'impossibile dire se qualcun altro ha scoperto questa vulnerabilità prima e se è stata utilizzata per scopi dannosi. Dal momento che la libreria di chiusura viene utilizzata anche in altri prodotti Google, questa vulnerabilità potrebbe aver interessato Gmail, Mappe, Documenti e altri servizi.