mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
225 lines
18 KiB
Markdown
225 lines
18 KiB
Markdown
# Спеціальні HTTP заголовки
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## Списки слів та інструменти
|
||
|
||
- [https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers](https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers)
|
||
- [https://github.com/rfc-st/humble](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`
|
||
|
||
{{#ref}}
|
||
../../pentesting-web/abusing-hop-by-hop-headers.md
|
||
{{#endref}}
|
||
|
||
## HTTP Запит на контрабанду
|
||
|
||
- `Content-Length: 30`
|
||
- `Transfer-Encoding: chunked`
|
||
|
||
{{#ref}}
|
||
../../pentesting-web/http-request-smuggling/
|
||
{{#endref}}
|
||
|
||
## Заголовки кешу
|
||
|
||
**Заголовки кешу сервера**:
|
||
|
||
- **`X-Cache`** у відповіді може мати значення **`miss`**, коли запит не кешувався, і значення **`hit`**, коли він кешується
|
||
- Схоже поводження у заголовку **`Cf-Cache-Status`**
|
||
- **`Cache-Control`** вказує, чи ресурс кешується, і коли буде наступний раз кешуватися: `Cache-Control: public, max-age=1800`
|
||
- **`Vary`** часто використовується у відповіді для **вказівки додаткових заголовків**, які розглядаються як **частина ключа кешу**, навіть якщо вони зазвичай не є ключованими.
|
||
- **`Age`** визначає час у секундах, протягом якого об'єкт перебував у кеші проксі.
|
||
- **`Server-Timing: cdn-cache; desc=HIT`** також вказує, що ресурс був кешований
|
||
|
||
{{#ref}}
|
||
../../pentesting-web/cache-deception/
|
||
{{#endref}}
|
||
|
||
**Заголовки локального кешу**:
|
||
|
||
- `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 байтів**.
|
||
|
||
## Запити діапазону
|
||
|
||
- **`Accept-Ranges`**: Вказує, чи підтримує сервер запити діапазону, і якщо так, в якій одиниці може бути виражений діапазон. `Accept-Ranges: <range-unit>`
|
||
- **`Range`**: Вказує частину документа, яку сервер повинен повернути. Наприклад, `Range:80-100` поверне байти з 80 по 100 оригінальної відповіді зі статус-кодом 206 Partial Content. Також пам'ятайте, щоб видалити заголовок `Accept-Encoding` з запиту.
|
||
- Це може бути корисно для отримання відповіді з довільним відображеним JavaScript-кодом, який інакше міг би бути втечений. Але для зловживання цим вам потрібно буде вставити ці заголовки в запит.
|
||
- **`If-Range`**: Створює умовний запит діапазону, який виконується лише у разі, якщо вказаний etag або дата збігаються з віддаленим ресурсом. Використовується для запобігання завантаженню двох діапазонів з несумісних версій ресурсу.
|
||
- **`Content-Range`**: Вказує, де в повному тілі повідомлення належить часткове повідомлення.
|
||
|
||
## Інформація про тіло повідомлення
|
||
|
||
- **`Content-Length`:** Розмір ресурсу в десяткових байтах.
|
||
- **`Content-Type`**: Вказує медіа-тип ресурсу
|
||
- **`Content-Encoding`**: Використовується для вказівки алгоритму стиснення.
|
||
- **`Content-Language`**: Описує людську мову(и), призначену для аудиторії, щоб дозволити користувачу відрізняти відповідно до власної переваги мови.
|
||
- **`Content-Location`**: Вказує альтернативне місцезнаходження для повернених даних.
|
||
|
||
З точки зору пентесту ця інформація зазвичай є "марною", але якщо ресурс **захищений** 401 або 403 і ви можете знайти якийсь **спосіб** отримати цю **інформацію**, це може бути **цікаво.**\
|
||
Наприклад, комбінація **`Range`** та **`Etag`** у запиті HEAD може витікати вміст сторінки через запити HEAD:
|
||
|
||
- Запит з заголовком `Range: bytes=20-20` і відповіддю, що містить `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"`, витікає, що 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" призначений для завантаження та збереження.
|
||
|
||
## Заголовки безпеки
|
||
|
||
### Політика безпеки вмісту (CSP) <a href="#csp" id="csp"></a>
|
||
|
||
{{#ref}}
|
||
../../pentesting-web/content-security-policy-csp-bypass/
|
||
{{#endref}}
|
||
|
||
### **Довірені типи**
|
||
|
||
Забезпечуючи Довірені типи через CSP, програми можуть бути захищені від атак DOM XSS. Довірені типи гарантують, що лише спеціально створені об'єкти, які відповідають встановленим політикам безпеки, можуть використовуватися в небезпечних викликах веб-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, '<').replace(/>/g, '>');
|
||
});
|
||
}
|
||
```
|
||
|
||
```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, практика, яка може призвести до вразливостей XSS. Він забезпечує, щоб браузери поважали типи MIME, вказані сервером.
|
||
```
|
||
X-Content-Type-Options: nosniff
|
||
```
|
||
### **X-Frame-Options**
|
||
|
||
Щоб боротися з clickjacking, цей заголовок обмежує, як документи можуть бути вбудовані в `<frame>`, `<iframe>`, `<embed>`, або `<object>` теги, рекомендується всім документам явно вказувати свої дозволи на вбудовування.
|
||
```
|
||
X-Frame-Options: DENY
|
||
```
|
||
### **Політика ресурсів з крос-доменним доступом (CORP) та Крос-доменний обмін ресурсами (CORS)**
|
||
|
||
CORP є важливим для визначення, які ресурси можуть бути завантажені веб-сайтами, зменшуючи крос-сайтові витоки. CORS, з іншого боку, дозволяє більш гнучкий механізм обміну ресурсами між різними доменами, послаблюючи політику однакового походження за певних умов.
|
||
```
|
||
Cross-Origin-Resource-Policy: same-origin
|
||
Access-Control-Allow-Origin: https://example.com
|
||
Access-Control-Allow-Credentials: true
|
||
```
|
||
### **Політика вбудовування з різних джерел (COEP) та Політика відкривача з різних джерел (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
|
||
```
|
||
## Header Name Casing Bypass
|
||
|
||
HTTP/1.1 визначає імена полів заголовків як **незалежні від регістру** (RFC 9110 §5.1). Проте, дуже часто можна зустріти кастомне проміжне програмне забезпечення, фільтри безпеки або бізнес-логіку, які порівнюють *літерне* ім'я заголовка, отримане без попередньої нормалізації регістру (наприклад, `header.equals("CamelExecCommandExecutable")`). Якщо ці перевірки виконуються **чутливо до регістру**, зловмисник може обійти їх, просто надіславши той же заголовок з іншим написанням.
|
||
|
||
Типові ситуації, в яких виникає ця помилка:
|
||
|
||
* Кастомні списки дозволів/заборон, які намагаються блокувати “небезпечні” внутрішні заголовки до того, як запит досягне чутливого компонента.
|
||
* Внутрішні реалізації псевдозаголовків зворотного проксі (наприклад, санітизація `X-Forwarded-For`).
|
||
* Фреймворки, які відкривають кінцеві точки управління / налагодження і покладаються на імена заголовків для аутентифікації або вибору команд.
|
||
|
||
### Abusing the bypass
|
||
|
||
1. Визначте заголовок, який фільтрується або перевіряється на стороні сервера (наприклад, читаючи вихідний код, документацію або повідомлення про помилки).
|
||
2. Надішліть **той же заголовок з іншим регістром** (змішаний регістр або верхній регістр). Оскільки стекі HTTP зазвичай канонізують заголовки лише *після* виконання коду користувача, вразливу перевірку можна пропустити.
|
||
3. Якщо нижній компонент обробляє заголовки незалежно від регістру (більшість так роблять), він прийме значення, контрольоване зловмисником.
|
||
|
||
### Example: 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: /"
|
||
```
|
||
Заголовки досягають компонента `exec` без фільтрації, що призводить до віддаленого виконання команд з привілеями процесу Camel.
|
||
|
||
### Виявлення та пом'якшення
|
||
|
||
* Нормалізуйте всі назви заголовків до єдиного регістру (зазвичай малими літерами) **перед** виконанням порівнянь дозволу/заборони.
|
||
* Відхиляйте підозрілі дублі: якщо присутні обидва `Header:` і `HeAdEr:`, розглядайте це як аномалію.
|
||
* Використовуйте позитивний список дозволів, що застосовується **після** канонізації.
|
||
* Захищайте управлінські кінцеві точки за допомогою аутентифікації та сегментації мережі.
|
||
|
||
## Посилання
|
||
|
||
- [CVE-2025-27636 – RCE в Apache Camel через обхід регістру заголовків (блог OffSec)](https://www.offsec.com/blog/cve-2025-27636/)
|
||
- [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
|
||
- [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)
|
||
- [https://web.dev/security-headers/](https://web.dev/security-headers/)
|
||
- [https://web.dev/articles/security-headers](https://web.dev/articles/security-headers)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|