Когда mysql_real_escape_string знает, какой сервер БД в данный момент отвечает? - PullRequest
1 голос
/ 26 марта 2012

При таком вызове функции

$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 ]

1 голос
/ 26 марта 2012

Когда mysql_real_escape_string узнает, какой сервер БД в данный момент отвечает?

Из руководства :

Еслиидентификатор ссылки не указан, предполагается последняя ссылка, открытая 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
0 голосов
/ 27 марта 2012

Помимо глупого вопроса, на который можно ответить, просто прочитав страницу руководства, существует гораздо более важная проблема:

Будет ли функция safe правильно обрабатывать инъекции SQL?

Нет.

Поскольку функция safe() в основном не делает ничего, кроме применения mysql_real_escape_string к переданному аргументу, она не должна называться таким образом. Потому что применение mysql_real_escape_string не имеет ничего общего с инъекциями или безопасностью вообще.

По крайней мере эта функция должна добавлять кавычки вокруг переданного значения в дополнение к экранированию. Это сделает некоторые запросы ошибочными, но, по крайней мере, безопасными.

Есть ли способ написать удобную функцию, например, вышеупомянутую строку, при этом убедитесь, что все переменные, помещенные в безопасную функцию, правильно экранированы.

Конечно.
Используйте заполнители.

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

Пользовательский обработчик заменит заполнитель ? на безопасно подготовленное значение.

Вот функция, которую я написал давным-давно с тем же намерением, что и у вас, но более разумный, с учетом безопасности и простоты использования.
Это, безусловно, не идеально - нет необходимости вводить символы % непосредственно в запрос, так как он использует синтаксис printf. И у него нет заполнителя для идентификаторов (как и многих других удобных заполнителей). И, конечно, реализация ООП была бы намного более гибкой, имея аккуратные отличные методы вместо уродливой переменной «mode».
Но если вы хотите функцию

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

Абсолютно бессмысленно иметь такую ​​функцию. Когда нужно использовать обработчик базы данных, он, очевидно, должен знать, к какому драйверу базы данных он принадлежит. Ой. И я надеюсь, что вы не собираетесь использовать mysql_real_escape_string с ms sql.

0 голосов
/ 26 марта 2012

Для правильного экранирования 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();
...