Вопрос по безопасности SQL-запросов

Тема в разделе "Как сделать...", создана пользователем verfaa, 19 сен 2013.

  1. verfaa

    verfaa

    Регистр.:
    29 янв 2007
    Сообщения:
    373
    Симпатии:
    41
    Всегда обрабатывал строковые переменные в SQL-запросах ф-ей mysql_real_escape_string(), числовые - intval.
    Недавно мне попал в руки скрипт, в котором программист заключает переменные в SQL-запросах просто в { }
    Например, такой запрос
    SELECT COUNT(*) FROM contacts WHERE user_id = {$user} AND folder_id = {$folder}
    насколько безопасен?
    Почему переменные не обрабатываются intval? В этом запросе есть SQL-уязвимость?

    И ещё несколько вопросов по SQL:
    Нужно обрабатывать переменные только пришедшие извне (из GET POST и т.д.) или абсолютно все переменные, которые присутствуют в запросе? (Даже те которые устанавливаются в теле скрипта, например $user_id = 28473;)

    И ещё, есть ли разница и какой вариант лучше выбрать?
    1) SELECT COUNT(*) FROM contacts WHERE user_id = '".intval($user_id)."'

    2)
    $user = intval($user_id);
    SELECT COUNT(*) FROM contacts WHERE user_id = '".$user."'

    Работаю с БД MySQL
     
    Последнее редактирование: 19 сен 2013
  2. dandandan

    dandandan

    Регистр.:
    7 авг 2008
    Сообщения:
    975
    Симпатии:
    255
    На сколько мне известно структура {$user} применяется с двойными кавычками. Знаки {} говорят интерпритатору php о том, что в них точно находится переменная, в которую нужно вставить соответствующее значение.

    Исходя из этого, код без экранирования параметров - дырявый. Можно сделать sql иньекцию.

    Этот лучше. По крайней мере в выборку попадет только числовое значение параметра.

    Проверять нужно все параметры, пришедшие от пользователя: пост, гет запросы, куки, иногда сессии. Для программистов - параноиков - лучше обрабатывать полностью все входящие параметры. Может получиться так, что часть параметра берется из другой таблицы и без обработки теоретически будет возможна иньекция.
     
  3. BDSG

    BDSG

    Регистр.:
    28 фев 2009
    Сообщения:
    203
    Симпатии:
    109
    через mysql_real_escape_string() должны обрабатываться 100% передаваемых в запрос параметров.. безотносительно источника их происхождения.. точка..
     
  4. demolg

    demolg

    Регистр.:
    13 авг 2007
    Сообщения:
    231
    Симпатии:
    76
    Да? А в prepared statements тоже надо обрабатывать mysql_real_escape_string() ?
     
  5. BDSG

    BDSG

    Регистр.:
    28 фев 2009
    Сообщения:
    203
    Симпатии:
    109
    давайте ещё postgresql, oracle, mssql и т.п. вспомните.. тут речь явно о модуле mysql.. prepared statements в нем нет..
     
  6. vipTelnet

    vipTelnet Постоялец

    Регистр.:
    14 янв 2013
    Сообщения:
    133
    Симпатии:
    11
    советую использовать PDO
     
  7. dazed

    dazed

    Регистр.:
    31 мар 2007
    Сообщения:
    208
    Симпатии:
    55
    Два варианта одинаковы по защищенности. Какой больше нравится стиль написания тот и используйте.
    Я обычно для красоты кода, второй вариант использую.

    А вообще читайте FAQ по инъекицям в mysql. Много интересного можно узнать:)
     
  8. ImNIK

    ImNIK Писатель

    Регистр.:
    7 июл 2012
    Сообщения:
    3
    Симпатии:
    0
    А если переменная текст, разве в таком случае последними двумя вариантами нельзя сделать инъекцию?
     
  9. BACZ

    BACZ

    Регистр.:
    18 июн 2008
    Сообщения:
    608
    Симпатии:
    381
    Если переменная текст то intval от неё будет 0. Инъекцию можно сделать теоретически и для первого и второго варианта, т.к. в примерах в запрос идёт не сама переменная, а intval от неё, а она сама не меняется. Например, инъекция может быть, если user_id где то потом (в коде) пойдёт в запрос без интвала и переменная $user_id получилась из пользовательского ввода. Допустим, в адресной строке user_id=8 union select 1, тогда intval($user_id)=8 а сама переменная не убивается и union в ней путешествует от запроса к запросу
     
  10. f0rsaken198

    f0rsaken198 Создатель

    Регистр.:
    19 янв 2009
    Сообщения:
    8
    Симпатии:
    1
    Используйте PDO и prepared statements - будет вам счастье.