Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
PRIMO ESEMPIO
Abbiamo un form che deve prendere un numero di telefono in input. Come forziamo
questa regola? Whitelisting? Servono numeri, eventualmente spazi oppure trattini. Se è
un’applicazione internazionale servirà un + all’inizio. Qualche paese ha pure le parentesi.
Queste sono le cose che servono, nient’altro. La whitelisting accetterà stringhe contenenti
numeri e i simboli + - ( ) /. Con queste regole, c’è qualcosa che un attaccante potrebbe
inserire e generare problemi per il sistema? Beh dipende dal backend. Per esempio
questo input non fissa una lunghezza massima. Se a server side il linguaggio non controlla
la lunghezza, dovremmo tagliare i caratteri in eccesso. Per esempio si può fissare il limite
massimo a 20 caratteri perché difficilmente superi quella cifra per scrivere un numero di
telefono. Ma questi simboli come fanno a fare danni? Al massimo c’è il + che è simile a *
nella shell, quindi SE (e il SE è gigante) quel numero è usato in una query per leggere il
file system, il + potrebbe causare problemi, ma è MOOOLTO improbabile… Dipende tutto
dal backend system.
SECONDO ESEMPIO
Qui facciamo qualcosa di più complicato: creiamo un blog con articoli e possiamo scrivere
dei commenti. Una cosa che fanno tutti ma a quanto pare non è una buona idea secondo il
prof e HA RAGIONE AHAHAH. Se il commento è una semplice stringa che l’utente scrive
e alla fine fa Send, quando poi viene messo nell’HTML senza filtri crea dei problemi…
<script>alert(“BAND E SCIEM”)</script>.
Metti caso che uno nel commento scrive È un
codice eseguibile, e se viene incorporato nella pagina, chiunque apre il blog e va
nell’articolo con quel codice tra i commenti si ritrova un bel pop-up. E qui il codice è
stupido, ma può contenere qualunque cosa… Questa vulnerabilità è chiamata CROSS
SITE SCRIPTING (XSS). È detto cross site perché del codice viene iniettato in una
pagina da qualcuno che non è il programmatore della pagina stessa, ma qualcun altro.
Una regola importante di Javascript è che esso può accedere e manipolare i dati della
pagina in cui il codice stesso si trova (SAME ORIGIN POLICY – SOP). È un principio
implementato da tutti i browser. Javascript può accedere a tutti gli elementi, leggerli,
inviarli… è quello che fai normalmente quando navighi. Ma se tipo uno script proveniente
da www.evil.com fosse eseguibile su www.facebook.com potrebbe leggere tutto quello che
vuole. Invece forzando che Facebook può eseguire solo codice proveniente da Facebook
risolviamo il problema. È una policy di sicurezza facilissima e che ha senso. Ma se il
codice viene iniettato tramite XSS quello risulta proveniente da facebook.com ma è stato
scritto da qualcun altro, e quel qualcun altro può leggerti i cookie per l’autenticazione, se li
manda e ti entra nel profilo. Un XSS può accadere in due modi: STORED oppure
REFLECTED. Quello che abbiamo appena visto è stored, perché è memorizzato nel
server da qualche parte ed è visualizzato a chiunque va a leggere quella pagina. Il
reflected invece come funziona? Per esempio hai un form di un motore di ricerca, il quale
se non trova niente ti ritorna una pagina d’errore con la stringa che hai scritto. Se quello
che hai scritto contiene del codice, ti viene ritornato ed eseguito… E tu dici a che cavolo
serve attaccarmi da solo? Non sono così scemo, E INVECE NO: OGNI RICHIESTA HTTP
È UN LINK, SE TU A QUALCUN ALTRO MANDI IL LINK CON QUELLA QUERY DI
RICERCA MALIGNA CHI CI CLICCA VIENE ATTACCATO. I social network con phishing
spesso funzionano così, ti mandano un messaggio dicendoti clicca questo link perché c’è
una foto di te ubriaco e il link contiene in realtà del Javascript maligno. Per eseguire il
codice devi convincere qualcuno a cliccarci, ed è un compito notoriamente facile. Il SOP
può non funzionare in alcuni casi… nel senso che spesso alcune risorse sono condivise
tra diversi siti (per esempio gli script di Google Analytics). Questo rende il SOP un po’ più
nebuloso, perché stai permettendo a qualcuno di fare XSS in qualche modo. Poi ogni
browser permette i plugin per estendere le funzionalità, ma in genere la policy di sicurezza
applicata ai plugin è meno forte, visto che le estensioni le metti tu volontariamente, mentre
Javascript viene dall’esterno ed è maggiormente controllato… Torniamo però all’esempio
dei commenti: come li filtriamo? E qui c’è da divertirsi… Facendo whitelisting in un
commento permetti di scrivere lettere, numeri, segni di punteggiatura e nient’altro. È
sensato no? Se questi segni di punteggiatura non includono < e > allora risolviamo il
problema, perché non puoi scrivere <script> e nessun altro tipo di tag. Ma supponiamo
che dobbiamo permettere quei caratteri per qualche motivo, magari è un sito di
matematica e ci servono quei caratteri, e mo so cazzi. Chiunque può scrivere degli script,
come facciamo? Proviamo con il blacklisting… vietiamo l’uso di <script>! EH NO, it is an
EXTREMELY BAD IDEA. Innanzitutto “script” è solo uno dei tanti tag, ma ci sono anche
<applet>, <iframe> e altri tag che permettono di caricare altre pagine con dentro codice
malevolo. Ma basta un qualsiasi tag come img o svg con l’attributo onload oppure onerror
e quelli permettono l’inserimento di codice Javascript. Se facciamo il blacklist di OGNUNO
di essi, è esattamente come se facessi la lista di quelli che non possono entrare ad una
festa. Aggiungi che ad ogni aggiornamento di HTML si creano nuovi tag e attributi, dovresti
riscrivere tutto. Persino i tag con gli attributi href e src possono eseguire codice Javascript
se quegli attributi iniziano con javascript: e allora cosa fai? Vieti la parola Javascript? Beh
molti browser ignorano i caratteri di spazio e di carriage return, quindi se nel commento
scrivi javas + nuova linea + ncript il browser toglie la nuova linea ottenendo la stringa
javascript ed esegue il codice. Se volessi persino inserire in blacklist questo caso, l’HTML
permette comunque di inserire i caratteri non stampabili con delle entità, che poi vengono
cancellati (per esempio javas	cript poi diventa javascript). E allora togli pure questi
caratteri? Ma si possono inserire lo stesso perché come le stringhe di formato del C
permettono l’inserimento di infiniti parametri… Mettiamo caso che siamo riusciti a filtrare
persino questo...
Then you pick a "random browser with a letter as a logo"® and:
<IMG SRC="&{alert('JavaScript Executed')};">
VIENE ESEGUITO, E NON CHIEDETEMI IL PERCHÉ
E allora diciamo che pure &{ è vietato, ma poi...
<IFRAME SRC="java&{script{alert('JavaScript Executed')};">
Insomma penso che hai capito che il blacklist è una strada che non deve manco passarti
nell’anticamera del cervello. Qui c’è una bellissima lista di metodi per scrivere script senza
scrivere “script”
https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
https://html5sec.org/
E come risolviamo sto benedetto problema allora? Ci aiuta l’ESCAPING, che entra in
gioco quando ci sono caratteri che possono creare problemi ma ci servono. Li trasformi in
qualcos’altro che non crea problemi. In HTML, dato che < e > vengono usati per i tag ma
potrebbero anche essere simboli testuali che vuoi scrivere nella pagina, se li vuoi scrivere
puoi usare > e < (così come & è &). Questo è il metodo da usare, li puoi
escapare facilmente: ABBIAMO RISOLTO IL PROBLEMA (gif degli applausi). Per scrivere
script servono tag, e così non puoi scrivere nessun tag → nessuno script. È esattamente
come nella command line quando devi scrivere il nome di un file che ha degli spazi:
mettendo \ davanti ad uno spazio, dici alla shell che lo spazio non è il separatore dei
parametri ma è proprio il carattere spazio che fa parte del parametro corrente.
Ed ecco un’altra vulnerabilità molto nota… l’SQL INJECTION. Abbiamo un form in cui
inserire username e password. A lato server abbiamo una stringa di formato che piazza gli
argomenti così come sono stati scritti nella query al database. La query viene eseguita,
ma se come input nello username metti alla fine ‘; -- ottieni che la query controlla solo lo
username ma non la password, quindi anche senza conoscerla hai accesso all’account. E
se non conosci il nome utente ti basta scrivere ‘ OR ‘1’=’1’;-- ed entri nell’account di
qualcuno. Il problema di fondo è analogo a XSS… ci sono dei simboli che vengono
interpretati come sintassi SQL e non come parte dell’input. È questo il problema alla base:
dobbiamo disambiguare i simboli speciali come parte dell’input o come significato
sintattico di un linguaggio. Se vuoi capire se c’è un SQL Injection, il test più semplice è
inserire un apostrofo nel campo di input e se succedono cose strane hai capito subito che
c’è una vulnerabilità di questo tipo. Questi due sono solo esempi, ma una volta che
un’applicazione contiene questa vulnerabilità, possiamo scrivere qualsiasi query che
vogliamo. Anche delle subquery o delle union, dove possiamo scrivere nuove query da
zero. E con determinati DBMS possiamo anche modificare il database o memorizzare
delle funzioni da eseguire in seguito…
Vediamo come prevenire questa vulnerabilità. Partiamo dal form di login applicando i
metodi noti, partendo dal whitelisting. Quali caratteri ci servono in uno username? Se deve
contenere solo numeri, lettere e al massimo un punto in mezzo, abbiamo risolto il
problema. Con questi caratteri non puoi rompere una query SQL. Come vedi, se
applichiamo la whitelisting con metodo, risolviamo il problema senza nemmeno doverci
pensare direttamente. Pensiamo solo a quello che vogliamo. Ma se questo è facile per lo
username, per la password è un po’ più complicato… Nel caso di una password vogliamo
che tutti i caratteri siano ammessi. Ogni carattere non ammesso, riduce la sicurezza della
password. In questo caso specifico, filtrando l’apostrofo o al massimo il punto e virgola e il
trattino risolviamo l’SQL Injection e la robustezza della password rimane elevata. Oppure li
possiamo escapare trasformando per esempio l’apostrofo in caratteri alfabetici. Ma c’è
un’altra soluzione che è quella veramente usata dai sistemi. Si sa che le password non
veng