От автора: поводом к записи данного урока послужил вопрос на нашем форуме, который звучал следующим образом — как защитить сайт от CSRF -атак? Конечно мы сразу же ответили по данной теме и привели небольшой алгоритм по реализации механизма защиты. Но так как, скорее всего форум читают, далеко не все наши читатели я решил записать отдельный урок по вышеуказанному вопросу.
Сразу же хотел бы отметить, что в текущем видео не будет приведено полноценное готовое решение, которое можно внедрить на необходимый сайт. Потому как у каждого из Вас есть или же будет сайт, с уникальной логической структурой, то есть совсем не похожий на другие, а значит невозможно создать готовый скрипт защиты, соблюдая абсолютно все возможные варианты реализации.
Да и это не нужно, так как суть механизма защиты довольно проста, и поэтому в текущем видео на примере тестового сайта, Вы увидите, как можно защититься от вышеуказанного типа атаки, а далее на основе полученных знаний Вы проделаете аналогичные шаги на собственном проекте. Итак, давайте приступать.
CSRF – это аббревиатура образованная английскими словами Cross-Site Request Forgery, что означает межсайтовая подделка запросов. Данный термин введен уже достаточно давно еще 2001 году Питером Воткинсом, но говорить о возможных атаках подобного рода начали еще в далеком 1988 году. При этом заметьте, прошло уже достаточное количество времени, но все же данной атаке подвергается большая часть веб-сайтов интернета. Сразу же возникает вопрос – почему так? И ответ довольно прост и заключается в том, что уязвимость к атакам CSRF — это не ошибка кода приложения, а следствие вполне обычной работы браузера и веб-сервера.
Суть атаки заключается в том, что злоумышленник может выполнить на незащищенном сайте различные действия от имени другого зарегистрированного (авторизированного) пользователя. Другими словами данный тип атаки предусматривает посещение пользователем сайта злоумышленника, что в свою очередь приводит к тому, что незаметно для него выполняются некоторые заранее прописанные действия на другом сайте или сервисе, на котором этот пользователь в данный момент авторизован.
При этом, как правило, целями CSRF-атак являются различные интерактивные Web-приложения, которые выполняют конкретные действия, к примеру, сервисы по отправке электронной почты, различные форумы, платежные системы и т.д. То есть, хакер может выполнять некоторые действия от имени других пользователей — отправлять сообщения, добавлять новые учетные записи, осуществлять финансовые операции и т.д.
Теперь давайте рассмотрим действие указанной атаки на примере тестового сайта.
Предположим, что есть веб-сайт, задача которого сводится к отправке электронного сообщения по указанному адресу от имени некого авторизированного пользователя. То есть на главной странице мы видим форму, для отправки сообщения. Более того здесь же предусмотрен механизм отправки сообщений, при передачи определенных параметров через GET запрос (просто для примера). При этом страница авторизации выглядит следующим образом.
Данная страница вполне обычная, но в глаза бросается чек-бокс “Member”, который используется для сохранения данный авторизации в куках браузера. Собственно данный механизм очень удобен пользователям, так как упрощает повторный доступ к странице, но крайне не желателен с точки зрения безопасности. Но все же ради посетителей часто приходится идти на определенные уступки.
Код отправки сообщений двумя методами (GET и POST) выглядит примерно следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//Отправка сообщения if($this->isGet() && !empty($_GET['email']) ) { $body = "Hello this is message form - ".$this->user['name']; $body .= ' Content - from GET - '.$_GET['content'].'From - '.$_GET['email']; mail('mail@yandex.ru','New message',$body); } if($this->isPost()) { $body = "Hello this is message form - ".$this->user['name']; $body .= ' Content - FROM POST - '.$_POST['content'].'From - '.$_POST['email']; mail('mail@yandex.ru','New message',$body); } |
Теперь, рассмотрим еще один сайт – сайт хакера.
На котором он может разместить, довольно простой , но очень эффективный код ,если необходимо произвести атаку по запросу типа GET:
1 |
<img src="//localhost/csrf/index.php?option=admin&email=haker@mail.ru&content=Hello world"> |
То есть, по сути, мы видим тег img, в атрибуте src которого располагается путь к сайту, предполагаемого для атаки, с набором необходимых параметров, для выполнения конкретного действия. В нашем случае это отправка сообщения, а значит, теперь злоумышленнику достаточно заманить пользователя на текущий сайт и незаметно от него, будет осуществлен запрос к интересующему сайту, так как браузер будет пытаться загрузить изображение, путь к которому указан в атрибуте src. При этом мы помним, что в куках браузера хранятся данные для авторизации и, конечно же, приложение сразу же их использует и соответственно вышеуказанный запрос успешно будет обработан сервером. А это означает, что будет отправлено сообщение от имени пользователя.
Если посмотреть набор заголовков, которые отправляются вместе с запросом, то действительно, мы сможем увидеть и куки, с данными для входа в учетную запись, что само собой означает – как было сказано выше, что запрос будет воспринят как исходящий от аутентифицированного пользователя.
Точно такая же ситуация обстоит и с отправкой запроса методом POST, единственно в этом случае злоумышленник создаст на своем сайте форму, которая будет автоматически отправляться при помощи JavaScript ,как только посетитель зайдет на данный сайт.
Таким образом защищаться от атак подобного рода нужно обязательно и единственный наиболее эффективный способ защиты – это использование специальных токенов.
Защитный токен – это строка, которая генерируется случайным образом под конкретного пользователя и передается в каждом запросе, который предусматривает изменение данных. Помимо этого токен ,так же сохраняется и в сессии. Таким образом, суть защиты, сводится к простой проверке соответствия токена, который передается в запросе и токена который хранится в сессии. Если оба токена идентичны, значит, запрос отправил авторизированный пользователь. Если токены не совпадают, или в запросе его вообще нет – с большой уверенностью можно судить, что осуществляется атака, а значит, никакие действия выполнять нельзя.
Заметьте, что защищать нужно абсолютно все запросы, которые направлены на изменение или же выполнение определенных действий.
Собственно на данном этапе текстовая часть урока завершена и продолжим говорить поданной теме мы уже в видео версии. При этом мы рассмотрим способы генерации токенов и практически реализуем алгоритм работы защиты, который описан выше. А сейчас давайте прощаться. Удачного кодирования!!!