見出し画像

DRF_セキュリティ関係の基礎知識(Ajax, Cookie, 同一オリジンポリシー, CORS) #172日目

Django REST Framework (以下、DRF) の学習を進めています。
本日はセキュリティ関係の基礎についてアウトプットしたいと思います。

特にDRFはAPI開発に使われるのでフロントエンドとバックエンドを別々のオリジンに配置するケースがあり、その場合には「クロスオリジン」という概念が必要になったりします(後述する同一オリジンポリシーやCORSという概念が関係します)。

まずは前提知識として、Ajax、Cookie、同一オリジンポリシー、CORSについてです。

Ajax (Asynchronous JavaScript + XML) とは

Ajaxはブラウザ内でデータの送受信を非同期でおこなう技術を指します。つまり、ブラウザの画面全体を更新させずに一部のコンテンツのみ書き換えたりでき、ユーザビリティを向上させることができる技術です。

通常のWebアプリのリクエストはHTMLコンテンツを受け取りますが、Ajaxを使ったリクエストではXMLやJSON形式の断片的なデータを非同期で受け取ることができます(XMLだけじゃない)。通信には通常のリクエストと同様HTTPプロトコルを使います。

また、AjaxではHTTPリクエストヘッダの値を変更したり、カスタムヘッダを任意に追加したりできます(この機能が後ほど大事な役割を果たします)。かつ、Ajaxは同一オリジンまたはCORSで許可されたオリジン以外ではレスポンスが読み取れないという性質を持っています。


Cookieとは

よく聞く単語ですが、CookieはWebブラウザ内部の一時的な保存領域を指します。WebブラウザからWebサーバーにHTTPリクエストを出して、WebサーバーからのHTTPレスポンスのメッセージヘッダに「Set-Cookie」が含まれる場合、Cookieにキーと値、送信元ドメインが保存されます。

【HTTPレスポンスのメッセージヘッダにSet-Cookieが含まれる場合】
・キーと値    (例)test = 123
・送信元ドメイン (例)Domain = example.com

ちなみにCookieに値が保存された後のリクエストで、送信元のドメインと同じドメインにリクエストを再度行う際、Cookieに保存されているすべての値が自動的にHTTPリクエストのヘッダに書き込まれて送信されます。

この辺がセキュリティ攻撃の的になってしまうこともあるので、対策が必要です。


同一オリジンポリシー

これはWebブラウザの制御機構で、Webサイトが持っているリソースが別のサイトに悪用されることを防ぐためのものです。Web APIのセキュリティを考える上で重要な前提条件になります。

以下の図で示す通り、スキーム、ホスト、ポート番号をセットにしたものを「オリジン (Origin)」と定め、全てが一致している場合は「同一オリジン」として同じ保護対象のリソースとして取り扱います

逆に一つでも異なる場合は「別オリジン」あるいは「クロスオリジン」として、リソースの利用が制限されます。この制限は、APIに関するものはAjaxとCookieの主に2つです。

Ajaxでは、同一オリジンでは無条件にAjaxレスポンスにアクセスできます(ブラウザでレスポンスの読み出しが可能)が、別オリジンではこれができません。例えば「https://test.com/」から「https://example.com/」へのAjaxリクエストでは、サーバーからのレスポンスを読み出せません。

Cookieでは、「ホスト」が異なる場合にはCookieの値が送信されないように制限されています。つまり、Cookieの値は基本的に、Cookieの保存を指示したサーバーでのみ利用できるように制御されています。


CORSとは

上記のようなAjaxの制限はセキュリティ的には安心ですが、例えばフロントエンドとバックエンドが別々のオリジンで配信されるWeb APIを利用したアプリケーションなどでは、レスポンスを読み出せなくて困ることになります。

そこで、同一オリジンではない正規サイトを許可するため、正規サイトのオリジンをホワイトリスト形式で許可してAjaxの制限解除する仕組みがあります。それが「CORS (Cross-Origin Resource Sharing: オリジン間リソース共有)」です。

Access-Control-Allow-Origin: 許可するサイトのURL
Access-Control-Allow-Origin: *  # 全オリジンを許可する場合

ちなみにDjangoでは「django-cors-headers」というパッケージを使うことで、簡単にHTTPレスポンスに「Access-Control-Allow-Origin」ヘッダをセットできます。


ここまでお読みいただきありがとうございました!!

この記事が気に入ったらサポートをしてみませんか?