Monday, January 4, 2010

Recipe 18.5. Eliminating SQL Injection










Recipe 18.5. Eliminating SQL Injection



18.5.1. Problem


You need to eliminate

SQL injection vulnerabilities in your PHP applications.




18.5.2. Solution


Use a database library such as PDO that performs the proper escaping for your database:


<?php

$db = new PDO('mysql:host=localhost;dbname=users',
$_SERVER['DB_USER'],
$_SERVER['DB_PASSWORD']);

$statement = $db->prepare("INSERT
INTO users (username, password)
VALUES (:username, :password)");

$statement->bindParam(':username', $clean['username']);
$statement->bindParam(':password', $clean['password']);

$statement->execute();

$db = NULL;

?>





18.5.3. Discussion


Using bound parameters ensures your data never enters a context where it is considered to be anything except raw data, so no value can possibly modify the format of the SQL query.


If you do not have access to PDO, you can use a database library written in PHP, such as

PEAR::DB, that offers a similar feature:


<?php

$st = $db->query('INSERT
INTO users (username, password)
VALUES (?, ?)',
array($clean['username'], $clean['password']));

?>



Although this method still intermingles your data with the SQL query, PEAR::DB ensures that the data is quoted and escaped properly, so there is no practical risk of SQL injection.




18.5.4. See Also


Chapter 10 for more information about PDO, particularly Recipes Recipe 10.6 and Recipe 10.7; documentation on PDO at http://www.php.net/pdo; on PEAR::DB at http://pear.php.net/manual/en/package.database.db.php.













No comments: