Elementi di
Sicurezza e Privatezza
Lezione 15
Web Security Code Injection (1)
Chiara Braghin
[email protected]
Le 2 maggiori vulnerabilità dei siti Web
• SQL Injection
 Il browser spedisce dell’input malizioso ad un
server (tramite un form)
 La mancata verifica dell’input porta a query
SQL maliziose
 di TIPO 1: rilasciano informazione sensibile
 di TIPO 2: modificano dati critici (e sensibili)
• XSS – Cross-site scripting
 Un Web server “cattivo” spedisce a una vittima
innocente uno script che ruba informazioni da
un server Web onesto
1
Code Injection
• SQL Injection e XSS sono un esempio del
più generico attacco di tipo Code (o
Command) injection
• Input “non fidato” viene inserito in una
query o in un’istruzione
 La stringa in input altera la semantica prevista
dell’istruzione
 Es: SQL Injection - dati non verificati vengono
usati per fare una query ad un database
• Approfitta di vulnerabilità insite nei
siti Web dinamici
2
Code Injection (1)
• Permette all’attaccante di eseguire codice arbitrario a lato
server
• Esempio: code injection basato su eval (funzione PHP)
• Si supponga di avere una calcolatrice a lato server:
http://site.com/calc.php
…
$in = $_GET[‘exp'];
eval('$ans = ' . $in . ';');
…
• Attacco: inserire 10; system(‘rm *.*’), ovvero
http://site.com/calc.php?exp=“ 10; system(‘rm *.*’) ”
3
Code Injection (2)
• Esempio basato sull’uso della funzione system():
 Codice PHP per spedire email:
$email = $_POST[“email”]
$subject = $_POST[“subject”]
system(“mail $email –s $subject < /tmp/mailbody”)
 L’attaccante può inserire:
http://yourdomain.com/mail.php?
[email protected] &
subject=foo < /usr/passwd; ls
 Oppure:
http://yourdomain.com/mail.php?
[email protected]&subject=foo;
echo “evil::0:0:root:/:/bin/sh">>/etc/passwd; ls
4
SQL Injection
SQL Injection
• Input “non fidato” viene inserito in una
query
 La stringa in input altera la semantica
prevista della query al database
 Possibile nel caso in cui non vengano
controllati i dati in input
• Approfitta di vulnerabilità insite nei
siti Web dinamici
6
SQL Injection - Funzionamento di base
Server Vittima
1
m
input
e
r
i
r
e
Ins
n form
u
n
i
so
alizio
2
3 riceve (o modifica)
dati sensibili
query SQL non
voluta
Attaccante
DB SQL Vittima
7
SQL Injection - Elementi base (1)
• Client-side: Form per inserire i dati
8
SQL Injection - Elementi base (2)
• Server-side: Script che recupera i dati e li
utilizza (e.g., costruisce la query)
• Esempio (codice PHP):
$username = $_POST[‘username’];
$sql = "SELECT PersonID FROM Users WHERE
username='$username' ";
$rs = $db->executeQuery($sql);
• Problema:
 L’input dell’utente contenuto in username
viene inserito direttamente in un comando
SQL
9
SQL Injection - Elementi base (3)
• Server-side: Database su cui viene
fatta la query
Users
PersonID
username
1 mrossi
2 escarpa
lastName
Rossi
Scarpa
name
Mario
Enzo
SSN
265432A
345679Y
Users
SELECT name, lastName, SSN
FROM Users
lastName
Rossi
Scarpa
name
SSN
Mario 265432A
Enzo 345679Y
10
I tag HTML (1)
• I tag sono gli elementi della pagina HTML che servono per
definire il tipo e il formato del contenuto, in questo modo
il testo scritto appare nel formato voluto
• Caratteristiche principali:
 sono racchiusi da parentesi <angolate>
 <HTML>
 molti elementi possono avere argomenti (chiamati attributi) all'interno dei
tag che definiscono parametri sulla gestione dell'elemento stesso da parte
del browser
 <BODY BGCOLOR=“red”>
 la maggior parte dei tag ha un inizio (tag di apertura) e una fine (tag di
chiusura)
 <HTML> e </HTML>
 Per chiudere un tag basta aggiungere / al tag iniziale
 i tag possono essere scritti indifferentemente con lettere maiuscole o
minuscole
11
I tag HTML (2) - Regole di scrittura
• Regole per una corretta scrittura (non tutte
obbligatorie):
 I tag vanno scritti sempre nello stesso modo
 non <HTML> e </html>
 I tag vanno aperti e chiusi sempre nello stesso ordine ma devono
essere annidati fra loro e non sovrapposti:
 <THIS><THAT></THIS></THAT> - tag sovrapposti, sbagliato
 <THIS><THAT></THAT></THIS> - tag annidati, giusto
 Esempio: non si deve scrivere <body><p>Contenuto della
pagina</body></p>
 I valori vanno inseriti tra “virgolette” o ‘apici’
• Il browser interpreta al meglio pagine web che non
rispettino queste regole, ma browser diversi possono
dare risultati visivi diversi.
12
SQL (1)
• Una query SQL agisce sulle tabelle definite
nella base di dati e restituisce come risultato
una tabella
• Nei casi più semplici una query SQL deve
specificare:
 quali sono le informazioni che interessano
 SELECT Attributo1, Attributo2,…
 in quali tabelle si trovano
 FROM Tabella1, Tabella2,…
 quali proprietà devono avere (la condizione, opzionale, è
espressa sugli attributi delle tabelle specificate nella clausola
FROM)
 WHERE Condizione
13
SQL (2)
• Il comando di base di SQL:
SELECT [DISTINCT] Attributo {, Attributo}
FROM Tabella [Ide] {, Tabella [Ide]}
[ WHERE Condizione ]
• Semantica: restrizione + prodotto + proiezione
• Note:
 la condizione è opzionale
 in generale, una tabella nel linguaggio SQL non è un insieme, ma
un multinsieme, a meno che non venga selezionata l’opzione
DISTINCT
 per evitare ambiguità quando si opera sul prodotto di tabelle con
gli stessi nomi dei campi, un attributo A di una tabella “R ide” si
denota come R.A oppure ide.A
14
SQL (3)
• La condizione presente nella clausola WHERE è
un’espressione boolena costruita combinando
predicati semplici con gli operatori AND, OR,
NOT
• Alcuni predicati semplici:
 Expr Confronto Expr
 Expr Confronto (Sottoselect che torna un
valore)
 [NOT] EXISTS (Sottoselect)
 Confronto: <, >, =, <>, <=, >=
15
SQL Injection (1)
• Query (vulnerabile!) usata spesso per il
login:
SELECT * FROM Users
WHERE username = ’chiara'
AND passwd = '123'
(Se ritorna qualcosa -i.e. l’utente esiste-, allora login)
• Sintassi del server ASP/MS SQL:
var sql = "SELECT * FROM Users
WHERE username = '" + username +
"' AND passwd = '" + passwd + "'";
16
SQL Injection (2)
Web
Browser
(Client)
inserire username
e password
Web
Server
SELECT * FROM Users
WHERE username=’io'
AND passwd=’io23'
DB
Query “normale”
17
SQL Injection (3)
• Dati inseriti dall’utente:
username = ' or 1=1 – –
passwd = ahah
• Query finale:
SELECT * FROM Users
WHERE username = ' ' or 1=1
– – ' AND password = 'ahah'
• Effetto:
 Seleziona un’intera tabella invece che solo una riga!
 L’utente viene loggato in quanto la query ritorna qualcosa
 -- commenta ciò che segue
18
SQL Injection (4)
• Dati inseriti dall’utente:
username = ' ; DROP TABLE Users – –
passwd = boh
• Query finale:
SELECT * FROM users
WHERE username = ' ' ; DROP TABLE Users
– – ' AND password = 'boh'
• Effetto:
 Cancella la tabella degli utenti!!
 Allo stesso modo si possono aggiungere utenti,
modificare le password, etc.
19
Esempio (1.1)
• Esempio di come ottenere le
informazioni sensibili contenute nel DB:
Un form per richiedere
gli ordini mensili di
pizza.
Si inserisce il numero
del mese e viene
visualizzata una tabella
riassuntiva.
20
Esempio (1.2)
Query
SQL
“SELECT pizza, toppings, quantity, date
FROM orders
WHERE userid=” . $userid .
“AND order_month=” . _GET[‘month’]
• Supponiamo che:
month = “ 0 AND 1=0
UNION SELECT name, CC_num, exp_mon, exp_year
FROM creditcards
”
• L'operatore UNION esegue l'unione insiemistica di due
tabelle generate da comandi SELECT
21
Esempio (1.3)
• Risultato: vengono visualizzati i numeri di
carta di credito dei clienti!!
22
Esempio (1.4)
• Altro attacco:
SELECT pizza, toppings,
quantity, order_day
FROM orders
WHERE userid=4123
AND order_month=0 OR 1=1
La condizione è sempre vera
23
Esempio (2) - :-)
Source: http://xkcd.com/327/
24
Attacco a CardSystems
• CardSystems
 Una compagnia che gestiva il pagamento
avvenuto tramite carte di credito
 Attacco SQL injection nel giugno 2005
• L’attacco in numeri:
 263,000 numeri di carte di credito rubati dal
database (i numeri venivano memorizzati in
chiaro…)
 43 milioni di numeri di carte di credito esposti
all’attacco
25
Attacco dell’aprile 2008 (1)
26
Attacco dell’aprile 2008 (2)
• Come ha funzionato l’attacco:
 (1) Usato Google per trovare siti che usano un
particolare stile di ASP vulnerabile ad attacchi di
tipo SQL injection
 (2) Usato SQL injection su questi siti, modificando la
pagina facendo in modo che includa un link al sito
cinese nihaorr1.com (NON VISITARE IL SITO!!!!!)
 (3) Il sito nihaorr1.com usa script JavaScript che
sfruttano vulnerabilità in IE, RealPlayer, QQ Instant
Messenger
•
I passi (1) e (2) sono eseguiti in automatico da un tool che può venire
configurato in modo che inietti qullo che si vuole nei siti vulnerabili
27
Esistono delle soluzioni?
1. Whitelisting al posto di Blacklisting
2. Validazione dell’input
3. Usare Prepared Statements
28
Problemi del Blacklisting
• Blacklisting: indicare i caratteri che non devono
essere presenti nelle stringhe di input
• Filtrare apici, spazi bianchi, ; e… ?
 Si potrebbe sempre scordare un carattere pericoloso
 Blacklisting non è una soluzione esauriente
 Es: parametri numerici?
• Può essere in conflitto con alcuni requisiti
funzionali:
 Come memorizzare O’Brien nel DB se gli apici non sono
permessi?
29
Whitelisting
• Whitelisting – permette solo input che rientrano in
un ben definito insieme di valori
 L’insieme di valori in genere viene definito usando
espressioni regolari
 RegExp è il pattern con cui confrontare le stringhe in
ingresso
• Es: parametro month: intero non-negativo
 RegExp: ^[0-9]*$ - 0 o più cifre, insieme “sicuro”
 ^ e $ indicano l’inizio e la fine della stringa
 [0-9] indica cifre, * indica 0 o più
30
Prepared Statements & Bind Variables
• Meccanismo di base per SQL Injection: Alcuni
metacaratteri (e.g. apici) servono per distinguere i
dati dal controllo nelle query
 Nella maggior parte degli attacchi: dati interpretati come
controllo
 Altera la semantica della query
• Bind Variable: ? segnaposto che garantiscono si
tratti di dati (non di controllo)
• Prepared Statements permettono la creazione di
query statiche con bind variables
 Preserva la struttura della query attesa
 I paramentri non vengono considerati in fase di parsing
della query
31
Java Prepared Statements
PreparedStatement ps =
db.prepareStatement("SELECT pizza, toppings, quantity, order_day "
+ "FROM orders WHERE userid=? AND order_month=?");
ps.setInt(1, session.getCurrentUserId());
ps.setInt(2, Integer.parseInt(request.getParamenter("month")));
ResultSet res = ps.executeQuery();
Bind Variable:
segnaposto per i dati
• Le bind variable sono tipate: l’input
deve essere del tipo che ci si aspetta
(e.g. int, string)
32
PHP Prepared Statements
$ps = $db->prepare(
'SELECT pizza, toppings, quantity, order_day '.
'FROM orders WHERE userid=? AND order_month=?');
$ps->execute(array($current_user_id, $month));
• Non c’è la tipizzazione dei parametri
come in Java
• SQL injection è ancora possibile!
33
Conclusione
• Gli attacchi di tipo SQL injection sono delle minacce
che possono:
 Rilasciare dati sensibili
 Alterare o danneggiare dati critici
 Dare ad un attaccante un accesso non autorizzato ad un DB
• Idea chiave per combatterli: Usare diverse
soluzioni, in modo consistente!
 Validazione dell’input basato su whitelisting
 Prepared Statements con bind variable (meglio se tipate)
34
Web, vulnerabilità e
attacchi
Attacchi comuni
(2006)
• Cross-site scripting (XSS) – 22%
• SQL Injection – 14 %
• PHP Include – 10%
• Buffer overflow – 8%
Il 2005 è stato il primo anno
In cui XSS ha superato gli
attacchi di tipo buffer
overflow.
36
Attacchi - aggiornamento (2009)
http://www-935.ibm.com/services/us/iss/xforce/trendreports/
37
Dati recenti (1)
• Le vulnerabilità più diffuse nelle applicazioni Web (%
Vulns ALL)
38
Dati recenti (2)
• Percentuale di diffusione delle vulnerabilità
delle applicazioni Web (% Vulns ALL)
39
Riferimenti
• The Web Application Security Consortium
 http://projects.webappsec.org/
• Web-Hacking-Incident-Database
 http://projects.webappsec.org/WebHacking-Incident-Database
 http://www.xiom.com/whid-about
• The IBM X-Force Trend and Risk Report
 http://www935.ibm.com/services/us/iss/xforce/tr
endreports/
40