Главная   Новости   Поиск   
Азбука программиста




Яндекс.Метрика

Уязвимости в SQL запросах

Уязвимости в SQL запросах

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

1-ая уязвимость касается движка MySQL

В MySQL существует параметр, который именуется max_packet_size. По-умолчанию ему присвоено значение 1МБ. Он держит под контролем наибольший размер пакетов, которые передаются меж SQL клиентом и сервером. Если запросы либо итог их выполнения не укладывается в размер пакета – появляется ошибка.Это значит, что очень длинноватые SQL запросы никогда не отправляются серверу , а следовательно, никогда не выполнятся.

Это может привести к трагедии, если взломщик может передать огромные блоки данных, которые позже употребляются в SQL запросах.

К примеру, представьте запросы авторизации, которые объединяют информацию из HTTP заголовков, id сессий и логов. В итоге выходит большой запрос, который не укладывается в размер пакета.

Очередной пример – чистка таблицы сессий, при которой поначалу создается PHP массив из всех сессий, которые соответствуют определенным характеристикам, после чего производится чистка, а в конце создается один большой запрос на удаление со всеми id избранных сессий. Разумеется, что таковой запрос может быть весьма упитанным.

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

2-ая уязвимость касается длины столбцов.

Если не инспектировать длину данных, приобретенных извне, может появиться уязвимость, связанная с отбрасыванием части данных при вставке в таблицу (SQL Column Truncation Vulnerabilities).

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

В MySQL можно активировать режим sql_mode STRICT_ALL_TABLES чтоб перевоплотить эти предупреждения в ошибки (errors). Но большая часть web приложений работают на серверах, запущенных в обыкновенном режиме.

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

К примеру, представим такую ситуацию.

  1. web приложение представляет собой форум;
  2. имя админа понятно, к примеру, «gogi1»;
  3. MySQL работает в обыкновенном режиме;
  4. в приложении отсутствует ограничение на длину имени юзера;
  5. длина поля в базе данных равна 16-ти символам.

Взломщик может попробовать зарегистрироваться под именованием «gogi1» (с пробелом в конце), но это ему не получится, если производится проверка на существование такового имени.

Дело в том, что MySQL не ассоциирует данные в двоичном режиме. По-умолчанию употребляется более эластичная система проверок. При которой пробелы в конце строк отбрасываются. Это значит, что строчки «gogi1» «gogi1 » равны.

Т.е. запрос

SELECT * FROM user WHERE username=gogi1 '

возвратит данные реального админа и в регистрации с таким именованием будет отказано.

Но что произойдет, если взломщик употребляет имя «admin х» (одиннадцать пробелов после слова admin и в конце буковка «х»)? Такое имя найдено не будет, так как нереально отыскать зарегистрированного пользователя с длонной логина  17 знаков, если поле базы данных имеет ограничение в 16 знаков.

Т.е. приложение сможет добавить пользователя с таким логином в базу . Но при всем этом имя будет обрезано до ширины столбца. Т.е. MySQL откинет последнюю буковку «х» и имя перевоплотится в «gogi1 » (одиннадцать пробелов в конце).

Вот здесь и появляется уязвимость. К примеру, для авторизации юзера употребляется последующий код.

$userdata = null; if (isPasswordCorrect($username, $password)) { $userdata = getUserDataByLogin($username); ... }

Если функция isPasswordCorrect употребляет запрос вида:

SELECT username FROM users WHERE username = ? AND passhash = ?

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

После чего производится функция getUserDataByLogin, которая обычно содержит запрос вроде

SELECT * FROM users WHERE username = ?

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

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

За статью благодарим сайт http://tour-rus.ru



Безопасность

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

Читать далее