Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Что плохого в таком коде?
 
 автор: vtos   (28.03.2010 в 20:25)   письмо автору
 
 

Всем здравствуйте!
Ребят, объясните пожалуйста - если человек пишет вот такую строку кода:
$q = mysql_query("SELECT * FROM some_table WHERE id = {$_GET['id']}");

и при этом ранее в своем коде он выполняет такую операцию -
$_GET['id'] = intval($_GET['id']);
,
то что плохого в этом коде? Какие уязвимости, какие замечания по стилю?
Напишите, пожалуйста свое мнение.
Спасибо.

  Ответить  
 
 автор: Красная_шляпа   (28.03.2010 в 21:51)   письмо автору
 
   для: vtos   (28.03.2010 в 20:25)
 

Тут нет уязвимостей

  Ответить  
 
 автор: Саня   (28.03.2010 в 22:27)   письмо автору
 
   для: vtos   (28.03.2010 в 20:25)
 

Отрицательные числа проскочат.

  Ответить  
 
 автор: vtos   (28.03.2010 в 22:53)   письмо автору
 
   для: Саня   (28.03.2010 в 22:27)
 

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

  Ответить  
 
 автор: Саня   (28.03.2010 в 23:41)   письмо автору
 
   для: vtos   (28.03.2010 в 22:53)
 

Это недочёт. Зачем нагружать MySQL заведомо бессмысленными запросами?

  Ответить  
 
 автор: vtos   (28.03.2010 в 23:50)   письмо автору
 
   для: Саня   (28.03.2010 в 23:41)
 

А вот еще такой момент - через GET может быть передано число, оно будет даже положительным, но, допустим, такого id в базе нет. Тогда получается нечто похожее на ситуацию с отрицательным числом - в базе заведомо нет такого id, значит MySQL будет так же гоняться впустую. Предлагался такой вариант - сначала проверять, есть ли вообще такой id в базе (это, скорее всего, будет выглядеть как SELECT COUNT(*) FROM... WHERE id = ...), и если есть, то только тогда уже выполнять целевой запрос... Но это как-бы тоже дополнительная нагрузка на сервер БД. Что скажете?

  Ответить  
 
 автор: Саня   (29.03.2010 в 00:09)   письмо автору
 
   для: vtos   (28.03.2010 в 23:50)
 

Скажу что это бред.

> Тогда получается нечто похожее на ситуацию с отрицательным числом - в базе заведомо нет такого id.
А вот это как раз нельзя назвать "заведомо", так как мы не знаем этого заранее, без запроса к СУБД.
Например для поля MEDIUMINT UNSIGNED заведомо некорректные данные — не числа, дробные числа и числа, не входящие в промежуток от 0 до 16777215.

> через GET может быть передано число, оно будет даже положительным
Не забываем, что intval() переводит в число всё, даже пустую строку. Так что запрос сработает в любом случае, даже если передавать не числа.

  Ответить  
 
 автор: vtos   (29.03.2010 в 00:40)   письмо автору
 
   для: Саня   (29.03.2010 в 00:09)
 

Спасибо за пояснения!

  Ответить  
 
 автор: Trianon   (29.03.2010 в 00:38)   письмо автору
 
   для: vtos   (28.03.2010 в 20:25)
 

мне не нравится только стиль

  Ответить  
 
 автор: vtos   (29.03.2010 в 00:42)   письмо автору
 
   для: Trianon   (29.03.2010 в 00:38)
 

А как конкретно можно аргументировать это "не нравится"? Имеется в виду написание кода, его читаемость, зрительное восприятие? Поясните, пожалуйста.

  Ответить  
 
 автор: Trianon   (29.03.2010 в 00:47)   письмо автору
 
   для: vtos   (29.03.2010 в 00:42)
 

1) Когда я вижу надпись $_GET['id'] , я изначально считаю, что там находится пользовательский ввод и ничто иное.
2) Я не допускаю присваивания переменным суперглобальных массивов (кроме $_SESSION и $GLOBALS конечно) каких-либо значений. Суперглобальные массивы заполняет php на старте и точка. Единственное исключение из этого правила - откат магических кавычек. Именно откат - до состояния пользовательского ввода. Поэтому это скорее не исключение, а подтверждение правила.

Вышеуказанные строки эту позицию грубо нарушают.

  Ответить  
 
 автор: vtos   (29.03.2010 в 00:49)   письмо автору
 
   для: Trianon   (29.03.2010 в 00:47)
 

Все понятно, благодарю.

  Ответить  
 
 автор: Trianon   (29.03.2010 в 00:51)   письмо автору
 
   для: vtos   (29.03.2010 в 00:49)
 

еще момент

3) Код, формирующий оператор SQL, я пытаюсь писать так, чтобы ситуация с отсутствием инъекций была ясна из текста самого оператора, и не требовала глядеть куда-то сильно далеко от точки этого текста.

  Ответить  
 
 автор: vtos   (29.03.2010 в 00:56)   письмо автору
 
   для: Trianon   (29.03.2010 в 00:51)
 

То есть, приведенный мною пример следовало бы записать так:
$q = mysql_query("SELECT * FROM some_table WHERE id = ".intval($_GET['id']));

Я правильно понял?

  Ответить  
 
 автор: Trianon   (29.03.2010 в 02:09)   письмо автору
 
   для: vtos   (29.03.2010 в 00:56)
 

Да. В таком виде оператор выглядит абсолютно безопасно.

  Ответить  
 
 автор: Николай2357   (29.03.2010 в 09:17)   письмо автору
 
   для: vtos   (29.03.2010 в 00:56)
 

Вот так лучше:
$res = mysql_query("SELECT * FROM some_table WHERE id = ". (int)$_GET['id']);

1. Функция mysql_query возвращает указатель на результат ($res), а не запрос ($q)
2. (int) - языковая конструкция, а intval() - функция. А значит первая работает на много быстрее.

  Ответить  
 
 автор: Тень*   (29.03.2010 в 09:42)
 
   для: Николай2357   (29.03.2010 в 09:17)
 

На сколько наносекунд быстрее-то?

  Ответить  
 
 автор: Николай2357   (29.03.2010 в 11:15)   письмо автору
 
   для: Тень*   (29.03.2010 в 09:42)
 

На порядок. Мелочь, а приятно.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования