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

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

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

Для тестирования создан файл bad.php, который доступен по адресу http://test4.codeby.net/bad.php?t=MiAl

То, что передаётся параметру t прямиком отправляется в sql-запрос.

В нём набран заведомо уязвимый скрипт:

Подставляем кавычку http://test4.codeby.net/bad.php?t=MiAl'

Получаем ожидаемое

Тестируем:

01

Естественно, как и следовало ожидать.

1. Экранирование спец символов

Для mysqli функция экранирования называется real_escape_string. Т.е. «более правильней» наш скрипт должен бы выглядеть так:

Всего одна новая строка избавила от всех проблем:

61

Помните, что экранировать (как и фильтровать) нужно абсолютно все данные, приходящие "с той стороны", т.е. от пользователя. Даже куки, даже те, которые, казалось бы, жёстко прописаны: например, в выпадающем списке три опции — и выбранная опция отправляется на сервер. Казалось, как предопределённая величина может помочь в SQL-инъекциях? Всё очень просто, современные браузеры, даже без специальных плагинов, позволяют редактировать HTML-код на лету. Т.е. вы ожидаете одно из трёх значений, а получаете хитро сконструированный SQL-запрос.

Ещё одна распространённая ошибка — начинающие программисты думают, что есть страница "для всех" — это те, которые отвечают за работу сайта. А есть страницы только для веб-мастера: админка, технические скрипты и т.п. И эти программисты ленятся (или не считают нужным) экранировать/фильтровать данные. Это грубая ошибка — нужно экранировать и фильтровать везде!

2. Фильтрация данных и приведение к ожидаемому типу

Вы обратили внимание, что вместо $_GET[‘t’] я использую filter_input(INPUT_GET, 't')? Я это делаю не просто так.

Вместе с filter_input я могу использовать фильтры. Например очищающие фильтры.

Если мы ожидаем получить только число, то использовать примерно так filter_input(INPUT_GET, 't', FILTER_SANITIZE_NUMBER_INT)

Если мы хотим, чтобы были отброшены все тэги и все специальные символы, то мы можем использовать filter_input(INPUT_POST, 't', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW) в результате чего удаляются все тэги, удаляются и кодируются специальные символы.

Давайте возьмём наш самый первый уязвимый скрипт и попробуем в нём фильтровать данные таким образом:

62

Результат полностью аналогичен предыдущему — попытка SQLMAP с треском провалилась.

Для строки можно сделать так

(кодирует в формат URL, удаляет специальные символы).

(просто экранируются одиночная кавычка ('), двойная кавычка ("), обратный слэш () и NUL (NULL байт)).

3. Ставьте передаваемые в запрос строки в кавычки

Давайте посмотрим на этот код:

Т.е. мы экранируем кавычки, но мы забыли взять в одинарные кавычки переменную $name, которая является частью запроса. А вот результат:

63

Результат плачевный, не смотря на экранирование кавычек, наш скрипт подвержен SQL-инъекции.

4. Не выводите сообщения об ошибках

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

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

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

Не нужно показывать оскорбительных надписей вроде «F*ck you, hacker!», это может обидеть некоторых тестеров. И вместо обычной процедуры «попробовал-не нашёл-переключился на следующий», тестер может взяться за ваш сайт серьёзно.

Рассмотрим такой вариант скрипта:

Т.е. ничего не фильтруется и даже не поставлены кавычки вокруг $name. Результат следующий:

64

Т.е. в первый момент sqlmap назвала параметр не способным к инъекциям, но очень скоро спохватилась:

Т.е. параметр уязвим к слепой инъекции.

5. Проверяйте все переменный на возможность инжекта

Переменные, про которые часто забывают:

  • скрытые поля в формах, которые пользователь, по вашему мнению, не видит и не может отредактировать (будьте уверены — и видит и может отредактировать)
  • части адреса страницы (даже если у вас mod_rewrite и адреса страниц вроде site.ru/catalog/page/84, даже при правильной настройки .htaccess, нужно понимать, что остаётся возможность обратиться к вашему сайту по адресу site.ru?razd=catalog&type=page&number=84)
  • имена пользователей
  • данные передаваемые методом POST
  • данные из кукиз
  • данные из referer и т.д.

6. Используйте mod_security (или другой файервол для веб-приложений).

mod_security не решит за вас всех проблем, если вы используете скрипты, изобилующие ошибками и дырами. Но, тем не менее, он здорово усилит любой сервер. Рекомендую мои же статьи:

Заключение

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

Похожие темы

Фреймворк для тестирования на проникновение под на... https://codeby.net/forum/threads/dedsploit-framework.58526/ Dedsploit – предназначается для атак по SSH, SMTP и HTTP. Авторы говорят, что данный фр...
Анонимный пентест с Kali linux через Whonix Gatewa... https://codeby.net/forum/threads/anonimnyj-pentesting-kali-linux-posredstvom-whonix-gateway.58152/ Kali linux через шлюз Whonix Gateway и все это...
oclHashcat на Kali Linux: установка, проблема с «A... Чтобы не путаться в названиях, сразу определимся, что: Hashcat — программа для перебора (взлома паролей) oclHashcat — то же...
Обход UAC на удаленном компьютере жертвы... https://codeby.net/forum/threads/bypass-uac-metasploit.57901/ Всем привет! В этой статье я бы хотел описать один важный прием в работе с Meterpre...
100% эксплоит, который не детектится антивирусами... https://codeby.net/forum/threads/100-ehksploit-ne-detektitsja-antivirusami.58382/ Хочу Вас познакомить с одним замечательным генератором TheFatRat....