1

I currently use mysql_real_escape_string to escape a variable when querying the database to prevent SQL injection. For example,

   $keyword = mysql_real_escape_string($keyword);
        $guideline = mysql_real_escape_string($guideline);  
        mysql_query("INSERT INTO table1 VALUES('$keyword','$guideline')");

$get = mysql_query("SELECT * FROM table2 WHERE keyword='$keyword'");

  while($row = mysql_fetch_assoc($get)) {
  //code
  }

After reading about SQL injection prevention, i've read this isn't enough to stop SQL injection(so much code to go over now and correct) and i should be using PDO prepared statements? Can i have an example of how to do PDO prepared statements with the same $variables above?

9
  • 1
    @jeroen: no, it isn't. It is vulnerable to character set related injections. However, this is somewhat harder to achieve by the attacker, but it is still false to claim that one is safe from it. Commented Jul 3, 2012 at 12:36
  • Thanks, so many conflicting opinions. I don't use any variable to change table names i only use them to change values, mysql_real_escape_string is enough in that scenario? Commented Jul 3, 2012 at 12:39
  • I would only be replicating the existing answers so i'll just highly suggest reading this article/tutorial net.tutsplus.com/tutorials/php/… Commented Jul 3, 2012 at 12:40
  • @eis Don't remember about that, I always set the charset after connecting (both in PDO and before in mysql_*)... Commented Jul 3, 2012 at 12:40
  • @eis:So do PDO/prepared statements 100% of the time? How exactly does PDO/prepared statements prevent SQL injection? Commented Jul 3, 2012 at 12:41

4 Answers 4

4

Its pretty simple really:

$db = new PDO($dsn, $user, $password);
$stmt = $db->prepare('INSERT INTO table1 VALUES(?,?)');
$stmt->execute(array($keyword, $guideline));
$stmt->close();

$stmt2 = $db->prepare('SELECT * FROM table2 WHERE keyword= ?');
$stmt->execute(array($keyword));
while(false !== ($row = $stmt->fetch())) {
   // do stuff
}

Note that you can also use named placeholders which can help make your code a bit more readable though a bit more verbose:

$stmt2 = $db->prepare('SELECT * FROM table2 WHERE keyword= :keyword');
$stmt2->execute(array(':keyword' => $keyword));
Sign up to request clarification or add additional context in comments.

1 Comment

This is precisely what you asked for OP, so kudos to prodigitalson, but @user892134 I'd caution you to read up on PDO: php.net/manual/en/book.pdo.php . Prepared statements do sanitize inputs, but there are other ways to use PDO which do not, and the manual will help you understand those. Great idea to move to using PDO, though. Not a full blown ORM, but enough of an abstraction layer that also helps add some security.
3

First you must create a PDO object:

$dbh = new PDO("mysql:dbname=$dbname", $username, $password);

Then there are different ways to associate your parameters with your queries:

  1. As an argument to execute():

    $qry = $dbh->prepare("INSERT INTO table1 VALUES(?, ?)");
    $qry->execute(array($keyword, $guideline));
    
  2. By binding values (retains value assigned at time of function call):

    $qry = $dbh->prepare("SELECT * FROM table2 WHERE keyword = ?");
    $qry->bindValue(1, $keyword);
    $qry->execute();
    
    while ($row = $qry->fetch()) {
      // code
    }
    
  3. By binding parameters (updates when underlying variable changes):

    $qry = $dbh->prepare("SELECT * FROM table2 WHERE keyword = ?");
    $qry->bindParam(1, $keyword);
    $qry->execute();
    
    while ($row = $qry->fetch()) {
      // code
    }
    

You can even use named placeholders instead of anonymous ?:

$qry = $dbh->prepare("SELECT * FROM table2 WHERE keyword = :kw");
$qry->bindValue(":kw", $keyword);

2 Comments

So the second example would be for a static variable and the third example would be for a dynamic variable?
@user892134: You can use either in either case. The third example is especially useful if you want to execute the query multiple times with different parameter values: then you only need to change $keyword and call $qry->execute() again -- whereas with the second example you would need to bindValue() each time too.
2

This one makes more sense

<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);

// insert one row
$name = 'one';
$value = 1;
$stmt->execute();

// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
?>

http://www.php.net/manual/en/pdo.prepared-statements.php

Comments

0

Here is what I do, not claiming to be a ninja, but have been at it for a while.

//connection
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);

//get Post data
$name = filter_input(INPUT_POST, $name, FILTER_SANITIZE_STRING);

//SQL
$SQL = $conn->prepare('SELECT * FROM users WHERE user_name=:name;');
$SQL->execute(array(':name' => $name));

//While Loop
while($names = $SQL->fetch(PDO::FETCH_OBJ){
 echo $names->user_email
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.