CORS - Misconfigurations & Bypass
Last updated
Last updated
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)
Cross-Origin Resource Sharing (CORS)標準は、サーバーが自分の資産にアクセスできる者を定義し、外部ソースから許可されるHTTPリクエストメソッドを定義することを可能にします。
同一オリジンポリシーは、リソースを要求するサーバーとリソースをホストするサーバーが同じプロトコル(例:http://
)、ドメイン名(例:internal-web.com
)、およびポート(例:80)を共有することを義務付けます。このポリシーの下では、同じドメインとポートからのウェブページのみがリソースにアクセスできます。
http://normal-website.com/example/example.html
の文脈における同一オリジンポリシーの適用は以下のように示されます:
アクセスされたURL | アクセスは許可されますか? |
---|---|
| はい:同一のスキーム、ドメイン、ポート |
| はい:同一のスキーム、ドメイン、ポート |
| いいえ:異なるスキームとポート |
| いいえ:異なるドメイン |
| いいえ:異なるドメイン |
| いいえ:異なるポート* |
*Internet Explorerは同一オリジンポリシーの施行においてポート番号を無視し、このアクセスを許可します。
Access-Control-Allow-Origin
ヘッダーこのヘッダーは、複数のオリジン、null
値、またはワイルドカード*
を許可することができます。しかし、複数のオリジンをサポートするブラウザはありません、またワイルドカード*
の使用には制限があります。(ワイルドカードは単独で使用する必要があり、Access-Control-Allow-Credentials: true
と一緒に使用することは許可されていません。)
このヘッダーは、ウェブサイトによって開始されたクロスドメインリソースリクエストに対する応答としてサーバーによって発行され、ブラウザは自動的にOrigin
ヘッダーを追加します。
Access-Control-Allow-Credentials
ヘッダーデフォルトでは、クロスオリジンリクエストはクッキーやAuthorizationヘッダーのような資格情報なしで行われます。しかし、クロスドメインサーバーは、Access-Control-Allow-Credentials
ヘッダーを**true
**に設定することで、資格情報が送信された場合に応答の読み取りを許可できます。
true
に設定されている場合、ブラウザは資格情報(クッキー、認証ヘッダー、またはTLSクライアント証明書)を送信します。
特定の条件下でクロスドメインリクエストを開始する際、例えば 非標準HTTPメソッド(HEAD、GET、POST以外の任意のもの)を使用したり、新しい ヘッダー を導入したり、特別な Content-Typeヘッダー値 を使用したりする場合、プレフライトリクエストが必要になることがあります。この予備リクエストは、OPTIONS
メソッドを利用して、サーバーに今後のクロスオリジンリクエストの意図、使用するHTTPメソッドやヘッダーを通知します。
クロスオリジンリソースシェアリング(CORS) プロトコルは、このプレフライトチェックを義務付けており、要求されたクロスオリジン操作の実行可能性を確認するために、許可されたメソッド、ヘッダー、およびオリジンの信頼性を検証します。プレフライトリクエストが不要となる条件についての詳細な理解は、Mozilla Developer Network (MDN) が提供する包括的なガイドを参照してください。
プレフライトリクエストがない場合でも、レスポンスに認証ヘッダーを含める必要があることに注意することが重要です。これらのヘッダーがないと、ブラウザはクロスオリジンリクエストからのレスポンスを処理することができません。
以下は、PUT
メソッドと Special-Request-Header
というカスタムヘッダーを使用することを目的としたプレフライトリクエストの例です:
応答として、サーバーは受け入れられたメソッド、許可されたオリジン、およびその他のCORSポリシーの詳細を示すヘッダーを返す場合があります。以下に示します:
Access-Control-Allow-Headers
: このヘッダーは、実際のリクエスト中に使用できるヘッダーを指定します。これは、サーバーによって設定され、クライアントからのリクエストで許可されるヘッダーを示します。
Access-Control-Expose-Headers
: このヘッダーを通じて、サーバーはクライアントに対して、単純なレスポンスヘッダー以外にレスポンスの一部として公開できるヘッダーを通知します。
Access-Control-Max-Age
: このヘッダーは、プレフライトリクエストの結果がどのくらいの間キャッシュできるかを示します。サーバーは、プレフライトリクエストによって返される情報が再利用できる最大時間(秒単位)を設定します。
Access-Control-Request-Headers
: プレフライトリクエストで使用されるこのヘッダーは、クライアントによって設定され、実際のリクエストで使用したいHTTPヘッダーをサーバーに通知します。
Access-Control-Request-Method
: プレフライトリクエストでも使用されるこのヘッダーは、クライアントによって設定され、実際のリクエストで使用されるHTTPメソッドを示します。
Origin
: このヘッダーはブラウザによって自動的に設定され、クロスオリジンリクエストの起源を示します。サーバーは、CORSポリシーに基づいて、受信リクエストを許可するか拒否するかを評価するために使用します。
通常、GET/POSTリクエストではプレフライトリクエストは送信されません(リクエストは直接送信されます)が、レスポンスのヘッダー/ボディにアクセスしたい場合は、Access-Control-Allow-Origin ヘッダーがそれを許可する必要があります。 したがって、CORSはCSRFから保護しません(ただし、役立つ場合があります)。
Access-Control-Request-Local-Network
: このヘッダーは、クライアントのリクエストに含まれ、問い合わせがローカルネットワークリソースを対象としていることを示します。これは、リクエストがローカルネットワーク内から発信されていることをサーバーに通知するマーカーとして機能します。
Access-Control-Allow-Local-Network
: サーバーはこのヘッダーを使用して、要求されたリソースがローカルネットワーク外のエンティティと共有することが許可されていることを伝えます。これは、異なるネットワーク境界を越えたリソースの共有を許可するためのグリーンライトとして機能し、セキュリティプロトコルを維持しながら制御されたアクセスを確保します。
ローカルネットワークリクエストを許可する有効なレスポンスには、レスポンスにヘッダー Access-Controls-Allow-Local_network: true
も含まれている必要があります。
注意してください、linuxの 0.0.0.0 IPは、localhostにアクセスするためのこれらの要件をバイパスするのに機能します。このIPアドレスは「ローカル」と見なされません。
また、ローカルネットワークの要件をバイパスすることも可能です。ローカルエンドポイントのパブリックIPアドレス(ルーターのパブリックIPなど)を使用する場合です。なぜなら、いくつかの状況では、パブリックIPにアクセスしていても、ローカルネットワークからであれば、アクセスが許可されるからです。
次の構成が非常に許可的に見えるかもしれないことに注意してください:
これはブラウザによって許可されておらず、したがってこのリクエストに対して資格情報は送信されません。
Access-Control-Allow-Credentials
を**true
に設定することがほとんどの実際の攻撃**の前提条件であることが観察されています。この設定により、ブラウザは資格情報を送信し、応答を読み取ることができ、攻撃の効果が高まります。これがなければ、ブラウザにリクエストを発行させることの利点は減少し、ユーザーのクッキーを利用することが不可能になります。
被害者のネットワーク位置が認証の一形態として機能する例外があります。これにより、被害者のブラウザをプロキシとして使用し、IPベースの認証を回避してイントラネットアプリケーションにアクセスすることが可能になります。この方法はDNSリバインディングと影響が似ていますが、悪用が簡単です。
Access-Control-Allow-Origin
におけるOrigin
の反映Origin
ヘッダーの値がAccess-Control-Allow-Origin
に反映される現実のシナリオは、これらのヘッダーを組み合わせる制限により理論的にはあり得ません。しかし、複数のURLに対してCORSを有効にしようとする開発者は、Origin
ヘッダーの値をコピーすることでAccess-Control-Allow-Origin
ヘッダーを動的に生成することがあります。このアプローチは脆弱性を引き起こす可能性があり、特に攻撃者が正当であるように見える名前のドメインを使用する場合、検証ロジックを欺くことになります。
null
オリジンの悪用null
オリジンは、リダイレクトやローカル HTML ファイルのような状況で指定され、特異な位置を占めています。一部のアプリケーションは、ローカル開発を促進するためにこのオリジンをホワイトリストに登録しており、結果として、任意のウェブサイトがサンドボックス化された iframe を通じて null
オリジンを模倣することを許可し、CORS 制限を回避することができます。
ドメインホワイトリストに遭遇した際は、攻撃者のドメインをホワイトリストに登録されたドメインに追加することや、サブドメインの乗っ取り脆弱性を利用するなど、バイパスの機会をテストすることが重要です。さらに、ドメイン検証に使用される正規表現は、ドメイン名の命名規則の微妙な違いを見落とす可能性があり、さらなるバイパスの機会を提供します。
Regexパターンは通常、英数字、ドット(.)、およびハイフン(-)文字に集中し、他の可能性を無視します。たとえば、ブラウザや正規表現パターンによって異なる解釈をされる文字を含むように作成されたドメイン名は、セキュリティチェックをバイパスすることができます。Safari、Chrome、Firefoxのサブドメインにおけるアンダースコア文字の取り扱いは、このような不一致がドメイン検証ロジックを回避するためにどのように利用されるかを示しています。
このバイパスチェックの詳細情報と設定については: https://www.corben.io/advanced-cors-techniques/ および https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397
開発者は、情報をリクエストすることが許可されたドメインをホワイトリストに登録することで、CORSの悪用から保護するための防御メカニズムを実装することがよくあります。これらの予防策にもかかわらず、システムのセキュリティは完全ではありません。ホワイトリストに登録されたドメイン内に脆弱なサブドメインが1つでも存在する場合、XSS(クロスサイトスクリプティング)などの他の脆弱性を通じてCORSの悪用が可能になります。
例として、ドメインrequester.com
が別のドメインprovider.com
からリソースにアクセスするためにホワイトリストに登録されているシナリオを考えてみましょう。サーバー側の設定は次のようになるかもしれません:
このセットアップでは、requester.com
のすべてのサブドメインがアクセスを許可されています。しかし、例えばsub.requester.com
というサブドメインがXSS脆弱性で侵害された場合、攻撃者はこの弱点を利用できます。例えば、sub.requester.com
にアクセスできる攻撃者は、XSS脆弱性を利用してCORSポリシーをバイパスし、provider.com
上のリソースに悪意を持ってアクセスすることができます。
PortSwiggerのURL検証バイパスチートシートは、一部のブラウザがドメイン名内で奇妙な文字をサポートしていることを発見しました。
ChromeとFirefoxは、Origin
ヘッダーを検証するために実装された正規表現をバイパスできるアンダースコア_
をサポートしています:
Safariは、ドメイン名に特別な文字を受け入れることにおいてさらに緩いです:
HTTPヘッダーインジェクションを通じてサーバーサイドキャッシュポイズニングを悪用することで、保存されたクロスサイトスクリプティング(XSS)脆弱性が引き起こされる可能性があります。このシナリオは、アプリケーションが不正な文字に対してOrigin
ヘッダーをサニタイズできない場合に展開され、特にInternet ExplorerおよびEdgeユーザーに対して脆弱性を生じさせます。これらのブラウザは(0x0d)を正当なHTTPヘッダーの終端子として扱い、HTTPヘッダーインジェクションの脆弱性を引き起こします。
Origin
ヘッダーが操作された以下のリクエストを考えてみてください:
Internet Explorer と Edge は、レスポンスを次のように解釈します:
この脆弱性を直接悪用するために、ウェブブラウザに不正なヘッダーを送信させることは実現可能ではありませんが、Burp Suiteのようなツールを使用して手動で作成されたリクエストを生成することができます。この方法は、サーバー側のキャッシュが応答を保存し、他のユーザーに誤って提供する可能性があります。作成されたペイロードは、ページの文字セットをUTF-7に変更することを目的としており、これは特定のコンテキストでスクリプトとして実行される可能性のある方法で文字をエンコードできるため、XSS脆弱性に関連付けられることがよくあります。
保存されたXSS脆弱性についてのさらなる情報は、PortSwiggerを参照してください。
注意: HTTPヘッダーインジェクション脆弱性の悪用、特にサーバー側のキャッシュポイズニングを通じて、すべてのユーザー提供入力(HTTPヘッダーを含む)を検証およびサニタイズすることの重要性が強調されます。常に、こうした脆弱性を防ぐために入力検証を含む堅牢なセキュリティモデルを採用してください。
このシナリオでは、適切なエンコーディングなしにカスタムHTTPヘッダーの内容を反映するウェブページのインスタンスが観察されます。具体的には、ウェブページはX-User-id
ヘッダーに含まれる内容を反映し、悪意のあるJavaScriptを含む可能性があります。これは、ヘッダーにJavaScriptコードをロード時に実行するように設計されたSVG画像タグが含まれている例で示されています。
Cross-Origin Resource Sharing (CORS)ポリシーは、カスタムヘッダーの送信を許可します。しかし、CORS制限によりブラウザによって応答が直接レンダリングされない場合、そのようなインジェクションの有用性は限られているように見えるかもしれません。重要なポイントは、ブラウザのキャッシュ動作を考慮する際に生じます。Vary: Origin
ヘッダーが指定されていない場合、悪意のある応答がブラウザによってキャッシュされる可能性があります。その後、このキャッシュされた応答は、URLに移動する際に直接レンダリングされ、初回リクエスト時の直接レンダリングの必要が回避されます。このメカニズムは、クライアントサイドキャッシングを利用することで攻撃の信頼性を高めます。
この攻撃を示すために、ウェブページの環境で実行されるように設計されたJavaScriptの例が提供されます。このスクリプトは、指定されたURLに悪意のあるJavaScriptを含むカスタムヘッダーでリクエストを送信するという簡単なアクションを実行します。リクエストが成功裏に完了すると、ターゲットURLに移動し、Vary: Origin
ヘッダーが適切に処理されていない場合、キャッシュされた応答があれば、注入されたスクリプトの実行をトリガーする可能性があります。
この攻撃を実行するために使用されるJavaScriptの要約は以下の通りです:
XSSI、またはクロスサイトスクリプトインクルージョンは、スクリプトタグを使用してリソースを含める際に同一オリジンポリシー (SOP) が適用されないという事実を利用する脆弱性の一種です。これは、スクリプトが異なるドメインから含まれる必要があるためです。この脆弱性により、攻撃者はスクリプトタグを使用して含まれた任意のコンテンツにアクセスし、読み取ることができます。
この脆弱性は、特に動的なJavaScriptやJSONP(パディング付きJSON)に関して重要です。特に、クッキーのような環境権限情報が認証に使用される場合です。異なるホストからリソースをリクエストすると、クッキーが含まれ、攻撃者がアクセスできるようになります。
この脆弱性をよりよく理解し、軽減するために、https://github.com/kapytein/jsonp で入手可能なBurpSuiteプラグインを使用できます。このプラグインは、Webアプリケーション内の潜在的なXSSI脆弱性を特定し、対処するのに役立ちます。
XSSIの異なるタイプとそれを悪用する方法について詳しく読む。
リクエストに**callback
** パラメータを追加してみてください。ページがデータをJSONPとして送信するように準備されているかもしれません。その場合、ページはContent-Type: application/javascript
でデータを返し、CORSポリシーをバイパスします。
Access-Control-Allow-Origin
制限をバイパスする方法の一つは、Webアプリケーションにあなたの代わりにリクエストを行わせ、応答を返させることです。しかし、このシナリオでは、最終的な被害者の資格情報は、リクエストが異なるドメインに対して行われるため送信されません。
CORS-escape: このツールは、リクエストとそのヘッダーを転送するプロキシを提供し、要求されたドメインに一致するようにOriginヘッダーを偽装します。これにより、CORSポリシーを効果的にバイパスします。以下はXMLHttpRequestを使用した例です。
simple-cors-escape: このツールは、リクエストをそのまま渡すのではなく、サーバーが指定されたパラメータで独自のリクエストを行う代替アプローチを提供します。
e.origin === window.origin
のようなCORSチェックをiframeを作成し、そこから新しいウィンドウを開くことによってバイパスできます。詳細は以下のページにあります:
TTLによるDNSリバインディングは、DNSレコードを操作することによって特定のセキュリティ対策をバイパスするために使用される技術です。以下はその仕組みです:
攻撃者はWebページを作成し、被害者にアクセスさせます。
攻撃者は自分のドメインのDNS(IP)を変更して、被害者のWebページを指すようにします。
被害者のブラウザはDNS応答をキャッシュし、TTL(生存時間)値がDNSレコードが有効と見なされる期間を示します。
TTLが切れると、被害者のブラウザは新しいDNSリクエストを行い、攻撃者が被害者のページでJavaScriptコードを実行できるようになります。
被害者のIPを制御し続けることで、攻撃者は被害者サーバーにクッキーを送信することなく情報を収集できます。
ブラウザにはキャッシングメカニズムがあり、この技術の即時悪用を防ぐ場合があることに注意が必要です。特に低TTL値の場合です。
DNSリバインディングは、被害者によって実行される明示的なIPチェックをバイパスするのに役立つ場合や、ユーザーやボットが長時間同じページに留まるシナリオで役立ちます。
DNSリバインディングを迅速に悪用する方法が必要な場合は、https://lock.cmpxchg8b.com/rebinder.htmlのようなサービスを使用できます。
独自のDNSリバインディングサーバーを実行するには、DNSrebinder(https://github.com/mogwailabs/DNSrebinder)のようなツールを利用できます。これには、ローカルポート53/udpを公開し、それを指すAレコードを作成し(例:ns.example.com)、以前に作成したAサブドメインを指すNSレコードを作成することが含まれます(例:ns.example.com)。ns.example.comのサブドメインのいずれかは、あなたのホストによって解決されます。
さらに理解と実験のために、http://rebind.it/singularity.htmlで公開されているサーバーを探索することもできます。
DNSキャッシュフラッディングによるDNSリバインディングは、ブラウザのキャッシングメカニズムをバイパスし、2回目のDNSリクエストを強制するために使用される別の技術です。以下はその仕組みです:
最初に、被害者がDNSリクエストを行うと、攻撃者のIPアドレスで応答されます。
キャッシング防御をバイパスするために、攻撃者はサービスワーカーを利用します。サービスワーカーはDNSキャッシュをフラッドし、効果的にキャッシュされた攻撃者サーバー名を削除します。
被害者のブラウザが2回目のDNSリクエストを行うと、今度はIPアドレス127.0.0.1で応答され、通常はローカルホストを指します。
サービスワーカーでDNSキャッシュをフラッドすることにより、攻撃者はDNS解決プロセスを操作し、被害者のブラウザに2回目のリクエストを行わせ、今回は攻撃者の望むIPアドレスに解決させることができます。
キャッシング防御をバイパスする別の方法は、DNSプロバイダーで同じサブドメインに対して複数のIPアドレスを利用することです。以下はその仕組みです:
攻撃者はDNSプロバイダーで同じサブドメインに対して2つのAレコード(または2つのIPを持つ単一のAレコード)を設定します。
ブラウザがこれらのレコードを確認すると、両方のIPアドレスを受け取ります。
ブラウザが攻撃者のIPアドレスを最初に使用することを決定した場合、攻撃者は同じドメインに対してHTTPリクエストを実行するペイロードを提供できます。
しかし、攻撃者が被害者のIPアドレスを取得すると、被害者のブラウザへの応答を停止します。
被害者のブラウザは、ドメインが応答しないことに気づくと、与えられた2番目のIPアドレスを使用するようになります。
2番目のIPアドレスにアクセスすることで、ブラウザは同一オリジンポリシー(SOP)をバイパスし、攻撃者がこれを悪用して情報を収集し、外部に送信できるようになります。
この技術は、ドメインに対して複数のIPアドレスが提供されたときのブラウザの動作を利用しています。応答を戦略的に制御し、ブラウザのIPアドレスの選択を操作することで、攻撃者はSOPを悪用し、被害者から情報にアクセスできます。
ローカルホストにアクセスするには、Windowsでは127.0.0.1をリバインドし、Linuxでは0.0.0.0をリバインドする必要があります。 godaddyやcloudflareのようなプロバイダーは私がIP 0.0.0.0を使用することを許可しませんでしたが、AWS route53は2つのIPのうちの1つが"0.0.0.0"であるAレコードを作成することを許可しました。
詳細については、https://unit42.paloaltonetworks.com/dns-rebinding/を確認できます。
内部IPが許可されていない場合、0.0.0.0を禁止するのを忘れているかもしれません(LinuxとMacで動作します)
内部IPが許可されていない場合、localhostへのCNAMEで応答します(LinuxとMacで動作します)
内部IPがDNS応答として許可されていない場合、www.corporate.internalのような内部サービスへのCNAMEで応答できます。
前述のバイパス技術と以下のツールの使用方法についての詳細は、Gerald Doussot - State of DNS Rebinding Attacks & Singularity of Origin - DEF CON 27 Conferenceのトークで確認できます。
Singularity of Origin
は、DNSリバインディング攻撃を実行するためのツールです。攻撃サーバーのDNS名のIPアドレスをターゲットマシンのIPアドレスにリバインドし、ターゲットマシン上の脆弱なソフトウェアを悪用するための攻撃ペイロードを提供するために必要なコンポーネントが含まれています。
内部サービスでTLSを使用する
データにアクセスするための認証を要求する
Hostヘッダーを検証する
https://wicg.github.io/private-network-access/: 公共サーバーが内部サーバーにアクセスする際に常にプレフライトリクエストを送信する提案
CORSポリシーの誤設定をファズする
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)