Как привести Bigint, чтобы предотвратить инъекции SQL в PHP? - PullRequest
3 голосов
/ 08 июля 2010

Я использую 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 ]

10 голосов
/ 08 июля 2010

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

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

3 голосов
/ 08 июля 2010

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

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

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

1 голос
/ 08 июля 2010

Используйте подготовленные параметризованные операторы на стороне сервера (и, таким образом, устраните необходимость в 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 голос
/ 08 июля 2010

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

http://www.php.net/is_numeric

0 голосов
/ 19 апреля 2014

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

0 голосов
/ 13 декабря 2012

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

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-битной системе и, таким образом, крошится в научную нотацию при приведении к строке.
И простое регулярное выражение для всего остального

...