Безопасность PHP: Что такое инъекция в заголовки Header Injection и как она может привести к перенаправлению пользователя на фишинговый сайт?
Header Injection (инъекция в заголовки) — это уязвимость веб-приложений, при которой злоумышленник внедряет произвольные HTTP-заголовки через пользовательский ввод, не прошедший должную валидацию. В PHP эта проблема особенно актуальна при использовании функции header(), которая напрямую передаёт строку в HTTP-ответ сервера.
**Как работает атака**
HTTP-заголовки разделяются символами перевода строки: rn (CRLF — Carriage Return + Line Feed). Если приложение принимает данные от пользователя и подставляет их в заголовок без фильтрации, атакующий может вставить эти символы и добавить собственные заголовки.
Пример уязвимого кода:
php
$url = $_GET[‘redirect’];
header(‘Location: ‘ . $url);
Если злоумышленник передаст значение:
https://example.com%0d%0aLocation:%20https://phishing-site.com
То сервер отправит два заголовка Location, и браузер может перенаправить пользователя на фишинговый сайт.
**Последствия Header Injection**
1. **Open Redirect** — пользователь перенаправляется на вредоносный сайт, замаскированный под легитимный. Это используется для кражи учётных данных.
2. **HTTP Response Splitting** — атакующий полностью контролирует тело HTTP-ответа, что позволяет внедрять вредоносный HTML или JavaScript.
3. **Cookie Injection** — через заголовок Set-Cookie можно установить поддельные куки, перехватывая сессии.
4. **Cache Poisoning** — отравление кэша прокси-серверов.
**Пример фишинговой атаки через Header Injection**
Пользователь получает ссылку вида:
https://trusted-bank.com/redirect?url=https://trusted-bank.com%0d%0aLocation:%20https://fake-bank.com
Браузер видит домен trusted-bank.com в адресной строке, но сервер отправляет перенаправление на fake-bank.com. Жертва доверяет ссылке, переходит и вводит данные на фишинговом сайте.
**Как защититься от Header Injection в PHP**
1. **Валидация и белые списки**: разрешайте только заранее определённые URL для редиректов.
php
$allowed = [‘https://example.com/page1’, ‘https://example.com/page2’];
if (in_array($_GET[‘redirect’], $allowed)) {
header(‘Location: ‘ . $_GET[‘redirect’]);
}
2. **Фильтрация CRLF-символов**: удаляйте r и n из входных данных.
php
$url = str_replace([«r», «n»], », $_GET[‘redirect’]);
3. **Использование filter_var()**: проверяйте корректность URL.
php
$url = filter_var($_GET[‘redirect’], FILTER_VALIDATE_URL);
if ($url) {
header(‘Location: ‘ . $url);
}
4. **Обновление PHP**: начиная с PHP 7.4, функция header() автоматически блокирует CRLF-инъекции, выбрасывая исключение.
5. **Использование относительных путей**: вместо полных URL используйте только пути внутри вашего домена.
Грамотная валидация входных данных и использование актуальных версий PHP — ключевые меры защиты от Header Injection.
