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, которые находятся в рабочей группе. Контроллер домена отсутствует. |