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