PDO bindValue for table and column

833 views Asked by At

Ok so I just found out that I can't use placeholders for table names and columns

$table = 'users';

$stmt = $db->prepare('SELECT * from ?');
$stmt->bindValue(1, $rable, ??);

So what is really an alternative to having dynamic table names?

$stmt = $db->prepare('SELECT * from '.$table);

This would be vulnerable. Is there an escape_string method for PDO? I went through the manual but didn't seem to catch one. All I found was quote but that doesn't work for tables and columns. Is there any way I can securely implement this functionality, or will I have to switch back to using mysqli?

3

There are 3 answers

3
user2486495 On BEST ANSWER

For escape String

From the link:http://php.net/manual/en/pdo.prepare.php

Calling PDO::prepare() and PDOStatement::execute() for statements that will be issued multiple times with different parameter values optimizes the performance of your application by allowing the driver to negotiate client and/or server side caching of the query plan and meta information, and helps to prevent SQL injection attacks by eliminating the need to manually quote the parameters.

Prepare values are only for fields.

Regarding dynamic table names

Append it table name to query as u did in second statement.

Example

$pdo = new PDO('mysql:host=localhost;dbname=site;',USER,PASS);

$query = $pdo->prepare("DESCRIBE :table");

$query->bindValue(':table', $table, PDO::PARAM_STR, strlen($table));

$query->execute();

while($field = $query->fetch(PDO::FETCH_NUM)){
    var_dump($field);
    //do something
}

unset($pdo);
2
nihylum On

Bindable Marks (?) or Bindable named Marks (:foo) couldn't appear as table-names or (pseudo-dynamic-) fieldnames. Both are limited to field-values.

You should avoid dynamic tables inside of your application. Just normalize your database to an more agile and intelligent structure.

0
h2ooooooo On

If you use ticks, then you can simply replace ticks in the user input, and you should be fine:

$column = 'foo';
$table = 'bar';

$query = 'SELECT ' . $column . ' FROM ' . $table; // Insecure!

$query = 'SELECT `' . str_replace('`', '', $column) . '` FROM `' . str_replace('`', '', $table) . '`'; // Not insecure