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 c8f67f783..8b94fbce4 100644 --- a/src/network-services-pentesting/pentesting-web/special-http-headers.md +++ b/src/network-services-pentesting/pentesting-web/special-http-headers.md @@ -7,9 +7,9 @@ - [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,99 @@ - `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` (ホップバイホップヘッダーを確認) +- `Connection: close, X-Forwarded-For` (hop-by-hop ヘッダーも確認すること) -**場所**の書き換え: +ロケーションを書き換える: - `X-Original-URL: /admin/console` - `X-Rewrite-URL: /admin/console` -## ホップバイホップヘッダー +## Hop-by-Hop ヘッダー -ホップバイホップヘッダーは、リクエストを処理しているプロキシによって処理され、消費されることを目的としたヘッダーであり、エンドツーエンドヘッダーとは対照的です。 +Hop-by-hop header は、end-to-end header とは対照的に、リクエストを現在処理している proxy によって処理・消費されることを目的としたヘッダーです。 - `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` で応答してクライアントにリクエストボディの送信を続行させるという動作が可能です。しかし、一部の proxy はこのヘッダーを好まない場合があります。 + +`Expect: 100-continue` の興味深い挙動: +- HEAD リクエストにボディを付けて送信したところ、サーバーが HEAD リクエストにはボディがないことを考慮せず、接続をタイムアウトするまで開いたままにした。 +- 別のサーバーはレスポンスにソケットから読み取ったランダムなデータや秘密鍵などの奇妙なデータを返したり、フロントエンドがヘッダー値を削除するのを防いだりした。 +- バックエンドが 100 ではなく 400 を返したため、`0.CL` desync が発生した。proxy のフロントエンドは当初のリクエストのボディを送る準備をしていたためボディを送信し、バックエンドはそれを新しいリクエストとして扱った。 +- `Expect: y 100-continue` のバリエーションを送ることでも `0.CL` desync を引き起こした。 +- バックエンドが 404 を返した類似のエラーは `CL.0` desync を発生させた。悪意あるリクエストが `Content-Length` を示すため、バックエンドは悪意あるリクエスト本体に加え次のリクエスト(被害者)の `Content-Length` バイトを読み込む。これによりキューがずれて、バックエンドは悪意あるリクエストに対して 404 を返しつつ被害者のレスポンスも返すが、フロントエンドは一つのリクエストしか送信されていないと思い、二番目のレスポンスを別の被害者リクエストへ送ってしまい、以降もずれていく。 + +HTTP Request Smuggling の詳細は以下を参照してください: + +{{#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`** もリソースがキャッシュされていることを示します。 +- **`X-Cache`**: レスポンス内でリクエストがキャッシュされていない場合は **`miss`**、キャッシュされている場合は **`hit`** の値を持つことがある。 +- 同様の挙動は **`Cf-Cache-Status`** ヘッダーにも見られる。 +- **`Cache-Control`** はリソースがキャッシュされるかどうか、および次にいつキャッシュが有効かを示す: `Cache-Control: public, max-age=1800` +- **`Vary`** はレスポンスで、通常はキャッシュキーに含まれないヘッダーでもキャッシュキーの一部として扱われる追加のヘッダーを示すためによく使われる。 +- **`Age`** はオブジェクトが proxy キャッシュに存在していた時間を秒単位で示す。 +- **`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`: **`Warning`** 一般HTTPヘッダーは、メッセージの状態に関する可能な問題についての情報を含みます。レスポンスに複数の `Warning` ヘッダーが表示されることがあります。 `Warning: 110 anderson/1.3.37 "Response is stale"` +- `Pragma: no-cache` は `Cache-Control: no-cache` と同じ +- `Warning`: 一般的な HTTP ヘッダーで、メッセージの状態に関する可能性のある問題についての情報を含む。レスポンスに複数の `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` が **37バイト** の **Sha1** であることを示しています。 +- `If-Modified-Since` と `If-Unmodified-Since` を用いたリクエストは、レスポンスヘッダー `Last-Modified` が異なる日時を含む場合にのみデータが返される。 +- `If-Match` と `If-None-Match` を用いた条件付きリクエストは Etag 値を使用し、データ(Etag)が変更されていればサーバーはレスポンスの内容を送る。`Etag` は HTTP レスポンスから取得される。 +- Etag 値は通常レスポンスのコンテンツに基づいて計算される。例えば、`ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` は Etag が 37 バイトの Sha1 であることを示す。 -## レンジリクエスト +## Range リクエスト -- **`Accept-Ranges`**: サーバーがレンジリクエストをサポートしているかどうか、またその場合はどの単位でレンジを表現できるかを示します。 `Accept-Ranges: ` -- **`Range`**: サーバーが返すべきドキュメントの部分を示します。例えば、`Range:80-100` は、元のレスポンスのバイト80から100を返し、ステータスコード206 Partial Contentを持ちます。また、リクエストから `Accept-Encoding` ヘッダーを削除することを忘れないでください。 -- これは、そうでなければエスケープされる可能性のある任意の反射されたJavaScriptコードを含むレスポンスを取得するのに役立ちます。しかし、これを悪用するには、リクエストにこのヘッダーを挿入する必要があります。 -- **`If-Range`**: 指定されたetagまたは日付がリモートリソースと一致する場合にのみ満たされる条件付きレンジリクエストを作成します。リソースの互換性のないバージョンから2つのレンジをダウンロードするのを防ぐために使用されます。 -- **`Content-Range`**: 完全なボディメッセージのどこに部分メッセージが属するかを示します。 +- **`Accept-Ranges`**: サーバーが範囲リクエストをサポートしているか、およびどの単位で範囲が表現されるかを示す: `Accept-Ranges: ` +- **`Range`**: サーバーが返すべきドキュメントの一部を示す。例えば、`Range: 80-100` は元のレスポンスのバイト80から100を 206 Partial Content で返す。リクエストから `Accept-Encoding` ヘッダーを削除することも忘れないでください。 +- これは、通常はエスケープされる任意の反射型 JavaScript コードを含むレスポンスを得るのに有用な場合がある。しかしこれを悪用するにはリクエストにこれらのヘッダーを注入する必要がある。 +- **`If-Range`**: 指定した etag または日付がリモートリソースと一致する場合にのみ実行される条件付き範囲リクエストを作成する。互換性のないバージョンのリソースから二つの範囲をダウンロードしてしまうのを防ぐために使われる。 +- **`Content-Range`**: 部分メッセージが完全な本文メッセージのどこに属するかを示す。 -## メッセージボディ情報 +## メッセージ本文情報 -- **`Content-Length`:** リソースのサイズ、バイト数の10進数。 -- **`Content-Type`**: リソースのメディアタイプを示します。 -- **`Content-Encoding`**: 圧縮アルゴリズムを指定するために使用されます。 -- **`Content-Language`**: 対象となる人間の言語を説明し、ユーザーが自分の好みの言語に応じて区別できるようにします。 -- **`Content-Location`**: 返されたデータの代替位置を示します。 +- **`Content-Length`**: リソースのサイズ(十進数のバイト数)。 +- **`Content-Type`**: リソースのメディアタイプを示す。 +- **`Content-Encoding`**: 圧縮アルゴリズムを指定するために使われる。 +- **`Content-Language`**: 対象となる利用者向けの自然言語を記述し、ユーザーが好みの言語に応じて区別できるようにする。 +- **`Content-Location`**: 返却されるデータの代替場所を示す。 -ペンテストの観点から、この情報は通常「無駄」です。しかし、リソースが **401** または **403** で **保護されている** 場合、何らかの **方法** でこの **情報** を **取得** できると、これは **興味深い** かもしれません。\ -例えば、HEADリクエストでの **`Range`** と **`Etag`** の組み合わせは、HEADリクエストを介してページの内容を漏洩させることができます。 +pentest の観点ではこの情報は通常役に立たないことが多いですが、リソースが 401 や 403 で保護されていて、何らかの方法でこの情報を取得できる場合は興味深いことがあります。例えば HEAD リクエストで **`Range`** と **`Etag`** を組み合わせることで、HEAD リクエスト経由でページの内容が leak することがあります: -- ヘッダー `Range: bytes=20-20` を持つリクエストと、`ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` を含むレスポンスは、バイト20のSHA1が `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y` であることを漏洩しています。 +- ヘッダー `Range: bytes=20-20` を付けたリクエストと、レスポンスに `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` が含まれる場合、バイト20の SHA1 が `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y` であることが leak している。 ## サーバー情報 @@ -108,28 +127,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)` レスポンスを待ち、これによりサーバーの確認を待つことでネットワーク利用を最適化できる。 ## ダウンロード -- HTTPレスポンスの **`Content-Disposition`** ヘッダーは、ファイルを **インライン**(ウェブページ内)で表示するか、**添付ファイル**(ダウンロード)として扱うかを指示します。例えば: +HTTP レスポンス内の **`Content-Disposition`** ヘッダーは、ファイルをウェブページ内に表示する(inline)か、添付ファイルとして扱ってダウンロードさせる(attachment)かを指示します。例えば: ``` Content-Disposition: attachment; filename="filename.jpg" ``` -これは「filename.jpg」という名前のファイルがダウンロードされ、保存されることを意図していることを意味します。 +これは "filename.jpg" という名前のファイルがダウンロードされ保存されることを意図していることを意味します。 ## セキュリティヘッダー ### コンテンツセキュリティポリシー (CSP) + {{#ref}} ../../pentesting-web/content-security-policy-csp-bypass/ {{#endref}} -### **信頼されたタイプ** +### **Trusted Types** -CSPを通じて信頼されたタイプを強制することで、アプリケーションはDOM XSS攻撃から保護されます。信頼されたタイプは、確立されたセキュリティポリシーに準拠した特定のオブジェクトのみが危険なWeb API呼び出しに使用できることを保証し、デフォルトでJavaScriptコードを保護します。 +CSPを通じてTrusted Typesを強制することで、アプリケーションはDOM XSS攻撃から保護されます。Trusted Typesは、確立されたセキュリティポリシーに準拠した特別に作成されたオブジェクトのみが危険な web API 呼び出しで使用できるようにすることで、JavaScriptコードをデフォルトで保護します。 ```javascript // Feature detection if (window.trustedTypes && trustedTypes.createPolicy) { @@ -148,19 +168,19 @@ el.innerHTML = escaped // Results in safe assignment. ``` ### **X-Content-Type-Options** -このヘッダーはMIMEタイプのスニッフィングを防ぎます。これはXSS脆弱性につながる可能性があります。サーバーによって指定されたMIMEタイプをブラウザが尊重することを保証します。 +このヘッダーはMIMEタイプのスニッフィングを防ぎ、XSS脆弱性を引き起こす可能性のある挙動を抑えます。ブラウザがサーバーで指定されたMIMEタイプを尊重するようにします。 ``` X-Content-Type-Options: nosniff ``` ### **X-Frame-Options** -クリックジャッキングに対抗するために、このヘッダーはドキュメントが``、`