Questa è la traduzione dell'articolo Vulnerability Scanning Web 2.0 Client-Side Components di Shreeraj Shah pubblicato originariamente su SecurityFocus il 27 novembre 2006. La traduzione viene qui presentata con il consenso dell'editore.
Introduzione
Le cosiddette applicazioni Web 2.0 sono una combinazione di diverse tecnologie: Asynchronous JavaScript and XML (Ajax), Flash, JavaScript Object Notation (Json), Simple Object Access Protocol (Soap), Representational State Transfer (Rest). Tutte queste tecnologie, assieme all'accesso ai dati cross-domain, accrescono la complessità dell'applicazione. Stiamo assistendo, dunque, ad un potenziamento del browser che avviene attraverso il caricamento di nuovi programmi e librerie.
Tutti questi cambiamenti introducono nuovi problemi nelle attività di scansione di sicurezza, sia per gli utenti sia per i software. Il fine di questo articolo è quello di far comprendere i seguenti concetti e le seguenti tecniche:
- La complessità di scansione e i problemi che ci sono nelle applicazioni web di nuova generazione
- Gli obiettivi e le metodologie nella scansione di applicazioni Web 2.0
- La scoperta di vulnerabilità in ambito Web 2.0 (in particolare gli XSS nei feed RSS)
- L'injection cross-domain con Json
- Le contromisure e le difese attraverso un sistema di filtraggio ottenibile per mezzo del browser
- Interfaccia lato client complessa
- Origine dei dati
- Struttura dei dati
- Protocolli
- Scansione delle componenti lato server
href
articolo precedente tradotto ndr - Scansione delle componenti lato client
XMLHTTPRequest
- Le risorse example.com
- Il proxy per i feed
XMLHTTPRequest
example.com - Accesso ai blog example.com example.com
- Rilevazione della tecnologia e delle librerie
- Punti informativi esterni inaffidabili
- Punti di accesso al DOM
- Tracce di funzioni e variabili per individuare le vulnerabilità
- L'uso di Dojo dojo.js
- Dal browser possono essere visualizzati i file che, gestiti da un'applicazione di feed RSS, contengono funzioni al loro interno. Eccone una breve lista:
- Il file rss_xml_parser.js
processRSS()
GetRSS().
- Il file XMLHTTPReq.js
makeGET()
makePOST()
- Il file dojo.js
- Il file rss_xml_parser.js
document.getElementById(name).innerHTML:
document.write()
Complessità della scansione di sicurezza nel Web 2.0
Le applicazioni Web 2.0 di nuova generazione sono molto complesse e impongono nuovi problemi nella scansione ai fini della sicurezza. La complessità può essere attribuita ai seguenti fattori:
L'applicazione oggetto della nostra scansione potrebbe recuperare feed RSS da diversi siti, scambiare informazioni con diversi blog utilizzando Json e comunicare con un portale di informazioni finanziarie usando Soap. Tutti questi servizi sono incorporati sotto forma di Rich Internet Application (RIA) che usano Ajax o Flash.
I problemi nella scansione di sicurezza nelle applicazioni Web 2.0
I problemi nella scansione di applicazioni possono essere suddivisi in due parti:
Obiettivi della scansione lato client
Per comprendere gli obiettivi della scansione prendiamo come esempio un semplice scenario visualizzato in figura 1. Abbiamo un'applicazione Web che viene eseguita sul sito example.com. Il client accede a questa applicazione mediante il browser.

Questa applicazione può essere suddivisa nelle seguenti sezioni in base al suo uso e alla sua logica.
Ecco allora quattro obiettivi critici che bisogna assumere in una scansione destinata alla scoperta delle vulnerabilità lato client:
La scansione client side di un'applicazione (Feed)
In questa sezione adotteremo un approccio manuale al processo di scansione. Questa metodologia può essere automatizzata in alcuni punti ma data la complessità dell'applicazione potrebbe essere difficile scansionare ogni possibile combinazione.
Il nostro obiettivo è la pagina http://example.com/rss/news.aspx così come mostrata in figura 2.

La pagina mostrata sopra mostra diversi feed RSS impostati dall'utente finale. Entriamo ora nel processo richiesto per la scansione.
1. Scansione e identificazione della tecnologie
Tutti i possibili codici JavaScript caricati nel browser all'accesso ad una pagina possono essere identificati dalla pagina stessa visualizzando il codice sorgente così come mostrato in figura 3.

Se siete in possesso dell'estensione Web Developer per Firefox potete visualizzare tutti gli script in una singola pagina così come mostrato in figura 4.

L'esame di questi script JavaScript ci permette di ottenere le seguenti informazioni:
Tutte queste informazioni possono essere organizzate meglio per ottenere una migliore visione del processo.
2. Informazioni esterne non affidabili
La scansione del codice HTML della pagina ci restituisce il seguente codice:
<select id="feeds" onchange="GetRSS()
Il codice fa riferimento alla funzione GetRSS()
che, ad uno ad uno, esegue delle richieste al proxy per recuperare da vari server i feed la cui affidabilità non può essere controllata.
Nella seconda parte dell'articolo entreremo nel dettaglio del processo di ricerca delle vulnerabilità.
In questa seconda parte dell'articolo entriamo nel dettaglio del processo di ricerca delle vulnerabilità e cerchiamo di fornire dei metodi di protezione per le applicazioni web.
Punti di accesso al DOM
Dopo aver raccolto tutti gli script JavaScript possiamo iniziare ad individuare le strade attraverso le quali si ottiene accesso al DOM. Cercheremo dunque l'uso dell'istruzione document.* e limiteremo la ricerca a due potenziali candidati:
Ci potrebbero essere tuttavia alcune altre istruzioni che modificano il DOM nel browser. A questo punto, tuttavia, dovremmo concentrarci sulle due funzioni precedenti. Nel sorgente del file cercate di trovare la seguente funzione nella quale è utilizzata l'istruzione innerHTML:
function processRSS (divname, response) { var html = ""; var doc = response.documentElement; var items = doc.getElementsByTagName('item'); for (var i=0; i < items.length; i++) { var title = items[i].getElementsByTagName('title')[0]; var link = items[i].getElementsByTagName('link')[0]; html += "" + title.firstChild.data + " "; } var target = document.getElementById(divname); target.innerHTML = html; }
Funzioni e tracce di variabili per la scoperta di vulnerabilità
Possiamo organizzare tutte le informazioni ottenute nei passi precedenti e determinare, attraverso un debug, l'intero flusso della logica lato client dell'applicazione. Questa logica è mostrata in figura 5:

Da questa illustrazione è chiaro che il proxy del feed filtra alcuni caratteri particolari, come < e >, rendendo di fatto impossibile iniettare JavaScript nel DOM. Ancora, dal momento che l'esecuzione modifica l'istruzione innerHTML
nel DOM precaricato, non è possibile eseguire nessuno script. Ma osserviamo più da vicino la seguente linea di codice che costruisce dinamicamente l'HTML:
html += ""
Che cosa accade se una fonte di feed RSS non affidabile include un link nocivo? Il link non viene validato da nessuna parte come risulta evidente dal codice. Questo è un esempio di un nodo RSS che contiene un codice potenzialmente nocivo:
<title>Interesting news item</title> <link>javascript:alert("Simple XSS")</link> <description><![CDATA[]]></description> <author>XYZ news</author> <dc:date>2005-11-16T16:00:00-08:00</dc:date>
Notate come l'elemento link
dell'XML contiene del JavaScript. Dunque quando un utente cliccherà quel il link lo script verrà eseguito all'interno del contesto del DOM. Questo processo è illustrato nella figura 6:

L'inclusione di informazioni di una fonte non affidabile all'interno del DOM può mettere a rischio la sessione di un navigatore. Le applicazioni Web 2.0 solitamente mettono a disposizione in un'unica pagina informazioni prelevate da differenti fonti.
Facciamo un altro esempio per capire meglio questa tipologia di attacco.
Injection cross-dominio con JSON
JSON è una struttura di scambio di informazioni XML molto leggera e che può introdurre diverse informazioni aggiuntive. Molte applicazioni, come anche quelle di Google e Yahoo, hanno aggiunto ai loro Web service delle chiamate JSON. Con queste chiamate diverse informazioni cross-dominio possono essere intercettate e processate con funzioni specifiche.
Facciamo un esempio. Poniamo che un sito Web disponibile alla pagina http://blog.example.org ha ampliato i suoi servizi usando delle chiamate JSON per permettere a tutti di accedere alle informazioni usando JavaScript. Accediamo alle informazioni per l'id=10
puntando il browser o inviando una richiesta GET
al seguente indirizzo:
Richiesta:
http://blog.example.org/Getprofile.html?callback=profileCallback&id=10
Risposta:
profileCallback({"profile":[{"name":"John","email":"john@my.com"}]})
Come si può vedere riceviamo in risposta del codice JSON incluso all'interno dell'istruzione profileCallback
. Con questo codice la funzione profileCallback()
viene eseguita e l'output di JSON viene passato come argomento.
Allo stesso modo se richiediamo id=11
avremo la seguente risposta:
profileCallback({"profile":[{"name":"Smith","email":"smith@cool.com"}]})
Il nostro obiettivo, il sito example.com, ha integrato questo servizio nella sua applicazione. Se diamo uno sguardo al suo codice lato cliente e cerchiamo le istruzioni document.write
otteniamo la seguente porzione di codice conservata nella pagina showprofile.html.
<script> function profileCallback(result) { document.write(result.profile[0].name); document.write("<br />"); document.write(result.profile[0].email); } </script> <script src
Questo codice esegue dunque una chiamata cross-dominio al servizio di blog.example.org e processa il suo output nella funzione profileCallback.
Chiamando questa pagina otteniamo il seguente output, mostrato nella figura qui in basso:

Questa applicazione integrata nel sito example.com utilizza informazioni JSON non affidabili inviate da un sito terzo e le include nel suo codice senza nessuna validazione. Questo metodo rende esposti i dati sensibili degli utenti, come ad esempio sessioni e cookie. Ciò significa che se uno dei client cerca di ottenere informazioni per l'id=101
e questo ha incluso all'interno del codice JavaScript nel campo e-mail, del tipo di quello visualizzato qui sotto in rosso, potrebbe eseguire del codice nocivo nel computer.
profileCallback({"profile":[{"name":"Jack","email":"<script>alert('JSON XSS');</script>"}]})
Nella figura qui sotto forniamo l'immagine del browser della vittima mentre accede al sito example.com:

Applicazioni scritte in Ajax possono essere facilmente compromesse attraverso la gestione di informazioni non affidabili. In questo articolo ne abbiamo esaminate due che fanno transitare codici nocivi direttamente all'utente. Ne esistono comunque anche alcuni altri.
Contromisure
Per proteggere i browser lato-client è importante seguire una massima ripetuta più volte: "non affidarsi a informazioni di terze parti". Nella fase di design dell'applicazione è necessario definire con chiarezza l'ambito dell'applicazione e mettere a punto strumenti di validazione per tutte le informazioni che provengono da sorgenti esterne, siano esse in XML, RSS, JSON, JavaScript e così via. Questo processo è mostrato nella figura 9:

Per esempio, prima di inviare collegamenti al DOM è necessario farli filtrare da una semplice funzione, come quella mostrata qui in basso, che esamina qualsiasi tentativo di injection di codice JavaScript
function checkLink(link) { if(link.match(/javascript:|<|>/)) { return false; } else { return true; } }
È importante filtrare tutto il traffico in entrata prima che questo intacchi il DOM all'interno di un browser: una difesa per l'utente finale.
Conclusioni
Nell'ultimo periodo sono stati molti gli incidenti di sicurezza informatica causati da codice mal scritto in applicazioni Web 2.0. Le tecniche automatizzate o manuali di scansione dovranno essere potenziate con solidi meccanismi di individuazione degli errori che potrebbero intaccare il DOM lato client. Potrebbe essere una vera e propria sfida mettere in atto scansioni completamente automatiche per applicazioni Web 2.0, cosa che potrebbe essere risolta usando tecniche automatiche in combinazione con l'intelligenza dell'uomo. Alcune dei più vecchi attacchi come il Cross-Site Request Forgery (XSRF) sono nuovamente tirati in ballo nell'era Web 2.0. XSS, XSRF e altri attacchi lato client compaiono in diverse vulnerabilità e avvisi di sicurezza per le applicazioni web di nuova generazione.
Il controllo delle applicazioni Web 2.0 deve essere eseguito con attenzione per scoprire possibili attacchi lato client e per mitigare il rischio sui sistemi degli utenti. Questo articolo ha cercato di gettare luce su alcuni potenziali attacchi e sulle tecniche di scansione utilizzate per identificare punti vulnerabili dell'applicazione. Basta scalfire un po' la superficie delle applicazione per scoprire che molte di esse sono vulnerabili a questo tipo di attacchi e che possono essere compromesse da utenti malintenzionati, virus e worm.
Sull'autore
Shreeraj Shah, BE, MSCS, MBA, è il fondatore di Net Square ed è a capo delle attività di consulenza, formazione e ricerca e sviluppo di Net Square. Ha lavorato prima in Foundstone, Chase Manhattan Bank e IBM. È anche l'autore di Hacking Web Services (Thomson) e co-autore di Web Hacking: Attacks and Defense (Addison-Wesley). Oltre a ciò ha pubblicato diversi advisory di sicurezza, software e whitepaper e ha presenziato in numerose conferenze come RSA, AusCERT, InfosecWorld, HackInTheBox, Blackhat, OSCON, Bellua, Syscan e altre. Ha un blog all'indirizzo http://shreeraj.blogspot.com/.
© 2006 SecurityFocus