Привет, Хабр!
Безопасность — дело серьезное. И зачастую проблемы в этой области всплывают неожиданно и несут крайне неприятные последствия. Поэтому знания в этой теме крайне важны для каждого веб разработчика.
Оговорюсь сразу — я далеко не профи, но стремлюсь к этому. Поэтому буду рад критике, но лишь объективной. Этот материал для новичков, которые хотят повысить свой профессионализм и ценность, как специалиста.
И еще, я показываю максимально простую реализацию кода. Я знаю про исключения, знаю про ORM, про предусмотренную защиту в фреймворках. Моя цель — показать наглядно, так, чтобы поняли все.
И так, пора заканчивать со вступлением и приступать к практике.
Я не привык работать с теорией. Душа моя жаждет практики. Поэтому, говоря о теме безопасности, мы будем рассматривать практически все типы атак с практической точки зрения — как реализовать и как защититься. Да, вы можете сказать, что обучать взлому — не есть хорошо, но, не зная как происходит атака, мы не можем выстроить грамотную защиту.
Окей, первый тип атак — XSS. Да, старый добрый XSS, о котором слышал каждый. XSS (Cross Site Scripting) — это тип атак, который нацелен на посетителей сайта. Как это происходит: через поле для ввода злоумышленник пишет вредоносный код, который попадает в базу данных и делает свою работу. Обычно таким способом у пользователей крадут cookie файлы, что позволя��т входить в их аккаунты без пароля и логина.
Мы же реализуем более безобидный пример.
Наш разработчик сделал простую форму для добавления комментариев:
Код весьма прост и не нуждается в объяснениях.
Есть злоумышленник — Джон. Джону стало скучно и он наткнулся на сайт нашего разработчика.
Джон пишет в форму такое сообщение:
И теперь у всех пользователей сайта черный фон. Джон доволен, а разработчик получил опыт и выговор.
Что вообще произошло?
Джон добавил комментарий с JavaScript кодом. При выводе данных на страницу, текстовый комментарий преобразовывается в html код. Html код, увидев использование тега script, добавил его в разметку, а интерпретатор уже выполнил JavaScript код. То есть Джон просто добавил свой кусок js кода к имеющемуся коду сайта.
Как будем исправлять?
Чтобы исправить это недоразумение, была создана функция htmlspecialcars. Суть ее работы в том, что она заменяет символы типа кавычек и скобок на спец символы. Например, символ "<" будет заменён на соответствующий ему символьный код. С помощью этой функции мы обрабатываем данные из формы и теперь js код Джона уже не может причинить вред нашему сайту. Разумеется, если это единственная форма на сайте.
Изменения в коде будут выглядеть так:
Еще один из самых распространенных типов атак, о котором уже стали забывать. Забывают потому что появились подготовленные запросы и фреймворки.
Как раз о подготовленных запросах мы и поговорим.
В чем суть атаки: злоумышленник вводит в поле для ввода часть SQL запроса и производит отправку формы. Во время выполнения запроса, полученные д��нные добавляются в базу данных. Но так как в тексте находится код, то при добавлении записей он модифицирует логику работы нашего скрипта.
Окей, смоделируем ситуацию. Наш разработчик защитил форму от XSS атак. А Джон продолжает использовать свои знания, показывая на недостатки горе-разработчику.
То есть мы будем продолжать работать все с той же формой для добавления комментариев.
Внесем несколько изменений:
1) Предмодерация комментариев.
Суть в том, что на странице будут отображаться лишь те комментарии, которые одобрил модератор. Предмодерацию реализуем в простейшем виде, дабы не отвлекаться от основной части статьи.
Для реализации задумки добавим в таблицу с комментариями поле «is_moderate», которое будет принимать два значения — «1»(отображаем комментарий) или «0»(не отображаем). По умолчанию, разумеется, «0».
2) Изменим запрос.
Это нужно для большей наглядности. Пусть запрос для добавления комментариев будет выглядеть так:
Сейчас код работы формы выглядит следующим образом:
Окей, на сайт заходит Джон и, увидев, что комментарии начали проходить модерацию, решил поиздеваться над разработчиком. Тем более, что XSS атаки форма теперь успешно отражает и возможности повеселиться Джона уже лишили. Он оставляет комментарий такого типа: " LOL', is_moderate ='1 " и обходит модерацию.
Почему?
При подстановке комментария Джона в наш запрос происходит разрыв кавычки. То есть, как было сказано выше, Джон получил возможность выполнить произвольный SQL код.
При исполнении запроса с комментарием Джона запрос выглядит следующим образом:
Пр�� чем SQL-Инъекцию можно реализовать не только при отправке формы. Это так же может происходить и при получении записей по их идентификатору, обработке формы поиска и прочих не столь очевидных ситуациях.
Как исправить?
Метод решения проблемы известен уже достаточно давно — подготовленные запросы. Подготовленные запросы — это запросы, которые проходят специальную обработку перед выполнением. Обработка заключается в экранировании дополнительных кавычек. Должно быть вы слышали о такой функции. В PHP она реализована так: " \' ".
Наиболее популярным решением является PDO. PDO — это интерфейс для работы с базой данных. При чем достаточно удобный интерфейс. Только пользоваться им нужно грамотно.
PDO предоставляет возможность использования масок и плейсхолдеров для реализации подготовленных запросов.
Тогда наш запрос при использовании масок будет выглядеть следующим образом:
А при использовании плейсхолдеров так:
Теперь атака Джона перестает быть актуальной. По крайней мере для данной формы.
Кстати, реализованная нами модерация, даже в таком виде уже защищает еще от одного типа атак — SPAM. Все мы о нем слышали. SPAM — это рассылка каких-либо сообщений, в которых с помощью знаний социальной инженерии злоумышленники производят свои атаки. Теперь же единственный, кто подвергнется атаке — модератор. Да и то, если он не столь глуп, то либо удалит мусор из базы данных, либо, если ленивый, отклонит публикацию и все.
CSRF — Cross-Site Request Forgery. Опасен тем, что о нем мало кто знает. Хотя и сделать это достаточно просто.
Как происходит: злоумышленник с другого сайта подделывает форму и заставляет жертву перейти по этой форме. То есть происходит отправка POST запроса. Таким образом подделывается HTTP запрос и на сайте жертвы производится вредоносное действие.
Например, злоумышленник мог бы вашему отправить другу письмо в вк от вашего имени, а вы об этом и знать не будете.
Звучит слегка запутано. Предлагаю рассмотреть на практике.
Наш разработчик сделал форму, он молодец. Она уже умеет защищаться от XSS, SQL инъекций и держит напор Спама. Она выглядит так:
Но Джон не так прост. Он получает код формы(просто из исходного кода сайта в браузере) и добавляет форму себе на сайт.
Обратите внимание, что на сайте Джона место обработки формы — это файл с сайта нашего разработчика. А значит теперь любой пользователь, который кликнет по кнопке, будет отправлять не хорошие комментарии.
Это и есть CSRF атака. В простейшем варианте, разумеется.
У разработчика опять проблемы…
Как исправить уязвимость?
В один прекрасный момент разработчик нагуглит что такое csrf и логика защиты будет заключаться в следующем: для защиты нужно создать csrf токен(набор букв и цифр) и повесить на форму. Так же нужно закрепить этот же токен за пользователем(например, через сессию). А после, при обработке формы, сравнивать эти токены. Если совпали — можем добавлять комментарий.
Реализуем это:
Пожалуй самый известный тип атаки. Он нем слышал едва ли не каждый первый из фильмов про хакеров и им подобных.
В чем суть: есть форма для авторизации в панель администратора сайта. Нужен логин и пароль, которые Джон не знает. Но у него есть файл с популярными именами пользователей и паролями. И он радостно бежит опробовать их на наш сайт.
Что разработчик может противопоставить? Например, ограничение на количество попыток авторизации в определенный период времени.
Пусть первоначальный вариант формы авторизации выглядит так:
Как будем исправлять: самый простой вариант, как уже было сказано, это ограничение количества попыток авторизации за промежуток времени.
Для этого мы при попытке авторизации будем добавлять пользователю текущее значение времени в куки. И теперь, при попытке авторизации, будем смотреть, чтобы пользователь мог авторизоваться не чаще чем 1 раз в 5 секунд. При чем, при не правильном вводе пароля или логина, мы будем увеличивать таймаут до следующей попытки на 5 секунд.
Backtrace — это способ атаки через выводимые ошибки системы. Это и MySQL, и PHP.
Например, Джон ввел не корректный url и ему вывели ошибку о том, что в базе данных нет записи с таким id(если получение записи происходит через id из адресной строки — site.ru/article?id=12). Существуют даже так называемые «дорки» — определенные шаблоны адресов сайтов, при заходе на которые пользователь видит ошибки. А это открывает для Джона возможность с помощью бота пройтись по этому списку адресов и попробовать найти на вашем сайте данную уязвимость.
Как исправить? В данном случае обойдемся без примеров, ибо проблема решается просто с помощью закрытия вывода ошибок. Обычно это реализовывает хостинг, предоставляя вам в панели администратора записывать логи в отдельный файл, но не лишним будет и самому ограничить вывод ошибок.
Это можно сделать с помощью функции error_reporting()
Среди аргументов, которые она принимает, находятся: E_ERROR, E_WARNING, E_PARSE, E_NOTICE, E_ALL. Названия говорят сами за себя.
Например, если использовать error_reporting(E_NOTICE), то будут скрыты все ошибки, кроме ошибок типа Notice(предупреждения, например, о том, что отсутствуют данные в массиве $_POST).
Чтобы отключить вывод всех ошибок(что нам, собственно и нужно), нужно использовать эту функцию следующим образом: error_reporting(0)
Логические ошибки — одни из самых страшных. Потому что это ошибки по невнимательности. Они всплывают неож��данно и, порой, мы даже не догадываемся, где находится корень проблемы. Это ошибки логики работы сайта.
Ну, например, вы могли забыть поставить проверку на наличие данных авторизации в сессии и куках для одной из страниц панели администратора. А значит открыли доступ к данной странице для любого пользователя.
В данном случае вас спасет лишь одно — во время написания кода программы думайте о том, как его можно взломать.
DOS — тип атак на технику, в частности вычислительную машину. Атака нацелена на выведение машины из строя за счет перегрузки. DDOS отличается лишь тем, что в атаке участвует большее количество компьютеров для атаки.
То есть Джон зовет своих друзей и они дружно начинают отправлять запросы на сайт. При чем тут как нельзя будет уместен ботнет. Ботнет — это множество зараженных компьютеров, особенность в том, что злоумышленник может в какой-то мере управлять их работой(запускать процессы и т.д.). Они отправляют так много запросов, что сервер не выдерживает нагрузку и в лучшем случае начинает очень медленно работать, либо отказывает на не определенное количество времени.
Защиту от таких атак предоставляют либо сами хостинги, либо специальные сервисы по типу Cloudflare.
Как работает защита: сервис Cloudflare предоставляет вам свои DNS сервера, через которые будет проходить трафик. Там он фильтруется, проходя через алгоритмы, известные лишь владельцам и разработчикам сервиса. А после уже пользователь попадает к вам на сайт. Да, конечно, присутствует работа сервера, генерация страницы и все прочее, но мы сейчас не об этом.
К тому же, говоря о DDOS, нельзя не упомянуть про блокировку IP адресов, которую Cloudflare так же предоставляет.
Да, все это не даст 100% гарантии защиты, однако в разы повысит шансы вашего сайта остаться на плаву в момент атаки.
Man In The Middle — это тип атаки, когда злоумышленник перехватывает ваши пакеты и подменяет их. Все мы слышали, что данные по сети передаются пакетами. Так вот, при использовании протокола http, данные передаются в обычном, не зашифрованном виде.
Например, вы пишите другу «привет», а он получает «пришли мне деньги, вот кошелек».
Именно для решения этой проблемы и был создан протокол https. При его использовании данные будут зашифровываться и Джон не сможет ничего сделать с полученным трафиком.
А чтобы получить https протокол для сайта, нужно получить SSL сертификат. Ну или TLS. Вообще TLS по сути является приемником SSL, потому что основан на SSL 3.0. В их работе нет существенных отличий.
SSL сертификат предоставляет тот же Cloudflare, при чем бесплатно.
Еще немного теории. Ибо этот тип атаки может быть реализован множеством способов и нужно лишь уловить суть. Backdoor — это тип скрытой атаки, при котором скрипт сам делает что-то в «фоне». Чаще всего это плагины или темы WordPress, скачанные с торрента. Сам плагин/тема будет вполне адекватно работать, но определенный кусок скрипта, дописанный в код плагина/темы, будет в тайне делать что-то. Тот же SPAM, например. Это и есть причина всех предостережений о нежелательности скачивания файлов с торрента.
Да, разумеется, это да��еко не весь спектр атак. Но эти знания уже повысят безопасность ваших проектов
Безопасность — дело серьезное. И зачастую проблемы в этой области всплывают неожиданно и несут крайне неприятные последствия. Поэтому знания в этой теме крайне важны для каждого веб разработчика.
Оговорюсь сразу — я далеко не профи, но стремлюсь к этому. Поэтому буду рад критике, но лишь объективной. Этот материал для новичков, которые хотят повысить свой профессионализм и ценность, как специалиста.
И еще, я показываю максимально простую реализацию кода. Я знаю про исключения, знаю про ORM, про предусмотренную защиту в фреймворках. Моя цель — показать наглядно, так, чтобы поняли все.
И так, пора заканчивать со вступлением и приступать к практике.
Путь от реализации новичка до сколь-нибудь вменяемого результата
Я не привык работать с теорией. Душа моя жаждет практики. Поэтому, говоря о теме безопасности, мы будем рассматривать практически все типы атак с практической точки зрения — как реализовать и как защититься. Да, вы можете сказать, что обучать взлому — не есть хорошо, но, не зная как происходит атака, мы не можем выстроить грамотную защиту.
XSS
Окей, первый тип атак — XSS. Да, старый добрый XSS, о котором слышал каждый. XSS (Cross Site Scripting) — это тип атак, который нацелен на посетителей сайта. Как это происходит: через поле для ввода злоумышленник пишет вредоносный код, который попадает в базу данных и делает свою работу. Обычно таким способом у пользователей крадут cookie файлы, что позволя��т входить в их аккаунты без пароля и логина.
Мы же реализуем более безобидный пример.
Наш разработчик сделал простую форму для добавления комментариев:
Файл index.php
<?php
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
];
$pdo = new PDO("mysql:host=localhost;dbname=".$db,$user,$pass,$opt);
$pdo->exec("SET CHARSET utf8");
$query = $pdo->prepare("SELECT * FROM `comments`");
$query->execute();
$comments = $query->fetchAll();
if ($_POST) {
$username = trim($_POST['name']);
$comment = trim($_POST['comment']);
$query = $pdo->prepare("INSERT INTO `comments` (`username`,`message`) VALUES ('$username', '$comment')");
$query->execute();
if ($query) {
echo 'Комментарий добавлен!';
header("Location: index.php");
} else {
echo 'Произошла ошибка!';
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XSS</title>
</head>
<body>
<form method="POST" class="addComment">
<input type="text" name="name" placeholder="Username">
<textarea name="comment"></textarea>
<input type="submit" value="Добавить комментарий">
</form>
<div class="h2">Комментарии</div>
<div class="comments">
<?php
if ($comments):
foreach ($comments as $comment):?>
<div class="comment">
<div class="comment_username"><?php echo $comment['username'];?></div>
<div сlass="comment_comment"><?php echo $comment['message'];?></div>
</div>
<?php endforeach;?>
<?php else:?>
<div class="no_comments">Нет комментариев</div>
<?php endif;?>
</div>
</body>
</html>
Код весьма прост и не нуждается в объяснениях.
Есть злоумышленник — Джон. Джону стало скучно и он наткнулся на сайт нашего разработчика.
Джон пишет в форму такое сообщение:
<script>document.body.style.backgroundColor = "#000";</script>И теперь у всех пользователей сайта черный фон. Джон доволен, а разработчик получил опыт и выговор.
Что вообще произошло?
Джон добавил комментарий с JavaScript кодом. При выводе данных на страницу, текстовый комментарий преобразовывается в html код. Html код, увидев использование тега script, добавил его в разметку, а интерпретатор уже выполнил JavaScript код. То есть Джон просто добавил свой кусок js кода к имеющемуся коду сайта.
Как будем исправлять?
Чтобы исправить это недоразумение, была создана функция htmlspecialcars. Суть ее работы в том, что она заменяет символы типа кавычек и скобок на спец символы. Например, символ "<" будет заменён на соответствующий ему символьный код. С помощью этой функции мы обрабатываем данные из формы и теперь js код Джона уже не может причинить вред нашему сайту. Разумеется, если это единственная форма на сайте.
Изменения в коде будут выглядеть так:
Файл index.php
<?php
if ($_POST) {
$username = htmlspecialchars(trim($_POST['name']));
$comment = htmlspecialchars(trim($_POST['comment']));
///
}
SQL Инъекция
Еще один из самых распространенных типов атак, о котором уже стали забывать. Забывают потому что появились подготовленные запросы и фреймворки.
Как раз о подготовленных запросах мы и поговорим.
В чем суть атаки: злоумышленник вводит в поле для ввода часть SQL запроса и производит отправку формы. Во время выполнения запроса, полученные д��нные добавляются в базу данных. Но так как в тексте находится код, то при добавлении записей он модифицирует логику работы нашего скрипта.
Окей, смоделируем ситуацию. Наш разработчик защитил форму от XSS атак. А Джон продолжает использовать свои знания, показывая на недостатки горе-разработчику.
То есть мы будем продолжать работать все с той же формой для добавления комментариев.
Внесем несколько изменений:
1) Предмодерация комментариев.
Суть в том, что на странице будут отображаться лишь те комментарии, которые одобрил модератор. Предмодерацию реализуем в простейшем виде, дабы не отвлекаться от основной части статьи.
Для реализации задумки добавим в таблицу с комментариями поле «is_moderate», которое будет принимать два значения — «1»(отображаем комментарий) или «0»(не отображаем). По умолчанию, разумеется, «0».
2) Изменим запрос.
Это нужно для большей наглядности. Пусть запрос для добавления комментариев будет выглядеть так:
"INSERT INTO `comments` SET `username`='$username', `message`='$comment'"Сейчас код работы формы выглядит следующим образом:
Файл index.php
<?php
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
];
$pdo = new PDO("mysql:host=localhost;dbname=".$db,$user,$pass,$opt);
$pdo->exec("SET CHARSET utf8");
$query = $pdo->prepare("SELECT * FROM `comments` WHERE `is_moderate`='1'");
$query->execute();
$comments = $query->fetchAll();
if ($_POST) {
$username = htmlspecialchars(trim($_POST['name']));
$comment = htmlspecialchars(trim($_POST['comment']));
$query = $pdo->prepare("INSERT INTO `comments` SET `username`='$username', `message`='$comment'");
$query->execute();
if ($query) {
echo 'Комментарий добавлен!';
} else {
echo 'Произошла ошибка!';
}
}
?>
Окей, на сайт заходит Джон и, увидев, что комментарии начали проходить модерацию, решил поиздеваться над разработчиком. Тем более, что XSS атаки форма теперь успешно отражает и возможности повеселиться Джона уже лишили. Он оставляет комментарий такого типа: " LOL', is_moderate ='1 " и обходит модерацию.
Почему?
При подстановке комментария Джона в наш запрос происходит разрыв кавычки. То есть, как было сказано выше, Джон получил возможность выполнить произвольный SQL код.
При исполнении запроса с комментарием Джона запрос выглядит следующим образом:
"INSERT INTO `comments` SET `username`='John', `message`='LOL', `is_moderate`='1'"Пр�� чем SQL-Инъекцию можно реализовать не только при отправке формы. Это так же может происходить и при получении записей по их идентификатору, обработке формы поиска и прочих не столь очевидных ситуациях.
Как исправить?
Метод решения проблемы известен уже достаточно давно — подготовленные запросы. Подготовленные запросы — это запросы, которые проходят специальную обработку перед выполнением. Обработка заключается в экранировании дополнительных кавычек. Должно быть вы слышали о такой функции. В PHP она реализована так: " \' ".
Наиболее популярным решением является PDO. PDO — это интерфейс для работы с базой данных. При чем достаточно удобный интерфейс. Только пользоваться им нужно грамотно.
PDO предоставляет возможность использования масок и плейсхолдеров для реализации подготовленных запросов.
Тогда наш запрос при использовании масок будет выглядеть следующим образом:
Файл index.php
<?php
$query = $pdo->prepare("INSERT INTO `comments` SET `username`=:username, `message`=:comment");
$params = ['username' => $username,'comment' => $comment];
$query->execute($params);
А при использовании плейсхолдеров так:
Файл index.php
<?php
$query = $pdo->prepare("INSERT INTO `comments` SET `username`=?, `message`=?");
$params = [$username,$comment];
$query->execute($params);
Теперь атака Джона перестает быть актуальной. По крайней мере для данной формы.
Кстати, реализованная нами модерация, даже в таком виде уже защищает еще от одного типа атак — SPAM. Все мы о нем слышали. SPAM — это рассылка каких-либо сообщений, в которых с помощью знаний социальной инженерии злоумышленники производят свои атаки. Теперь же единственный, кто подвергнется атаке — модератор. Да и то, если он не столь глуп, то либо удалит мусор из базы данных, либо, если ленивый, отклонит публикацию и все.
CSRF атака
CSRF — Cross-Site Request Forgery. Опасен тем, что о нем мало кто знает. Хотя и сделать это достаточно просто.
Как происходит: злоумышленник с другого сайта подделывает форму и заставляет жертву перейти по этой форме. То есть происходит отправка POST запроса. Таким образом подделывается HTTP запрос и на сайте жертвы производится вредоносное действие.
Например, злоумышленник мог бы вашему отправить другу письмо в вк от вашего имени, а вы об этом и знать не будете.
Звучит слегка запутано. Предлагаю рассмотреть на практике.
Наш разработчик сделал форму, он молодец. Она уже умеет защищаться от XSS, SQL инъекций и держит напор Спама. Она выглядит так:
Файл index.php на сайте разработчика
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSRF</title>
</head>
<body>
<form action="action.php" method="POST">
<input type="text" name="username">
<textarea name="message"></textarea>
<input type="submit" value="Добавить комментарий">
</form>
</body>
</html>
Но Джон не так прост. Он получает код формы(просто из исходного кода сайта в браузере) и добавляет форму себе на сайт.
Файл index.php на сайте Джона
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSRF</title>
<style>
form input[type=submit]{
padding: 15px;
font-size: 20px;
color: #fff;
background: #f00;
cursor: pointer;
}
</style>
</head>
<body>
<form action="localhost/note/action.php" method="POST">
<input type="hidden" name="username" value="lol">
<input type="hidden" name="message" value="Какой плохой сайт! Фу таким быть!">
<input type="submit" value="Хочу денег!">
</form>
</body>
</html>
Обратите внимание, что на сайте Джона место обработки формы — это файл с сайта нашего разработчика. А значит теперь любой пользователь, который кликнет по кнопке, будет отправлять не хорошие комментарии.
Это и есть CSRF атака. В простейшем варианте, разумеется.
У разработчика опять проблемы…
Как исправить уязвимость?
В один прекрасный момент разработчик нагуглит что такое csrf и логика защиты будет заключаться в следующем: для защиты нужно создать csrf токен(набор букв и цифр) и повесить на форму. Так же нужно закрепить этот же токен за пользователем(например, через сессию). А после, при обработке формы, сравнивать эти токены. Если совпали — можем добавлять комментарий.
Реализуем это:
Файл index.php на сайте разработчика
<?php
session_start();
$token = '';
if (function_exists('mcrypt_create_iv')) {
$token = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
} else {
$token = bin2hex(openssl_random_pseudo_bytes(32));
}
$_SESSION['token'] = $token;
?>
...
<form action="action.php" method="POST">
<input type="text" name="username">
<textarea name="message"></textarea>
<input type="hidden" name="csrf_token" value="<?php echo $token;?>">
<input type="submit" value="Добавить комментарий">
</form>
Файл action.php
<?php
session_start();
if ($_POST) {
if ($_SESSION['token'] == $_POST['csrf_token']) {
echo 'Комментарий добавлен!';
} else {
echo 'Ошибка!';
}
}
Brute Force и Publick Passwords
Пожалуй самый известный тип атаки. Он нем слышал едва ли не каждый первый из фильмов про хакеров и им подобных.
В чем суть: есть форма для авторизации в панель администратора сайта. Нужен логин и пароль, которые Джон не знает. Но у него есть файл с популярными именами пользователей и паролями. И он радостно бежит опробовать их на наш сайт.
Что разработчик может противопоставить? Например, ограничение на количество попыток авторизации в определенный период времени.
Пусть первоначальный вариант формы авторизации выглядит так:
Файл index.php
<?php
$opt = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC];
$pdo = new PDO("mysql:host=localhost;dbname=".$db,$user,$pass,$opt);
$pdo->exec("SET CHARSET utf8");
if (isset($_POST['autorizе'])) {
$username = htmlspecialchars(trim($_POST['login']));
$password = htmlspecialchars(trim($_POST['password']));
$query = $pdo->prepare("SELECT * FROM `users` WHERE `username`=:username AND `password`=:password");
$query->execute(['username' => $username,'password' => $password]);
$find_user = $query->fetchAll();
if ($find_user) {
echo 'Пользователь найден!';
} else {
echo 'Пользователь не найден!';
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Brute Force и Public Passwords</title>
</head>
<body>
<form method="POST">
<input type="text" name="login" placeholder="Login">
<input type="password" name="password" placeholder="Password">
<input type="submit" value="Войти" name="autorize">
</form>
</body>
</html>
Как будем исправлять: самый простой вариант, как уже было сказано, это ограничение количества попыток авторизации за промежуток времени.
Для этого мы при попытке авторизации будем добавлять пользователю текущее значение времени в куки. И теперь, при попытке авторизации, будем смотреть, чтобы пользователь мог авторизоваться не чаще чем 1 раз в 5 секунд. При чем, при не правильном вводе пароля или логина, мы будем увеличивать таймаут до следующей попытки на 5 секунд.
Файл index.php
<?php
$count_next_minit = $_COOKIE['count_try'] ? $_COOKIE['count_try'] : 1;
$seconds_to_new_try = 5;
$opt = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC];
$pdo = new PDO("mysql:host=localhost;dbname=".$db,$user,$pass,$opt);
$pdo->exec("SET CHARSET utf8");
if (isset($_POST['autorize'])) {
if ($_COOKIE['last_try']) {
if ($_COOKIE['last_try'] < time() - $seconds_to_new_try * $count_next_minit) {
$username = htmlspecialchars(trim($_POST['login']));
$password = htmlspecialchars(trim($_POST['password']));
$query = $pdo->prepare("SELECT * FROM `users` WHERE `username`=:username AND `password`=:password");
$query->execute(['username'=>$username,'password'=>$password]);
$find_user = $query->fetchAll();
setcookie('last_try', time(), time() + 3600);
if ($_COOKIE['count_try']) {
$old_value = (int)$_COOKIE['count_try'];
setcookie('count_try', $old_value + 1, time() + 3600);
} else {
setcookie('count_try', 1, time() + 3600);
}
if ($find_user) {
var_dump('Пользователь найден!');
} else {
var_dump('Пользователь не найден!');
}
}else{
var_dump('Слишком часто вводишь пароль! Следующая попытка через ' . $seconds_to_new_try * $count_next_minit . ' секунд');
}
}else{
setcookie('last_try', time(), time() + 3600);
}
}
?>
Backtrace
Backtrace — это способ атаки через выводимые ошибки системы. Это и MySQL, и PHP.
Например, Джон ввел не корректный url и ему вывели ошибку о том, что в базе данных нет записи с таким id(если получение записи происходит через id из адресной строки — site.ru/article?id=12). Существуют даже так называемые «дорки» — определенные шаблоны адресов сайтов, при заходе на которые пользователь видит ошибки. А это открывает для Джона возможность с помощью бота пройтись по этому списку адресов и попробовать найти на вашем сайте данную уязвимость.
Как исправить? В данном случае обойдемся без примеров, ибо проблема решается просто с помощью закрытия вывода ошибок. Обычно это реализовывает хостинг, предоставляя вам в панели администратора записывать логи в отдельный файл, но не лишним будет и самому ограничить вывод ошибок.
Это можно сделать с помощью функции error_reporting()
Среди аргументов, которые она принимает, находятся: E_ERROR, E_WARNING, E_PARSE, E_NOTICE, E_ALL. Названия говорят сами за себя.
Например, если использовать error_reporting(E_NOTICE), то будут скрыты все ошибки, кроме ошибок типа Notice(предупреждения, например, о том, что отсутствуют данные в массиве $_POST).
Чтобы отключить вывод всех ошибок(что нам, собственно и нужно), нужно использовать эту функцию следующим образом: error_reporting(0)
Логические ошибки
Логические ошибки — одни из самых страшных. Потому что это ошибки по невнимательности. Они всплывают неож��данно и, порой, мы даже не догадываемся, где находится корень проблемы. Это ошибки логики работы сайта.
Ну, например, вы могли забыть поставить проверку на наличие данных авторизации в сессии и куках для одной из страниц панели администратора. А значит открыли доступ к данной странице для любого пользователя.
В данном случае вас спасет лишь одно — во время написания кода программы думайте о том, как его можно взломать.
DDOS
DOS — тип атак на технику, в частности вычислительную машину. Атака нацелена на выведение машины из строя за счет перегрузки. DDOS отличается лишь тем, что в атаке участвует большее количество компьютеров для атаки.
То есть Джон зовет своих друзей и они дружно начинают отправлять запросы на сайт. При чем тут как нельзя будет уместен ботнет. Ботнет — это множество зараженных компьютеров, особенность в том, что злоумышленник может в какой-то мере управлять их работой(запускать процессы и т.д.). Они отправляют так много запросов, что сервер не выдерживает нагрузку и в лучшем случае начинает очень медленно работать, либо отказывает на не определенное количество времени.
Защиту от таких атак предоставляют либо сами хостинги, либо специальные сервисы по типу Cloudflare.
Как работает защита: сервис Cloudflare предоставляет вам свои DNS сервера, через которые будет проходить трафик. Там он фильтруется, проходя через алгоритмы, известные лишь владельцам и разработчикам сервиса. А после уже пользователь попадает к вам на сайт. Да, конечно, присутствует работа сервера, генерация страницы и все прочее, но мы сейчас не об этом.
К тому же, говоря о DDOS, нельзя не упомянуть про блокировку IP адресов, которую Cloudflare так же предоставляет.
Да, все это не даст 100% гарантии защиты, однако в разы повысит шансы вашего сайта остаться на плаву в момент атаки.
MITM
Man In The Middle — это тип атаки, когда злоумышленник перехватывает ваши пакеты и подменяет их. Все мы слышали, что данные по сети передаются пакетами. Так вот, при использовании протокола http, данные передаются в обычном, не зашифрованном виде.
Например, вы пишите другу «привет», а он получает «пришли мне деньги, вот кошелек».
Именно для решения этой проблемы и был создан протокол https. При его использовании данные будут зашифровываться и Джон не сможет ничего сделать с полученным трафиком.
А чтобы получить https протокол для сайта, нужно получить SSL сертификат. Ну или TLS. Вообще TLS по сути является приемником SSL, потому что основан на SSL 3.0. В их работе нет существенных отличий.
SSL сертификат предоставляет тот же Cloudflare, при чем бесплатно.
Backdoor
Еще немного теории. Ибо этот тип атаки может быть реализован множеством способов и нужно лишь уловить суть. Backdoor — это тип скрытой атаки, при котором скрипт сам делает что-то в «фоне». Чаще всего это плагины или темы WordPress, скачанные с торрента. Сам плагин/тема будет вполне адекватно работать, но определенный кусок скрипта, дописанный в код плагина/темы, будет в тайне делать что-то. Тот же SPAM, например. Это и есть причина всех предостережений о нежелательности скачивания файлов с торрента.
В заключение
Да, разумеется, это да��еко не весь спектр атак. Но эти знания уже повысят безопасность ваших проектов