установка пространства имен для UTF-8 какой-либо формы защиты от инъекций SQL? - PullRequest
1 голос
/ 25 марта 2012

Я использую немного заимствованного кода и обеспокоен его уязвимостью для SQL-инъекций ...

// Set the default namespace to utf8
$mysqli->query("SET NAMES 'utf8'");
$userID = $_POST['userID'];
$json   = array();
if($result = $mysqli->query("SELECT * FROM towns WHERE userID=".$userID)) {
while ($row=$result->fetch_assoc()) {
    $json[]=array(
        'townID'=>$row['townID'],
        'townName'=>$row['townName']
    );
}
}
$result->close(); 
header("Content-Type: text/json");
echo json_encode(array( 'towns'  =>   $json ));

Вопрос 1. Есть ли у $mysqli->query("SET NAMES 'utf8'"); какая-либо помощь в инъекции sql? Вопрос 2: я должен использовать некоторую форму real_escape_string?

Если мне нужно использовать real_escape_string, я должен установить переменную следующим образом:

$userID = $_POST['userID'];
$userID = $mysqli->real_escape_string($userID);

Тогда я могу использовать его так же, как в настоящее время в моем запросе?

Спасибо

Ответы [ 2 ]

2 голосов
/ 25 марта 2012

Экранирование $userId недостаточно.

Также необходимо указать значение в запросе или фильтр $userId (чтобы разрешить только цифры).

if($result = $mysqli->query("SELECT * FROM towns WHERE userID='".$userID."'")) {
//                                                            ^         ^^^^
0 голосов
/ 26 марта 2012

Вопрос 1: выполняет ли $ mysqli-> query ("SET NAMES 'utf8'"); есть какая-либо помощь в инъекции sql?

Так сказано - определенно НЕТ.
Но посмотрите записку внизу.

Вопрос 2. Должен ли я использовать какую-то форму real_escape_string?

Вы из заблуждения спрашиваете, что побег имеет какое-то отношение к уколам, а это не так. Итак, давайте перефразируем ваш вопрос:

Вопрос 2а. Должен ли я принять некоторые меры предосторожности против инъекций SQL?

Да.
У вас есть три варианта.

  1. Поскольку $ userID является числом, вы можете явно привести его к этому типу, $userID = intval($_POST['userID'];)
  2. Mysql (когда не в режиме STRICT) позволяет вам отправить число в виде строки. Строки должны быть отформатированы в соответствии с этими двумя простыми правилами, как показано в ответе Роба:
    • он должен быть ограничен одинарными кавычками
    • эти цитаты должны быть экранированы.
  3. Вы можете использовать подготовленные заявления. Чтобы использовать такой модный способ выполнения SQL-запросов, вы должны использовать prepare() + execute() методы вместо query() и связать вашу переменную, используя bind_param().

Примечание относительно заглавного вопроса.

устанавливает ли пространство имен для utf-8 какую-либо форму защиты от SQL-инъекций?

Да, в некотором смысле.
В некоторых, крайне редких случаях, это так.
Для некоторых редких кодировок функция семейства real_escape_string может не сработать из-за выхода правильного разделителя. Чтобы избежать этого, необходимо настроить кодировку клиента, используя семейную функцию set_charset, в вашем случае mysqli->set_charset().

...