Как проверить целочисленные значения, чтобы избежать внедрения SQL? - PullRequest
1 голос
/ 12 марта 2012

Лучший способ избежать внедрения SQL для определенного типа значения, такого как числа, состоит в проверке значения;так как это легче сделать по сравнению с подготовкой mysqli.В PHP мы можем сделать это путем.

1. if(!is_numeric($value)) {$value=0;}
2. $value=floatval($value);
3. $value=intval($value);
4. $value=$value * 1;

Какой самый надежный?или лучшая идея?

ОБНОВЛЕНИЕ: Хотя я уже говорил в первоначальном вопросе, большинство людей подчеркивали полезность параметризованных запросов.Определенно, это самый эффективный способ избежать внедрения SQL.Но когда мы можем просто проверить целочисленное числовое значение;ИМХО, нет необходимости в параметризации.

Ответы [ 6 ]

5 голосов
/ 12 марта 2012

Для целых чисел и чисел с плавающей запятой вы можете использовать это, если вы не хотите делать параметризованный запрос.

$clean_number = (int)$value;

$clean_number = (float)$value;

Они на самом деле приводят значение как int и float, это быстрее, чем intval() и floatval(), например, потому что оно не переносит служебную нагрузку функции.

3 голосов
/ 12 марта 2012

Я предпочитаю использовать расширение фильтра :

$id = filter_var($id, FILTER_SANITIZE_NUMBER_INT);

Вы должны окончательно перейти на параметризованные запросы.

2 голосов
/ 12 марта 2012
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';

try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

$sth = $dbh->prepare('SELECT * FROM table WHERE id = :id');
$sth->bindParam(':id', $id, PDO::PARAM_INT); 
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
2 голосов
/ 12 марта 2012

Вы можете использовать intval(), чтобы привести значение к целому числу. Самый надежный способ избежать внедрения SQL-кода - использовать параметризованные запросы.

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

Если вы хотите опытный совет, вы должны передумать. Полностью.

То, что является вашей главной заботой, на самом деле является самой незначительной вещью в мире. Вы можете использовать тот или иной способ без малейшей разницы. Не существует «самого надежного» пути. Это всего лишь несколько способов сделать то же самое.

С другой стороны, «нет необходимости в параметризации» - это серьезное заблуждение.
Параметризованные запросы могут принести пользу только в том случае, если они используются явным образом по всему сайту, без исключений. Одно исключение может испортить всю защиту.

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

$data = $db->getAll("SELECT * FROM table WHERE id = :placeholder:",$id);

и будь в полной безопасности
без уродливого ручного переплета.
без подверженного ошибкам ручного литья.

Еще один пример, демонстрирующий силу заполнителей

$sql = "SELECT * FROM table WHERE tstamp BETWEEN ?i AND ?i AND flag=?s AND IN in (?a)";
$data = $db->getAll($sql,$min,$max,$flag,$array_of_ids);

Две строки.

Я не слишком хорош в PDO, но это будет похоже на дюжину строк кода даже без подключения

$in  = implode(',', array_fill(0, count($array_of_ids), '?'));
$sql = "SELECT * FROM table WHERE tstamp BETWEEN ? AND ? AND flag=? AND id IN ($in)"
$sth = $dbh->prepare($sql);
$stmt->bindValue(1, $min);
$stmt->bindValue(2, $max);
$stmt->bindValue(3, $flag);
foreach ($array_of_ids as $i => $id) {
  $stmt->bindValue(($i+4), $id);
}
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_ASSOC);

И сопоставимое количество с вашим текущим ручным литьем.

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

Сапиенти сат

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

Вы можете использовать эту функцию mysql_real_escape_string () для пробела специальных символов, но то, что вы делаете, прекрасно для защиты атаки sqli.

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