2010-10-28 21 views
11

Capisco il modo giusto per proteggere un db dall'iniezione SQL utilizzando le istruzioni preparate. Mi piacerebbe capire come le istruzioni preparate proteggono il mio db.In PHP, come protegge PDO dalle iniezioni SQL? Come funzionano le dichiarazioni preparate?

Per i principianti, le istruzioni preparate sono la stessa cosa di "query parametrizzate"?

Ad esempio, sto incollando sotto il mio codice per l'inserimento di un nuovo utente in una tabella utente. È sicuro? Come funziona la PDO per renderla sicura? C'è ancora qualcosa da fare per proteggere il db dall'iniezione?

In 'Class_DB.php':

class DB { 
private $dbHost; 
private $dbName; 
private $dbUser; 
private $dbPassword; 
function __construct($dbHost, $dbName, $dbUser, $dbPassword) { 
    $this->dbHost=$dbHost; 
    $this->dbName=$dbName; 
    $this->dbUser=$dbUser; 
    $this->dbPassword=$dbPassword; 
} 
function createConnexion() { 
    return new PDO("mysql:host=$this->dbHost;dbName=$this->dbName", $this->dbUser, $this->dbPassword); 
} 
} 

In 'DAO_User.php':

require_once('Class_DB.php'); 

class DAO_User { 
private $dbInstance; 
function __construct($dbInstance){ 
    $this->dbInstance=$dbInstance; 
} 
function createUser($user){ 
    $dbConnection=$this->dbInstance->createConnexion(); 
    $query=$dbConnection->prepare("INSERT INTO users (userName, hashedPassword, userEmail) VALUES (?,?,?)"); 
    $query->bindValue(1, $user->userName); 
    $query->bindValue(2, $user->hashedPassword); 
    $query->bindValue(3, $user->userEmail); 
    $query->execute(); 
} 
} 

Grazie,

JDelage

+2

correlato: http://stackoverflow.com/questions/134099/are-pdo-prepared-statements-sufficient-to-prevent-sql-injection –

+0

Grazie Haim, la risposta troelskn risponde alla mia domanda. – JDelage

+0

'le istruzioni preparate sono la stessa cosa di" query parametrizzate "?' Sì. Inoltre, permettimi di indicarti un altro problema relativo a SQL injection, descritto nella mia risposta precedente: http://stackoverflow.com/questions/2993027/in-php-when-submitting-strings-to-the-db-should- i-take-care-of-illegal-characters/2995163 # 2995163 poiché non abbiamo solo dati inseriti nelle nostre query, e le dichiarazioni preparate non lo aiuterebbero –

risposta

20

Ok, ho trovato la risposta alla mia domanda in questa domanda relativa: Are PDO prepared statements sufficient to prevent SQL injection?

Grazie ad Haim per averlo Q per me.

In termini non tecnici, ecco come istruzioni preparate proteggono da iniezione:

Quando una query viene inviata ad una base di dati è tipicamente inviato come stringa. Il motore db tenterà di analizzare la stringa e separare i dati dalle istruzioni, basandosi su virgolette e sintassi. Pertanto, se si invia "SELEZIONA * DOVE" l'utente ha inviato i dati "EQUALS" nome riga tabella ", il motore sarà in grado di analizzare l'istruzione.

Se si consente a un utente di entrare in quello che sarà inviato dentro 'utente dati presentati', allora possono includere in questo qualcosa come' ... "O SE 1 = 1 ERASE DATABASE'. Il motore db avranno difficoltà parsing this e prenderà il sopra come un'istruzione piuttosto che una stringa senza senso

Il modo in cui funziona PDO è che invia separatamente l'istruzione (preparare ("INSERIRE IN ...)) e i dati. I dati vengono inviati separatamente, chiaramente intesi come dati e solo dati. Il motore db non tenta nemmeno di analizzare il contenuto della stringa di dati per vedere se contiene istruzioni e qualsiasi snipet di codice potenzialmente dannoso non viene preso in considerazione.

+2

So che questa è una vecchia risposta, ma dovrebbe essere presente in ogni voce libro di testo di livello su PHP e database. Molto chiaro ed eeasy da capire! – MaDaHoPe

3

Ecco il mio un po 'limitata vista sul importa ...

Un'istruzione preparata viene compilata sul server DB con i segnaposto per l'input variabile.

Quando si associa un parametro, si indica al DB quali valori utilizzare quando si esegue la query. Passerà quindi il valore alla dichiarazione compilata.

La differenza tra i parametri di binding e la semplice stringa di input vecchia è che con il primo, il valore non è interpolato ma piuttosto assegnato. Durante l'esecuzione, il DBMS colpisce un segnaposto e richiede il valore da utilizzare. In questo modo, non c'è possibilità di citare personaggi o altri sguardi che si intrufolano nella dichiarazione vera e propria.

2

Senza utilizzare istruzioni preparate, non è possibile utilizzare segnaposto (?) Nella query.

Invece, è necessario includere il valore che si desidera inserire direttamente nell'istruzione SQL. Ciò risulterebbe in una diversa istruzione SQL per ogni inserto (male per le prestazioni) e se non si sta attenti a quali stringhe inserite nell'istruzione si potrebbe anche finire con una dichiarazione che fa qualcos'altro rispetto a ciò che si intendeva (ad esempio L'iniezione SQL potrebbe accadere).

Questa situazione è in qualche modo simile ad avere una funzione Javascript che fa un po 'di codice fisso con parametri di input variabili, invece di incollare i parametri di input nella sorgente di Javascript e quindi evalificarlo.

-1

la fonte è protetta dall'attacco sqli.

è un esempio e non sicuro quando ne selezioni uno dal database.

// example: localhost/user.php?username=admin 

$getdata = $_GET['username']; 

$dbConnection=$this->dbInstance->createConnexion(); 
$query=$dbConnection->prepare("SELECT * FROM users WHERE username=".$getdata."); 

// PHP simple 
+0

Mi chiedo chi risparmierà questa risposta che ha completamente perso la domanda posta qui –

Problemi correlati