Consigli di programmazione (in)sicura

Stavo facendo un giro su Digg nella sezione sicurezza e mi sono imbattuto in una segnalazione di un articolo sulla programmazione sicura con PHP di Jeff Skrysak.

L’articolo affronta punto per punto le principali problematiche di sicurezza che si presentano al momento della scrittura di una Web Application. Il fatto è che alcuni dei consigli sono sbagliati.

  • Handle errors gracefully
    Place the ampersat symbol (@) in front of many of your PHP function calls. If they fail, the ampersand will stop from from showing that failure in the browser window. This is very useful when making database calls but your database is down, or the SQL statement returns an error. Such messages would only give feedback to intruders, or look unprofessional to regular users.
  • Strip backslashes, HTML, SQL and PHP tags from any form field data
    If someone maliciously tries to send HTML, SQL or PHP code through a text field entry not meant to expect it, they can disrupt or break your code. Use the following PHP functions to strip out such text: strip_tags(), str_replace() and stripslashes().
    Example: $login = @strip_tags($login); Example: $login = @stripslashes($login);
  • Add “LIMIT 1″ to the end of your SQL statements
    That will limit the number of results to just 1. If someone successfully hijacks your site, and is able to run a SQL statement that returns data, or deletes it, placing “LIMIT 1″ at the end of any SQL string will help limit the amount of data they are able to see or damage.
    Example: SELECT * FROM useraccount WHERE Login=’$login’ AND Password=’$encrypted’ LIMIT 1
  • Use $_POST not $_REQUEST
    If your HTML form uses POST to send the data to the login script, then make sure your login script gets the input data using $_POST, and not $_REQUEST. The latter would allow someone to pass data via GET, on the end of the URL string.

Gli errori ritornati dalle funzioni non andrebbero nascosti all’utente tramite “@” ma attraverso le varie funzioni di PHP: in primis set_error_handler() potendo così anche salvare tutti gli errori su un database o su un file. In linea generale il metodo “security through obscurity” non è ottimo, ma nelle Web Application potrebbe aiutare a nascondere ad un attaccante dettagli necessari come la posizione sul file system dei file, la versione del linguaggio usato, il tipo di database utilizzato, ecc…

Le funzioni strip_tags e stripslashes suggerite non sono sufficenti ad evitare l’iniezione di codice Javascript.
Se vi fosse una pagina che riceve dati da un form in questo modo:
//...
$url = striptags(stripslashes($_POST['url']));
echo '<a href="'.$url.'">Url</a>';
//...

passando tramite la variabile “url”, inviata via metodo POST, una stringa uguale a questa è possibile creare un XSS:

" onmouseover=”myJSfunc();

Un metodo più efficace contro l’iniezione di codice JS è questo:
$url = htmlentities(strip_tags($_POST['url']),ENT_QUOTES);
così facendo tutti i tag HTML verranno cancellati e tutti caratteri speciali verranno convertiti nelle rispettive entità HTML. Ovviamente tali funzioni dovrebbero essere sempre usate come ultima spiaggia dopo aver validato la stringa con espressioni regolari o con la nuova funzione filter_input di PHP 5.
Nel caso di dati da inserire in un DataBase ci viene incontro una ottima funzione nativa di PHP: {mysql,mysqli,ps,sqlite}_escape_string. Una ottima contromusira alle SQL Injection la forniscono anche le “prepared statements” disponibili con PHP 5 e Zend Framework.
L’aggiunta dell’istruzione “LIMIT 1″ alla fine di una query non rende immune ad attacchi un’applicazione che non effettua i dovuti controlli sui dati ricevuti. Se vi fosse una pagina che riceve dati da un form in questo modo:
//...
$id = $_POST['id'];
$query = '<SELECT * FROM users WHERE id='.$_POST['id'].' LIMIT 1';
//...

passando tramite la variabile “id”, inviata via metodo POST, una stringa uguale a questa sarebbe possibile creare una SQL Injection bypassando anche la direttiva “LIMIT 1″:

1 OR 1=1; –

Per concludere, l’utilizzo del metodo POST al posto di GET o del più generale REQUEST aiuta certo ad evitare XSS di tipo 1 ma non rende più difficile, ad un attaccante, manipolare i paramentri inviati alla Web Application.

 

Nessun Commento.. Puoi essere il primo!

Lascia un Commento