tags: DOM-Based_Attack


La manipolazione del DOM di per sé non è un problema. Anzi, è parte integrante del funzionamento dei siti web moderni. Tuttavia, il codice JavaScript che gestisce i dati in modo non sicuro può consentire diversi tipi di attacchi. Le vulnerabilità basate sul DOM si verificano quando un sito web contiene codice JavaScript che prende un valore controllabile da un attaccante, noto come sorgente, e lo passa a una funzione pericolosa, nota come destinazione.

Per sfruttare o mitigare queste vulnerabilità, è importante innanzitutto familiarizzarsi con i principi di base del flusso di contaminazione tra sorgenti e destinazioni perchè per sfruttare questa vulnerabilità abbiamo bisogno sia del parametro sorgente che quello di destinazione(Sink) vulnerabili, se uno dei due è sanitizzato la vulnerabilità non esiste.

Sorgenti

Una sorgente è una proprietà JavaScript che accetta dati potenzialmente controllabili da un malintenzionato. Un esempio di sorgente è la proprietà location.search, poiché legge l’input dalla stringa di query, che è relativamente semplice da controllare per un attaccante. In definitiva, qualsiasi proprietà che può essere controllata da un attaccante è una potenziale sorgente. Ciò include l’URL di provenienza (esposto dalla stringa document.referrer), i cookie dell’utente (esposti dalla stringa document.cookie) e i messaggi web.

Sink

Un sink è una funzione JavaScript o un oggetto DOM potenzialmente pericoloso che può causare effetti indesiderati se gli vengono passati dati controllati da un attaccante. Ad esempio, la funzione eval() è un sink perché elabora l’argomento che le viene passato come codice JavaScript. Un esempio di sink HTML è document.body.innerHTML perché potenzialmente consente a un attaccante di iniettare codice HTML dannoso ed eseguire codice JavaScript arbitrario.

Fondamentalmente, le vulnerabilità basate sul DOM si verificano quando un sito web passa dati da una sorgente a un sink, che poi gestisce i dati in modo non sicuro nel contesto della sessione del client.

La sorgente più comune è l’URL, a cui si accede in genere tramite l’oggetto location. Un attaccante può costruire un link per indirizzare una vittima a una pagina vulnerabile con un payload nella stringa di query e frammentare porzioni dell’URL. Consideriamo il seguente codice:

goto = location.hash.slice(1)
if (goto.startsWith('https:')) {
  location = goto;
}

Questo codice è vulnerabile agli attacchi di reindirizzamento aperto basati sul DOM perché la sorgente location.hash viene gestita in modo non sicuro. Se l’URL contiene un frammento hash che inizia con https:, questo codice estrae il valore della proprietà location.hash e lo imposta come proprietà location della finestra. Un utente malintenzionato potrebbe sfruttare questa vulnerabilità costruendo il seguente URL:

https://www.innocent-website.com/example#https://www.evil-user.net

Quando una vittima visita questo URL, il codice JavaScript imposta il valore della proprietà “location” su https://www.evil-user.net, reindirizzando automaticamente la vittima al sito malevolo. Questo comportamento potrebbe essere facilmente sfruttato per realizzare un attacco di phishing, ad esempio.

Sorgenti utili per attaccare

Queste sono le sorgenti più comuni per effettuare un attacco DOM-Based:

document.URL
document.documentURI
document.URLUnencoded
document.baseURI
location
document.cookie
document.referrer
window.name
history.pushState
history.replaceState
localStorage
sessionStorage
IndexedDB (mozIndexedDB, webkitIndexedDB, msIndexedDB)
Database

Sink Utili per attaccare

document.write()
window.location
document.cookie
eval()
document.domain
WebSocket()
element.src
postMessage()
setRequestHeader()
FileReader.readAsText()
ExecuteSql()
sessionStorage.setItem()
document.evaluate()
JSON.parse()
element.setAttribute()
RegExp()