CORS - Misconfigurations & Bypass
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Fpentest.eu%2FRENDER_WebSec_10fps_21sec_9MB_29042024.gif&width=768&dpr=4&quality=100&sign=bc0743d1&sv=1)
CORSとは?
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
ヘッダー
Access-Control-Allow-Origin
ヘッダーこのヘッダーは、複数のオリジン、null
値、またはワイルドカード*
を許可することができます。しかし、複数のオリジンをサポートするブラウザはありません、またワイルドカード*
の使用には制限があります。(ワイルドカードは単独で使用する必要があり、Access-Control-Allow-Credentials: true
と一緒に使用することは許可されていません。)
このヘッダーは、ウェブサイトによって開始されたクロスドメインリソースリクエストに対するサーバーによって発行され、ブラウザは自動的にOrigin
ヘッダーを追加します。
Access-Control-Allow-Credentials
ヘッダー
Access-Control-Allow-Credentials
ヘッダーデフォルトでは、クロスオリジンリクエストはクッキーやAuthorizationヘッダーのような資格情報なしで行われます。しかし、クロスドメインサーバーは、資格情報が送信される際に応答の読み取りを許可するために、Access-Control-Allow-Credentials
ヘッダーを**true
**に設定することができます。
true
に設定されている場合、ブラウザは資格情報(クッキー、認証ヘッダー、またはTLSクライアント証明書)を送信します。
CSRF プレフライトリクエスト
クロスドメイン通信におけるプレフライトリクエストの理解
特定の条件下でクロスドメインリクエストを開始する際、例えば 非標準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
の反映
Access-Control-Allow-Origin
におけるOrigin
の反映Origin
ヘッダーの値がAccess-Control-Allow-Origin
に反映される現実のシナリオは、これらのヘッダーを組み合わせる制限により理論的にはあり得ません。しかし、複数のURLに対してCORSを有効にしようとする開発者は、Origin
ヘッダーの値をコピーすることでAccess-Control-Allow-Origin
ヘッダーを動的に生成することがあります。このアプローチは脆弱性を引き起こす可能性があり、特に攻撃者が正当であるように見える名前のドメインを使用する場合、検証ロジックを欺くことになります。
null
オリジンの悪用
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
サブドメイン内のXSSから
開発者は、情報をリクエストすることが許可されたドメインをホワイトリストに登録することで、CORSの悪用から保護するための防御メカニズムを実装することがよくあります。これらの予防策にもかかわらず、システムのセキュリティは完全ではありません。ホワイトリストに登録されたドメイン内に脆弱なサブドメインが1つでも存在する場合、XSS(クロスサイトスクリプティング)などの他の脆弱性を通じてCORSの悪用が可能になります。
例として、ドメインrequester.com
が別のドメインprovider.com
からリソースにアクセスするためにホワイトリストに登録されているシナリオを考えてみましょう。サーバー側の設定は次のようになるかもしれません:
このセットアップでは、requester.com
のすべてのサブドメインがアクセスを許可されています。しかし、例えばsub.requester.com
というサブドメインがXSS脆弱性で侵害された場合、攻撃者はこの弱点を利用できます。例えば、sub.requester.com
にアクセスできる攻撃者は、XSS脆弱性を利用してCORSポリシーをバイパスし、provider.com
上のリソースに悪意を持ってアクセスすることができます。
サーバーサイドキャッシュポイズニング
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画像タグが含まれている例で示されています。
クロスオリジンリソースシェアリング(CORS)ポリシーは、カスタムヘッダーの送信を許可します。しかし、CORS制限により応答がブラウザによって直接レンダリングされない場合、そのようなインジェクションの有用性は限られているように見えるかもしれません。重要なポイントは、ブラウザのキャッシュ動作を考慮する際に生じます。Vary: Origin
ヘッダーが指定されていない場合、悪意のある応答がブラウザによってキャッシュされる可能性があります。その後、このキャッシュされた応答は、URLに移動する際に直接レンダリングされ、初回リクエスト時の直接レンダリングの必要が回避されます。このメカニズムは、クライアントサイドキャッシングを利用することで攻撃の信頼性を高めます。
この攻撃を示すために、ウェブページの環境で実行されるように設計されたJavaScriptの例が提供されます。このスクリプトは、指定されたURLに悪意のあるJavaScriptを含むカスタムヘッダーでリクエストを送信するという簡単なアクションを実行します。リクエストが成功裏に完了すると、ターゲットURLに移動し、Vary: Origin
ヘッダーが適切に処理されていない場合、キャッシュされた応答があれば、注入されたスクリプトの実行をトリガーする可能性があります。
この攻撃を実行するために使用されるJavaScriptの要約は次のとおりです:
バイパス
XSSI (クロスサイトスクリプトインクルージョン) / JSONP
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: このツールは、リクエストをそのまま渡すのではなく、サーバーが指定されたパラメータで独自のリクエストを行う代替アプローチを提供します。
Iframe + ポップアップバイパス
e.origin === window.origin
のようなCORSチェックをiframeを作成し、そこから新しいウィンドウを開くことでバイパスできます。詳細は次のページにあります:
TTLによるDNSリバインディング
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リバインディング
DNSキャッシュフラッディングによるDNSリバインディングは、ブラウザのキャッシングメカニズムをバイパスし、2回目のDNSリクエストを強制するために使用される別の技術です。以下はその仕組みです:
最初に、被害者がDNSリクエストを行うと、攻撃者のIPアドレスで応答されます。
キャッシング防御をバイパスするために、攻撃者はサービスワーカーを利用します。サービスワーカーはDNSキャッシュをフラッドし、キャッシュされた攻撃者サーバー名を効果的に削除します。
被害者のブラウザが2回目のDNSリクエストを行うと、今度はIPアドレス127.0.0.1で応答され、通常はローカルホストを指します。
サービスワーカーでDNSキャッシュをフラッドすることで、攻撃者はDNS解決プロセスを操作し、被害者のブラウザに2回目のリクエストを行わせ、今度は攻撃者の望むIPアドレスに解決させることができます。
キャッシュによるDNSリバインディング
キャッシング防御をバイパスする別の方法は、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で応答できます。
DNSリバインディングの武器化
前述のバイパス技術と、次のツールの使用方法についての詳細は、Gerald Doussot - State of DNS Rebinding Attacks & Singularity of Origin - DEF CON 27 Conferenceのトークで確認できます。
Singularity of Origin
は、DNSリバインディング攻撃を実行するためのツールです。攻撃サーバーのDNS名のIPアドレスをターゲットマシンのIPアドレスに再バインドし、ターゲットマシン上の脆弱なソフトウェアを悪用するための攻撃ペイロードを提供するために必要なコンポーネントを含んでいます。
DNSリバインディングに対する実際の保護
内部サービスでTLSを使用する
データにアクセスするために認証を要求する
Hostヘッダーを検証する
https://wicg.github.io/private-network-access/: 公共サーバーが内部サーバーにアクセスする際に常にプレフライトリクエストを送信する提案
ツール
CORSポリシーの誤設定をファズする
参考文献
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Fpentest.eu%2FRENDER_WebSec_10fps_21sec_9MB_29042024.gif&width=768&dpr=4&quality=100&sign=bc0743d1&sv=1)
Last updated