Как обезопасить сайт
Я уже много раз говорил, что самые безопасные сайты - это сайты, написанные самостоятельно с нуля. Фактически, Вы защищатесь тем самым от всяких школьников, мнящих себя великими хакерами, которых очень много. Однако, имеются люди, знания которых достаточно для взлома весьма серьёзных сайтов, написанных с нуля. Поэтому чтобы Ваш сайт выдержал эту атаку, я решил написать эту статью и рассказать, как обезопасить сайт.
Самое главное - это всегда задавать самому себе вопрос: "А что будет, если...?". Если Вы всегда будете задаваться таким вопросом, то Ваш сайт всегда будет защищён практически на 100%.
Теперь же давайте разберём самые основные способы защиты. Самое уязвимое место - это скрипты-обработчики входящих данных из форм. Всегда проверяйте то, что вводится пользователем в форму. Для этого используйте регулярные выражения.
Также всегда вызывайте функцию htmlspecialchars(), которая заменяет опасные символы на сущности. Исключение - те данные, в которых и должен быть HTML-код.
Если в запросе к базе данных используются данные, ведённые пользователем, то всегда эти входные данные экранируйте с помощью функции addslashes(). Эту функцию надо использовать только, если отключена директива magic_quotes_gpc. Если она включена, то все входящие данные экранируются автоматически.
Всегда отключайте директиву register_globals. Как показывает практика, абсолютное большинство программистов не инициализируют переменные. Приведу простой пример:
<?php
$mysqli = new mysqli("localhost", "root", "", "mydb");
$array["first"] = "1";
$array["second"] = "2";
foreach ($array as $key => $value) {
$mysqli->query("DELETE FROM `my_table` WHERE `field`='$value'");
}
?>
Если бы Вы проиницилизировали массив так: $array = array();, то всё было бы в порядке. Однако, уверен, что далеко не все из Вас так делают. В результате, злоумышленник переходит по такому адресу: http://адрес_сайта/адрес_скрипта.php?array[zero]=0, и Ваш скрипт благополучно удаляет ту запись, которую удалять не стоило. А ничего не было бы, если бы была отключена директива register_globals.
Подведу небольшой итог:
- Всегда пропускайте входящие данные через htmlspecialchars(), за исключением тех случаев, где необходимо оставить HTML-теги.
- Проверяйте все входящие данные на правильность, используя строковые функции и/или регулярные выражения.
- Пропускайте входящие данные через функции stripslashes(), если они будут использоваться в запросах к базе данных. Не пугайтесь, что в базу попадут экранированные символы. Нет, данные в базе будут такими же, какими их отправляли в форме. Просто сам запрос будет безопасным.
- Отключайте register_globals.
- Всегда проверяйте работу скриптов на самых различных входных данных. Не забывайте, что если Вы просите ввести, например, фамилию, пользователь не захочет ввести какой-нибудь JS-код.
Это лишь часть самых простых и самых основных правил о том, как обезопасить сайт. В большинстве случаев их соблюдение уже более, чем достаточно, чтобы Вы могли спать спокойно.
-
- Михаил Русаков
Комментарии (32):
Михаил ! А как же тогда защитится от прямого ввода в строку адреса ссылки тыпа этой?! http://адрес_сайта/адрес_скрипта.php?array[zero]=0 запрос на удаление у меня идет вот так... <a href='action.php?del=$id'>ссылка на удаление</a> а вот сам экшн : if($_GET['del']){ $q = mysql_query("SELECT COUNT(id) FROM table WHERE id='$_GET[del]'"); $r = mysql_result($q,0); mysql_query("DELETE FROM table WHERE id='$_GET[del]' LIMIT 1"); Действительно я упустил из виду что злоумышленник может методом брута подобрать ссылку и удалить не нужную запись. Как тогда в моем случае защититься?
Ответить
Для этого и существует авторизация и права доступа. Сделайте так, чтобы только администратор мог так удалять.
Ответить
А к примеру если это записи на стене у пользователя, и вот ему написали сообщение с недостойное сообщение на его стене, и он хочет удалить его. но если злоумышленник будет перебирать записи может так попортить не мало записей...как защититься тогда?
Ответить
Снова права доступа. Удалять свои записи может только сам пользователь. Если кто-нибудь другой попытается так удалить, то его должна постичь неудача.
Ответить
Михаил, а реально полностью защититься от SQL-инъекций, XSS атак и прочего? И каких правил нужно придерживаться, чтобы хотя бы снизить риск до самого минимума? Сам использую те же способы, что описаны в этой статье + обрамляю SQL запросы кавычками. Но все-равно кажется, что этого мало...
Ответить
Полностью защититься нереально, в статье достаточно того, что написано. А там если будут взламывать вдруг, то будете закрывать дыры постепенно. Так все и делают.
Ответить
То есть, как я понял, все же еще есть какие-то способы защиты? Просто меня не очень греет мысль, что потом, в случае взлома, придется делать какие-то лишние телодвижения, к тому же мысль об украденной базе(ах) - беспокоит больше всего. Хочется свести риск к минимуму, даже если взламывать никто не будет - на будущее уже буду знать, как защищаться. Да и остальным людям, думаю, будет интересно узнать способы защиты.
Ответить
Нет других способов, это всё частные варианты для конкретного сайта.
Ответить
Понятно. Спасибо, Михаил.
Ответить
Михаил, а как отключить register_globals ???
Ответить
В htaccess php_value register_globals 0
Ответить
Спасибо!
Ответить
Здравствуйте! У меня проблемы с htmlspecialchars! Когда обрабатываю ним русский текст перед добавлением в базу, то в базу попадает пустая строка вместо русского текста. С английским текстом всё хорошо работает! На форумах рекомендуют использовать htmlspecialchars не при записи, а при выводе; я боюсь это делать! Как быть? Что делать?
Ответить
htmlspecialchars не может превратить в пустую строку, выведите её перед добавлением в базу и посмотрите.
Ответить
Пробовал и выводить перед записью (после обработки htmlspecialchars). После обработки выводит "" - ничего, а английский текст выводит правильно. Дело в том, что раньше всё работало, но как только на хостинге что-то поменяли (я думаю версию пхп), то появилась эта проблема. Жду ихнего ответа уже 3 суток - ответа нет. А есть другая функция для обработки тегов? А эти символы случайно не нужно перечислять для обработки (те которые надо обработать)?
Ответить
htmlentities() можно использовать.
Ответить
и эта функция удаляет русский текст! а другие не подходят, так как они вырезают теги, а не преобразуют. Что ещё можно придумать?
Ответить
str_replace().
Ответить
Ура, проблема решена. Хостинг исправил ошибки! Вопрос 2: я разрешил запись одинарной кавычки в базу функцией addslashes, но вывожу текст из базы без каких-то там замен одинарных кавычек (слэшей). Всё работает, а это значит, что злоумышленник может так выполнить GET-запрос? Да???
Ответить
Вопрос не понятен.
Ответить
Перед записью коммента в базу, я обработал его функцией addslashes. Запись попала в базу с одинарными кавычками. Потом вывожу её (запись с од.кавычками) из базы без обработок функциями, подобными addslashes (просто я не знаю какими функциями обрабатывать уже обработанные одинарные кавычки). Их (од.кавычки) нужно ещё раз обрабатывать когда уже вывожу из базы? Как, почему?
Ответить
2) Можно пожалуйста два примере, как запустить сессию на конкретное время: первый пример - на 10 мин. второй - 20 мин. Спасибо! 3) Если я пишу статью о шахматах, в которой много одинаковых слов (домино) можно сделать ссылками на статью о домино, то лучше сделать 1 ссылку из шахмат на домино или все слова "домино"? В первую очередь, хочу узнать, как поисковые системы относятся к большому количеству одинаковых ссылок. Спасибо!
Ответить
http://myrusakov.ru/php-session-lifetime.html
Ответить
Нет, не нужно. Это только HTML-теги иногда при выводе обрабатываются.
Ответить
1) А разве злоумышленник не сможет выполнить GET-запрос (скрипт) если выводить из базы одинарные кавычки без обработки? 2) А что там по поводу ссылок? Примером могут быть ссылки в статьях у ВИКИПЕДИИ.
Ответить
И ещё. Я заметил, что в выдаче Яндекса, на каждой странице ТВОЕГО САЙТА присутствует фавикон, а в моего сайта в Яндексе только один фавикон - у главной страницы! Почему? Строку в кодах страниц я прописал по твоему уроку.
Ответить
Это уже лучше спросить у поддержки Яндекса.
Ответить
1) Нет. 2) Ничего не будет.
Ответить
Можно ли указать поисковым системам то, что именно Я являюсь автором статьи? Просто я заметил свой материал, который нагло скопировали из моего сайта и не указали ссылку на мой сайт. А так как тот сайт постарше, то в выдаче люди идут на "нехороший сайт", а не на мой! Разве это справедливо? Какими способами можно указать поисковикам, что именно Я являюсь автором этой работы? Спасибо за подробное описание!
Ответить
Можно попытаться пожаловаться в поддержку поисковой системы. А вообще поисковые системы стараются определять, кто автор статьи, а кто её скопировал.
Ответить
Здраствуйте, Михаил.Я создаю сайт с нулья на Html,Css,Php.Какой должень быть пароль админ панели, чтобы пароль не смогли взломать через подбор паролей.
Ответить
Здравствуйте Абай Калдыбаев. Чтобы не сомневаться в надежности Вашего пароля, используйте сторонний сервис генерации паролей: http://generator-paroley.ru/
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.