2010-07-08 2 views
7

У меня есть приложение, которое берет данные через запрос POST. Я использую эти данные для вставки новой строки в базу данных. Я знаю, что использование mysql_real_escape_string() (плюс удаление% и _) - это путь для строк, но как насчет целых значений? Прямо сейчас, я использую функцию PHP intval().Санитарный ввод базы данных Integer

Однако я хотел убедиться, что intval() совершенно безопасен. Я не вижу способ атакующего, который предварительно формирует атаку SQL-инъекций, когда переменные запускаются через intval() (так как он всегда возвращает целое число), но я хотел убедиться, что это случай от людей, у которых больше опыта, чем у меня .

Спасибо.

+0

Heads up: Если вы имеете дело с номерами размером более 32 или 64 бит (в зависимости от вашей платформы) 'intval()' будет возвращать ноль. Это явно нежелательно, если вы пытаетесь хранить очень большие цифры в своей базе данных. Например, идентификаторы facebook не вписывались в 32 бита в течение многих лет. Http://developers.facebook.com/blog/post/45 –

+0

@Frank Farmer: Хм .. это интересно. Спасибо за головы. Я рассмотрю, что мы можем сделать, чтобы решить эту проблему, если это необходимо. –

ответ

21

Да, intval() безопасен. Невозможно выполнить SQL-инъекцию, когда параметр преобразуется в целое число, потому что (очевидно) формат целого не позволяет помещать в него ключевые слова SQL (или кавычки или что-то еще).

+0

Хорошо, вот что я подумал. Спасибо. –

+4

Вы также можете использовать '(int) $ id', потому что литье выполняется намного быстрее, чем использование функции' intval ($ id) '. Проверьте: http://hakre.wordpress.com/2010/05/13/php-casting-vs-intval/ – DaFrenk

+0

Вы уверены? Дело в том, что intval много разрешает то, что требуется в качестве входного параметра. Этот код дает правильные целочисленные результаты, но я бы никогда не захотел таких значений внутри своих запросов: '$ var =" 123TYPE_JUGGLING "; var_dump (is_numeric ($ var)); var_dump ((int) $ var); var_dump (intval ($ var)); ' –

4

Самый простой способ предотвратить SQL-инъекцию - всегда использовать подготовленные записи. Используйте Mysqli библиотеки или еще лучше ОРМ, такие как доктрины и т.д.

Ваши запросы затем становятся чем-то вроде:

$stmt = $db->prep_stmt("select * from .... where userid = ? and username = ?"); 

/* Binding 2 parameters. */ 
$stmt->bind_param("is", $userid, $username); 

$userid = 15; 
$username = "don"; 

/* Executing the statement */ 
$stmt->execute() or die ("Could not execute statement"); 
+2

+1 для подготовленных заявлений. Тем не менее, я все еще проверяю входные данные пользователя перед выполнением вставки, чтобы избежать исключения SQL. Если, конечно, ORM или рамки не делали этого для меня. –

+0

К сожалению, подготовленные заявления недоступны для данного проекта. –

2

Я всегда делаю

$var = (int)$_POST['var']; 

, чтобы убедиться, что $ вар обрабатывается как целое число во всех обстоятельствах и никогда больше не смотрите на $ _POST ['var']. Глядя на руководство, intval() делает то же самое.

Какой бы путь вы ни выбрали, в подпоследовательности $ var будет фактическим целым числом, которое вполне безопасно обрабатывать.

2

Подготовленный статус - лучший способ справиться с SQL-инъекцией. или используйте PDO , в противном случае intval лучше, чем is_numeric

Смежные вопросы