Спеціальні HTTP заголовки

Reading time: 10 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Словники та інструменти

Заголовки для підміни локації

Підміна джерела IP:

  • X-Originating-IP: 127.0.0.1
  • X-Forwarded-For: 127.0.0.1
  • X-Forwarded: 127.0.0.1
  • Forwarded-For: 127.0.0.1
  • X-Forwarded-Host: 127.0.0.1
  • X-Remote-IP: 127.0.0.1
  • X-Remote-Addr: 127.0.0.1
  • X-ProxyUser-Ip: 127.0.0.1
  • X-Original-URL: 127.0.0.1
  • Client-IP: 127.0.0.1
  • X-Client-IP: 127.0.0.1
  • X-Host: 127.0.0.1
  • True-Client-IP: 127.0.0.1
  • Cluster-Client-IP: 127.0.0.1
  • Via: 1.0 fred, 1.1 127.0.0.1
  • Connection: close, X-Forwarded-For (Перевіряйте hop-by-hop заголовки)

Підміна локації:

  • X-Original-URL: /admin/console
  • X-Rewrite-URL: /admin/console

Заголовки Hop-by-Hop

Заголовок hop-by-hop — це заголовок, який призначений для обробки та використання проксі, що наразі обробляє запит, на відміну від end-to-end заголовка.

  • Connection: close, X-Forwarded-For

hop-by-hop headers

HTTP Request Smuggling

  • Content-Length: 30
  • Transfer-Encoding: chunked

HTTP Request Smuggling / HTTP Desync Attack

Заголовок Expect

Клієнт може відправити заголовок Expect: 100-continue, після чого сервер може відповісти HTTP/1.1 100 Continue, щоб дозволити клієнту продовжити відправлення тіла запиту. Однак деякі проксі не дуже добре працюють з цим заголовком.

Цікаві результати використання Expect: 100-continue:

  • Відправка HEAD-запиту з тілом — сервер не врахував, що HEAD не має тіла, і тримає з'єднання відкритим до тайм-ауту.
  • Деякі сервери повертали дивні дані: випадкові байти, прочитані з сокету в відповіді, секретні ключі або навіть дозволяли запобігти видаленню значень заголовків фронтендом.
  • Також це спричиняло 0.CL десинхронізацію, коли бекенд відповів 400 замість 100, але фронт-проксі був готовий відправити тіло початкового запиту, тож відправляє його, а бекенд сприймає це як новий запит.
  • Відправка варіації Expect: y 100-continue також викликала 0.CL десинхронізацію.
  • Схожа помилка, коли бекенд відповідав 404, породжувала CL.0 десинхронізацію: шкідливий запит вказує Content-Length, тому бекенд відправляє шкідливий запит плюс Content-Length байтів наступного запиту (жертви). Це десинхронізує чергу, бо бекенд надсилає 404 відповідь для шкідливого запиту плюс відповідь жертви, тоді як фронтенд думав, що надіслано лише 1 запит, тому друга відповідь відправляється другому потерпілому запиту, а відповідь того — наступному, і так далі...

Для більше інформації про HTTP Request Smuggling дивіться:

HTTP Request Smuggling / HTTP Desync Attack

Заголовки кешу

Server Cache Headers:

  • X-Cache в відповіді може мати значення miss, коли запит не кешований, і hit, коли він кешований.
  • Подібна поведінка у заголовку Cf-Cache-Status.
  • Cache-Control вказує, чи кешується ресурс і коли ресурс знову стане застарілим: Cache-Control: public, max-age=1800
  • Vary часто використовується у відповіді, щоб вказати додаткові заголовки, які враховуються як частина ключа кешу, навіть якщо зазвичай вони не є ключовими.
  • Age визначає час у секундах, протягом якого об'єкт знаходиться в кеші проксі.
  • Server-Timing: cdn-cache; desc=HIT також вказує, що ресурс був кешований.

Cache Poisoning and Cache Deception

Локальні заголовки кешу:

  • Clear-Site-Data: Заголовок для вказання кешів, які слід видалити: Clear-Site-Data: "cache", "cookies"
  • Expires: Містить дату/час, коли відповідь має втратити актуальність: Expires: Wed, 21 Oct 2015 07:28:00 GMT
  • Pragma: no-cache те ж саме що й Cache-Control: no-cache
  • Warning: Загальний HTTP-заголовок Warning містить інформацію про можливі проблеми зі статусом повідомлення. У відповіді може з'явитися кілька Warning заголовків. Приклад: Warning: 110 anderson/1.3.37 "Response is stale"

Умовні запити

  • Запити з заголовками If-Modified-Since та If-Unmodified-Since отримають відповідь з даними тільки якщо заголовок відповіді Last-Modified містить інший час.
  • Умовні запити з використанням If-Match та If-None-Match використовують значення Etag, тому веб-сервер надішле вміст відповіді, якщо дані (Etag) змінилися. Etag береться з HTTP-відповіді.
  • Значення Etag зазвичай обчислюється на основі вмісту відповіді. Наприклад, ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI" вказує, що Etag — це Sha1 для 37 байтів.

Range-запити

  • Accept-Ranges: Вказує, чи підтримує сервер range-запити, і в яких одиницях можна задати діапазон. Accept-Ranges: <range-unit>
  • Range: Вказує частину документа, яку сервер повинен повернути. Наприклад, Range:80-100 поверне байти з 80 по 100 оригінальної відповіді зі статусом 206 Partial Content. Також не забувайте видаляти заголовок Accept-Encoding з запиту.
  • Це може бути корисно, щоб отримати відповідь з довільним відбитим javascript-кодом, який інакше був би екранований. Але для зловживання цим потрібно вміти інжектити ці заголовки в запит.
  • If-Range: Створює умовний range-запит, який виконується тільки якщо вказаний etag або дата відповідає віддаленому ресурсу. Використовується, щоб запобігти завантаженню двох діапазонів з несумісних версій ресурсу.
  • Content-Range: Вказує, куди в повному тілі повідомлення належить часткове повідомлення.

Інформація про тіло повідомлення

  • Content-Length: Розмір ресурсу у десятковому числі байтів.
  • Content-Type: Вказує медіа-тип ресурсу.
  • Content-Encoding: Використовується для вказання алгоритму стиснення.
  • Content-Language: Описує людські мови, для яких призначено вміст, щоб дозволити користувачу відрізняти згідно з власними мовними уподобаннями.
  • Content-Location: Вказує альтернативне розташування для повернутих даних.

З точки зору pentest ця інформація зазвичай "марна", але якщо ресурс захищений кодом 401 або 403 і ви можете знайти якийсь спосіб отримати цю інфо, це може бути цікаво.
Наприклад, поєднання Range та Etag у HEAD-запиті може leak вміст сторінки через HEAD-запити:

  • Запит з заголовком Range: bytes=20-20 та у відповіді ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y" leak-ить, що SHA1 байта 20 — ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y

Інформація про сервер

  • Server: Apache/2.4.1 (Unix)
  • X-Powered-By: PHP/5.3.3

Контролі

  • Allow: Цей заголовок використовується для повідомлення HTTP-методів, які ресурс може обробляти. Наприклад: Allow: GET, POST, HEAD, що вказує, що ресурс підтримує ці методи.
  • Expect: Використовується клієнтом для повідомлення очікувань, які сервер має виконати для успішної обробки запиту. Частий приклад — заголовок Expect: 100-continue, який сигналізує про намір клієнта відправити великий об'єм даних. Клієнт очікує відповідь 100 (Continue) перед тим, як продовжити передачу. Цей механізм допомагає оптимізувати мережевий трафік, очікуючи підтвердження від сервера.

Завантаження

  • Заголовок Content-Disposition у HTTP-відповідях визначає, чи файл має відображатися вбудовано (в межах сторінки) або поводитися як вкладення (завантажуватись). Наприклад:
Content-Disposition: attachment; filename="filename.jpg"

Це означає, що файл із назвою "filename.jpg" призначений для завантаження та збереження.

Заголовки безпеки

Content Security Policy (CSP)

Content Security Policy (CSP) Bypass

Trusted Types

Застосовуючи Trusted Types через CSP, додатки можна захистити від атак DOM XSS. Trusted Types гарантують, що для небезпечних викликів web API можуть використовуватися лише спеціально сформовані об'єкти, які відповідають встановленим політикам безпеки, тим самим за замовчуванням захищаючи JavaScript-код.

javascript
// Feature detection
if (window.trustedTypes && trustedTypes.createPolicy) {
// Name and create a policy
const policy = trustedTypes.createPolicy('escapePolicy', {
createHTML: str => str.replace(/\</g, '&lt;').replace(/>/g, '&gt;');
});
}
javascript
// Assignment of raw strings is blocked, ensuring safety.
el.innerHTML = "some string" // Throws an exception.
const escaped = policy.createHTML("<img src=x onerror=alert(1)>")
el.innerHTML = escaped // Results in safe assignment.

X-Content-Type-Options

Цей заголовок запобігає MIME type sniffing — практиці, яка може призвести до XSS-вразливостей. Він гарантує, що браузери дотримуються MIME-типів, вказаних сервером.

X-Content-Type-Options: nosniff

X-Frame-Options

Щоб протидіяти clickjacking, цей заголовок обмежує, як документи можуть бути вбудовані в <frame>, <iframe>, <embed> або <object> теги, і рекомендує всім документам явно вказувати свої права на вбудовування.

X-Frame-Options: DENY

Політика ресурсів між походженнями (CORP) та Спільний доступ до ресурсів між походженнями (CORS)

CORP має вирішальне значення для визначення того, які ресурси можуть завантажуватися вебсайтами, зменшуючи cross-site leaks. CORS, з іншого боку, дозволяє більш гнучкий механізм спільного доступу до ресурсів між походженнями, послаблюючи політику одного походження за певних умов.

Cross-Origin-Resource-Policy: same-origin
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

Cross-Origin Embedder Policy (COEP) and Cross-Origin Opener Policy (COOP)

COEP та COOP необхідні для активації міждоменної ізоляції, що суттєво знижує ризик атак типу Spectre. Вони відповідно контролюють завантаження міждоменних ресурсів та взаємодію з міждоменними вікнами.

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin-allow-popups

HTTP Strict Transport Security (HSTS)

Нарешті, HSTS — це функція безпеки, яка змушує браузери спілкуватися з серверами лише через захищені HTTPS-з'єднання, тим самим підвищуючи конфіденційність і безпеку.

Strict-Transport-Security: max-age=3153600

Обхід перевірки регістру імен заголовків

HTTP/1.1 визначає імена полів заголовків як без врахування регістру (RFC 9110 §5.1). Тим не менш, дуже часто зустрічаються користувацькі middleware, security filters або бізнес-логіка, що порівнюють буквальне ім'я заголовка, не нормалізуючи регістр спочатку (наприклад, header.equals("CamelExecCommandExecutable")). Якщо такі перевірки виконуються з урахуванням регістру, атакуючий може їх обійти, просто відправивши той самий заголовок з іншим використанням великих/малих літер.

Типові ситуації, де ця помилка зустрічається:

  • Користувацькі allow/deny списки, які намагаються блокувати “dangerous” internal headers перед тим, як запит досягне чутливого компонента.
  • Внутрішні реалізації reverse-proxy псевдозаголовків (наприклад, X-Forwarded-For sanitisation).
  • Фреймворки, що відкривають management / debug endpoints і покладаються на імена заголовків для аутентифікації або вибору команд.

Зловживання обходом

  1. Визначте заголовок, який фільтрується або валідирується на стороні сервера (наприклад, шляхом читання вихідного коду, документації або повідомлень про помилки).
  2. Відправте той самий заголовок з іншим регістром (mixed-case або upper-case). Оскільки HTTP-стеки зазвичай канонізують заголовки лише після виконання користувацького коду, вразлива перевірка може бути пропущена.
  3. Якщо компонент нижчого рівня обробляє заголовки без врахування регістру (більшість так робить), він прийме значення, контрольоване атакуючим.

Приклад: Apache Camel exec RCE (CVE-2025-27636)

У вразливих версіях Apache Camel маршрути Command Center намагалися блокувати недовірені запити, видаляючи заголовки CamelExecCommandExecutable та CamelExecCommandArgs. Порівняння виконувалося за допомогою equals(), тому видалялися лише заголовки з точно відповідним регістром.

bash
# Bypass the filter by using mixed-case header names and execute `ls /` on the host
curl "http://<IP>/command-center" \
-H "CAmelExecCommandExecutable: ls" \
-H "CAmelExecCommandArgs: /"

Headers потрапляють у компонент exec без фільтрації, внаслідок чого відбувається remote command execution з привілеями процесу Camel.

Виявлення та пом'якшення

  • Нормалізуйте всі header names до одного регістру (зазвичай lowercase) перед виконанням allow/deny comparisons.
  • Відхиляйте підозрілі дублікати: якщо одночасно присутні Header: і HeAdEr:, розцінюйте це як аномалію.
  • Використовуйте позитивний allow-list, застосований після canonicalisation.
  • Захищайте management endpoints за допомогою authentication та network segmentation.

Джерела

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks