Привет ребята! Есть вот такое - Код (PHP): $tar = mysql_fetch_array(mysql_query("SELECT * FROM `users` WHERE `login` = '{$_POST['target']}' LIMIT 1;")); Я где-то слышал что если делать так, то есть риск получить иньекцию, подскажите как это исправить? Говорят есть mysql-real-escape-string Это будет выглядеть так - Код (PHP): $_POST['target'] =mysql_real_escape_string($_POST['target']); $tar = mysql_fetch_array(mysql_query("SELECT * FROM `users` WHERE `login` = '{$_POST['target']}' LIMIT 1;")); ?
это не защита от инъекций, а просто экранирование а вообще, всё что приходит от пользователя нужно проверять и простого экранирования может не хватить Добавлено спустя 59 секунд: Код (PHP): $target =mysql_real_escape_string($_POST['target']); $tar = mysql_fetch_array(mysql_query("SELECT * FROM `users` WHERE `login` = ' . $target . ' LIMIT 1;"));
Это получается целый обработчик делать потом сдевить его глобал по сайту и во всех постах предпроверка будет с ним?
тебе нужна безопасность или "простенький код"? Сделай отдельный класс, в котором просто и проверяй определённые типы по своим правилам. Ну или воспользуйся filter_var() Например, у меня (если не считать HTML-код) процентов 60-70 от всего кода - это проверка на безопасность
экранирование это защита от sql-инъекций, необходимая и достаточная. давай не путать мух с супом. "проверять данные" это более общая задача. чтобы случайно не забыть экранировать строки, имеет смысл перейти на prepared statesment — это тру вэй. ну а если почему-то хочется остаться на интерфейсе mysql (не mysqli и не pdo mysql), то было бы неплохо написать свой симулятор плейсхолдеров, работающий с mysql_real_escape_string(). Добавлено спустя 41 минуту 42 секунды: Если быть совсем честным, то есть трудности в сочетании mysql_real_escape_string() и mysql_query('set names utf8'). Некоторые зловредные многобайтовые символы неправильно экранируются и могут быть использованы для атаки. Описано, например, здесь: http://stackoverflow.com/questions/1220182/does-mysql-real- ... -injection Проблема происходит от того, что эскейпинг не знает, что мы решили использовать мультибайтную UTF-8, наш 'set names utf8' проходит для него незамеченным Выход: переключение на utf-8 через вызов mysql_set_charset(), тогда все всё знают и умеют правильно экранировать. Это НЕ значит, что экранирование недостаточная мера. Это значит, что надо правильно всё настраивать. PHP. Character sets
Для удобного использования плэйсхолдеров можешь воспользоваться библиотекой DBSimple, там все это реально просто реализовано.
Вот только наоборот. И экранирование это не защита(!). Это просто экранирование спецсимволов. А если я передаю строку где нет спецсимволов? Это большое заблуждение когда народ считает что экранированием спасётся от инъекций... Экранирование это чтобы запрос не посыпался при обработке Самый простейший пример из ВИКИ Передаём через POST значение ID '-1 OR 1=1'; и мы получаем запрос Код (Text): SELECT login, password FROM user WHERE id = $_POST['id'] т.е. Код (Text): SELECT login, password FROM user WHERE id = -1 OR 1=1 Т.е. хоть об экранируйся, но получим мы все пароли и логины из базы Добавлено спустя 2 минуты 59 секунд: не в качестве рекламы, но я уже предлагал в подобных случаях свой класс... )) Он современнее DBSimple и развивается =) https://github.com/GoDr/GDLDatabase
LOL. это пример корявой логики программиста, а не ущербности функции экранирования. в общем случае, если ты экранируешь строку, ты подразумеваешь, что это СТРОКА. значит запрос наверное содержит строку в апострофах: Код (PHP): $id = mysql_real_escape_string($id); mysql_query("SELECT login, password FROM user WHERE id = '{$id}'"); // у нас здесь строка -- В АПОСТРОФАХ оно, кстати, не вызовет ошибки, даже если поле id целое пожалуйста, попробуй подсунуть сюда инъекцию. сумеешь — я тебе куплю пиво, обещаю! или, если мы работаем с id как с целым, без апострофов: Код (PHP): $id = intval($id); mysql_query("SELECT login, password FROM user WHERE id = {$id}"); // у нас здесь целое это правильная логика Добавлено спустя 5 минут 34 секунды: это был "ручной" способ. а плейсхолдеры (те которые "родные") сами понимают где строка, а где не строка. если мы реализуем свою функцию плейсхолдеров, мы должны добавить простую логику типа: Код (PHP): $id = is_string($id) ? ("'" . mysql_real_escape_string($id) ."'") : (is_null($id) ? 'NULL' : $id);
Вот видишь , ты сам к этому пришёл Экранирование - это экранирование... И все данные нужно готовить... Это я привёл самый простейший пример, что такое вообще может иметь место... А если смотреть сам вопрос темы, то такое может иметь место т.к. глобальное значение просто тупо вставлено в запрос =) А инъекции могут быть очень и очень навороченные, и даже предусматривающие экранирование. В итоге мы приходим с чего я начал.. ID - это integer, а следовательно $_POST[id] нужно к этому привести Добавлено спустя 1 минуту 6 секунд: ВИКИ пока не доступна самая полная документация тут http://forum.vingrad.ru/index.php?showtopic=357736&view=findpost&p=2528484
Gold Dragon, мы с тобой видимо в разных реальностях живем. на моем русском языке фраза "экранирование это защита от sql-инъекций, необходимая и достаточная." понимается однозначно. никакая логика программы не отменяет нужности и не доказывает беспомощности экранирования. не надо демагогии, я вас умоляю.
да без проблем. даже и не собирался. Просто для моих проектов этого мало =) А чтобы завершить эту тему, достаточно просто двух цитат из официальных источников
Мы видим абсолютно одинаково, только для меня экранирование это БОЛЬШОЙ плюс при борьбе с инъекциями, но это не панацея. С другой стороны, я уже полностью перешёл на MySQLi и подготовленные выражения, так что экранирование так каковое для меня это что-то древнее =) PS есть у меня такая не хорошая черта - навязать своё мнение и оставить последнее слово за собой ))) но я активно борюсь с этим.. Хотя этот чуждо только для бесхарактерных ))))
фигня. притянуто за уши. значения в кавычки кто будет брать? это даже не хороший тон а синтаксис SQL. Код (PHP): $_POST['id'] = '-1 OR 1=1'; $sql = "SELECT login, password FROM user WHERE id ='".mysql_escape_string($_POST['id'])."' "; echo $sql;// SELECT login, password FROM user WHERE id ='-1 OR 1=1' и никаких паролей из БД ты неполучишь!
да чтож такое то... я не собираюсь писать реальные запросы и что-то доказывать.. Просто привёл пример что такое возможно =)
да тут нечего доказывать. mysql_escape_string() экранирует данные делая их(для БД) - данными, а не управляющими конструкциями. если в рамках запроса данные обнесены кавычками, то никакие инъекции не пролезут.