这个示例sql语句是否被认为是参数化的,因此是安全的?

时间:2012-02-12 19:25:55

标签: php mysql sql-injection prepared-statement

$dbh->prepare("INSERT INTO whatever (col1,col2) values (%d,%s)",$_GET['unescaped_and_unfiltered_col1_value'],$_GET['unescaped_and_unfiltered_col2_value']);

就SQL-Injection转义而言,上述方法与使用bindParam或bindValue方法有何不同?

2 个答案:

答案 0 :(得分:3)

如果您使用的是PDO。这是错误的。

查看PDO manual

您的代码将是

$stmt = $dbh->prepare("INSERT INTO whatever (col1,col2) values (?, ?)");
$stmt->execute(array($_GET['key1'], $_GET['key2']));

这些值将被转义并且可以安全使用。

答案 1 :(得分:1)

好吧,如果你要模仿这种行为,使用像%d,$ s这样的符号表示你的数据,而不实现某些基础技术,那显然是不安全的。 %d和$ s符号没有任何神奇含义,无论安全数据是什么。

如果你打算使用某些,你会发现,并且想问一下,如果这个库安全与否,你必须至少命名它,但是更好地呈现技术它正在用来让人们了解你所要求的东西。

好的,这都是关于符号的 就像我上面所说的那样,如果你的意思是%s,而不是$s,这些只是printf()函数占位符,与安全性和数据库完全无关。

但是,您仍然可以创建一个实现此类占位符的安全系统,当然,必须将这些参数转义为它的基础级别。

这种功能的一个简单例子:

function prepare() {
  $args = func_get_args();
  $query = array_shift($args);
  foreach ($args as $key => $val) {
    $args[$key] = mysql_real_escape_string($val);
  }
  return vsprintf($query, $args);
}

以这种方式使用

$sql = $dbh->prepare("INSERT INTO whatever (col1,col2) values (%d,'%s')",
                     $_GET['unescaped_and_unfiltered_col1_value'],
                     $_GET['unescaped_and_unfiltered_col2_value']);

您可以确定您的数据值是安全的。然而标识符和关键字钢需要保护。

希望我能解决所有问题。