Newsgroup: it.comp.www.php
Titolo: PHP / SQL injection

Buon pomeriggio,
utilizzando le prepared statement e quindi il bind fra i vari parametri
e le variabili di input, sono "automaticamente" cautelato da eventuali
tentativi di SQL injection (perchï¿œ ï¿œ il "driver" che ci pensa a
"ripulire" i parametri) oppure mi ritrovo nella stessa situazione in cui
sarei se usassi banali string di codice SQL ?
Esempio:
$stmt = mysqli_prepare($link, 'INSERT INTO foo(bar) VALUE (?)');
mysqli_stmt_bind($stmt, 's', $myparam);
mysqli_stmt_execute($stmt);
ï¿œ ugualmente insicuro (se non controllo la variabile $myparam) a
mysqli_query($link, "INSERT INTO foo(bar) VALUE ('${myparam}')");
Grazie in anticipo per le risposte
saluti,
M.

Mau C ha scritto:

puoi settare gpc magic quote on (globale)
o fare mysql_real_escape_string (solo su)
o rullare le variaili e renderle docili (dipende)

 o fare mysql_real_escape_string (solo su)
grazie;
questa, unita allo stripslashes, ï¿œ la soluzione che mi serve.
Per blocchi di testo piï¿œ complessi (textarea, html, ...) ho deciso di
usare la coppia base64_encode/decode.
La mia domanda era comunque un po' piï¿œ sottile:
con le prepared statement e il bind variabili/parametri, ho la /reale/
necessitï¿œ di fare questo ?
Proveniendo dall'ambiente di sviluppo Java / Oracle, dove il bind toglie
spesso dall'imbarazzo delle stringhe mal quotate, mi ponevo la stessa
domanda per PHP / MySQL.
saluti,
M.

 domanda per PHP / MySQL.
Di solito il metodo escape_string() ti toglie d'impaccio.
Sconsiglierei gli automatismi di quoting perche' potrebbero portare a casini e
comunque non ti salvano dalla provenienza dei dati da altre fonti, tipo il
risultato di una query sul database che ritorna degli apici.
Ciao,
luigi
-- 
/
+--[Luigi Rosa]--
\
A computer scientist is someone who, when told to "Go to Hell" sees
the "go to" rather than the destination as harmful.
       --Dr. Roger M. Firestone

 risultato di una query sul database che ritorna degli apici.
In effetti,
incuriosito dai vostri interventi ho fatto delle prove. Con la prepared
statement posso inserire qualsiasi porcheria nel db, che poi mi viene
correttamente restituita dalla query di SELECT.
Se uso l'escape, tutti i caratteri quotati vengono inseriti con il
carattere di escape '\' che viene poi restituito dalla SELECT.
Sembra quindi che la prepared mi tuteli in automatico da qualsiasi
porcheria. Il "sembra" ï¿œ d'obbligo, volevo trovare della documentazione
a riguardo che confermi la mia impressione.
saluti,
M.

 a riguardo che confermi la mia impressione.
Il modo corretto per eseguire SQL in un linguaggio ospite sono i
prepared statement, tutti gli altri sono accrocchi. Tra l'altro i
database seri (sicuramente Oracle, probabilmente non mysql) riconoscono
lo stesso prepared statement quando gli viene sottoposto la seconda
volta ed evitano di riparsarlo, mentre invece concatenando le costanti
nel SQL alla burina ogni statement per loro ï¿œ diverso dall'altro e viene
fatto il parse tutte le volte.
Y.

 fatto il parse tutte le volte.
Depurando il post dalle sfumature polemiche, ï¿œ tutto corretto. Esistono
comunque delle situazioni in cui non ï¿œ possibile sapere a priori il
numero di parametri / where conditions e la query viene costruita
on-line. In queste situazioni le prepared statement, a meno di non usare
una spatasciata di if ... else, sono inusabili.
saluti,
M.

 una spatasciata di if ... else, sono inusabili.
Ma no, perchï¿œ? Basta fare un loop sui parametri, no?

 Ma no, perchï¿œ? Basta fare un loop sui parametri, no?
Se a priori io non sono in grado di sapere se dovrï¿œ fare una INSERT /
UPDATE con 1, 2, 3, 4, ... 100 parametri; oppure non sono in grado di
sapere se dovrï¿œ fare una SELECT con 1, 2, 3, 4, ... 10 clausole WHERE,
non posso usare le prepared perchï¿œ a priori non so come fare il bind.
saluti,
M.

 una spatasciata di if ... else, sono inusabili.
E' vero, ma e` anche vero che la stessa spatasciata di if...else la usi 
per costruire una normale query.
Personalmente sono passato (quasi) direttamente da mysql_query a Zend_DB, 
e posso fare roba tipo
$select = $this->select();
if ($par1) {
 $select->where("par1 = ?", $par1);
}
if ($par2) 
 blablabla
if ($order) {
 $select->order($order);
}
return $this->fetchAll($select);
ecc. ecc. Naturalmente il codice lo scrivo piu` chiaro, era per dare 
un'idea.
Bye.

 non posso usare le prepared perchï¿œ a priori non so come fare il bind.
In PHP il problema non esiste perchï¿œ ï¿œ typeless e la funzione di bind ï¿œ
generica, in un linguaggio typed come ad esempio Java puoi sempre andare
 a vedere com'ï¿œ definita la colonna nel DB e richiamare la funzione di
bind corrispondente al datatype.

 un'idea.
I framework sono belli e comodi (Hibernate su Java per farne un esempio)
ma da buon "vecchio" programmatore (a volte sospettoso...) mi piace
tener sott'occhio quello che l'applicazione fa "a basso livello".
Sono quindi sicuro che Zend, alla resa dei conti, faccia delle prepared
statement pulite.
Non sono ancora migrato a Zend, per cui presto lo farò e mi documenterò.
grazie!
saluti,
M.

 statement pulite.
Infatti, e` quello che fa (usa PDO) quando richiami il fetchAll sulla 
select. Il bello e` che essendo tutto in PHP ti puoi anche guardare i 
sorgenti e capire cosa fa.
E, a parte qualche punto oscuro, per il 95% sono abbastanza chiari e 
lineari. :)
Bye.


non posso non quotare, per motivi fi studio ho aperto i sorgenti di
Zend Framework moltissime volte e sono chiarissimi, si dovrebbero
usare come spunto
per scrivere codice pulito (almeno a me è servito in questo senso)