Я последнее время интересуюсь защитой от SQL-инъекций. И недавно наткнулся вот на это видео на YouTube (). Т.к. я только обучаюсь всем премудростям программирования (php+mysql), то у меня возник вопрос: поможет ли данный метод от SQL-инъекций? За ранее благодарен.
в рамках составления запроса не важно делается ли склейка или форматирование строки. главное что с данными было сделано ДО этого. ответ - нет, sprintf скорее для удобства составления запроса, но безопасности там даже процента не нагребется.
Спасибо за оперативность))) Просто я провел небольшой эксперимент такого типа: 1. Вначале сделал такой запрос: $news = mysql_query("SELECT * FROM `news` WHERE `id`='$id'",$db); и попробовал провести sql-запрос такого плана (news.php?id=1') - он мне отобразил ошибку (mysql_fetch_array() expects parameter 1 to be resource, boolean given in...). 2. Далее я сделал почти так как говорилось в видео: $news = "SELECT * FROM `news` WHERE `id`='%d'"; $news_1 = sprintf($news,$id); $news_2 = mysql_query($news_1,$db); и попробовал провести sql-запрос такого плана (news.php?id=1') - ошибка не вылетела. Потом начал пробовать разные sql-инъекции такого плана: UNION SELECT 1,2,3,4,5 or1=1 При первом варианте ошибки вылетали, а при втором - нет. И заметьте, я намеренно не фильтровал входящие данные. Вот по этому я и обратился к гуру по данному вопросу)) P.S. Если что-то назвал не своими именами - прошу сильно не пинать - я только учусь))) P.S.2 Забыл упомянуть - тестирую все на денвере.
Вы про что имеете ввиду? Я это к тому, что у меня в голове каша образовалась от всей информации, которую я прочитал в интернете по поводу защиты от SQL-инъекций...
короче чтобы всякие слова не были интерпретированы как служебные в случаях, если они таковыми не являются, их заключают в кавычки. встретив кавычки, парсер mysql резонно полагает, что перед ни данные, а не команды. первый бастион защиты - это кавычки. можно обойтись и без них, если как у вас в запросе выбирается по числу. тогда $id = (int)$id; гарантированно обезопасит от вреда. В случае со строковыми данными такой фокус не пройдёт. И мы возвращаемся к кавычкам. Чтобы победить кавычки достаточно передать в данных такую же кавычку. Парсер резонно (опять-таки) сочтёт это концом строки. Всё что дальше будет истолковано, как запрос со всеми вытекающими. Как же нам передать с базу данных строку, содержащую кавычки? - Как обычно, поставив перед ними слешики. По уму они именуются "эскейп последовательности". Для автоматической расстановки слешей используется real_escape_string. Почему она называется real*? Потому что она учитывает текущую кодировку соединения. Это важно. Ибо есть способ впендюрить галку в строку если она конвертируется из UTF в какую-то там однобайтную, не помню какую. Поэтому очень важно после соединения с сервером, установить кодировку (и желательно в UTF, ибо XXI век на дворе). Соответственно, для борьбы с инъекциями надо сделать как минимум: - установить кодировку - заюзать real_escape_string - взять её результат в кавычки Эскейпить надо все данные, которые идут в запрос. Если конечно вы их не заинвалили как $id. Об этом обычно забывают, и эскейпят только при внесении данных в базу. Потом при выборке, поиске и прочем, эти данные могут быть использованы в запросе. Программисты считают, что раз в БД данные прошли чисто, то данные чистые, и не эскейпят их. Вот тут и косяк может быть. Будет инъекция со всеми вытекающими. К счастью это не единственный способ. Есть еще более надёжный способ. Называется "Prepared Statements". Информацию почерпнёте сами.
я сразу сказал что защиты от форматирования строки примерно 1 процент. и вы тут же смогли угадать о чем я говорю - конструкция %d. ну есть еще %f, %x, %b и тому подобное. главное НЕ %s. эти форматы гарантированно изуродуют данные если на входе идет не число а строка. а в случае с %s у вас просто пролетит все в исходном виде и привет инъекция. поэтому еще раз: для формирования кода оно иногда удобно (я вот например почти постоянно так формирую запросы), но для защиты все равно используются другие методы. они стандартны и не понимаю почему все так стесняются ими пользоваться.
В одинарные или двойные (Типа: ...WHERE `id`='$id'...) ? Это Вы про PDO и подобные ему стандарты? P.S. Спасибо Вам всем за подробные и быстрые ответы.
да зачем в пдо-то углубляться?) его раньше не было а люди как-то обходились... я про _real_escape_string. прийтись им по строке и дальше не важно что будет дальше - конкатенация или форматированная строка обращайтесь )))
Это имеется ввиду про такие запросы: "SELECT * FROM `news` WHERE `id`='$id'" или вот такие:"SELECT * FROM `news`" или про оба варианта?
второе это "жестко кодированный" запрос. в нем не меняется ничего. первое - "динамически кодированный" то есть от значения переменной id будут разные вариации итоговой строки запроса. теперь сами подумайте где у вас могут проскакивать данные которые нужно экранировать?
да пофик лучше не портить содержимое переменных, вдруг придется переспросить у юзера исправить данные. Код (PHP): "...WHERE `id`='" . $mysqli->real_escape_string($id) . "'"; но в данном случае я бы заюзал (int)$id и без кавычек.
Недавно взломали твиттер Барака Обамы, так что думаю ты можешь быть спокойным, твой сайт взломают тоже =)
Чем выше защита, тем меньше вероятности, что мой сайт взломает какой-нибудь школьник. А по поводу максимальной защиты - я в курсе, что можно взломать любой сайт.
Просто нехрен на пароль кличку собаки ставить - раз. И два - роботы кейлоггеры и трояны всякие бдят денно и нощно. Добавлено спустя 52 секунды: По инъекциям вопросы остались?
Я про то, что Вы мне рассказали теорию про SQL-инъекции, а мне нужно теперь перейти к практике. Я к тому, что нужно в дальнейшем проверить мой код на инъекции. Ну это уже моя головная боль)))) Остается еще вопрос (если не затруднит ): какие виды взлома сайта еще существуют? И где можно прочитать про защиту от ионных?