MySQL è un database relazionale (RDBMS) da sempre in primo piano per ciò che concerne il mondo Web e l'interazione con PHP. Come in ogni altro RDBMS, i dati vengono logicamente suddivisi in database e tabelle, gestiti fisicamente da MySQL come, rispettivamente, directory e file su filesystem, contenuti all'interno della directory dei dati.
Il numero di file che descrivono ogni tabella dipende dall'engine di memorizzazione usato, e spaziano da uno a tre. A MySQL 5 HTML.it ha dedicato poco tempo fa una guida completa.
Al fine di poter accedere ai dati contenuti nel database, i programmi client (ad esempio PHP stesso tramite l'apposita estensione) devono connettersi al server database (mysqld
), il quale è l'unico a poter accedere fisicamente al filesystem. La connessione avviene via TCP/IP o socket di dominio UNIX.
Il programma server mysqld
gira sul sistema operativo come un dato utente definito: ciò vuol dire che qualsiasi operazione mysqld
esegua sul sistema (lettura filesystem, esecuzione programmi) è limitata dai permessi che quell'utente "virtuale" possiede.
Criteri di protezione
L'obiettivo è fare in modo che solamente gli utenti in possesso delle corrette autorizzazioni possano accedere ai dati del database, assicurando:
- segretezza e confidenzialità: i dati devono poter essere consultati e/o modificati soltanto da parte di chi è debitamente autorizzato;
- integrità ed autenticità: i dati non devono poter essere manipolati dolosamente o accidentalmente e la loro provenienza deve essere verificabile.
La protezione del server mysqld
(e di qualsiasi altro servizio) si attua ponendo in essere le classiche protezioni interna ed esterna e scongiurando o limitando gli effetti di attacchi di tipo DoS.
La protezione interna impone di proteggere l'accesso alla directory dei dati dagli utenti che hanno login sul server (compresi gli utenti con cui girano i servizi); in altre parole la directory dei dati e tutto il suo contenuto dovranno essere ad esclusivo accesso dell'utente con cui gira il server database mysqld
. Di conseguenza, quindi, nessun altro utente (fuorché ovviamente root) accederà in lettura o scrittura a tale albero di directory.
La protezione della directory dei dati dall'"interno" è fondamentale per due ragioni. Primo perché, a meno di attacchi locali riusciti, se un altro servizio viene crackato dall'esterno, l'utente con cui gira non avrà accesso via filesystem alla directory dei dati di MySQL; in secondo luogo perché la directory dei dati contiene anche la tabella dei permessi: modificare questa tabella implica poter modificare gli utenti accreditati ad accedere al database, e quindi ad averne pieno controllo.
La protezione esterna impone di proteggere l'accesso al server mediante la creazione di utenti accreditati alla connessione, differenziandone le azioni che possono compiere sulle tabelle e validandone successivamente le credenziali attraverso l'uso di username e password. Tali utenti sono relativi a MySQL e non al sistema operativo. L'aggettivo "esterna" si applica anche al caso in cui le connessioni al database avvengano solo da locale: è un termine di uso comune, a volte fuorviante, che noi però ci adeguiamo ad usare.
Se, al contrario, la connessione al database avviene via rete (in generale in LAN), è opportuno usare un tunneling SSL sicuro, ciò che MySQL mette a disposizione. Per prevenire infine attacchi di tipo DoS è possibile limitare il numero di connessioni e query per unità di tempo, cosa che, per la verità, è indispensabile fare (a monte) nel programma applicativo o Web che utilizzi il database (ad es. imporre una pausa tra due query complesse consecutive) rispetto che che qui (a valle).
È inoltre necessario indicizzare le tabelle ove opportuno: questo riduce il carico di lavoro del server di svariati ordini di grandezza nel caso di query complesse e tabelle grandi che richiedano join. Prevenzione da attacchi DoS e politiche di backup e ripristino dei dati garantiscono l'accessibilità degli stessi: i dati devono essere sempre disponibili eventualmente anche attraverso il loro immediato ripristino.