Messa in sicurezza di PHP: step-by-step
by Valentino R.
Ultimo Aggiornamento 18 Settembre 2003


1. Introduzione

Nel precedente articolo ("Messa in sicurezza di Apache: Step-by-Step") ho descitto il metodo per mettere in sicurezza il Web Server Apache contro gli accessi non autorizzati da internet. Grazie a quanto descritto è possibile raggiungere un discreto liverllo di sicurezza, ma solo sull'elaborazione di pagine HTML. Ma come si può migliorare la sicurezza quando l'interazione con l'utente è necessaria ed i dati degli utenti devono essere conservati in una database locale?
Questo articolo mostra i punti di base nell'installazione di PHP, una linguaggi script più popolari e usati per generare le pagine dinamiche su un web-server. Per evitare di ripetere le informazioni descritte nell'articolo precedente, verranno descritte soltanto le differenze relative al processo di installazione di Apache.

1.1 Sistema Operativo


Come ne precedente articolo, il sistema operativo dove viene installato è Slackware 9.0. Tuttavia, i metodi presentati dovrebbero anche applicarsi sulla maggior parte dei sistemi UNIX moderni e UNIX-Like. Questo articolo presume che il database server MySQL è presente all'interno dell'host, ed in precisamente nella directory "/usr/local/mysql".

1.2 Funzionalià


In generale, le funzionalità saranno molto simile a quella descritta nell'articolo precedente. Tuttavia, ci sono alcuni cambiamenti:
  • Il web server deve poter elaborare il linguaggio script PHP
  • PHP deve essere in grado di riuscire a leggere e a scrivere da un database MySQL, installato localmente

1.3 Presupposti di sicurezza


Nel caso di presupposti di sicurezza, si dovranno seguire le seguenti regole:
  • La configurazione di PHP dovrebbe approfittare dei meccanismi incorporati di sicurezza;
  • Gli script PHP dovranno essere eseguiti in un ambiente chrooted;
  • L' Apache server dovrà rifiutare tutte le richieste (GET e POST), che contengano tags HTML (del tipo Cross-Site-Scripting attack) oppure caratteri apostrofi/quotati (possibile attacco SQL Injection);
  • Nessun messaggio di avvertimento o di errore di PHP dovrà essere visualizzato ai visitatori dell'applicazione web;
  • Dovrebbe essere possibile archiviare le richieste tipo GET e POST all'interno di un file di testo che permetterà di usare un sistema di host-based intruder detection system (HIDS), e.s. swatch.

1.4 Preparare il Software


In primo luogo, dobbiamo scaricare l'ultima versione del codice sorgente di Apache, di PHP e del modulo mod_security. Il modulo sarà utilizzato per effettuare la protezione contro attacchi tipo iniezione di codice SQL e di CSS. Dopo aver scaricato il software ed effettuato il trasferimento dei dati e scompattato il contenuto degli archivi, deve essere disposto nella home directory. Il codice sorgente di mod_security dovrebbe essere copiato all'interno della directory di apache, nella sottodirectory "./src/modules/extra":

gzip -dc apache_1.3.28.tar.gz | tar xvf -
gzip -dc php-4.3.3.tar.gz | tar xvf -
gzip -dc mod_security-1.7RC1.tar.gz | tar xvf -
cp mod_security_1.7RC1/apache1/mod_security.c apache_1.3.28/src/modules/extra/


Se sono disponibili eventuali patch di sicurezza, queste dovranno essere scaricate ed applicate.
Prima di cominciare a compilare il software, dobbiamo anche decidere quale metodo di installazione di PHP dobbiamo utilizzare:
  • come modulo statico del web server
  • come modulo dinamico del web server
  • come interprete CGI

Ciascuno di suddetti metodi presenta i relativi vantaggi e svantaggi. Compilare PHP come modulo statico, significa che beneficerà delle prestazioni il web-server, ma nel caso in cui si vuole aggiornare PHP, bisogna ricompilare tutto il web-server. La secondia opzione, compilarlo in modo dinamico, non ha quest'ultimo svantaggio, ma nello stesso tempo il web-server ne risente come prestazioni, circa del 5%. Il terzo metodo è quello di installare PHP come interprete CGI - insieme al meccanismo suEXEC di Apache - è una soluzione interessante. Sfortunatamente, se non installato opportunamente, potrebbe essere una seria minaccia alla sicurezza.
Come si è visto nel punto precendente, la scelta migliore è quella di compilare PHP come modulo statico. Quindi, si procederà per l'installazione di PHP col metodo statico.

2 Installazione di PHP


Generalmente, il processo di installazione di Apache con PHP è veramente molto simile al processo di installazione di Apache senza PHP, come già descritto nell'articolo precedente. L'unica differenza è l'uso dei moduli addizionali: mod_php e mod_security.
Come nell'articolo precedente, si inizia creando l'account ed il gruppo "apache". Per preparare Apache web server fai quanto segue:

cd apache_1.3.28
./configure


... e compila il modulo PHP:

cd ../php-4.3.3
./configure --with-mysql=/usr/local/mysql --with-apache=../apache_1.3.28 --enable-safe-mode
make
su
make install


Succesivamente, ci si sposta nella directory del codice sorgente di Apache e csi continua l'installazione:

cd ../apache_1.3.28
./configure --prefix=/usr/local/apache --disable-module=all --server-uid=apache --server-gid=apache --enable-module=access --enable-module=log_config --enable-module=dir --enable-module=mime --enable-module=auth --activate-module=src/modules/extra/mod_security --enable-module=security --activate-module=src/modules/php4/libphp4.a
make
su
make install
chown -R root:sys /usr/local/apache


Con l'esecuzione del comando "./configure", verranno installati soltanto i moduli necessari a garantire la sicurezza. La scelta dei moduli è già stata discussa in dettaglio nell'artico precedente. Ora il prossimo passaggio è quello di entrare nella directory del codice sorgente di PHP e di copiare il file di configurazione di PHP:

cd ../php-4.3.3
mkdir /usr/local/lib
chmod 755 /usr/local/lib
cp php.ini-recommended /usr/local/lib/php.ini
chown root:sys /usr/local/lib/php.ini
chmod 644 /usr/local/lib/php.ini


Per far si che il nostro web server visualizzi correttamente le nostre pagine dinamiche create con PHP, è necessario inserire all'interno del file /usr/local/apache/conf/httpd.conf la seguente riga:

AddType application/x-httpd-php .php


A questo punto è possibile avviare Apache e controllare se PHP riesce anche a comunicare con MySQL. Per far ciò, basta creare un file denominato "test.php" all'interno della directory dove sono presenti tutte le pagine che Apache elabora. All'interno di questo file inserite il codice ch'è riportato all'interno della box succesiva. Sostituire i valori "user_name" e "password" con quelli del vostro database server.:
<html><body>
<?php
    $link = mysql_connect("localhost", "user_name", "password")
      or die;
    print "Everything works OK!";
    mysql_close($link);
?>
</body></html>


Il file test.php, è possibilie visualizzarlo tramite un semplice browser web. Se tutte le istruzioni sono state eseguite correttamente e la connessione al database MySQL è stabilita correttamente, possiamo iniziare a mettere in sicurezza il nostro software. Altrimenti, se qualcosa è andata storta, è pozzibilie analizzare i relativi file di log di Apache e di MySQL, e procedere nell'eliminazione delle cause.

3 Chrooting del server


Il primo passo della sicurezza del server è di preparare l'ambiente chroot per il server Apache con il modulo PHP.
A questo punto, devi effettuare tutti i passi descritti nella sezione "Chrooting del server" dell'articolo precedente. In più, per avviare Apache in un ambiente chroot per la prima volta, dovete anche copiare le seguenti librerie (sono necessarie affinchè PHP funzioni correttamente):

cp /usr/local/mysql/lib/mysql/libmysqlclient.so.12
/produzione/httpd/usr/lib/
cp /usr/lib/libm.so.2 /produzione/httpd/usr/lib/
cp /usr/lib/libz.so.2 /produzione/httpd/usr/lib/


Ulteriormente, dobbiamo copiare il file di configurazione di default di PHP:

umask 022
mkdir -p /produzione/httpd/usr/local/lib
cp /usr/local/lib/php.ini /produzione/httpd/usr/local/lib/


... e creare la directory /produzione/httpd/tmp. Il proprietario di questa directory è l'utente "root", e l'accesso deve essere settato in modalità 1777. Dopo la creazione del nuovo ambiente dovrà essere testato, se Apache è avviato correttamente:

chroot /produzione/httpd /usr/local/apache/bin/httpd


Prima di iniziare a configurare PHP, dobbiamo curarci della comunicazione tra PHP e MySQL. La comunicazione tra PHP e MySQL utilizza la socket che si trova in /tmp/mysql.sock, che dovrà essere presete nell'ambiente chroot altrimenti non sarà possibile comunicare tra di loro. Per risolvere questo problema, basta creare un link fisso (hard link) nell'ambiente chroot di Apache:

ln /tmp/mysql.sock /produzione/httpd/tmp/


Si noti che per creare questo link di comunicazione tra PHP e MySL, la socket "/tmp/mysql.sock" e la directory "/produzione/httpd/tmp" dovranno essere presenti sullo stesso file system (i link fissi non si possono instaurare tra file system).

4. Configurazione di PHP


Il processo di messa in sicurezza di Apache, che è stato descitto nell'articolo precedente, potrà essere applicato anche in questo articolo. Come punto di partenza per mettere in sicurezza PHP, si inizia dal file di configurazione. All'interno del file di configurazione di Apache (http.conf) si devono aggiungere le seguenti righe di configurazione:

AddModule mod_php4.c
AddType application/x-httpd-php .php
AddType application/x-httpd-php .inc
AddType application/x-httpd-php .class


È opportuno notare che oltre all'estezione "*.php", sono state aggiunte due estensioni che possono contenere script PHP: "*.inc" e "*.class". I programmatori includono spesso file supplementari, con un'estensione come "*.inc", "*.class" o similari. Di default queste estensioni vengono trattare come file standard per pagine web, quindi nel caso in cui non includiamo queste righe all'interno del file di configurazione, il browser ci visualizzerà il contenuto senza elaborare il codice PHP. Ciò potrebbe portare anche alla rivelazione della username e della password di accesso al database server o a qualunque altra risorsa accessibilie.
Alcuni cambiamenti devono anche essere fatti nel file di configurazione di PHP (/produzione/httpd/usr/local/lib/php.ini). E' molto importante effettuare questi cambiamente come segue:
Parametro Descrizione
safe_mode = On Attivando il parametro safe_mode, si consente agli script PHP di accedere ad altri file soltanto se il proprietario dei file a cui si accede è lo stesso del script PHP che si sta eseguendo. Questo è un importante meccanismo di sicurezza interno di PHP. Neutralizza efficacemente i tentativi non autorizzati di accedere al file di sistema (e.s. /etc/passwd) e aggiunge molte limitazioni che rendono l'accesso non autorizzato più difficile.
safe_mode_gid = Off Attivando il safe_mode e disattivando safe_mode_gid, gli script PHP sono abilitati ad accedere ai file non soltanto quando l'UID è lo stesso, ma anche quando il gruppo di appartenenza del owner del file dello script PHP è lo stesso del file a cui si vuole accedere.
open_basedir = directory[:...] Quando il parametro open_basedir è attivato, PHP potrà accedere When the open_basedir parameter is enabled, PHP potrà accedere soltanto a quei file presenti nella directory specificata (ed anche le relative sotto-directories).
safe_mode_exec_dir = directory[:...] Quando il safe_mode è attivo, le funzioni quali system(), exec() ed altre ancora, le quali eseguono i programmi di sistema rifiuteranno di avviare quei programmi se questi non sono residenti nella directory specificata in questo parametro.
expose_php = Off Impostando il parametro expose_php in modo "off" farà si che PHP non invierà informazioni su di se nelle intestazioni del HTTP che vengono trasmesse nelle richieste web effettuate dai client.
register_globals = Off Quando il parametro register_globals è impostato in "on", tutte le variaibili EGPCS (Environment, GET, POST, Cookie e Server) sono automaticamente come variabili glabali. Poiché può essere una minaccia seria alla nostra sicurezza, è suggerito vivamente disattivare questo parametro (a partire dalla versione 4.2.0, questo parametro è impostato in "off" di default).
display_errors = Off Il parametro display_errors è settato in "off", in questo modo i messaggi di eventuali errori di programmazione di PHP non vengono visualizzati. Poichè tali messaggi possono rivelare preziosi informazioni come la path, le queries SQL, etc. , è fortemente raccomandato impostare il parametro in "off" su un server sul quale girano applicazioni produttive.
log_errors = On Il parametro log_errors è impostato in "on", tutte i messaggi di worning e di errore vengono loggati all'interno di un file specificato con il parametroerror_log parameter. Se questo file non è accessibilie, gli errori verrenno loggati dal server Apache.
error_log = filename Il parametro error_log serve a specificare il percorso del file che dovrà contenere le informazioni di warning e di errore (attenzione: questo file deve permettere la scrittura da parte dell'utente o dal gruppo Apache).

In più, considerare anche la possibilità di cambiare l'estensione dei file. Per esempio "*.php" in "*.asp", "*.dhtml" o persino "*.html". Un tal cambiamento renderà difficile che eventuali curiosi riescano a rilevare chiaramente quale tecnologia usi il nostro server. Per effettuare questo cambiamento, tutti i file "*.php" dovranno essere rinominati in "*.dhtml" (per esempio), e cambiare la seguente riga all'interno del file /produzione/httpd/usr/local/apache/conf/httpd.conf:

AddType application/x-httpd-php .php


... con la seguente:

AddType application/x-httpd-php .dhtml


Grazie a ciò, l'utente web non vede l'estensione del file specificato nell'URL, che suggerisce immediatamente quale tipo di script viene utilizzata all'interno del server.

4.1 Difesa contro attacchi CSS e SQL Injection


L'ultimo passo nel mettere in sicurezza il nostro server è l'implementazione dei payloads GET e POST, e implementare la protezione contro gli attacchi Cross-Site-Scripting e SQL Injection. Per effettuare ciò, si utilizza il modulo mod_security, che si attiva aggiungendo le seguenti line all'interno del file httpd.conf:
AddModule mod_security.c

Per attivare il logging delle richieste GET e POST, è sufficiente aggiungere la seguente section all'interno di httpd.conf:
<IfModule mod_security.c> AddHandler application/x-httpd-php .php SecAuditEngine On SecAuditLog logs/audit_log SecFilterScanPOST On SecFilterEngine On </IfModule>

I suddetti comandi permettono di attivare l'Audit Engine, che è il responsabile per le richieste di logging, e il Filtering POST Engine, che permette di loggare le richieste di POST. Per proteggere le applicazioni web contro gli attacchi CSS, le seguenti righe devono essere inserite prima di "</IfModule>":
SecFilterDefaultAction "deny,log,status:500" SecFilter "<(.|\n)+>"

La prima riga causa che il server restituisca il messaggio "Internal Server Error", quando la richiesta contiene dati specificati nella variaibile SecFilter. La seconda linea setta il filtro che deve essere effettuato sui tags HTML all'interno delle richieste GET e POST.
Una firma tipica di un'attacco di tipo SQL Injection è quando appare l'apostrofo (') o le virgolette(") in una richiesta di tipo GET o POST, Rifiutando tutte le richieste che contengono questi caratteri, possiamo assicurarci di rendere un po' più complicato sottoporre la nostra applicazione ad un'attacco di SQL Injection:
SecFilter "'" SecFilter "\""

Nota, quando filtrate questi caratteri <, >, ', " per difendersi contro gli attacchi CSS e SQL Injection, può portare al malfunzionamento dell'applicazione PHP. Accade, perché gli utenti normali non possono usare quei caratteri nelle form HTML. Per risolvere questo problema con il linguaggio JavaScript, è possibile sostituire questi caratteri non permessi con i tags speciali, e.s. &lt; &gt; &quot; etc.

Sommario


Realizzare un livello elevato di sicurezza sul web server, dove risiedono tecnologie lato-server (PHP, asp, JSP ecc.) in pratica è un'operazione molto difficile. La natura stessa dell'interazioni con un web server fa diminuire la sicurezza del server web. Ecco perchè gli script lato-server dovrebbero essere usati soltanto dove è assolutamente necessario.

I metodi descritti in questo articolo ci permette di diminuire il rischio di una ebetuale interruzione di servizio da parte di qualche utente della rete un po' malizioso. Ciò sarà possibile fino a quando non vengono rilevate nuove vulnerabilità su Apache, PHP e MySQL. Naturalmente, questo articolo non tratta completamente l'argomento di come mettere in sicurezza la tecnologia di PHP, in quanto sono stati trattati soltanto le nozioni di base -. Se si applicano queste poche regole che sono state finora descritte, il livello di sicurezza della nostra macchina aumenterà ma non dimenticate che il nostro livello di sicurezza non dipende solo da Apache o PHP o MySQl.

mappa - disclaimer
Elav-Web le tue soluzioni contattaci
Soluzioni Informatiche Soluzioni Informatiche
Sviluppo software WebBased.
Elav-Web la tua soluzione I partner di Elav-Web news dal mondo IT

Tutorial


Sei il visitatore n° dal 22 settembre 2003.

Valid robots.txt Valid robots.txt Valid HTML 4.01 Transitional Valid CSS!