diff --git a/src/network-services-pentesting/pentesting-web/special-http-headers.md b/src/network-services-pentesting/pentesting-web/special-http-headers.md index 1f0f7d85f..14f2edca0 100644 --- a/src/network-services-pentesting/pentesting-web/special-http-headers.md +++ b/src/network-services-pentesting/pentesting-web/special-http-headers.md @@ -2,14 +2,14 @@ {{#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 джерела**: +Підміна джерела IP: - `X-Originating-IP: 127.0.0.1` - `X-Forwarded-For: 127.0.0.1` @@ -26,80 +26,101 @@ - `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) +- `Connection: close, X-Forwarded-For` (Перевіряйте hop-by-hop заголовки) -Перезаписати **місцезнаходження**: +Підміна локації: - `X-Original-URL: /admin/console` - `X-Rewrite-URL: /admin/console` -## Заголовки hop-by-hop +## Заголовки Hop-by-Hop -Заголовок hop-by-hop - це заголовок, який призначений для обробки та споживання проксі, що наразі обробляє запит, на відміну від заголовка end-to-end. +Заголовок hop-by-hop — це заголовок, який призначений для обробки та використання проксі, що наразі обробляє запит, на відміну від end-to-end заголовка. - `Connection: close, X-Forwarded-For` + {{#ref}} ../../pentesting-web/abusing-hop-by-hop-headers.md {{#endref}} -## HTTP Запит на контрабанду +## HTTP Request Smuggling - `Content-Length: 30` - `Transfer-Encoding: chunked` + {{#ref}} ../../pentesting-web/http-request-smuggling/ {{#endref}} +## Заголовок 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 дивіться: + +{{#ref}} +../../pentesting-web/http-request-smuggling/ +{{#endref}} + + ## Заголовки кешу -**Заголовки кешу сервера**: +**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`** також вказує, що ресурс був кешований. -- **`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"` +- `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 байтів**. +- Запити з заголовками **`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`**: Вказує, чи підтримує сервер запити діапазону, і якщо так, в якій одиниці може бути виражений діапазон. `Accept-Ranges: ` -- **`Range`**: Вказує частину документа, яку сервер повинен повернути. Наприклад, `Range:80-100` поверне байти з 80 по 100 оригінальної відповіді зі статус-кодом 206 Partial Content. Також пам'ятайте про видалення заголовка `Accept-Encoding` з запиту. -- Це може бути корисно для отримання відповіді з довільним відображеним кодом JavaScript, який інакше міг би бути втечений. Але для зловживання цим вам потрібно буде вставити ці заголовки в запит. -- **`If-Range`**: Створює умовний запит діапазону, який виконується лише якщо вказаний etag або дата збігаються з віддаленим ресурсом. Використовується для запобігання завантаженню двох діапазонів з несумісних версій ресурсу. -- **`Content-Range`**: Вказує, де в повному тілі повідомлення належить часткове повідомлення. +- **`Accept-Ranges`**: Вказує, чи підтримує сервер range-запити, і в яких одиницях можна задати діапазон. `Accept-Ranges: ` +- **`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`**: Вказує альтернативне місцезнаходження для повернених даних. +- **`Content-Length`:** Розмір ресурсу у десятковому числі байтів. +- **`Content-Type`**: Вказує медіа-тип ресурсу. +- **`Content-Encoding`**: Використовується для вказання алгоритму стиснення. +- **`Content-Language`**: Описує людські мови, для яких призначено вміст, щоб дозволити користувачу відрізняти згідно з власними мовними уподобаннями. +- **`Content-Location`**: Вказує альтернативне розташування для повернутих даних. -З точки зору пентесту ця інформація зазвичай "марна", але якщо ресурс **захищений** 401 або 403 і ви можете знайти якийсь **спосіб** отримати цю **інформацію**, це може бути **цікаво.**\ -Наприклад, комбінація **`Range`** та **`Etag`** у запиті HEAD може витікати вміст сторінки через запити HEAD: +З точки зору pentest ця інформація зазвичай "марна", але якщо ресурс **захищений** кодом 401 або 403 і ви можете знайти якийсь **спосіб** отримати цю **інфо**, це може бути **цікаво.**\ +Наприклад, поєднання **`Range`** та **`Etag`** у HEAD-запиті може leak вміст сторінки через HEAD-запити: -- Запит з заголовком `Range: bytes=20-20` і з відповіддю, що містить `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` витікає, що SHA1 байта 20 є `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y` +- Запит з заголовком `Range: bytes=20-20` та у відповіді `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` leak-ить, що SHA1 байта 20 — `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y` ## Інформація про сервер @@ -108,28 +129,29 @@ ## Контролі -- **`Allow`**: Цей заголовок використовується для спілкування HTTP-методів, які ресурс може обробляти. Наприклад, його можна вказати як `Allow: GET, POST, HEAD`, що вказує, що ресурс підтримує ці методи. -- **`Expect`**: Використовується клієнтом для передачі очікувань, які сервер повинен виконати для успішної обробки запиту. Загальним випадком використання є заголовок `Expect: 100-continue`, який сигналізує, що клієнт має намір надіслати великий обсяг даних. Клієнт чекає на відповідь `100 (Continue)` перед продовженням передачі. Цей механізм допомагає оптимізувати використання мережі, очікуючи підтвердження від сервера. +- **`Allow`**: Цей заголовок використовується для повідомлення HTTP-методів, які ресурс може обробляти. Наприклад: `Allow: GET, POST, HEAD`, що вказує, що ресурс підтримує ці методи. +- **`Expect`**: Використовується клієнтом для повідомлення очікувань, які сервер має виконати для успішної обробки запиту. Частий приклад — заголовок `Expect: 100-continue`, який сигналізує про намір клієнта відправити великий об'єм даних. Клієнт очікує відповідь `100 (Continue)` перед тим, як продовжити передачу. Цей механізм допомагає оптимізувати мережевий трафік, очікуючи підтвердження від сервера. ## Завантаження -- Заголовок **`Content-Disposition`** у HTTP-відповідях вказує, чи файл повинен відображатися **вбудовано** (в межах веб-сторінки) або розглядатися як **додаток** (завантажений). Наприклад: +- Заголовок **`Content-Disposition`** у HTTP-відповідях визначає, чи файл має відображатися **вбудовано** (в межах сторінки) або поводитися **як вкладення** (завантажуватись). Наприклад: ``` Content-Disposition: attachment; filename="filename.jpg" ``` -Це означає, що файл з назвою "filename.jpg" призначений для завантаження та збереження. +Це означає, що файл із назвою "filename.jpg" призначений для завантаження та збереження. ## Заголовки безпеки -### Політика безпеки контенту (CSP) +### Content Security Policy (CSP) + {{#ref}} ../../pentesting-web/content-security-policy-csp-bypass/ {{#endref}} -### **Довірені типи** +### **Trusted Types** -Забезпечуючи Довірені типи через CSP, програми можуть бути захищені від атак DOM XSS. Довірені типи гарантують, що лише спеціально створені об'єкти, які відповідають встановленим політикам безпеки, можуть використовуватися в небезпечних викликах веб-API, тим самим забезпечуючи безпеку JavaScript-коду за замовчуванням. +Застосовуючи Trusted Types через CSP, додатки можна захистити від атак DOM XSS. Trusted Types гарантують, що для небезпечних викликів web API можуть використовуватися лише спеціально сформовані об'єкти, які відповідають встановленим політикам безпеки, тим самим за замовчуванням захищаючи JavaScript-код. ```javascript // Feature detection if (window.trustedTypes && trustedTypes.createPolicy) { @@ -148,74 +170,75 @@ el.innerHTML = escaped // Results in safe assignment. ``` ### **X-Content-Type-Options** -Цей заголовок запобігає визначенню типу MIME, що може призвести до вразливостей XSS. Він забезпечує, щоб браузери поважали типи MIME, вказані сервером. +Цей заголовок запобігає MIME type sniffing — практиці, яка може призвести до XSS-вразливостей. Він гарантує, що браузери дотримуються MIME-типів, вказаних сервером. ``` X-Content-Type-Options: nosniff ``` ### **X-Frame-Options** -Щоб боротися з clickjacking, цей заголовок обмежує, як документи можуть бути вбудовані в ``, `