
編集者注記: 本稿の筆者Mike Shemaは、Qualysの技術部長だ。同社はクラウドのセキュリティとコンプライアンスのプロバイダである。Mikeは最近出版された本 “Hacking Web Apps: Detecting and Preventing Web Application Security Problems”(Webアプリケーションをハックする: Webアプリケーションのセキュリティ問題の発見と防止)の著者でもある。彼へのコンタクトはここから。
HTML5は、これまでWebを20年あまり支えてきた技術を再び活気づけている。とくに注目すべきは、現代のブラウザが今もなお圧倒的多数派である初期的な古いサイトを表示している一方、新しい現代的なサイトは、ブラウザにこれまでにない強力なプラットホームを期待できることだ。FacebookはHTML5だけによるモバイルアプリを作るという先進的な試みに挑戦したが、10億近いユーザを抱えるサイトにとっては限界があることを発見した。しかし、そうやって問題が明らかになったことは、良いことだ。
HTMLのこの新規格は、セキュリティも強化した。しかし、Webサイトがページに<!doctype html>を加えただけでその恩恵に与るわけではなく、ブラウザがさまざまなソースからのコンテンツを共有し解釈しようとするとき、そのやり方をサイトの作者がコントロールすることによって、HTML5の新しいセキュリティ機能を活かすことができるのだ。また、ブラウザのセキュリティと直接関係のない新しい機能として、多くのデータを保存できる能力や、クッキーの大幅改良などが加わったが、これらの機能は正しく使わないとセキュリティやプライバシーの新しい問題をもたらす。
ブラウザのセキュリティはSame Origin Policy(SOP, 同一出所制限)に大きく依存している。これによってサイトは、スクリプトなどの実行対象を自己起源のものに限定することができる。このポリシーはいわば、複数のサイトを互いに相互排他的にする。しかしそれは、ブラウザに対する攻撃…HTMLインジェクション(HTML injection)(またの名クロスサイトスクリプティング(cross-site scripting))やクロスサイトリクエストフォージェリcross-site request forgery, CSRF)、クリックジャッキング(clickjacking)、マルウェアなど…を完全には防ぎきれない。しかもSOPはサイトの正しいアーキテクチャを妨害し、その結果、デベロッパが不格好であまりセキュアでない回避策をとることもある。
Cross-Origin Resource Sharing(クロスオリジンリソースシェアリング, CORS)は、このバリアを上げることによって、たとえばサイトが異なるドメインのAPIを使ったり、ユーザが生成したコンテンツにアクセスしたり、セキュリティに敏感なアクションをあえてすることによって、仕事のより柔軟な分割を図ることができる。しかもそれは、そのドメイン等を信ずるか信じないかという、オールオアナッシングの指定ではない。
むしろ、ここで重要なのは柔軟性だ。CORSはサーバからのリスポンスヘッダの情報を見てブラウザに対し、ほかのサイトが自分のコンテンツを見ることの可否を決定する。そうしてサイトは、ほかのサイトのHTMLを覗いたり、リスポンス中のJSONデータを見たりできるようになる。Webアプリケーションは、この信用(の可否)を明示的に指定しなければならない。すなわち、単にブラウザがそれをリクエストしたからといって、自動的にSOPをゆるめる許可がもらえるわけではない。
CORSはブラウザ内のリードアクセスを制御する。それはブラウザのセキュリティ境界であり、サーバサイドのセキュリティではない。すべての起源・出所に対して信用を与えることは、避けるべきだ。これはAPIにとっては意味があるが、あなたがCSRF攻撃から保護したいと思っているページに対してはノーだ。CORSでは、信用の宣言に寿命(有効期限)を指定でき、また、その起源・出所の異なるページにあるメソッドやヘッダのどれに対応するか/無視するかも指定できる。OKの指定は、サイトがどうにか稼働できる範囲内で最少に抑えるべきだ。すべてのブラウザに対してすべてをオープンにするようなことは、すべきでない。
iFrameサンドボックスはブラウザがコンテンツを信用する際の制御を、CRSとは別の方法で提供する。これもやはりブラウザ内のセキュリティでありサーバは関係ないが、力点はコンテンツの共有よりむしろ、コンテンツがやってもよいことへの制限にある。
サンドボックスに対し、次のような指定ができる…allow-scripts、allow-forms、allow-same-origin、allow-top-navigation、allow-popups(スクリプトを許容、フォームを許容、同一起源を許容、トップへのナビゲーションを許容、ポップアップを許容)。どれも意味はお分かりと思うが、何も指定しないとサンドボックス内のiFrameは次のようなデフォルトの行動をとる:
iFramesはHTML5よりも前から、ある種の隔離室の役を提供していた。今回サンドボックス化が加わることによって、ブラウザはさらに、悪質なコンテンツの封じ込めができるようになる。とくにサーバサイドのセキュリティフィルタに穴があるようなときには、頼もしい防御手段となる。ただし、データを調べて攻撃の有無を判断することは、依然として重要だ。HTML5対応のブラウザは、あなたが何かを忘れていたときの被害をやや軽くしてくれるだけだから。
各10年代ごとに、新しいバズワードが登場する。2010年代のバズワードである“ビッグデータ”は、今後ますますその地位を固めるだろう。現代のWebサイトは、まさにビッグデータを扱う。それはユーザに関する、数テラバイトもの情報だ。またクラウドに押し込まれるさまざまなタイプのコンピューティングも、それにアクセスするのはもっぱらブラウザだ。
HTML5が提供する新しいAPI、ローカルストレージ(Local Storage)やインデクスドデータベース(IndexedDB)などは、この傾向を逆転して、Webアプリケーションが大量のデータをブラウザ側に保存する。それらは巨大化したクッキーであり、同様のセキュリティとプライバシーの懸念を抱える。ここでのセキュリティは、アクセスの管理(SOPによる)と、保存されるデータの内容(何が保存され利用されるのか、それは正しいデータか)、この両方が重要だ。
ブラウザに保存されるものは何でも、薄い壁の向こうでクロスサイトスクリプティングが盗んでやろうと待ちかまえている。ウィルスやマルウェアは、システムを壊し、ローカルストレージから楽々と情報を盗むだろう。ローカルストレージはコンテンツをキャッシングしたり、機密性のないユーザデータを保存するには適しているが、パスワードやクレジットカードの番号など、暗号化してセキュアな場所に、あるいはサーバサイドのデータストアに保存すべき情報を、そこに置いてはならない。
ブラウザ側のストレージは、処理の負荷の一部をサーバからブラウザに移すことによって、アプリケーションのデータ収集〜処理に柔軟性をもたらす。しかしそれは、セキュリティを楽にしてはくれない。むしろ、まったく新しいセキュリティの要求をもたらし、データへのアクセスだけでなくデータの値も重要な問題になる。
HTML5では、ブラウザのコンピューティング環境がサーバと肩を並べるぐらいに強力になる。それによりデベロッパは、複雑なデスクトップ級のアプリケーションやゲームをJavaScriptや多様なAPIを駆使して書けるようになり、しかもそれらは、これまでのアプリケーションと違ってほぼ完全にクロスプラットホームだ。HTML5がもたらすこのような新しい環境においては、セキュリティの課題も新しい。
まず、CORS自身には、共有されるコンテンツの安全性を判定する能力はない。あるサイトの脆弱性が、別のサイトへクロスサイトスクリプティングによる攻撃をお漏らしするかもしれない。サンドボックス化したiFrameは、悪質なコンテンツからの攻撃を防ぎ、単純なSOPにはない細かい粒度の制御を可能にするが、ただしそれは、ブラウザがそれをサポートしている場合にかぎる。ブラウザのストレージはアプリケーションに数メガバイトものユーザデータの保存場所を提供するが、しかしデベロッパがうっかりそこにパスワードをプレーンテキストで置いてしまったら、長期にわたるセキュリティは確保できない。
ブラウザはよりセキュアなWebのエコシステムへ向けて、一歩々々前進している。クロスサイトスクリプティングという迷惑は永遠になくならないだろうが、しかしこれから登場するContent Security Policy(CSP, コンテンツセキュリティポリシー)のような規格は、相当強力な反撃になりえる(CSPはCORSとiFrameサンドボックスを合わせたようなもの)。CORS関連のヘッダによって、ある種のCSRF攻撃は防げる。またアプリケーションがX-Frame-Optionsヘッダをセットすれば、クリックジャッキングは完全に防げる。しかし、以上のどれに関しても、ブラウザがそれらをサポートしていることが肝要だ。
ブラウザは、ある意味、戦いの場所だ。HTML5を採用するときには、このことを忘れてはならない。その機能によってブラウザ内のデータは安全になるかもしれないが、それらのデータが外部のサーバやデータベースなどの荒野に向かって旅をするときには、その安全のためにあなたの助けを必要とする。
