Joomla 1.5 – come scrivere query sql sicure.



L’attacco più pericoloso verso un database è la SQL injection.
Tramite questo tipo di attacco è possibile  ottenere l’accesso, oppure è possibile provocare l’interruzione del servizio e a volte la distruzione di tutti i dati.
Questa capitolo spiega come possiamo garantire che le nostre richieste siano protette da questi attacchi utilizzando il Joomla! framework.

Come prima cosa abbiamo bisogno del handler (gestore) del nostro database.
$db = & JFactory:: getDBO ();

A questo punto dobbiamo tenere conto principalmente di due fattori:

  • Identificatori e nomi
  • Valori letterali (stringhe e caratteri)

Per indicare in modo sicuro identificatori e nomi si deve utilizzare il metodo JDatabase:: nameQuote ().

Iniziamo con un esempio semplice, un nome costituito da un unico identificatore.
$name = $db->nameQuote  (‘columnIdentifier’);

Dobbiamo stare attenti quando si tratta di nomi da più parti (cioè, i nomi che includono più di un identificatore separati da un punto).
Se ad esempio scriviamo tentiamo di utilizzare tableIdentifier.columnIdentifier, non avremo alcun risultato.
Questo è il metodo corretto:

/ / Prepariamo gli  identificatori
$tableIdentifier     =   $db->nameQuote(‘tableIdentifier’);
$columnIdentifier  =   $db->nameQuote(‘columnIdentifier’);
/ / Creiamo il nome
$name = “$tableIdentifier.$columnIdentifier”;


Invece di utilizzare il metodo JDatabase::nameQuote() ,
si potrebbe utilizzare questo sistema:
$sql = ‘SELECT * FROM `#__foobar_groups#` AS `gruppo` ‘.
Questo modo di lavorare  funziona, ma la query è legata a quel database e quindi non rispetta il concetto di incapsulamento degli oggetti,
obbligandoci a modificare il codice in caso di cambio di database.


In MySQL, le stringhe sono incluse tra virgolette doppie o singole. Questo metodo è normale e semplice. Purtroppo, le stringhe possono contenere
anche le virgolette come parte del messaggio. Quindi bisogna trovare un modo per ovviare al problema.
Usiamo quindi il metodo il JDatabase::Quote():
$tableIdentifier = $db->nameQuote(‘tableIdentifier’);
$columnIdentifier = $db->nameQuote(‘columnIdentifier’);
$sql = “SELECT * FROM $tableIdentifier “. “WHERE $columnIdentifier “. ‘ = ‘ . $db->Quote(“Vuoi un’ aranciamandarino ?”);

Il metodo JDatabase::Quote() cerca i caratteri “pericolosi (“,’,…) e vi antepone il carattere “” che indica alsistema di non interpretare il carattere ma di considerarlo una parte della stringa, quindi:
Originale                                       Trattata
Vuoi un’ aranciamandarino ?    ‘Vuoi un’ aranciamandarino ?


Attenzione !
Quanto indicato non si deve applicare quando si utilizza la clausola “LIKE”


Spesso nella query si utilizzano i numeri.
In MySQL, ci sono due tipi di numeri: integers (numeri interi) e floats (numeri decimali).
Ora vi mostriamo degli esempi nei quali viene indicato prima il metodo non sicuro, poi il metodo “sicuro” utilizzando le funzioni *val() del PHP.

/ / Intero
$safeNumber      = (int) $unsafeValue;
$SafeNumber     = intval($unsafeValue);
/ / In virgola mobile
$safeNumber    = (float) $unsafeValue;
$SafeNumber    = floatval($unsafeValue);

Nella maggior parte dei casi, $unsafeValue verrà  estratto dai dati della richiesta, per esempio, index.php? option = com_foobar & int = unsafeInt & FLT = unsafeFlt.

In questi casi, possiamo utilizzare JRequest:
/ / Intero
$safeInt  = JRequest::getInt (‘int’);
$safeInt  = JRequest::getVar (‘int’, 0, ‘Default’, ‘INT’);
$safeInt  = JRequest::getVar (‘int’, 0, ‘Default’, ‘INTEGER’);
/ / Virgola mobile
$safeFlt  = JRequest::getFloat (‘float’);
$safeFlt  = JRequest::getVar (‘float’, 0, ‘Default’, ‘FLOAT’);
$safeFlt  = JRequest::getVar (‘float’, 0, ‘Default’, ‘DOUBLE’);

Più tardi spiegheremo meglio i dettagli della JRequest.

Utilizzo della classe  JFilterInput:

/ / Crea il filtro
$filtro = JFilterInput::getInstance ();
/ / Integer
$safeInt = $filtro->clean($unsafeValue, ‘INT’);
$safeInt = $filtro->clean($unsafeValue, ‘INTEGER’);
// floating-point
$safeFlt = $filtro->clean($unsafeValue, ‘FLOAT’);
$safeFlt = $filtro->clean($unsafeValue, ‘DOUBLE’);


Per aumentare la nostra difesa, possiamo anche trattare un numero come una stringa.
Per esempio, potremmo usare $db->Quote((int)$unsafeValue).


Annunci sponsorizzati:
Condividi su Facebook Condividi su Twitter!
Pinterest