Как защитить ODBC-запрос от SQL-инъекции - PullRequest
2 голосов
/ 16 февраля 2012

Как лучше всего защитить этот запрос от SQL-инъекций?Этот пример - просто пример, я прочитал несколько статей в Интернете, но не могу разобраться с параметризованными запросами.Любые ссылки на полезные статьи получат право голоса, но я думаю, что этот пример поможет мне лучше всего.

$id = $_GET["id"];
$connection = odbc_connect("Driver={SQL Server};Server=SERVERNAME;Database=DATABASE-NAME;", "USERNAME", "PASSWORD");
$query = "SELECT id firstname secondname from user where id = $id";
$result = odbc_exec($connection, $query);
while ($data[] = odbc_fetch_array($result));
odbc_close($connection);

Спасибо,

РЕДАКТИРОВАТЬ: Я не сделал это очевидным, но я 'Я использую SQL Server, а не MySQL.Это всего лишь пример, это не всегда будет число, которое я ищу.Было бы неплохо, если бы в ответе использовались параметризованные запросы, как полагают многие, и он был бы одинаковым для всех запросов вместо разных типов проверки для разных типов пользовательского ввода.

Ответы [ 4 ]

3 голосов
/ 16 февраля 2012

Я думаю, объекты PDO являются лучшими.

В двух словах, вот как вы их используете.

$databaseConnection = new PDO('mysql:host='. $host .';dbname=' . $databaseName, $username, $password);

$sqlCommand = 'SELECT foo FROM bar WHERE baz=:baz_value;';
$parameters = array(
    ':baz_value'    => 'some value'
);

$preparedStatement = $databaseConnection->prepare($sqlCommand);
$preparedStatement->execute($parameters);

while($row = $preparedStatement->fetch(PDO::FETCH_ASSOC))
{
    echo $row['foo'] . '<br />';
}

Значения, которые вы вводите дляКритерии SELECT заменяются параметрами (например, :field_value), которые начинаются с двоеточия.Параметрам затем присваиваются значения в массиве, которые передаются отдельно.

По моему мнению, это намного лучший способ обработки запросов SQL.

Параметры отправляются в базу данных отдельно отзапрашивает и защищает от внедрения SQL.

1 голос
/ 16 февраля 2012

Используйте готовые заявления.Сначала создайте оператор с помощью функции odbc_prepare (), затем передайте ему параметры и выполните его с помощью odbc_execute ().

Это намного более безопасно и проще, чем экранирование строки самостоятельно.

Совет Льюиса Бассетта о PDO хорош, но можно использовать подготовленные операторы с ODBC, не переключаясь на PDO.

Пример кода, не проверено!

try {
  $dbh = new PDO(CONNECTION_DETAILS_GO_HERE);
  $query = 'SELECT id firstname secondname from user where id = :id';
  $stmt = $dbh->prepare($query);
  $stmt->bindParam(':id', $id, PDO::PARAM_STR);
  $result = $stmt->execute();
  $data = $stmt->fetchAll();
} catch (PDOException $e)
  echo 'Problem: ', $e->getMessage;
}

Примечание: $ e-> getMessage ();может показывать вещи, которые вы не хотите раскрывать, поэтому вы, вероятно, захотите сделать что-то другое в этой строке, когда ваш код заработает.Тем не менее, это полезно для отладки.

Редактировать: Не уверен, что вам нужен пример PDO или ODBC, но в основном это то же самое для обоих.

Редактировать: Если вы меня отрицаете, оставьте комментарийи скажи мне почему.

1 голос
/ 16 февраля 2012

Для начала, будьте осторожны с переменными, которые вы используете в своих запросах, особенно те, которые поступают из внешних источников, таких как $ _ GET, $ _POST, $ _COOKIE и $ _FILES .Чтобы использовать переменные внутри ваших запросов, вы должны:

  • Привести числовые данные к целому или с плавающей точкой (в зависимости от того, что подходит)
  • Использовать соответствующее экранирование для экранирования других данных

Простой пример для баз данных mysql:

$id = $_GET["id"];     // contains: OR 1 = 1
$name = $_GET["name"]; // contains: ' OR '' ='
$query = "SELECT * FROM table WHERE id = " . intval($id) . " AND name = '" . mysql_real_escape_string($name) . "'";
// SELECT * FROM table WHERE id = 0 AND name = '\' OR \'\' =\''

Для других баз данных практика экранирования варьируется.Но обычно вы должны экранировать символ ' с помощью '', поэтому:

$id = $_GET["id"];     // contains: OR 1 = 1
$name = $_GET["name"]; // contains: ' OR '' ='
$query = "SELECT * FROM table WHERE id = " . intval($id) . " AND name = '" . str_replace("'", "''", $name) . "'";
// SELECT * FROM table WHERE id = 0 AND name = ''' OR '''' ='''

Сказав это, возможно, вы захотите переключиться на PDO .Это позволяет вам использовать подготовленные операторы , драйвер PDO выполняет все экранирование.

0 голосов
/ 16 февраля 2012

Вариант mysql поставляется с методом mysql_real_escape_string, который подходит для целевой версии SQL.Лучшее, что вы можете сделать, это написать метод, чтобы избежать Id.Важно, чтобы ваш метод escape соответствовал целевой базе данных .Вы также можете выполнить базовую проверку типов, например, is_numeric для числовых входов немедленно отклонит вставки строк SQL.

См. Как экранировать строки в SQL Server с помощью PHP? и перейти по некоторым связанным ссылкамявные примеры

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...