|
||||
|
|
#1 (permalink) | |
|
Moderatore Globale ![]() ![]()
4,461 Messaggi
![]() ![]() ![]() ![]() |
PHP 5.x: Nozioni di sicurezza
Indice degli argomenti:
Un ringraziamento particolare per la stesura di questo articolo va a Matteo ( Bottomap ) Le argomentazioni relative agli aspetti sulla sicurezza riguardanti lo sviluppo di applicazioni, rappresentano oggi una delle tante problematiche da valutare bene durante la progettazione e lo sviluppo di applicazioni orientate al web, per il semplice motivo che soluzioni del genere residenti su web server e dunque teoricamente accessibili a chiunque, sarebbero maggiormente piu' esposte a vari tipi di attacchi rispetto alle tradizionali applicazioni desktop, disponibili esclusivamente su determinati terminali client a deteminati “utenti” e dunque una percentuale di rischi sulla sicurezza minore, almeno teoricamente. Sebbene la completa e perfetta “sicurezza” nell'ambito dei sistemi informatici e' pura utopia, esistono diverse tecniche e soluzioni specifiche per prevenire possibili attacchi e ridurre in questo caso, rischi e danni verso le nostre applicazioni web. PHP rientra attualmente tra i linguaggi di programmazione web, piu' diffusi, seguiti e utilizzati al mondo, per lo sviluppo di siti dinamici e/o complete applicazioni web. Negli ultimi tempi, l'argomento relativo alla sicurezza, ha suscitato un enorme interesse tra i vari programmatori che utilizzano questo linguaggio, difatti, esempi negativi come le innumerevoli falle di sicurezza su sistemi Open Source, come il noto forum di discussione phpBB 2.x e nuove tecniche di cracking, come: XSS ( Cross Site Scripting ) per il defacing di siti web; SQL Injection ( Iniezioni sulle SQL ) per alterare i risultati o manipolare informazioni residenti su Database; Bot Automatici per la compilazione e l' invio di moduli web per la generazione di messaggi SPAM; E tante altre tecniche, hanno incentivato tanti programmatori sparsi in tutto il mondo, a diffondere tantissimi articoli, testi completi, documentazioni ufficiali e anche creazione di comunita' specifiche sulla sicurezza in PHP, all'organizzazione di convegni e a tanto altro ancora per evidenziare l'importanza di questo argomento, purtroppo ancora oggi, sottovalutato e spesso ignorato dai neofiti del settore. L' articolo che segue, nasce dalla volonta' di master85 e bottomap nel fornire un documento italiano abbastanza completo riguardo gli aspetti della sicurezza nel campo dello sviluppo web PHP, che possa approfondire alcuni tra gli argomenti piu' importanti riguardanti la sicurezza di applicazioni web sviluppate in PHP, si discutera' in modo particolare sul linguaggio di programmazione, senza considerare le configurazioni dei web server, permessi sul filesystem e specifici sistemi operativi. Nel corso dell'articolo verranno forniti inoltre una serie di riferimenti a siti o documenti esterni, sullo stesso argomento, da prendere seriamente in considerazione. Nello specifico andremo a soffermarci sui seguenti argomenti: register globals, magic quotes, filesystem, database e SQL injection, error reporting, prevenire lo SPAM, difenderci dal Cross Site Scripting ( XSS ) e la codifica dei Dati. Register Globals La direttiva “register globals” fa parte dell'insieme dei tanti parametri di configurazione del linguaggio ( file di configurazione php.ini ) che nelle ulime versione del PHP, dalla 4.2.0 in poi, viene impostato a OFF. Precedentemente impostato a ON, consentiva la registrazione di tutte le variabili EGPCS ( Environment, GET, POST, COOKIE, SERVER ) a livello globale all'interno del codice. Cio' consentiva allo sviluppatore di scrivere codice piu' velocemente ma allo stesso tempo poco sicuro, sebbene fosse piu' facile considerare qualsiasi variabile come variabile globale e quindi evitare di specificare la fonte, sia essa GET, POST o altra, allo stesso tempo, lo script appena scritto poteva essere soggetto ad attacchi di Injection delle stesse variabili e quindi scavalcare in tutta facilita' numerosi controlli di “sicurezza” e/o immettere dati falsati, per esempio sostituire tutte le variabili POST inviate da una form, con una serie di variabili GET impostate direttamente nella URL come querystring. Di seguito viene proposto un esempio concreto della direttiva “register globals”: Codice PHP:
Questo e' semplicemente uno dei tanti scenari in cui potremo trovarci, e' da ricordare che la direttiva “register globals” non e' configurabile a runtime, dovremo quindi chiedere informazioni a riguardo al nostro provider, oppure ricorrere alla funzione ini_get('register_globals') per controllare se la direttiva e' attiva o meno. Inoltre, e' consigliabile sempre inizializzare qualsiasi variabile utilizzata all'interno del nostro codice e ricorrere alle variabili predefinite messe a disposizione dal PHP per recuperare i vari tipi di dati inviati tramite GET, POST, SESSION o COOKIE, ad esempio: $_GET['nome_variabile'] per recuperare i dati inviati tramite querystring da URL oppure $_POST per il recupero dei dati inviati tramite FORM e cosi' via. A questo indirizzo http://www.php.net/manual/en/languag...predefined.php e' possibile consultare la documentazione ufficiale PHP sull'utilizzo delle variabili predefinite. Magic Quotes Le “Magic Quotes” rappresentano un processo automatico offerto da PHP, in grado di aggiungere i caratteri di "escapes" ( backslashes "\" ) a tutti i dati provenienti dall'esterno verso script PHP. Come la documentazione ufficiale sul PHP suggerisce, e' preferibile lavorare e quindi scrivere del codice con la direttiva "magic_quotes_gpc" ad off e quando necessario ricorrere alla direttiva "magic_quotes_runtime". La scelta sull'utilizzo di una direttiva o l'altra e' obbligata dal provider che offre il servizio di Hosting oppure, dal file di configurazione php.ini, qualora fossimo noi stessi gli amministratori del web server. Quando si fa riferimento all'argomento "Magic Quotes" e' bene tenere presente le tre direttive principali che lo compongono e quindi distinguere: magic_quotes_gpc - La direttiva, come l'abbrevizione indica "_gpc" ha effetto su tutti i dati di tipo GET, POST e COOKIE, non puo' essere impostata a runtime e nelle ultime versioni del PHP e' settata al valore "on" come default. Quando questa direttiva e' abilitata tutti i singoli apici ( ' - Single Quote ), doppi apici ( " - Double Quote ), \ ( Backslash ) ed i caratteri Nulli vengono anteceduti dal carettere \ ( Backslash ) di conseguenza la frase - l'albero e' verde - viene trasformata in - l\'albero e\' verde. Per capire se la direttiva magic_quotes_gpg sia abilitata o meno sul server, e' necessario ricorrere alla funzione get_magic_quotes_gpc(), ritornera' 0 in caso sia disattivata o 1 in caso contrario. E' bene ricordare che la direttiva magic_quotes_gpc non puo' essere impostata a runtime; magic_quotes_runtime - Se questa direttiva viene abilitata, la maggior parte dei dati restituiti da funzioni che elaborano fonti di dati esterni, come file di testo o database, dati GET, POST o COOKIE, presentaranno tutti i caratteri come singoli apici, doppi apici, backslash oppure caratteri nulli, anteceduti da un \ ( backslash ). La direttiva in questione e' impostata di default ad off e puo' essere settata a runtime mediante la funzione set_magic_quotes_runtime(valore) dove valore e' un valore numerico compreso tra 0 e 1, rispettivamente disabilitano e abilitano la direttiva. Invece, per controllare lo stato attuale della direttiva direttamente da codice, si ricorre alla funzione get_magic_quotes_runtime() che ritornera' 1 in caso sia attiva e 0 in caso contrario; magic_quotes_sybase - Quest'ultima direttiva, se attiva, sovrascrive completamente la precedente magic_quotes_gpc e tutti i singoli apici ( ' ) verranno anteceduti da un ulteriore singolo apice ed inoltre tutti gli altri caratteri come doppi apici, backslash e valori nulli resteranno inalterati. I motivi che spingono gli sviluppatori PHP ad usufruire delle direttive Magic Quotes sono principalmente due: Convenienza e Utilita' - utile durante la creazione di SQL e dunque l'inserimento di dati nel database, evita di ricorrere all'utilizzo della funzione addslashes() per prevenire errori di sintassi su dati che presentano caratteri speciali che necessitano di essere anteceduti da "backslash", come GET o POST ed inoltre, riduce i rischi di eventuali attacchi di tipo "Iniezioni SQL" ( SQL Injection ) dovute a dimenticanze da parte di programmatori poco esperti nel campo. Per quanto le Magic Quotes possano risultare veramente utili, ci sono dei casi da tenere bene in considerazione durante lo sviluppo di soluzioni Open Source oppure in previsione di inaspettati cambi di configurazione del web server e dunque, parliamo dell'argomento Portabilita': E' bene ricorrere alla funzione get_magic_quotes_gpc() per ricavare l'attuale stato della direttiva, qualora fosse disabilitata e ricorrere successivamente alla funzione set_magic_quotes_runtime() per attivarla a runtime, ovviamente se ce ne fosse bisogno. Un altro caso e' relativo alle Prestazioni del server, sebbene non tutti i dati gestiti da Script PHP e inseriti in eventuali SQL necessitano del processo delle Magic Quotes, e' bene ricorrere alla funzione addslashes() sui singoli dati, per avere maggiore efficienza, anziche' ricorrere alla soluzione globale su tutti i dati. Un ultimo caso sarebbe quello della Incovenienza, poiche' non tutti i dati necessitano del trattamento delle Magic Quotes, risulterebbe noioso ritrovarsi risultati inaspettati, ad esempio invio di email o il salvataggio delle informazioni su file di testo con parole o frasi contenenti il carattere inaspettato "\". Spesso l'utilizzo o meno delle direttive e' dettato da un preciso bisogno, prima di procedere a scrivere del codice e' bene accertarci del risultato che ci attendiamo, senza *imbarcarci* in problemi che effettivamente non esistono. Prima di proseguire verso il paragrafo successivo, proporremo alcuni esempi pratici sulle Magic Quotes, come attivarle a sistema oppure scrivere del codice PHP portabile indipendente dalle configurazioni del web server: 1. Esempio della sezione Magic Quotes del file di configurazione di PHP: codice:
; Magic quotes ; ; Magic quotes for incoming GET/POST/Cookie data. magic_quotes_gpc = Off ; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc. magic_quotes_runtime = Off ; Use Sybase-style magic quotes (escape ' with '' instead of \'). magic_quotes_sybase = Off codice:
php_flag magic_quotes_gpc off File: no_magic_quotes_gpc.php Codice PHP:
no_magic_quotes_gpc.php?myString=L'albero e' verde Come risultato otterremo la stringa inalterata, senza i backslashes di troppo, aggiunti automaticamente dalla direttiva magic_quotes_gpc. Filesystem Come e' stato per i paragrafi precedenti, e' bene soffermarsi ora sugli argomenti relativi agli aspetti sulla sicurezza del Filesystem. Dal momento che i permessi in lettura e scrittura per gli script PHP sul Filesystem, sono dettati dallo stesso filesystem e quindi, PHP viene considerato come un vero e proprio utente del sistema, e' necessario assicurarsi di aver impostato le corrette regole di lettura e scrittura sui diversi file che potrebbero essere aperti e quindi letti se non addirittura scritti dagli script PHP e conseguentemente portare ad una corruzione delle informazioni presenti sul Server, ad esempio leggere file come “/etc/passwd”, appropriarsi di informazioni importanti oppure avviare diversi servizi. In questo paragrafo verranno proposti esempi concreti sui possibili attacchi al Filesystem e diverse soluzioni per evitare furti di informazioni. Il primo esempio che andremo a considerare e' il medesimo proposto nella documentazione ufficiale del PHP: “Eliminare un file presente in una directory Utente, specificato come dato POST”: Codice PHP:
Di seguito vedremo come prevenire questo tipo di attacco al Filesystem, eseguendo opportuni controlli sui dati immessi mediante esempi concreti. Questa volta cercheremo di ricreare uno scenario molto semplice per capire meglio il concetto sulla sicurezza dei files presenti nel sistema e/o nelle directory delle nostre applicazioni web, ma prima di visualizzare script di esempio preoccupiamoci di visualizzare la struttura delle directory della nostra applicazione o sito dinamico: /main /main/scripts/ /main/scripts/pubblico.txt /main/privato.txt La directory principale della nostra applicazione e' rappresentata da “/main” mentre nella sotto-directory “/main/scripts/” saranno presenti i vari scripts PHP che proporremo piu' avanti ed avranno il compito di leggere vari files di testo. Infine troviamo il file “/main/privato.txt” rappresentera' il file di sistema protetto a cui non vi si potra' accedere dagli script PHP residenti in “/main/scripts/” mentre, il file “/main/scripts/pubblico.txt” potra' essere letto e teoricamente scritto da chiunque. Per iniziare, proporremo lo script PHP base che fa uso delle funzioni per la gestione del Filesystem per la lettura del file pubblico: /main/scripts/pubblico.txt: File: leggi_pubblico.php Codice PHP:
File: leggi_pubblico_alterato.php Codice PHP:
File: leggi_pubblico_migliorato.php Codice PHP:
In questo paragrafo si e' introdotto l'argomento relativo ad alcune problematiche del filesystem, ma come queste, potrebbero presentarsene molte altre, e' necessario pensare a tutti i possibili attacchi e cosa piu' importante cercare di ridurre i rischi. Database e SQL Injection L'archiviazione e la gestione dei dati che vengono serviti giornalmente dai tanti servizi oggi accessibili su internet, come applicazioni o portali web avviene per la maggior parte dei casi attraverso database server ( DBMS ). Uno degli argomenti piu' importanti per chi sviluppa applicazioni web basate su Database consiste nell'evitare un' eventuale compromissione degli stessi dati situati nel database poiche', in molti casi si potrebbe trattare di dati sensibili. In questo paragrafo affronteremo gli aspetti legati ai possibili attacchi verso le nostre applicazioni e quindi, verranno illustrate varie tecniche per accedere e manipolare i dati sfruttando direttamente le falle dei nostri script; ed inoltre, studieremo le regole di base per una progettazione sicura dei nostri Database. Oggigiorno tanti sviluppatori ignorano l'importanza ed i rischi che possono presentare le Structured Query Language ( SQL ) presumendo che queste siano comandi fidati che non potrebbero mai essere alterati dall'esterno degli stessi script e cosa piu' importante causare danni ai dati salvati nel Database, ma tutto cio' non e' vero. La tecnica delle SQL Injection, rappresenta probabilmente l'argomento piu' importante riguardo la sicurezza e lo sviluppo di applicazioni basate sul web e non solo. Viene spesso utilizzata per alterare, visualizzare o compromettere informazioni salvate nei Database e cosa piu' pericolosa attaccare direttamente il sistema operativo del Server che ospita il DB, tutto questo tramite delle iniezioni dirette di porzioni di stringhe SQL nella query che verra' generata in modo dinamico dallo script per mezzo di variabili ottenute dall'esterno, come COOKIE, POST o GET ed infine eseguita. Piu' avanti, nell'articolo proporremo degli esempi che renderanno meglio l'idea della pericolosita' delle SQL Injection ed infine si spieghera' come prevenire questa tipologia di attacchi. Come convenzione negli esempi proposti utilizzeremo delle variabili dichiarate localmente all'interno del codice PHP che andranno a simulare le possibili variabili d'ambiente GPC ( GET, POST o COOKIE ) proposte allo script e partiremo dal presupposto di essere gia' connessi al Database. Analizzeremo la situazione di partenza di ciascun script per poi capire i possibili exploit da utilizzare per iniettare porzioni SQL e quindi alterare il risultato finale della query ed eventualmente i dati visualizzati sulla pagina. Introdotta la tecnica delle SQL Injection ed illustrata la convenzione che andremo ad utilizzare non resta che soffermarci sul database di prova che utilizzeremo nei nostri esempi. Prenderemo in considerazione una semplice struttura di Database per la gestione di Articoli e Utenti per un sito di informazione. 1° Esempio – Elenco degli articoli pubblicati per Utente Originale Codice PHP:
Exploit : Codice PHP:
Seguendo questo semplice e banale esempio e' facile immaginare quali potrebbero essere i tanti rischi associati a queste tecniche, oggi conosciute come SQL Injection. Si potrebbero bypassare controlli utente, alterare dati mantenuti in un database e tanto altro ancora, per non parlare di attacchi diretti al Database Server e all'intero Sistema Operativo Host. Prevenire questa tipologia di attacco e' possibile, nei paragrafi seguenti studieremo quali sono le applicazioni piu' a rischi e quali sono i metodi per proteggersi. Le applicazioni piu' a rischio Generalmente la domanda che ci si pone piu' spesso e' – Quali sono le applicazioni piu' a rischio alle SQL Injection ? - Solitamente la risposta va sempre a discapito delle soluzioni Open Source, tutto cio' purtroppo e' vero. Il motivo e' del tutto semplice, avere a disposizione il codice sorgente aperto, significa essere a conoscenza delle eventuali falle e dei possibili exploit a disposizione, e cosa piu' importante, e' nota anche la struttura del database. Per chi esegue un attacco di tipo SQL Injection avere a dispozione tutte queste importanti informazioni significa essere in grado di creare nuovi attacchi di diversi livelli di pericolosita', a seconda delle varie misure di sicurezza adottate all'interno dell'applicazione. Sebbene le soluzioni piu' a rischio siano quelle Open Source e' anche vero che, “grazie” ai continui attacchi e ai famosi strumenti per la ricezione e la segnalazione di eventuali Bugs, gli sviluppatori interessati al mantenimento del progetto ( e quindi dell'applicazione ) possono fornire in tempi brevi le versioni aggiornate, sprovviste di falle. Ne consegue quindi, un continuo miglioramento dell'applicazione stessa nel tempo. Spesso, nel mondo dell' Open Source, un'applicazione ben collaudata e priva di bugs viene considerata STABLE e quindi disponibile per tutti gli utilizzatori finali che vogliono la versione realmente stabile e sicura. Al contrario per indicare le versioni in fase di sviluppo per l'introduzione di migliorie e nuove caratteristiche, viene utilizzato il termine UNSTABLE, generalmente queste versioni sono disponibili per tutti gli utenti finali, sviluppatori o utenti maliziosi che intendono rispettivamente, testarne le nuove caratteristiche e verficarne le nuove migliorie introdotte, apprendere nuovi concetti e tecniche di programmazione, trovare exploit e potenziali falle SQL Injection. Come proteggersi dalle SQL Injection Come si e' notato negli esempi precedenti, i rischi maggiori legati alle SQL Injection provengono da dati esterni come iniziezioni di valori POST, GET o COOKIE. Le tecniche ed i consigli da seguire per prevenire possibili attacchi SQL Injection sono riassunti in questa lista:
Una progettazione sicura del Database Generalmente quando si crea un database, ad esso viene associato un utente proprietario, che il piu' delle volte e' lo stesso utente che ha eseguito il comando per la creazione del DB oppure sara' lo stesso Amministratore ( il cosidetto superuser ). Questi due utenti dispongono di permessi amministrativi riguardo la struttura del database, di conseguenza sono in grado di alterare la struttura stessa, aggiungendo nuovi campi, cancellandone altri oppure rimuovere completamente delle tabelle, in alternativa, crearne delle nuove. Per motivi di sicurezza quindi, e' bene non avviare mai connessioni verso il database specificando come username lo stesso creatore oppure il superuser, bensi' specificare un utente creato ad-hoc con permessi limitati e specifici ( solo lettura e scrittura di dati ) sul database, se non del tutto, sulle singole tabelle. Per rafforzare la sicurezza all'interno delle applicazioni, potrebbe essere utile creare piu' utenti con permessi differenti, in base alle necessita' richieste dalle diverse aree dell'applicazione stessa. In questo modo, ammettendo per assurdo che qualche maleintenzionato possa violare i sistemi di sicurezza e quindi rubare l'identita' per l'accesso all'applicazione, sara' in grado di operare esclusivamente con i permessi concessi all'utente del database precedentemente assegnato per quella determinata area dell'applicazione. Sebbene il sistema di sicurezza e' stato violato, e' anche vero che i danni sono limitati. Error Reporting La fase di debugging e di testing rappresentano i passaggi piu' importanti per quanto concerne la sicurezza delle applicazioni web. E' necessario soffermarsi e dedicare molto tempo durante queste fasi per garantire almeno, al primo momento, la sicurezza “massima” dell'applicazione al rilascio della prima versione. Ma ovviamente non possiamo certo garantirne la sicurezza assoluta, exploits o bugs di varia natura potrebbero sorgere in qualsiasi momento. Prevenire eventuali bugs o malfunzionamenti e' possibile farlo tramite le funzioni PHP, dedite al report degli errori ( error_reporting() ). Le tecniche di “error reporting” rappresentano un utile strumento durante le fasi di “test” e di “debug” dei nostri scripts, in qualsiasi momento potremo essere a conoscenza di eventali malfunzionamenti del codice. Comunque, nella fase di “produzione” e quindi, al rilascio di eventuali versioni stabili destinate agli utenti finali e quindi, potenzialmente esposte a vari tipi di attacco, e' sempre una buona norma disabilitare ogni tipo di “error reporting”, sia esso gestito da PHP che da sistemi sviluppati “ad-hoc” all'interno del codice. Un utente malizioso, in cerca di utili informazioni sul funzionamento di determinati scripts, potrebbe facilmente repererile dai messaggi di errore generati da PHP. Nomi di variabili, informazioni sulla struttura di Database ed altro ancora sono tutte informazioni che non devono essere rese pubbliche, in nessuna circostanza nella fase di “produzione”. Il PHP, come spiegato in precedenza, fornisce utili strumenti per il report degli errori e logging, la funzione “error_reporting()” ( PHP: error_reporting - Manual ) ad esempio, in base a determinate impostazioni definite a runtime dallo stesso utente oppure dal file di configurazione PHP.INI, abilitera' o disabilitera' la visualizzazione di vari tipi di messaggi di errore in caso si verificasse un malfunzionamento nel codice, di qualsiasi genere. E' utile sapere che e' consentito impostare anche il tipo di messaggi di errore da visualizzare, che vengono suddivisi in categorie ben precise. Di seguito verra' proposto un semplice codice di esempio sul funzionamento dell'error reporting e una tabella riepilogativa dei vari messaggi di errori attivabili: Codice PHP:
Quote:
Prevenire attacchi SPAM Un'ulteriore e significativa problematica da considerare nello sviluppo di applicazioni web, portali o piccoli script che prevedono moduli pubblici, liberi di essere compilati ed inviati da chiunque – vedesi moduli web per i contatti, guestbook, commenti ed altro ancora - consiste nell'accertarsi della validita' delle informazioni inviate dall' “utente”. Come possiamo accertarci che i dati inviati soddisfano a pieno i requisiti richiesti dalla nostra applicazione, quindi che siano stati inviati da una reale persona fisica e non siano semplicemente dati falsati generati da sistemi automatici ( bot ) per produrre dello Spam e/o Compromissione dei dati da gestire ? In questo paragrafo verra' illustrata una delle migliori tecniche per prevenire questo genere di attacchi mediante una specifica Classe PHP 5, denominata “Check Spam” che provvedera' a gestire la creazione del codice di sicurezza CAPTCHA e il successivo controllo. Per chi non fosse a conoscenza del significato del termine CAPTCHA ( acronimo di: “completely automated public Turing test to tell computers and humans apart” ) e' bene soffermarsi sull'argomento. Come viene suggerito dall'acronimo stesso, CAPTCHA indica un test di Turing pubblico e completamente automatizzato per distinguere Umani da Computer ( nel nostro caso, i bot ). Generalmente si puo' ricorrere al CAPTCHA tramite diverse soluzioni, ad esempio: domande a risposta multipla, quesiti matematici oppure codici di sicurezza poco leggibili dall'occhio umano. Tramite queste tecniche potremo facilmente accertarci che l'utilizzatore del nostro “sistema” e' un umano e non un altro computer. Nel nostro esempio, come accennato precedentemente sfrutteremo l'ultima tecnica, ovvero la generazione di un codice di sicurezza poco leggibile dall'occhio umano e difficilmente comprensibile da sistemi OCR ( Optical Character Recognition ). Poiche' generare un codice di sicurezza non significa affatto che non sara' riconosciuto da sistemi automatici, quindi e' bene utilizzare sistemi CAPTCHA ben collaudati, stabili e sicuri come “Check Spam” ( PHP Classes - Class: Check spam ) che allo stato attuale risulta essere la migliore soluzione “anti-spam” disponibile su PHPClasses.org per la categoria PHP 5 e inoltre viene rilasciata sotto GPL ( General Public License ), per il corretto funzionamento di questa classe e' richiesta la libreria grafica GD con il supporto PNG. Nei vari esempi che proporremo verra' considerato lo scenario di un semplice script “Guestbook” ( un tradizionale libro degli ospiti ) che fa uso di un file di testo per la memorizzazione dei vari commenti lasciati da vari utenti. Lo script verra' realizzato in diversi passaggi, inizieremo a scrivere e commentare le versioni di script generalmente piu' comuni e piu' veloci da sviluppare e sicuramente meno sicuri, per terminare con una versione stabile, sicura e priva di eventuali exploit per capire a fondo le diverse procedure da seguire per sviluppare moduli web in tutta sicurezza. La prima fase di sviluppo del nostro modulo Guestbook prevede una serie di controlli per validare i dati inviati ed il modulo HTML da complilare. Il codice e' commentato e non necessita' di ulteriori note aggiuntive: File: gb_form.php ( codice completo ) Codice PHP:
Una delle tecniche piu' utilizzate dai vari “spammers automatici” consiste nell'utilizzo di librerie e/o funzioni specifiche per la connessione e la comunicazione verso diversi server e diversi protocolli, ad esempio HTTP, come nel nostro caso. Nel prossimo esempio studieremo uno script PHP che facendo uso della libreria cURL ( Client URL: PHP: CURL, Client URL Library Functions - Manual ) consente di avviare questo genere di attacchi. E' opportuno considerare che queste librerie vengono utilizzate anche per scopi “benevoli” nella programmazione, e non certo per generare esclusivamente attacchi e deturpare sistemi informatici. Lo script che segue e' abbastanza semplice da studiare, nelle prime righe di codice verra' inizializzata la connessione per l'host remoto ( curl_init() ) nelle righe successive verranno impostate diverse opzioni per avviare una comunicazione di tipo HTTP POST e specificando quali dati inviare, ed infine eseguiremo realmente la comunicazione ( per 3 volte ): File: gb_curl_attack.php Codice PHP:
Le tecniche per prevenire questo genere di attacchi, sono molteplici e variano a seconda della situazione in cui ci troviamo, ad esempio, si potrebbe ricorrere all'uso delle Sessioni, in questo caso, introducendo un opportuno controllo su una determinata sessione settata, possiamo facilmente dedurre se il modulo e' stato complilato da un “utente umano” o da un “sistema automatico”, ma tutto questo non sara' oggetto di studio in questo tutorial. Miglioriamo invece, il modulo web, con un controllo di tipo CAPTCHA introducendo l'uso della classe “Check Spam”. Una volta che abbiamo scaricato il pacchetto completo della classe menzionata sara' sufficiente copiare e incollare tutta la directory “checkspam_x.y” ( x e y indicano il numero della versione ) all'interno della directory radice del nostro script, seguire le semplici istruzioni sul funzionamento e aggiornare lo script del modulo web. Di seguito viene mostrato il codice PHP dello script “gb_form.php” aggiornato e reso piu' sicuro tramite l'introduzione del controllo CAPTCHA: File: gb_form.php ( aggiornato per il controllo CAPTCHA Check Spam ) Codice PHP:
Difenderci dal Cross Site Scripting ( XSS ) Il Cross-site scripting ( abbreviato in XSS o CSS ) e' un genere di falla riscontrabile in tutte quelle applicazioni web che permettono il code-injection (iniezione di codice) nelle pagine visualizzate da altri utenti. Il codice iniettato si compone generalmente di HTML e script client-side Javascript. Una falla che permette il cross-site scripting puo' essere usata da utenti malintenzionati per bypassare controlli d'accesso ed ottenere dati sensibili. Recentemente, vulnerabilita' di questo tipo sono state usate per creare pagine dedicate al phishing ed exploit verso determinati browser. Quando Netscape introdusse il linguaggio Javascript nel suo browser, furono chiari i rischi insiti nel permettere ad un server web di inviare codice eseguibile al browser. Il problema principale si presentava quando l'utente aveva piu' di una finestra del browser aperta. In alcuni casi, uno script proveniente da una pagina poteva avere accesso ai dati presenti in un'altra pagina o oggetto. Questo comportamento doveva essere bloccato, visto che un utente malintenzionato potrebbe in questo modo cercare di carpire informazioni sensibili. Per poter aggirare il problema, i browser introdussero la cosiddetta "same origin policy" (politica della stessa origine). Questo accorgimento permette le interazioni esclusivamente tra pagine originate dallo stesso dominio, sullo stesso protocollo e sulla stessa porta. In questo modo, un sito web malevolo non avrebbe avuto accesso a dati presenti in un'altra finestra attraverso Javascript. Da allora sono state introdotte numerose altre politiche di controllo da parte dei browser e dei linguaggi di scripting per proteggersi da questo genere di problematiche. Parlando in generale, una falla che permette il cross site scripting e' essenzialmente una vulnerabilita' presente in una pagina web che permette di aggirare i normali meccanismi di controllo. Trovando sistemi astuti per iniettare script malevoli nelle pagine servite da un certo dominio, un malintenzionato puo' ottenere diritti d'accesso elevati a pagine contenenti dati sensibili, cookie di sessione ed una larga varieta' di oggetti teoricamente protetti. Suddivideremo le falle di XSS in tre tipi distinti, che chiameremo per comodita' tipo 0,1 e 2. Le falle che piu' da vicino riguardano PHP sono quelle di tipo 1 e 2. In tutti i casi si tratta di pagine generate in maniera incauta, in cui gli input provenienti dall'esterno non vengono accuratamente vagliati e filtrati. Porre una certa attenzione nel parsing dei parametri che arrivano in GET e POST previene la maggior parte dei problemi e rende il sito abbastanza sicuro (di totalmente sicuro non esiste nulla) con poco lavoro. In particolare e' necessario prestare grande attenzione alla validazione di input provenienti dagli utenti che poi verrano usati nelle pagine (o nelle mail) generate. Tipo 0 Questa forma di XSS viene chiamata anche DOM-based o locale. Nella falla di tipo 0, il problema risiede nella parte di script client-side della pagina stessa. Per esempio, se un pezzo di codice Javascript accede ad i parametri GET ed usa queste informazioni per scrivere qualcosa sulla pagina (e questa informazione non e' filtrata in alcun modo), ci troviamo davanti ad una grave falla. L'informazione verra' stampata direttamente nella pagina come codice HTML, che potrebbe contenere script aggiuntivi se la richiesta viene malformata. Sfruttare questa falla e' molto simile allo sfruttare le falle di Tipo 1 (vedi sotto), eccetto che per una situazione importante. Per il modo in cui Internet Explorer tratta gli script client-side nelle pagine locali (ad esempio sull'hard disk di un client), una falla XSS di questo tipo si puo' risolvere nell'esecuzione remota di codice sulla macchina dell'utente. Se un sito malevolo, ad esempio, contiene un link verso una pagina vulnerabile che, in qualche modo, e' stata installata sul sistema locale di un client, puo' iniettare in essa uno script che girerebbe con i privilegi della macchina in cui viene scaricato. Questo aggira completamente ogni tipo di controllo client-side anche lato browser, non solamente le restrizioni cross-domain che vengono normalmente aggirate da altre tecniche XSS. Il fatto che la pagina debba essere installata localmente nel computer vittima, rende la falla di tipo 0 meno pericolosa delle altre, visto che e' necessario indurre in qualche modo la vittima ad effettuare questa operazione. Tipo 1 Questo tipo di falla viene detta anche Non-persistente o Riflessiva, ed e' il tipo piu' comune di falla XSS. Questo tipo di falla si presenta quando i dati provenienti da un client web vengono usati da script server-side per generare una pagina per l'utente (e' il caso di PHP se i dati provenienti in GET o POST non vengono controllati). Se i dati provenienti dal client vengono utilizzati nella pagina risultante senza controlli, sara' possibile iniettare uno script nella pagina generata dal server. Un esempio classico si puo' trovare nelle pagine di ricerca: Spesso la stringa viene replicata nella pagina risultato per sottolineare cosa si sta cercando, o comunque i termini di ricerca saranno inclusi nuovamente in una text box per permettere l'editing. Se si ricerca una stringa che contiene caratteri speciali HTML e le occorrenze dei termini di ricerca non vengono accuratamente filtrate (con htmlentities ad esempio) ne risultera' una falla XSS di Tipo 1. Qualsiasi utente potra' iniettare codice e vederselo eseguire nella pagina risultante. Questo potrebbe non sembrare un problema serio, visto che gli utenti sono in grado di iniettare codice solo nelle loro pagine. Con un po' di social engineering comunque, un utente malintenzionato potrebbe convincere la vittima a seguire un link malevolo che inserisce codice nella sua pagina risultato, dando nel frattempo al malintenzionato il pieno accesso ai dati contenuti nella pagina. Visto che e' necessario del social engineering, molti programmatori non ritengono importante questa falla e spesso non provvedono ad arginarla. Questa mancanza viene applicata spesso alle falle XSS in generale e spesso si risolve in una corsa ai ripari quando il danno avviene (e presto o tardi in genere succedera'). Tipo 2 Questo tipo di falla XSS viene chiamata anche Persistente o di Secondo Grado, e permette la forma peggiore di attacco. Una falla di tipo 2 esiste quando i dati inviati al server vengono salvati in qualche forma ( in un database, nel filesystem del server o in altra locazione ), e quindi mostrati in una pagina web senza essere filtrati. Un esempio classico sono i forum e le bacheche elettroniche, in cui i post degli utenti vengono salvati generalmente in un DB e possono essere riletti da un gran numero di altre persone. Queste falle sono molto piu' pericolose perché il malintenzionato deve iniettare il codice una sola volta. Cio' che inietta ha la capacita' di colpire un gran numero di utenti senza necessita' di social engineering. In casi estremi, l'intero server puo' diventare un veicolo per un cosiddetto virus XSS ( un tipo di virus che sfrutta le falle XSS per diffondersi ). I metodi di iniezione variano enormemente, ed il malintenzionato puo' non aver nemmeno bisogno di accedere alla web application per sfruttarne la falla. Qualsiasi dato ricevuto dal server che puo' essere controllato da un utente malevolo, andra' accuratamente filtrato prima di essere mostrato in una pagina dinamica, altrimenti puo' nascere una falla di questo tipo. In tutti e tre i casi, come detto, la falla si presenta quando nel creare una pagina non si effettua un filtro dei dati provenienti dall'esterno, almeno su quegli elementi che verranno usati per scrivere direttamente sulla pagina risultante. Osserviamo adesso un breve esempio di codice PHP che non pone l'attenzione verso XSS e puo' risultare soggetto ad attacchi: Esempio Il codice seguente e' soggetto a falle di tipo 0 ed 1. Immaginate di accedere via browser a hello.php?username=PIPPO<SCRIPT>alert('vulnerabile ');</SCRIPT> Passano al browser la stringa in questione dovrebbe far apparire una finestra con la scritta "vulnerabile". L'esempio e' banale, ma uno script costruito attentamente puo' provocare diversi problemi. Codice PHP:
Codice PHP:
Attenzione a non dare per scontato il fatto che la stringa contenente codice HTML sia sempre facilmente visibile (<SCRIPT>). Lo stesso identico url piu' sopra puo' essere codificato facilmente in un piu' sibillino: codice:
hello.php?username=PIPPO%3C%53%43%52%49%50%54%3E%61%6C%65%72%74%28%27%76%75%6C%6E%65%72%61%62%69%6C%65%27%29%3B%3C%2F%53%43%52%49%50%54%3E Di seguito illustriamo alcuni semplici scenari di attacco dei tre tipi menzionati. Sono situazioni tipiche avvenute spesso e volentieri, a volte anche a siti insospettabilmente prestigiosi. Utilizziamo dei nomi fittizi (inventati di sana pianta - ogni riferimento a fatti e persone esistenti e' pura fantasia) per meglio identificare le parti in causa. In tutti gli scenari, Matteo sara' il malintenzionato, Mirko sara' l'utente ignaro del pericolo e Giuseppe il proprietario di un sito che contiene una falla XSS Attacco di tipo 0:
Attacco di tipo 1
Attacco di tipo 2
In conclusione, uno sviluppatore attento alla sicurezza provvedera' a controllare tutti i possibili punti d'accesso ( in sostanza i parametri GET e POST ) al suo sito e filtrera' in maniera accurata tutto il testo che puo' provenire dagli utenti. Un modo veloce per verificare se esista una falla puo' essere quello di utilizzare il codice <SCRIPT>alert('falla')</SCRIPT> che ho proposto piu' sopra inserendolo un po'dovunque sia possibile (campi delle form, parametri in entrata sull'url). La comparsa di un messaggio a video implica la presenza di una falla XSS. NB: I browser piu' recenti sono dotati di sistemi che impediscono l'XSS (almeno fino ad un certo livello). Se si vuole testare la vulnerabilita' sara' necessario disabilitare temporaneamente tali sistemi (voi magari avete IE7 o l'estensione NoSCript per Mozilla, ma non e' detto che il sito non lo visiti un utente dotato di IE4). Conclusioni Nel tutorial appena letto si sono apprese diverse nozioni di sicurezza sullo sviluppo di applicazioni web, scritte in PHP. Rimane da aggiungere che attualmente, il PHP rientra tra i linguaggi di scripting lato server piu' potenti e versatili, una nota importante da tenere in considerazione e' ignorare i commenti negativi che spesso si leggono e sentiamo ripetere riguardo la poca sicurezza della applicazioni scritte in PHP, specialmente le soluzioni Open Source poiche' la “sicurezza” dell'applicazione non e' data dal linguaggio di programmazione utilizzato bensi' dai canoni di sicurezza adottati dagli sviluppatori di software. PHP mette a disposizione dello sviluppatore diverse tecniche per garantire la sicurezza, in questo tutorial ne abbiamo considerate alcune ma e' bene approfondire l'argomento e tenersi sempre aggiornati su quest'ultimo e cosa piu' importante, se sfruttiamo soluzioni Open Source per i nostri lavori, accertiamoci di aggiornarli ogni volta che si propone una versione aggiornata stabile e priva di exploits o bugs. Per concludere, oltre ai vari riferimenti proposti durante il tutorial, cerchero' di riassumere le diverse risorse sulla sicurezza, sparse per la grande rete: PHP: Security - Manual Main Page - SecurePHP PHP Security Consortium Essential PHP Security by Chris Shiflett the Month of PHP Bugs PHP Security Mistakes Buona programmazione !
__________________
- Il mio Blog ;- Leggi il Regolamento Ufficiale della comunità (Come porre le domande in modo intelligente); - Se le risposte di un utente ti hanno aiutato, usa il pulsante Commenta Intervento e accresci la sua reputazione; - Riguardo GNU/Linux e Free Software; Entra nel gruppo GNU/Linux; - PHP 5: Previeni gli attacchi SPAM verso le tue applicazioni web, Check spam.
Ultima modifica di Master85 : 14-09-2007 a 16:33. |
|
|
|
|
![]() |
«
Recensione: "PHP 5 & MySQL - La Guida"
|
PHP 5.x: Panoramica sulla programmazione orientata agli oggetti
»
| Strumenti della discussione | |
| Modalità di visualizzazione | |
|
|
Tutti gli orari sono GMT +1. Attualmente sono le 06:36.






;


Modalità lineare

