情報処理安全確保支援士試験 過去問 2019年(令和元年) 春期 午後Ⅰ 問1
Webサイトのセキュリティ
M社は、従業員数200名の小売業である。コーポレートサイトであるWebサイトA(URLは、https://site-a.m-sha.co.jp/)と、自社の特定のブランドを取り扱うECサイト(以下、ブランドサイトという)を複数運営している。現在運営しているブランドサイトは、WebサイトBからWebサイトFの五つである。Webサイトの開発や運用は自社の開発部で行っている。
WebサイトAは、ブランドサイト全体のポータルサイトでもあり、各ブランドのキャンペーン情報などを掲載している。会員専用の機能は有していない。
WebサイトB(URLは、https://site-b.m-sha.co.jp/)は、ブランドBの商品を扱うECサイトで、会員数は10万名である。WebサイトBでは、Cookieを利用したセッション管理を行っている。
会員情報は、各ブランドサイトで個別に管理している。
各ブランドサイトからWebサイトAへの情報連携
今回、各ブランドサイトの売上数を基にした、ブランド別の売れ筋商品情報を、WebサイトA上で表示するとともに、希望があれば、各ブランドサイトの会員に電子メールでも定期的に配信することにし、そのために売れ筋商品情報及び会員情報を取得する機能(以下、情報連携機能という)を実装することにした。具体的な機能は次のとおりである。
機能1 WebサイトAが各ブランドサイトの売れ筋商品情報を取得する。
機能2 希望する会員に電子メールを配信するために、WebサイトAは、当該会員の会員情報を取得する。
なお、配信の申込みは、WebサイトA上で行う。
情報連携機能の実装は、開発部のCさんが中心になって進めることになった。まず初めにWebサイトBからWebサイトAへの情報連携を行うために、次の二つのWeb APIをWebサイトBに実装することにした。
- WebサイトBの売れ筋商品情報を取得可能とするためのWeb API(以下、API-Xという)
- WebサイトBの会員情報を取得可能とするためのWeb API(以下、API-Yという)
なお、Web APIで受け渡されるデータは、JSON(JavaScript Object Notation)形式にする。Cさんは、API-Yからブランドサイトの会員情報を取得する際、配信を希望する会員の同意を得たいと考えた。そこで、会員情報の取得には、会員のWebブラウザを経由して行う方式を採用することにした。
WebサイトBからWebサイトAへの情報連携機能を図1に示す。
情報連携機能の実装についての検討
スクリプトZは、aポリシによって、b、c、dのいずれかが異なるリソースへのアクセスが制限される。そこで、Cさんは、この制限を回避するためにJSONP(JavaScript Object Notation with Padding)を用いることを開発部のD課長に提案した。次は、その時の会話である。
Cさん: API-Yからの会員情報の取得にJSONPを用いるつもりです。
D課長: JSONPは、アクセス先を制限する機能をもたないので、その実装では問題がある。例えば、まず、会員情報を窃取するように攻撃者がスクリプトZを変更して、攻撃者のWebサイトのページに置く。次に、被害者に①特定の操作をさせた上で、そのページにアクセスさせると、攻撃者が被害者の会員情報を窃取できてしまう。
Cさん: JSONPの代わりに何の技術を用いればよいでしょうか。
D課長: CORS(Cross-Origin Resource Sharing)を用いるのがよいだろう。
CORSの概要
CORSとは、あるWebサイトから他のWebサイトへのアクセスを制御することができる仕組みである。XMLHttpRequestを使って "https://test2.example.com/test" にリクエストを送るスクリプトの例を図2に示す。
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://test2.example.com/test', true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.send(null);
Webブラウザが "https://test1.example.com/" にアクセスし、図2のスクリプトを含むページを読み込んだとする。図2のスクリプトが実行されると、最初にWebブラウザは "https://test2.example.com/test" にプリフライトリクエストと呼ばれるリクエストを送る。そうすると、実際のリクエスト(以下、メインリクエストという)で許可されるメソッド名やヘッダフィールド名などがレスポンスとして返る。その後、メインリクエストを送り、レスポンスが返る。この一連の動作を図3に、また、図3中の(iii)~(vi)のリクエストとレスポンスの先頭部分の例を図4~図7に示す。
OPTIONS /test HTTP/1.1 Host: test2.example.com Access-Control-Request-Method: GET1) Access-Control-Request-Headers: x-requested-with2) Origin: https://test1.example.com3)
2)Access-Control-Request-Headers には,メインリクエストで利用したいヘッダフィールド名を指定する。
3)Origin は,スクリプトを含むページのオリジンであり, Webブラウザが付与している。
HTTP/1.1 200 OK Access-Control-Allow-Origin: https://test1.example.com Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: x-requested-with
2)Access-Control-Allow-Methods には, Webサイトが許可するメソッド名が返される。
3)Access-Control-Request-Headers には, Webサイトが許可するヘッダフィールド名が返される。
GET /test HTTP/1.1 Host: test2.example.com X-Requested-With: XMLHttpRequest Origin: https://test1.example.com
HTTP/1.1 200 OK Access-Control-Allow-Origin: https://test1.example.com
また、CORSでは通常、Webブラウザは、スクリプトを読み込んだページのオリジンだけにCookieや、ベーシック認証の情報を送る。図2では設定していないが、XMLHttpRequestのプロパティのwithCredentialsの値がtrueに設定されている場合、図3であれば、eの動作の際に、test2.example.comから発行されたCookieが送られる。
CORSを利用した実装
Cさんは、スクリプトZの実装にCORSを用いたときの一連の動作を検討し、表1にまとめた。
| No. | 内容 |
|---|---|
| 1 | WebブラウザはWebサイトAの売れ筋商品情報配信の申込ページにアクセスする。 |
| 2 | WebサイトAは、WebサイトBのAPI-Yを呼び出すスクリプトZを含むページをレスポンスとして返す。 |
| 3 | Webブラウザは、会員が申込みを行うと、WebサイトBにプリフライトリクエストを送信する。プリフライトリクエストは、OPTIONSメソッドの呼出しであり、Originヘッダフィールドには "https://site-a.m-sha.co.jp" が設定されている。 |
| 4 | API-Yは、送られてきたリクエストにOriginヘッダフィールドを付加し、その値がレスポンスを返す。Access-Control-Allow-Originヘッダフィールドの値は、"f"である。Originヘッダフィールドが存在しない場合、エラーを返す。 |
| 5 | Webブラウザは、gとAccess-Control-Allow-Originヘッダフィールドの値を照合し、アクセスが許可されていることを確認する。許可されている場合は、次の処理に進む。確認できない場合は、メインリクエストを送らずに終了する。 |
| ⋮ | ⋮ |
| 9 | スクリプトZは、受け取ったJSON形式の値を変数に格納し、表示する。さらに、受け取った値はWebサイトAに送られ、保存される。 |
Cさんは、表1についてD課長に確認した。次は、その時のD課長とCさんの会話である。
D課長: 今後、他のシステムでもCORSを利用することが考えられるので、コーディング規約も併せてまとめておきたい。Access-Control-Allow-Originヘッダフィールドに指定できるオリジンは一つだけなので、複数のオリジンからのアクセスを許可するような仕様であった場合に、No.4の内容では不十分である。Web APIのプログラム内に、許可するオリジンのリストを用意しておく必要がある。プリフライトリクエスト又はメインリクエストがWeb APIに送られてきたときに、そのリクエスト中のhを、iと突合し、jした値があればその値をAccess-Control-Allow-Originヘッダフィールドに設定するという内容もコーディング規約に含めればよいだろう。
Cさん: 分かりました。
CさんはCORSの利用に関するコーディング規約をまとめ、表1をこれに合うように修正し、D課長に再度確認した。修正後の内容で問題ないということだったので、Cさんは実装を行った。
その後、セキュリティ専門業者に脆弱性診断を依頼し、脆弱性が検出されないことを確認した上で、情報連携機能をリリースした。その後、同様に残り四つのブランドサイトからWebサイトAへの情報連携機能も実装した。