Sicurezza degli script PHP

Con gli script PHP, gli aspetti di sicurezza sono essenzialmente focalizzati su due punti. Prevenire lo scripting tra siti (CSS o XSS) e prevenire lo spionaggio dei dati o l'infiltrazione di codice. Per fare questo, è particolarmente necessario controllare tutte le voci che provengono dall'esterno. Ciò riguarda i dati trasferiti nell'URL, i dati dei moduli, i cookie e i file caricati.

Si prega di notare: L'elenco delle precauzioni di sicurezza qui riportato non deve essere considerato come un concetto di sicurezza completo, ma serve solo a rilevare i rischi fondamentali.

Un concetto di sicurezza copre sempre il software nella sua interezza e copre in modo coerente tutti i settori dell'elaborazione dei dati. La protezione degli script è solo una componente del concetto generale.

Inserisci codice tramite include()

Una vulnerabilità comune è che la funzione include() viene utilizzata con parametri variabili. In questo caso, un aggressore può iniettare codice estraneo passando un URL come parametro (ad es. http://evil-site.tld/exploit.txt). Questo codice, che può essere determinato liberamente dall'attaccante, viene poi eseguito come se facesse parte dello script. L'attaccante ha quindi a disposizione tutte le possibilità dello script. Evitare di chiamare include() con un valore variabile e utilizzare costanti invece di variabili. Se l'uso di variabili è inevitabile, filtrarne il contenuto di conseguenza. Questo può essere fatto, ad esempio, con il seguente codice.

if (strpos($variable, '://') !== FALSE || strpos($variable, '../') !== FALSE)
die('Illegal string'); 

Questo codice controlla se le stringhe ://, come in http:// o ftp://, oppure .., come in ../.../secret/passwords sono contenute nella stringa $variabile e termina l'esecuzione se necessario.

SQL Injection

Quando uno script utilizza query al database, è relativamente facile per un attaccante iniettare codice SQL arbitrario se lo script non è programmato correttamente. Ciò consente loro di leggere, modificare o addirittura cancellare dati ai quali altrimenti non avrebbero accesso.

Si supponga di utilizzare il seguente codice in uno script:

[...]
$sql = "SELECT * FROM adressen WHERE name='".$_GET['name']."'";
$result = mysql_query($sql);
[...]        

Questa o una query simile può apparire se si desidera filtrare l'indirizzo di un nome particolare da una tabella contenente gli indirizzi.
L'aggressore può ora chiamare l'URL http://dominio.tld/skript.php?name=';DELETE FROM adressen WHERE 1=1 OR name='.
Ne risulta una query SQL SELECT * FROM adressen WHERE name=''; DELETE FROM adressen WHERE 1=1 OR name='';. In primo luogo, il server del database seleziona tutti i record per i quali il campo Nome contiene una stringa vuota, quindi tutti i record vengono eliminati dalla tabella. Naturalmente, tale lacuna può essere utilizzata anche per altri scopi, la cancellazione del contenuto della tabella dovrebbe servire solo come esempio in questo caso.

Per evitare tale vulnerabilità, le variabili nelle query SQL dovrebbero sempre essere trasformate utilizzando la funzione mysql_real_escape_string(). I caratteri speciali, come le virgolette singole, vengono mascherati in modo da essere interpretati come parte dell'intera stringa e non come caratteri per la fine della stringa stessa. Se i valori vengono superati al di fuori delle virgolette (ad es. valori numerici), utilizzare la funzione intval() se possibile. Questo assicura che venga effettivamente utilizzato un solo valore numerico, ecco un esempio:

Trasferimento di parametri negli URL

Il passaggio di parametri negli URL (ad esempio http://domain.tld/script.php?id=1) è un modo comune per passare argomenti agli script. Tuttavia, si dovrebbe sempre essere consapevoli che questi parametri possono essere impostati a piacimento dall'utente. Ciò significa che il suo contenuto deve essere considerato inaffidabile. Lo stesso vale per i dati trasmessi via email HTTP e i cookie.

Questo è importante quando si esegue il reindirizzamento da uno script a un altro e si passano parametri nell'URL o come cookie. Il nuovo script non può considerare questi parametri affidabili, ma deve controllarli tutti di nuovo. Spesso è più facile usare le funzioni di sessione di PHP. I dati che sono stati controllati e memorizzati nella sessione possono ora essere classificati e utilizzati come sicuri. L'utente non ha la possibilità di modificare direttamente il contenuto della sessione.
L'identificatore di sessione viene passato come parametro con l'URL. Poiché si tratta di una stringa generata in modo casuale, la probabilità che un attaccante possa indovinare l'identificatore di una sessione estranea è estremamente bassa.

Variabili globali

Nelle versioni precedenti di PHP, i parametri passati dai form o nell'URL erano inseriti in variabili globali. Per ragioni di compatibilità, tuttavia, le versioni attuali riproducono ancora questo comportamento nella maggior parte dei sistemi.
Ad esempio, se viene richiamato l'URL http://dominio.tld/skript.php?variable=contenuto, viene impostata nello script una variabile con il nome $variabile e il contenuto.

Questo può diventare un problema se si utilizzano le variabili globali internamente senza inizializzarle correttamente in anticipo.

Esempio:

<?php
if ($_GET['password'] == 'geheim') {
$admin = true;
}

[...]

if ($admin) {
// Aktionen, die einem Administrator, der das Passwort kennt, vorbehalten sind
[...]
}
?>

Un aggressore può semplicemente chiamare l'URL http://dominio.tld/skript.php?admin=1 e ha immediatamente i diritti di amministratore, perché la variabile $admin restituisce true.

Con una corretta inizializzazione, questo può essere evitato

<?php
$admin = false;

if ($_GET['password'] == 'geheim') {
$admin = true;
}

[...]

if ($admin) {
// Aktionen, die einem Administrator, der das Passwort kennt, vorbehalten sind
[...]
}
?>

Ora il valore precedentemente impostato per $admin viene prima sovrascritto e impostato a true solo se la password è stata effettivamente passata.

In altri scenari, l'omissione dell'inizializzazione può essere utilizzata anche per le iniezioni SQL, ad esempio. Per questo motivo ci si dovrebbe abituare ad inizializzare tutte le variabili, anche se la sintassi di PHP non lo richiede.

Cross-Site-Scripting

Lo scripting tra siti è il caso in cui un aggressore inserisca codice JavaScript in un sito straniero per ottenere informazioni alle quali normalmente non ha accesso. Può essere utilizzato per accedere ad altri ID di sessione o per spiare i nomi utente.
A tale scopo, l'aggressore crea un URL in cui imposta i parametri che vengono immediatamente visualizzati nel testo della pagina. Se questo testo ora contiene codice script, viene eseguito nel contesto di sicurezza della pagina, ad esempio può leggere i cookie che sono stati impostati da questa pagina. Il pericolo di questo tipo di attacco è che sia quasi invisibile per l'utente quando si verifica in un fotogramma nascosto.

La soluzione è quella di usare la funzione htmlentities() nello script per tutte le variabili da produrre (specialmente quelle che contengono input dell'utente).
Questo sostituisce i caratteri con un significato speciale in HTML, come < >,">',", con le entità corrispondenti. Questa semplice misura consente di eliminare la maggior parte delle possibilità di attacco per lo scripting tra siti.


Il nuovo Centro Assistenza 1&1 IONOS con indicazioni e informazioni relative ai nostri prodotti e servizi per i domini.