第8章 マッシュアップ
クライアントサイドマッシュアップ: #4 対策に利用できる技術
Webクライアントにおけるセキュリティ対策対象レイヤ
クライアントサイドマッシュアップにおけるセキュリティ確保については、アプリケーションコードレベル、ライブラリレベル、ブラウザ(JavaScriptエンジン)レベルの各階層に分けて説明する。
特に、ブラウザレベルの対策が充実すると、開発者の負担は軽くなることが期待される。
サーバからブラウザ宛のレスポンスヘッダ内にアクセスを制御するポリシー項目が運ばれるようにする仕様が、複数、策定されている。
(1) セキュリティ対策機能をオンにするためのヘッダ
サーバからロードされるコンテンツに添えられるレスポンスヘッダに、何らかのセキュリティポリシーの執行をブラウザへ要請する用途のものが増えてきた。例えば、次のレスポンスヘッダである。
- X-Content-Security-Policy
- スクリプトのロードと実行等に強い制約を設ける
- X-XSS-Protection
- XSSフィルタの有効/無効
- X-Frame-Options
- コンテンツのフレーム内における表示を許す/許さない
- X-Content-Type-Options
- 内容からのコンテントタイプの推測をする/しない
主要なブラウザとこれらのヘッダのサポート状況は下表の通りである。
| ブラウザ | Mozilla Firefox |
Apple Safari |
Google Chrome |
Internet Explorer |
|---|---|---|---|---|
| 該当バージョン | 4以降 | 5以降 | 4以降※ | 8以降 |
| X-Content-Security-Policy | ◎ | × | × | × |
| X-XSS-Protection | × | ◎ | ◎ | ◎ |
| X-Frame-Options | ◎ | ◎ | ◎ | ◎ |
| X-Content-Type-Options | × | × | ◎ | ◎ |
◎=サポートあり ×=サポートなし ※=一部のマイナーバージョンを除く
出典: http://www.browserscope.org/
Mozilla Firefox の実装
2012年時点において、Mozilla FirefoxのX-Content-Security-Policy に対応する実装が一番細かく設定できるものとなっている。
Google Chrome Frame の影響
Google Chrome Frame(以下 GCF)は、Internet Explorer の上で HTML5 の機能をフルに利用できるようにすることを意図したプラグインである。GCF は、X-UA-Compatiblle: chrome=1等のレスポンスヘッダによって活性化され、Webページのレンダリングそのものを引き受ける。
Google Chrome Frame は、独立したブラウザGoogle Chrome と近い動きをするが、違いもある。上記の表のセキュリティ対策レスポンスヘッダも有効であるが、動作が必ずしも確実でない場合がある。
(2)「CSP(Contents Security Policy)」によるスクリプト動作の制限
Content Security Policyは、Firefox 4以降(厳密には HTMLレンダリングエンジン Gecko 2.0以降を使用するブラウザ)が備えるスクリプト注入(XSS)対策機能である。
これは、ブラウザがどこからスクリプトをロードするかについて、整然と制約を設けることによって、信頼できないサイトからのスクリプトの混入を防ごうというものである。
この対策機能は、
X-Content-Security-Policy: 仕様
の形のレスポンスヘッダを Firefox が受信すると活性化される。Webコンテンツ内のスクリプトの配置の自由度は減るが、どのスクリプトが実行されどれが禁止されるかを客観的に把握しつつ対策を行えるのが特長である。
最も単純な例
この仕様には複雑な指定が可能であるが、最も単純な指定の例は下記のようになる。
X-Content-Security-Policy: allow 'self '
これによって、ブラウザにおけるスクリプトの実行が次のように制約されるようになる。:
- HTML の途中に次のような形で記述する、いわゆる「インライン」のスクリプトは実行が禁止される。:
<script>スクリプトソースコード</script> ← これは禁止
- 動作させたいスクリプトは原則として、次の形で独立した別のコンテンツとして呼び込まなくてはならない。:
<script src="スクリプトURI"></script> ← この形式のみ許される
-
この「スクリプトURI」として許されるのは、この Webページの源泉と同じサーバに限られる。
- 文字列をスクリプトのソースコードとして解釈実行する eval()等の関数の実行が禁止される。
X-Content-Security-Policy のパラメータ
X-Content-Security-Policyレスポンスヘッダは、多くのパラメータもっていて、よりきめ細かな指定をすることができる。
X-Content-Security-Policy: allow ホスト...
[; options {inline-script | eval-script}...]
[; img-src ホスト...][; media-src ホスト...]
[; srcipt-src ホスト...][; object-src ホスト...]
[; frame-src ホスト...][; font-src ホスト...]
[; xhr-src ホスト...][; frame-ancesors ホスト...]
[; style-src ホスト...]
[; report-uri URI][; policy-uri URI]
- ホスト名を具体的に羅列することによって、Webページの源泉以外のサーバからのスクリプトのロードを許可/限定できる。:
script-src ホスト...
- スクリプトのロード元を許可するのと同様の要領で、画像等各種リソースのロード元のホストを明示できる。:
img-src ホスト...; media-src ホスト...; style-src ホスト...; ...
- Webページの源泉のホスト(自分自身のサーバ)からの追加リソースのロードを禁止することもできる。:
allow 'none' [別のホスト...]
- せっかくのインラインスクリプトやeval()の禁止機能であるが、その禁止を解除することもできる。:
options inline-script eval-script
- 現時点では、まだ報告される項目が少ないようであるが、指定されたホストにエラー報告を行うような機能も備わる模様である。:
report-uri URI
(3) 他ドメインJavaScript のサンドボックスを用いたロードと実行
ブラウザ自体あるいは Add-onツールを加えてサンドボックスが構築されて、それが一定のポリシーを適用する機能を果たすものがある。ブラウザ自体が実装しているのは Mozilla であり、Add-onツールとして提供されているのは、Dojox.secure である。いずれも、eval()関数を止めたり、innerHTMLを抑止したりする機能を備えている。
dojox.secure といったライブラリを使用すると、必ずしも信頼できるとは限らない他者のドメインからJavaScript をロードして呼び出す場面でも、そのスクリプトをいわゆる「サンドボックス」の中で安全に実行させることができる。
<div id="attatch_point">
サンドボックスにロードされるスクリプトからアクセスできるDOMの
要素は、このdivノードと、ここに作られる子孫のみに制限される
</div>
...
<script>
// sandbox部品の確保
dojo.require("dojox.secure.sandbox");
// サンドボックスオブジェクトの生成と、そこへのスクリプトのロード
var sb = dojox.secure.sandbox(dojo.byId("attatch_point"));
var foreignCode = sb.loadJS("http://others/foreign_code.js");
// ロードしたコードに対するメソッド呼出しや、イベントハンドラの接続
foreignCode.someMethod(...);
dojo.connect(foreignCode, "someEvent", function(arg){...});
...
</script>
...
(4) OAuth 2.0 を用いたクライアントサイドマッシュアップ
OAuth 2.0 を用いてクライアントの権限の委譲を伝えるしくみについては、別途作成している『アイデンティティ管理技術解説』中の「インターネット上の代理アクセス」の内容を踏まえて述べる予定である。
他源泉リクエスト状況におけるリクエスト強要対策
他源泉におけるリクエスト強要対策は、セッション対策 、XHR 2 の慎重な利用等から成る。
(1) セッション対策(トークン対策)
- 「非同期の他源泉リクエスト」においては、できるだけセッションを用いない。
- セッション維持が必要な場合であっても Cookie は用いない (Basic認証やDigest認証も同様)。セッションID を POSTデータで搬送する対策例を下図に示す。

- データ供給サイトのサーバで他者が推測困難なトークンを発行し、ブラウザから送られてきたトークンの照合を行う。トークンを照合する対策例を下図に示す。

- OAuth のアクセストークンを利用する。本稿執筆現在、OAuth 2.0が策定途中であり、一部の Webサイトではそれを先取りした実装の使用が始まっている。
(2) XHR 2の利用
他源泉リクエスト発行手段には XHR 2 を選ぶ。(IE 8専用には XDR を選ぶ。)
その際にサーバでは Origin: を厳密に検査する。
また、Access-Control-Allow-Origin: の発行を必要最小限にする。
(3) 他源泉リクエストを必要最小限に
そもそも、他源泉リクエストの使用を必要最小限に留める。
クライアントサイドマッシュアップからサーバサイドマッシュアップへ
クライアントサイドマッシュアップをサーバサイドマッシュアップに移行すると、#2節および #3節において説明した各種の脅威を低減することができる。移行のし易さや課題を #2節で取り上げた 3種類のAPI呼出しの実装形態別に示す。
| 実装形態 | 移行し易さ | 移行方法 |
|---|---|---|
| (1) サービス呼出し型実装 | ○ | サイト主催者のサーバでWebサービスを中継する仕組みをもつことができれば、サーバサイドマッシュアップへの切り替えが可能である。 なお、その場合、HTTPリクエストがひとつ余分にサーバを経由することになるため、サーバの応答時間が長くなることがユーザの操作性を著しく損なうことがないか考慮する必要がある。 |
| (2) スクリプト取り込み型実装 | △ | ロードするスクリプトモジュールのコピーを(権利者の許諾を得た上で)サイト主催者のサーバに配置することによって、サーバサイドマッシュアップへの切り替えが可能である。 ただし、スクリプトモジュールはその内部で第三者のサーバと通信したり、第三者のサーバからさらなるスクリプトモジュールをロードしたりすることがあり得る。 多くの場合(小規模なものでないかぎり)、第三者のAPIとその中で使用されるリソースすべてを自分のサイトへ配置することは、現実的でない。 |
| (3) ウィジェット型実装 | △ | (2) とほぼ同様 |