Search code examples
phppdosql-injection

Why do we need to specify the parameter type in bindParam()?


I am a bit confuse as to why we need to specify the type of data that we pass in the bindParam() function in PDO in Php. For example this query:

$calories = 150; 
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$sth->bindParam(1, $calories, PDO::PARAM_INT); 
$sth->bindParam(2, $colour, PDO::PARAM_STR, 12);
$sth->execute();

Is there a security risk if I do not specify the 3rd parameter. I mean if I just do in the bindParam():

$sth->bindParam(1, $calories); 
$sth->bindParam(2, $colour);

Solution

  • Using bindParam() with types could be considered safer, because it allows for stricter verification, further preventing SQL injections. However, I wouldn't say there is a real security risk involved if you don't do it like that, as it is more the fact that you do a prepared statement that protects from SQL injections than type verification. A simpler way to achieve this is by simply passing an array to the execute() function instead of using bindParam(), like this:

    $calories = 150; 
    $colour = 'red';
    
    $sth = $dbh->prepare('SELECT name, colour, calories
                          FROM fruit
                          WHERE calories < :calories AND colour = :colour');
    
    $sth->execute(array(
        'calories' => $calories,
        'colour' => $colour
    ));
    

    You're not obligated to use a dictionary, you can also do it just like you did with questionmarks and then put it in the same order in the array. However, even if this works perfectly, I'd recommend making a habit of using the first one, since this method is a mess once you reach a certain number of parameters. For the sake of being complete, here's what it looks like:

    $calories = 150; 
    $colour = 'red';
    
    $sth = $dbh->prepare('SELECT name, colour, calories
                          FROM fruit
                          WHERE calories < ? AND colour = ?');
    
    $sth->execute(array($calories, $colour));