Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #78, ИЮНЬ 2005 г.

FAQ

Степан Ильин aka Step

Хакер, номер #078, стр. 078-136-1


(faq@real.xakep.ru)

-----------------------------------------------------------

Задавая вопрос, подумай! Не стоит мне посылать вопросы, так или иначе связанные с хаком/кряком/фриком, - для этого есть hack-faq (hackfaq@real.xakep.ru). Не стоит также задавать откровенно ламерские вопросы, ответ на которые ты при определенном желании можешь найти и сам. Я не телепат, поэтому конкретизируй вопрос, присылай как можно больше информации.

-----------------------------------------------------------

Q: Я хочу опубликовать недавно написанный PHP-скрипт в интернете, но боюсь, что он полон уязвимостей и багов. Меня особенно интересует техника атаки SQL-Injection. Расскажи, как от нее можно защититься.

A: Напомню, SQL-инъекция — это возможность пользователя неправомерно выполнять SQL-запросы на сервере. От этого определения, собственно, и нужно танцевать. Чтобы хакер не передал на сервер свой SQL-запрос, надо лишить его такой возможности, залатав все дыры. Рассмотрим небольшой пример.

Многие сайты имеют систему авторизации пользователя на сервере. Как правило, она реализована крайне просто: специальный скрипт сверяет введенные юзером логин/пароль с данными из базы, после чего выдает соответствующий результат. На практике это выглядит примерно так:

$valid = mysql_query("SELECT Username, Password FROM Users WHERE Username = ' ".$_POST['username']." ' and Password = ' ".$_POST['password']." ' ");

С первого взгляда вполне безопасный код, но… Стоит ввести в поле имени пользователя «' OR 1=1 #» (без кавычек), и серверу передастся следующий запрос:

SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = ''

Хэш-символ (#) в SQL-запросах используется как указатель на комментарии, а все, что идет после него (все необходимые условия для выполнения запроса), сервером попросту игнорируется. Единица всегда равна единице (1=1), поэтому логическое условие OR 1=1 не накладывает ограничения на результат запроса. В итоге сервер, имея на то полные основания, вернет в качестве результата таблицу со всеми логинами и паролями. Как тебе?

Чтобы избавиться от бага, в нашем случае достаточно проверять введенную пользователем информацию на наличие кавычек. Не будет кавычек — не будет изменено условие запроса, а значит, не будет и инъекции. Для этого воспользуемся следующей функцией, которая добавляет перед кавычкой слэш и превращает его в управляющую последовательность: \'. Она не изменит запрос, а просто станет частью условия наравне со всеми остальными символами.

function safe_term($variable) {

$variable = addslashes(trim($variable));

return $variable;

}

А теперь с ее помощью изменим наш запрос:

$username = safe_term($_POST['username']);

$password = safe_term($_POST['password']);

$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = ' ".$username." ' and Password = ' ".$password." ' ");

Q: В нашей сети проблема: постоянно тормозит браузинг. Работать через сетевое окружение практически невозможно. Сеть состоит из 20 компьютеров с WinXP Pro, которые находятся в рабочей группе. Контроллер домена отсутствует.

Содержание  Вперед на стр. 078-136-2