Header Injection — это уязвимость, при которой злоумышленник внедряет произвольные HTTP-заголовки или модифицирует существующие, используя некорректно обработанные входные данные, содержащие символы перевода строки (CRLF), что может привести к изменению поведения сервера или клиента.
Принцип работы Header Injection
Уязвимость Header Injection возникает, когда веб-приложение или прокси-сервер принимает пользовательские данные, например, из URL-параметров или пользовательских заголовков, и использует их непосредственно для формирования HTTP-ответа или запроса без адекватной фильтрации или кодирования специальных символов. Ключевыми символами для такой атаки являются CR (Carriage Return, %0D или \r) и LF (Line Feed, %0A или \n), которые в совокупности (CRLF) обозначают конец строки в HTTP-протоколе. Внедрение CRLF позволяет злоумышленнику "завершить" текущий заголовок и начать новый, или даже полностью отделить заголовки от тела HTTP-сообщения.
Прокси-сервисы, выступая посредниками между клиентом и целевым сервером, могут быть как вектором для Header Injection, так и точкой для её предотвращения. Если прокси некорректно обрабатывает или передает пользовательские данные, содержащие CRLF, он может непреднамеренно способствовать атаке, либо сам стать целью, если его собственная логика обработки заголовков уязвима.
Типы Header Injection и их последствия
Header Injection не является самостоятельной атакой, а скорее вектором для реализации других, более сложных атак.
HTTP Response Splitting
Это наиболее распространенный сценарий Header Injection. Злоумышленник внедряет CRLF в часть HTTP-ответа, которую он контролирует (например, в значение заголовка Location для редиректа). Это позволяет ему внедрить новые заголовки и даже полностью новое тело ответа, отделяя его от оригинального.
Пример:
Предположим, сервер использует значение параметра redirect_url для формирования заголовка Location:
Location: /redirect?url=<redirect_url>
Если redirect_url содержит %0D%0AContent-Type: text/html%0D%0AHTTP/1.1 200 OK%0D%0A%0D%0A<script>alert('XSS')</script>, сервер может отправить два отдельных ответа:
HTTP/1.1 302 Found
Location: /redirect?url=
Content-Type: text/html
HTTP/1.1 200 OK
<script>alert('XSS')</script>
Клиент, вероятно, обработает второй ответ как легитимный, что приведет к XSS.
Cache Poisoning
При атаке на кэш злоумышленник заставляет прокси-сервер или CDN кэшировать вредоносный контент. Если прокси кэширует ответы на основе заголовков, которые могут быть манипулированы через Header Injection, он может обслуживать этот вредоносный контент другим пользователям.
Сценарий:
Атакующий внедряет заголовок Cache-Control: public, max-age=3600 и X-Injected-Content: <script>malicious_code</script> в ответ, который прокси затем кэширует для определенного URL. Последующие запросы к этому URL будут получать кэшированный, зараженный ответ.
Cross-Site Scripting (XSS) через заголовки
Как показано в примере HTTP Response Splitting, внедрение CRLF может привести к XSS, если атакующий может внедрить скрипт в тело ответа. Также возможна XSS, если приложение отображает пользовательские заголовки без санитаризации.
Session Fixation
Злоумышленник может использовать Header Injection для установки фиксированного идентификатора сессии для пользователя. Если пользователь входит в систему с этим фиксированным ID, сессия пользователя связывается с ID, который известен атакующему.
Пример:
Внедрение заголовка Set-Cookie: JSESSIONID=fixed_id через Header Injection. Если сервер не генерирует новый ID сессии при логине, пользователь будет использовать ID, заданный атакующим.
Обход механизмов безопасности
Header Injection может использоваться для обхода ограничений, наложенных WAF (Web Application Firewall) или другими системами безопасности, которые анализируют только определенные части запроса или ответа. Внедрение новых заголовков может изменить логику обработки запроса сервером.
Пример:
Внедрение заголовка X-Forwarded-For: 127.0.0.1 для обхода IP-фильтров, если приложение доверяет этому заголовку.
Роль прокси-сервисов в Header Injection
Прокси-сервис может быть как жертвой, так и инструментом или защитным барьером против Header Injection.
Прокси как вектор атаки
Если прокси-сервис не санитаризирует входящие запросы от клиентов, содержащие CRLF в URL, заголовках или других полях, которые затем передаются целевому серверу, он может стать вектором для Header Injection на целевой сервер.
Аналогично, если прокси генерирует собственные заголовки на основе пользовательского ввода (например, X-Forwarded-For на основе IP клиента), и этот ввод содержит CRLF, прокси может сам себе или последующему серверу внедрить вредоносные заголовки.
Прокси как цель атаки
Прокси-серверы, которые сами парсят или обрабатывают HTTP-заголовки и используют их в своей логике (например, для кэширования, маршрутизации, логирования), могут быть уязвимы для Header Injection, если они не корректно обрабатывают CRLF в значениях заголовков. Это может привести к DoS, обходу правил или другим проблемам.
Прокси как защитный барьер
Надежный прокси-сервис должен активно проверять и санитаризировать все входящие и исходящие HTTP-заголовки и URL на наличие CRLF и других потенциально опасных символов. Это включает:
* Фильтрацию CRLF в URL-путях, параметрах запроса и значениях заголовков.
* Кодирование специальных символов, которые могут быть интерпретированы как часть протокола.
* Ограничение длины заголовков.
Практические примеры уязвимого кода
Уязвимый PHP-код для редиректа
<?php
// index.php
$redirect_url = $_GET['url'];
header("Location: " . $redirect_url);
exit();
?>
Атака:
GET /index.php?url=%0D%0AContent-Type:%20text/html%0D%0AHTTP/1.1%20200%20OK%0D%0A%0D%0A<script>alert('XSS')</script>
Этот запрос приведет к HTTP Response Splitting и выполнению XSS в браузере.
Уязвимый Node.js-код с использованием пользовательского заголовка
// server.js
const http = require('http');
http.createServer((req, res) => {
const customData = req.headers['x-custom-data']; // Пользовательский заголовок
if (customData) {
// Уязвимость: если customData содержит CRLF, он может внедрить новые заголовки
// Например: X-Custom-Data: value%0D%0ASet-Cookie: malicious_cookie=injected; Path=/
res.setHeader('Set-Cookie', `data=${customData}; Path=/`);
}
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello from server!');
}).listen(3000, () => {
console.log('Server running on port 3000');
});
Атака:
Запрос с заголовком:
X-Custom-Data: value%0D%0ASet-Cookie: malicious_cookie=injected; Path=/
Это приведет к двум заголовкам Set-Cookie в ответе сервера:
Set-Cookie: data=value; Path=/
Set-Cookie: malicious_cookie=injected; Path=/
Таким образом, злоумышленник может внедрить произвольные куки для клиента.
Методы предотвращения Header Injection
Предотвращение Header Injection требует комплексного подхода на всех уровнях: от клиентского ввода до серверной обработки и настроек прокси-сервиса.
1. Строгая валидация и санитаризация ввода
- Фильтрация CRLF: Удаление или кодирование символов
CR(%0D) иLF(%0A) из всех пользовательских данных перед их использованием в HTTP-заголовках или URL. Это фундаментальная мера. - Белые списки: Использование белых списков допустимых символов или форматов для значений заголовков и URL-параметров.
- Регулярные выражения: Применение регулярных выражений для проверки соответствия входных данных ожидаемому формату.
2. Кодирование вывода
- Всегда кодировать пользовательские данные, которые будут вставлены в HTTP-заголовки, особенно в заголовки
LocationилиSet-Cookie. Функции URL-кодирования (например,urlencode()в PHP,encodeURIComponent()в JavaScript) должны применяться к значениям, а не к полному URL.
3. Ограничение длины заголовков
- Установка максимальной допустимой длины для пользовательских заголовков и значений параметров. Слишком длинные строки могут указывать на попытку инъекции или переполнения.
4. Использование безопасных API и фреймворков
- Современные веб-фреймворки и API часто предоставляют встроенные механизмы защиты от Header Injection, автоматически кодируя или фильтруя символы. Применение таких инструментов снижает риск.
5. Конфигурация прокси-сервиса
- На уровне прокси: Прокси-сервис должен быть настроен на активное сканирование и блокировку запросов, содержащих
CRLFв полях, которые могут быть использованы для инъекции. - WAF (Web Application Firewall): Внедрение WAF перед прокси-сервисом или целевым сервером может обеспечить дополнительный уровень защиты, обнаруживая и блокируя подозрительные паттерны запросов.
- Передача заголовков: При передаче заголовков от клиента к серверу (например,
X-Forwarded-For), прокси должен гарантировать, что эти заголовки формируются безопасно, без возможности внедренияCRLFиз пользовательских данных.
6. Использование HTTPS
- Хотя HTTPS не предотвращает Header Injection напрямую, он защищает от атак "человек посередине" (MitM), которые могут быть использованы для изменения заголовков в транзите. Это делает более сложным изменение заголовков после их генерации сервером.
Сравнение методов предотвращения
| Метод | Описание | Преимущества | Недостатки | Применимость (Прокси) |
|---|---|---|---|---|
| Валидация/Санитаризация | Удаление/кодирование CRLF из пользовательского ввода. |
Фундаментальная защита, предотвращает большинство атак. | Требует тщательной реализации во всех точках ввода. | Обязательно для входящих и исходящих заголовков. |
| Кодирование вывода | URL-кодирование значений перед их вставкой в заголовки. | Эффективно для динамически формируемых заголовков. | Применимо только к значениям, не к структуре заголовка. | Для заголовков, генерируемых прокси на основе ввода. |
| Ограничение длины | Установка максимальной длины для заголовков и их значений. | Простая в реализации, предотвращает переполнение. | Может блокировать легитимные, но длинные заголовки. | Для всех заголовков, проходящих через прокси. |
| Безопасные API/Фреймворки | Использование встроенных защитных механизмов. | Снижает сложность, автоматизирует защиту. | Зависимость от качества реализации фреймворка. | На уровне приложений, которые взаимодействуют с прокси. |
| WAF | Анализ трафика и блокировка вредоносных паттернов. | Дополнительный уровень защиты, централизованный контроль. | Может давать ложные срабатывания, требует настройки. | Перед прокси или как часть функционала прокси. |
| HTTPS | Шифрование трафика. | Защита от MitM, целостность данных. | Не предотвращает инъекции, если уязвимость на сервере. | Стандарт для любого прокси-сервиса. |