Простая защита от DoS и брутфорс атак

Наиболее типичными и опасными являются DoS(DDoS) и брутфорс атаки. Оба их вида подразумевают ежесекундную отправку тысячи запросов, которые перегружают сервера. Зачем такое позволять? Сегодня мы создадим собственное решение этой проблемы, которое хоть и не будет идеальным, но сможет выступить базовой защитой от злоумышленников.

Краткое введение

В этой статье рассмотрим только два самых распространенных вида атак, а также продемонстрируем реализацию простейшего, но при том надежного, вида защиты.

DoS-атака

DoS-атака не подразумевает взлома данных. Ее цель состоит в загрузке сервера большим количеством трафика, чтобы реальные пользователи не могли получить к нему доступ.

DDoS-атака

DDoS-атака аналогична DoS, но имеет ключевое отличие, а именно то, что в ней задействуется не одна атакующая машина, а множество. 

Наше решение не будет работать против такого вида атак. Поэтому с целью их предотвращения стоит обратиться к Akamai, Cloudflare и другим подобным сервисам, которые смогут оградить приложение прокси-сервером. 

Брутфорс атака

В ходе брутфорс атаки сервер подвергается сотням запросов в секунду. Как правило, эти запросы нацелены на получение доступа к системе через отправку множества форм авторизации со случайными именами и паролями. Это значит, что нам нужно создать API с учетом всевозможных ситуаций. 

Защиты против атак брутфорсом:

  • сложные пароли максимальной длины;
  • двухфакторная аутентификация;
  • reCAPTCHA;
  • ограничение попыток ввода.

Способы предотвращения

Обе атаки работают схожим образом, одновременно отправляя множество запросов на сервер. Таким образом, главным приоритетом будет обнаружить инициатора и ограничить количество его запросов в определенный промежуток времени.

1. Решение с reCAPTCHA

Это одно из типовых решений, которое работает только для форм авторизации/регистрации или любых других POST-методов, не давая атакующему отправлять случайные запросы.

Форма reCAPTCHA

Однако наша главная задача состоит не в этом. Нам нужно ограничить запрос определенной продолжительностью, а значит данное решение не подходит. Мы не хотим, чтобы злоумышленники могли продолжать перегружать систему.

2. Ограничитель частоты обращений

С помощью этого метода можно ограничить продолжительность запросов клиента до определенного времени, независимо от того, что именно он делает. В результате время совершения запроса ограничивается как для реального пользователя, так и для скрипта. Этот метод еще известен как инкрементная задержка или регулирование запросов. Вот некоторые из его особенностей.

  • Ограничитель частоты обращений может контролировать входящий и исходящий трафик.
  • Таким образом можно ограничивать количество запросов от конкретного пользователя.
  • Это помогает защититься от DoS и брутфорс атак.

А теперь создадим такой сами.

В данном случае будем использовать npm-пакет Express Rate Limit и создадим простой проект с помощью Express. Для других фреймворков есть ряд альтернативных пакетов, которые можно без проблем найти в Google.

Вот простой Express API для нашего эксперимента.

const express = require("express");
const app = express();
app.get("/login", (req, res) => res.send("Already Logged in"));
app.post("/login", (req, res) => res.send("Logged in"));

app.listen(3000, () => console.log("server running on port 3000"));

Здесь у нас два API. Один отвечает за получение, а второй за отправку. При этом никакого ограничения для них нет. Мы можем обращаться к этим API тысячи раз, что и представляет основной риск для авторизации или других чувствительных API.

А теперь ограничим этот API.

Здесь мы задействуем Express Rate Limit, так как работаем с Express.

const rateLimit = require("express-rate-limit");

// windowMS - это время в м/с, на которое устанавливается           // ограничение.
// max - это ограничение количества запросов от пользователя в     // определенный промежуток времени

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 минут
  max: 100 // ограничить каждый IP до 100 запросов в windowMs
});

//  применяем ко всем запросам
app.use(limiter);

Теперь настроим API.

const express = require("express");
// Импортируем ограничитель обращений
const rateLimit = require("express-rate-limit");
const app = express();
// Используем ограничитель обращений в express
app.use(
    // Настраиваем ограничитель обращений
    rateLimit({
        windowMs : 5 * 60 * 1000, // Ставим лимит в 5 минут
        max : 5, // Максимальная квота 5 запросов в заданный        // промежуток времени
        message : "Too many requests" // Сообщение, которое будет    // возникать при превышении лимита
    })
)

app.get("/login", (req, res) => res.send("Already Logged in"));
app.post("/login", (req, res) => res.send("Logged in"));

app.listen(3000, () => console.log("server running on port 3000"));

Это работает?

Вот результат для первых пяти запросов. Как и ожидалось, мы получили сообщение об успешном обращении и код состояния 200.

Запрос Postman

А теперь превысим наш лимит и взглянем еще раз. Мы получили сообщение, которое прописали в ограничителе обращений, а также код состояния 429. Значит, ограничение для нашей конечной точки работает.

Запрос Postman

Заключение

В это статье мы рассмотрели DoS и брутфорс атаки. Тем не менее для борьбы с DDoS-атаками этот метод не подойдет. Нужно быть начеку в отношении этого опасного вида воздействия на систему и стараться реализовывать необходимые защиты. 

Благодарю за чтение и хорошего вам дня!

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи Shoaib Mehedi: Preventing DoS and Brute-Force Attacks on Our Way

Предыдущая статьяКонвейер BitBucket CI/CD для синхронизации веток с GitHub
Следующая статьяВведение в байт-код Java