X-Forwarded-For: как поддельный IP может сломать защиту
Утром попалось на глаза объяснение, как один простой заголовок может превратить защиту сайта в игру с котом в шляпе. Считаю, что это не просто техническая тонкость — это фундаментальная уязвимость, которую многие игнорируют, пока не сработает блокировка или не начнётся массовый взлом.
О чём речь и почему это важно для сайта
Речь о заголовке X-Forwarded-For — он кажется незаметным, но на деле может стать точкой входа для любого, кто захочет обмануть систему. Я уже давно вижу, как сайты сбрасывают блокировки, не понимая, что их «защита» работает на ложных данных.
Считаю, что это критично: если система принимает адрес из заголовка, который может подделать любой, то всё, что на этом строится — от контроля доступа до логирования — уже не работает. И это не «случай», а системная ошибка, которую можно исправить заранее.
Как это устроено — что тут вообще происходит
Когда запрос проходит через прокси, он не просто передаётся дальше — он добавляет в заголовок X-Forwarded-For свои данные. Проблема в том, что сервер может принять это значение как реальный адрес клиента, даже если оно пришло извне.
Если в конфигурации nginx не настроено доверие к прокси (set_real_ip_from), то система может принять любой адрес, который кто-то вставил в заголовок. И тогда, например, блокировка по IP работает не на реальных атакующих, а на подставных адресах — включая документационные диапазоны, которые вообще не существуют в интернете.
Как понять, что это касается вашего сайта («как я это проверяю»)
Проверяю первым делом: смотрю, где в логах берётся IP-адрес. Если в коде используется только $http_x_forwarded_for или первый элемент из списка — это красный флаг.
Потом смотрю, включён ли real_ip_recursive и есть ли set_real_ip_from с конкретными адресами прокси. Если его нет или он слишком широкий — это уже риск. Плюс проверяю, как ведёт себя лог: если в одном запросе X-Forwarded-For длинный и содержит 198.51.100.7 — это сигнал, что кто-то вручную его подставляет.
Что с этим делать («что я делаю в таких случаях»)
Сразу включаю рекурсивный режим и прописываю только те адреса, которые на самом деле участвуют в цепочке. Никакой 10.0.0.0/8 — только те, кто реально передаёт запрос.
Переписываю логирование: теперь в логах всегда два поля — исходный адрес сокета и вычисленный. Если они расходятся, это сразу видно. Такие запросы я отмечаю как подозрительные — они не должны быть в нормальном потоке.
Что здесь даёт поддержка
На постоянной поддержке мы не просто чистим заражение — мы закрываем причину. Если система принимает IP из заголовка, который можно подделать, то любая защита будет обходной. Заражают не хакеры, выбравшие вас — а боты, которые массово пробуют подставить адреса, чтобы сбить блокировки или обойти ограничения.
У нас мониторинг каждые несколько минут, 24/7. Это значит, что если кто-то начинает подставлять заголовки, мы увидим аномалии в логах до того, как это приведёт к реальной проблеме. И не просто увидим — сразу начнём разбираться.
Приглашаю на бесплатный аудит безопасности — проверим, как ваш сайт определяет адреса, и убедимся, что его не могут обмануть через заголовок.