Как привести Bigint для предотвращения инъекций SQL в PHP?

Я использую php и запускаю sql запросы на сервере mysql. чтобы предотвратить инъекции sql, я использую mysql_real_escape_string.

я также использую (int) для приведения чисел, следующим образом:

$desired_age = 12;
$query = "select id from users where (age > ".(int)$desired_age.")";
$result = mysql_query($query);

эта работа.

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

$user_id = 5633847511239487;
$query = "select age from users where (id = ".(int)$user_id.")";
$result = mysql_query($query);
// this will not produce the desired result, 
// since the user_id is actually being cast to int

Есть ли другой способ приведения большого числа (например, BIGINT), кроме использования mysql_real_escape_string, когда речь идет о предотвращении инъекций sql?

6 ответов

Решение

Вы можете использовать что-то вроде:

preg_replace('/[^0-9]/','',$user_id);

заменить все нечисловые символы в вашей строке. Но на самом деле в этом нет необходимости, просто используйте mysql_real_escape_string(), так как ваше целочисленное значение в любом случае будет преобразовано в строку после построения $query.

Если вы генерируете идентификатор пользователя самостоятельно, нет необходимости приводить его к MySQL, поскольку нет шансов на внедрение SQL или другие строковые проблемы.

Если это пользовательское значение, используйте filter_var() (или же is_numeric()) чтобы убедиться, что это число, а не строка.

Подтвердите ввод. Не просто избежать этого, подтвердить его, если это число. Есть пара функций PHP, которые делают свое дело, например is_numeric() - Находит, является ли переменная числом или числовой строкой

http://www.php.net/is_numeric

Используйте подготовленные параметризованные операторы на стороне сервера (и, таким образом, устраните необходимость в xyz_real_escape_string()) и / или рассматривайте идентификатор как строку. Сервер MySQL имеет встроенные правила для преобразования чисел в строку<->, и если вы решите изменить тип / структуру поля id, вам также не нужно менять код php. Если у вас нет конкретных потребностей в (микро) оптимизации, обычно нет необходимости позволять коду делать такие предположения относительно структуры и диапазона значений поля id в базе данных.

$pdo = new PDO('mysql:...');
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

$stmt = $pdo->prepare('SELECT age FROM users WHERE id=?');
$stmt->execute(array('5633847511239487'));

Вы даже можете умножить переменную на *1, вы можете проверить минимальные и максимальные значения, которые вы можете принять (для возраста bigint это не вариант вообще... так зачем даже разрешать числа, превышающие значения, к которым вы подготовлены? И есть также PDO с его подготовкой запроса.

После некоторых исследований я пришел к такой установке

private function escapeInt($value)
{
    if (is_float($value))
    {
        return number_format($value, 0, '.', ''); // may lose precision on big numbers
    }
    elseif(preg_match('/^-?[0-9]+$/', $value))
    {
        return (string)$value;
    }
    else
    {
        $this->error("Invalid value");
    }
}

Отдельный случай для поплавков, потому что $i = 184467440737095; становиться плавающим в 32-битной системе и, таким образом, рушится в научную нотацию, когда приводится в строку.
И простое регулярное выражение для отдыха

Другие вопросы по тегам