mysql_real_escape_string什么时候知道哪个数据库服务器负责?

时间:2012-03-26 18:22:34

标签: php sql-injection mysql-real-escape-string

在像这样的函数调用中

$rs = getrs($dbh,"select firstname,lastname from users where userid='" . safe($uid) . "'")

安全功能会正确处理sql注入吗?

安全功能基本上什么都不做,只是在传递的参数上应用mysql_real_escape_string,在这种情况下是$ uid。

如果是这样,我不知道如何。

我不知道这是如何工作的,因为数据库句柄$dbh和函数safe()在不同的上下文中运行。

有没有办法编写一个方便的函数,比如上面的一个衬里,同时确保所有包含在类似安全函数中的变量都被正确转义。

并且PHP中还有一个函数,你传递4dbh它会告诉你它是mysql还是mssql句柄?

3 个答案:

答案 0 :(得分:1)

  

mysql_real_escape_string何时知道哪个数据库服务器负责   目前?

来自manual

  

如果未指定链接标识符,则打开最后一个链接   假设是mysql_connect()。如果没有找到这样的链接,它会尝试   创建一个,好像没有参数调用mysql_connect()。如果不   找到或建立连接,E_WARNING级别错误是   生成。

[...]

  

安全功能会正确处理sql注入吗?

在你的特定情况下,是的。

  

有没有办法编写一个方便的功能,如上面的一个班轮   同时确保所有包含在安全的变量中   功能被正确转义。

有些人喜欢使用sprintf。但是,现在正确的方法是使用参数化查询(PDO)。

  

并且在PHP中也有一个函数,你传递4dbh和它   告诉你它是mysql还是mssql句柄?

您可以使用get_resource_type

$dbh = mysql_connect();
echo get_resource_type($dbh); // mysql link

答案 1 :(得分:0)

要正确转义SQL,请使用http://php.net/manual/en/pdo.prepared-statements.php

<?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();

答案 2 :(得分:0)

除了可以通过阅读手册页面回答的愚蠢问题之外,还有更重要的问题:

  

safe函数会正确处理sql注入吗?

没有。

只要safe()函数基本上什么都不做,只是在传递的参数上应用mysql_real_escape_string,它就不应该这样命名。 因为应用mysql_real_escape_string与注射或安全无关。

至少此函数除了转义外,还必须在传递的值周围添加引号。它会使一些查询错误但至少是安全的。

  

有没有办法编写一个方便的函数,比如上面的一个衬里,同时确保所有包含在类似安全函数中的变量都被正确转义。

不确定。
使用占位符。

$rs = getrs($dbh,"select firstname,lastname from users where userid=?",$uid);

自定义处理程序将使用安全准备的值替换占位符?

这是我很久以前写的一个功能,其意图与你的“oneliner”相同,但更加明智,同时考虑到安全性和易用性。
它肯定不理想 - 不必将%字符直接放在查询中,因为它使用的是printf语法。并且它没有标识符的占位符(以及许多其他方便的占位符)。当然,OOP实现会更加灵活,具有简洁明了的方法而不是丑陋的“模式”变量 但是如果你想要一个功能

function dbget() {
  /*
  usage: dbget($mode, $query, $param1, $param2,...);
  $mode - "dimension" of result:
  0 - resource
  1 - scalar
  2 - row
  3 - array of rows
  */
  $args = func_get_args();
  if (count($args) < 2) {
    trigger_error("dbget: too few arguments");
    return false;
  }
  $mode  = array_shift($args);
  $query = array_shift($args);
  $query = str_replace("%s","'%s'",$query); 

  foreach ($args as $key => $val) {
    $args[$key] = mysql_real_escape_string($val);
  }

  $query = vsprintf($query, $args);
  if (!$query) return false;

  $res = mysql_query($query);
  if (!$res) {
    trigger_error("dbget: ".mysql_error()." in ".$query);
    return false;
  }

  if ($mode === 0) return $res;

  if ($mode === 1) {
    if ($row = mysql_fetch_row($res)) return $row[0];
    else return NULL;
  }

  $a = array();
  if ($mode === 2) {
    if ($row = mysql_fetch_assoc($res)) return $row;
  }
  if ($mode === 3) {
    while($row = mysql_fetch_assoc($res)) $a[]=$row;
  }
  return $a;
}
?>

您可以将$ dbh添加到它的调用中,但我认为没有任何意义。

  

在PHP中是否有一个函数,你传递$ dbh它会告诉你它是mysql还是mssql句柄

拥有这样的功能绝对没有意义。 当必须使用数据库处理程序时,他们显然必须知道它属于哪个数据库驱动程序 哦。我希望你不会在ms sql中使用mysql_real_escape_string。