За последние 24 часа нас посетили 19218 программистов и 1621 робот. Сейчас ищут 1059 программистов ...

правильный и безопасный синтаксис sql запроса

Тема в разделе "MySQL", создана пользователем yok, 15 мар 2010.

  1. yok

    yok Активный пользователь

    С нами с:
    15 мар 2010
    Сообщения:
    18
    Симпатии:
    0
    Добрый день всем.

    Я хотя и давно знаком с консолью sql в линуксе, но практически пхп сценарий с использованием запросов не писал.
    И вот понадобилось и не хотелось бы начинать с неправильных и небезопасных синтаксических ошибок.
    Подобной темы не нашел поэтому создал. Хотелось бы собрать рекомендации по этому вопросу.

    У меня есть запросы, и описание их.
    Где правильно, или может иначе, пожалуйста , Ваши мнения.

    Так вот, образцы запросов.
    1. $query_select = "SELECT `id` FROM `table` WHERE `login`='{$login}'"; // нашел что пишут так с {}, что дают фигурные скобки.???

    2. $query_select = "SELECT `id` FROM `table` WHERE `login`='".$login."'"; //тут переменную $login вставляют по таким правилам в стороку с точкой и кавычками

    3. $query_select = "SELECT `id` FROM `table` WHERE `login`='".mysql_real_escape_string($login)."'" //здесь обработка в тебе запроса.

    Я на основании прочитанного всего, думаю 3 самый правильный, но хотелось бы знать мнения профессионалов и не очень.
    Спасибо.

    уточню в этой комбинации WHERE `login`='". это после равно одиночная кавычка, потом двойдные кавычки и точка.

    Кстати при выборке не стоит пренебрежительно относиться к mysql_real_escape_string ?????? Ваше мнение?
     
  2. vuzy

    vuzy Активный пользователь

    С нами с:
    11 мар 2010
    Сообщения:
    199
    Симпатии:
    0
    Адрес:
    киев
    mysql_escape_string() екранирует спец символы которые используются в переменной...
    еще бы непомешал html_special_char() Который преображает тэги < > ? / & и прочие символы в бинарный год
    тоесть нериально будет вставить PHP код в БД и после его вывода удалить сайт либо получить ввести другой SQL запрос и получить информацию о БД...
    использование конкатенации (точек) на мой взгляд правельнее я ниразу не встречал что б переменные задавались фигуоными скобками...

    Да третий вариант самый правельный но mysql_real_escape_string($login) лучше проводить перед запросом сохраняя в переменную.
     
  3. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    1) Есть предположение, что там не должно быть знака доллара. Тогда это будет шаблон запроса. А далее той же str_replace заменяем на конкретное значение.
    2) Используется конкатенация. Можно писать переменную прям в теле строки. Переменная, перед этим, должна пройти обработку на всякую нехорошесть.
    3) Если запрос простой и переменных немного, то вполне да. Но при более сложных запросах, такой подход затрудняет чтение.
    Мне нравиться такой вариант:
    PHP:
    1.  
    2. <?php
    3. $var=$DB->escape($var);
    4. $query_select = "SELECT `id` FROM `table` WHERE `login`=$var";
     
  4. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    На... ээээ... Зачем?

    Чо?!
     
  5. vuzy

    vuzy Активный пользователь

    С нами с:
    11 мар 2010
    Сообщения:
    199
    Симпатии:
    0
    Адрес:
    киев
    ой прошу прощения за глупость.. забыл как функция выглядит.

    пишется htmlspecialchars()
    и он не меняет тэги <> и прочие он их нафиг стирает...
    для тогоч то б нельзя было написать яваскрипт в логине.
     
  6. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Удаляет теги strip_tags.

    htmlspecialchars() заменяет некоторые символы на html сущности.

    И вопросы когда применять эти функции (при записи в БД, при выводе на экран...) и нужно ли вообще их применять решаются для каждой переменной индивидуально.
     
  7. yok

    yok Активный пользователь

    С нами с:
    15 мар 2010
    Сообщения:
    18
    Симпатии:
    0
    Спасибо vuzy и Volt(220) за ответы.

    vuzy писал
    Вот тут пишется в конце пункта 2 о рекомендации использования этой функции именно в теле запроса
    http://phpforum.ru/index.php?showtopic=21213&hl=%EF%F0%EE%E2%E5%F0%EA%E0+e-mail

    и вот тут тоже в теле именно в теле, именно безопасный, в примерах. Но да , ты пишешь о количестве переменных, но думаю безопасность для меня важнее.
    http://doc.mpv.ru/php/function.mysql-real-escape-string.html

    Volt(220)
    Думаю это ктото написал в фигурных, а другие подхватили, видел несколько раз в фигурных и не шаблон.
    Значит это не правильно.

    Насчет htmlspecialchars() , рекомендаций по использованию перед запросами sql, не встречал. Надо подумать.
     
  8. vuzy

    vuzy Активный пользователь

    С нами с:
    11 мар 2010
    Сообщения:
    199
    Симпатии:
    0
    Адрес:
    киев
    про индивидуальность не спорю... но если юзер что то вводит и это что то должно быть простым текстом или цифрами то я думаю проверить его двумя функциями не помешает... mysql_escape_string() только экранирует что б не навредить базе а вот htmlspecialchars() борится... пользователь спросил про:
    безопасности много не бывает а особенно там где пользователь что то вводит.
     
  9. yok

    yok Активный пользователь

    С нами с:
    15 мар 2010
    Сообщения:
    18
    Симпатии:
    0
    vuzy
    Согласен на 100% надо обмазговать это дело.

    Кстати а не кто не обратил внимание что я написал о применении функции mysql_real_escape_string при выборке, именно при select, а не занесении в базу.

    Необходима ли она при выборке или может набедакурить запрос select без нее???
     
  10. vuzy

    vuzy Активный пользователь

    С нами с:
    11 мар 2010
    Сообщения:
    199
    Симпатии:
    0
    Адрес:
    киев
    они сказали что если есть функция тоесть отдельная функция как:
    PHP:
    1.  
    2. function bezopashayastroka($login)
    3. {
    4. mysq_real_escape_string($login)
    5. ...
    6. ..
    7. .
    8. }
    9.  
    А я говорю про совершенно иной случай это когда непосредственно перед запросом каждый раз когда такое выполняется:

    PHP:
    1.  
    2. <?
    3. $login=mysql_escape_string($login);
    4. $sql="INSERT INTO table SET login='".$login."'";
    5. ?>
    6.  
    тоесть функция выполняется последовательно и злоумышленник ну никак не сможет повлиять на результат ее выполнения... а если следовать примеру автора той статьи то может писать запрос сразу в Mysql_query?
     
  11. vuzy

    vuzy Активный пользователь

    С нами с:
    11 мар 2010
    Сообщения:
    199
    Симпатии:
    0
    Адрес:
    киев
    UPD:
    нет никто не обратил или обратили но тут ничего страшного если условие получаемое базой вводит пользователь то его надо проверять.
    ибо вот наглядный пример кстати по твоей ссылке..

    PHP:
    1.  
    2. <?
    3. $res = mysql_query("SELECT * FROM `table` WHERE `login`='my'; DELETE  FROM `table` WHERE `login`!='0'");
    4. ?>
    5.  
     
  12. yok

    yok Активный пользователь

    С нами с:
    15 мар 2010
    Сообщения:
    18
    Симпатии:
    0
    vuzy спасибо за уточнение, я читал это, но еще некоторый сумбур в голове присутствует, от всех функций и пониманий.
     
  13. vuzy

    vuzy Активный пользователь

    С нами с:
    11 мар 2010
    Сообщения:
    199
    Симпатии:
    0
    Адрес:
    киев
    Relax не переутомляйся.. PHP от тебя никуда не денется =)
    и еще об
    а что предлогаешь использовать его во время вывода информации на страницу?
    если зарание продумать скрипт то думаю можно... но я бы делал все перед вводом в MYSQL ибо считаю что так гараздо безопаснее.
    даже если мы после вывода данных из таблицы сделаем эту функцию зная что злоумышленник может написать ява VB или перл сценарий в сообщение мы будем думать что защитимся. Но тут присутствует человеческий фактор.
    Вот напишем мы скрипт а потом через три года надо будет что то к этой таблице дописать ... и функцию при выводе не использовали.. так как поставили ее на ввод а за три года кто то уже успел впиндюрить что нибудь плохое не будет же человек сидеть и перебирать всю БД на наявность таких вот нежелательных вещей.
     
  14. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
  15. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    vuzy
    У меня предложение - воздержаться от дальнейших рекомендаций.

    Именно для этого она и предназначена

    htmlspecialchars не имеет никакого отношения к безопасности БД.
     
  16. vuzy

    vuzy Активный пользователь

    С нами с:
    11 мар 2010
    Сообщения:
    199
    Симпатии:
    0
    Адрес:
    киев
    зато имеет прямое отношение к последующему выводу... выводу из базы данных и точно известно что вредоносный скрипт работать не будет.
    даже если это не так(В чем я лично сомневаюсь) то всегда можно перестраховатся и вызвать функцию еще раз перед выводом. но это даже не пригодится... ибо функция htmlspecialchars() передает в БД
    Код (Text):
    1. &lt;img src=http://ordch.ucoz.ru/WorkNiger.gif&gt
    вот такой набор символов... и при выводе на страницу будет
    HTML:
    1. <img src=http://ordch.ucoz.ru/WorkNiger.gif>
     
  17. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Читать умеем
    правильный и безопасный синтаксис sql запроса

    Поэтому еще раз.
    И применять по принципу "абы було" - не надо. Одно из главных правил промышленной разработки, входные данные неприкосновенны. Если они невалидны - мы их можем не сохранять, можем отфильтровать и предоставить пользователю принять решение что делать.
    Но входные данные должны храниться в неизменном виде.

    Потому что завтра потребуется вывести a > b в текстовый файл, в xml, в doc, pdf, xls, что вы получите из базы?
    Код (Text):
    1. a &gt; b
    И что с этим делать?

    Делиться знаниями это хорошо, когда знания есть. У вас же каша в голове. Поэтому думайте прежде чем что-либо советовать.
     
  18. lexa

    lexa Активный пользователь

    С нами с:
    22 июл 2007
    Сообщения:
    1.746
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    Simpliest, XML для количества вписал? :) Прямая экранизация символов это ж альтернатива CDATA.
     
  19. yok

    yok Активный пользователь

    С нами с:
    15 мар 2010
    Сообщения:
    18
    Симпатии:
    0
    Думаю в споре рождается ИСТИНА, особенно это понимает тот кто мало чего понимает, в частности я.

    Вообще рекомендации к применению mysql_real_escape_string() в теле запроса, в случае если переменных много, действительно не совсем понятно. Запрос действительно будет слишком сложным. И если перед запросом обработать, разве как то может быть ущерб нанесен?? Попытаюсь разобраться а пока вот что нашел.
    это тут http://doc.mpv.ru/php/security.database.sql-injection.html
    может стоит всегда запрос заканчивать так, нагрузки никакой, а просто интерпретируется как комментарий. И думаю такое врядли можно описать как "абы було".
    Как вы думаете?? Использует такое ктолибо.
     
  20. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    yok редко проводят инъекцию в конец запрос ... скорее в середину .. там где переменные .... переменные перед вставкой приводи к нужному типу и mysql_real_escape_string() на строковые переменные - не ленись... остальное уже сказали ....
     
  21. Содержимое страницы морально устарело лет на десять.

    Не читайте советских газет перед едой.
     
  22. yok

    yok Активный пользователь

    С нами с:
    15 мар 2010
    Сообщения:
    18
    Симпатии:
    0
    nimistar , бесспорно, mysql_real_escape_string() это обязательно использование, в последнем сообщении это я написал, о (мы обсуждали выше, что есть рекомендации применение ее именно в теле запроса), и вот не совсем понятно, если обработать прямо перед вставкой в запрос и самим запросом, возможен ли ущерб.?? Вот что является вопросом, где и когда, а не применение самой фунции, которую применять обязательно.

    Как и то, что нужно использовать апострофы и синтаксис WHERE `login`=' ".$login." '

    Но вот


    от сюда http://doc.mpv.ru/php/security.database.sql-injection.html

    именно примеры о дополнении в запрос. Уж слишком просто и не сложно для запроса, а польза от -- коментариев очевидна. Заманчиво применять.

    Прочитал флоппик, значит это устарело рекомендация о -- ???
    Жаль. Спасибо.

    Прав наверно Volt прав что "абы було", и разве вставить хоть как в такой запрос хоть что
    WHERE `login`=' ".mysql_real_escape_string($login)." '
    и -- это о комментариях бессмысленно и не нужно и подпадает под "абы було", точнее на "авось пригодится"
     
  23. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Хм, каких символов? И когда мы увидим эту экранизацию на экране? :)

    Я думаю стоит все же пользоваться CDATA, а не произвольным &amp; , &gt; , etc.

    Какой ущерб?
    Экранирование входных данных применяется для того чтобы запрос не был разрушен данными.
    Т.е. чтобы данные (например, даже такие SELECT * FROM mysql.user) всегда воспринимались именно как данные.
    А не стали отдельным запросом.

    Вставку неправильных(с точки зрения приложения) данных это не предотвращает. Например, если у тебя поле должно содержать только русские буквы, то эту проверку надо делать отдельно.

    Непосредственно перед вставкой в запрос. В остальных случаях зачем их обрабатывать?
     
  24. yok

    yok Активный пользователь

    С нами с:
    15 мар 2010
    Сообщения:
    18
    Симпатии:
    0
    Всем привет.

    Simpliest, наверно я неполно написал, а ты не правильно понял.
    Меня интересовал вопрос обработки фукцией mysql_real_escape_string или в самом запросе или перед запросом.
    Пример.
    1. SELECT * FROM `table` WHERE `id`=' ".mysql_real_escape_string($login)." ';

    2. $login=mysql_real_escape_string($login);
    SELECT * FROM `table` WHERE `id`=' ".$login." ';

    Вот о чем спрашиваю, почему он рекомендует именно в запросе обрабатывать, а не как во втором, сначала обработать а потом в запрос. В чем разница, не понимаю, но он пишет именно так, в зАпросе????

    Тут читал, и именно акцент что в запросе, а так как буквально понимать, то и задумался играет ли это роль. Он пишет непосредственно в самом запросе.
    о сюда выдержка http://phpforum.ru/index.php?showtopic=21213&hl=%EF%F0%EE%E2%E5%F0%EA%E0+e-mail


    А дообработку я делаю регулярным , в нем все и символы и длина.
     
  25. lexa

    lexa Активный пользователь

    С нами с:
    22 июл 2007
    Сообщения:
    1.746
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    yok, в приведённой цитате чел говорит о том, что если писать:
    PHP:
    1. <?
    2. $login=mysql_real_escape_string($login);
    И переменную $login потом ещё где-то использовать (не в другом запросе), то она выдаст каку, а не желаемое. Если ты помнишь свои переменные и от них приходит то, что ты ожидаешь, то пиши так, как тебе удобнее.

    Так же он пишет, что числовые данные лучше сразу приводить к типу:
    PHP:
    1. <?
    2. $id = '123fff';
    3. $id = (int)$id; // теперь $id это 123
    Но это спорно.

    Нет никаких правил для того и другого, тем более догм. Пиши так, как удобнее тебе.