IEBlog : IE8 Security Part V: Comprehensive Protection について、著者ではないのですが、David Rossさんに翻訳許可をもらいましたので、訳してみました。誤訳や指摘がありましたらガンガン突っ込みをお願いいたします(他の記事も時間をとって訳していこうと思います)。当然ながら、これは私が私的に訳したものであり、Microsoftによる公式な翻訳/見解ではありません。
長いので、とりあえず途中までです。続きはまた訳します。
訳注: 読んでいただければわかりますが、「サニタイズ」という語の意味がさっぱり不明です。かなり「サニタイズ脳」にやられているようですので、そのあたりは適当に割り引いて読んでください。
IE8の新機能である XDomainRequest(XDR) や Cross Document Messageing (XDM) については、id:amachang による JavaScript 最新動向 - Shibuya.JS in Kyoto 資料 - g:javascript などが参考になります。
IE8 Security Part V: Comprehensive Protection
こんにちは、私は Eric Lawrence、Internet Explorer のセキュリティプログラムマネージャです。先週の火曜日に、Dean が信頼できるブラウザを提供するための私たちの原則に関して書きました。今日、私はInternet Explorer 8 のセキュリティのために我々が投資した詳細に関してみなさんと共有できるのを嬉しく思います。このポストの長さから想像できるように、我々はこのリリースのためにたくさんのセキュリティに関連する働きを行いました。エンドユーザとして、ただ単純にIE8にアップグレードして、このセキュリティの改善による恩恵を受けてください。ドメインの管理者として、ネットワーク上でセキュアなデフォルトを設定するために、グループポリシーとIEAKを利用できます。Webデベロッパとして、Webアプリケーションとそのユーザを保護するために、これらの新機能が役に立ちます。
Internet Explorer 8 のプランに合わせ、我々のセキュリティチームは、実際の攻撃の共通性および攻撃者が次にどこに焦点をあわせるかを示すトレンドに注目しました。セキュリティの新しい機能を実装するにあたり、(ActivitiesやWeb Slicesのような)強力な新機能が攻撃箇所を局所化し、攻撃者に新しい攻撃目標を与えないことが確実となるよう、我々は懸命に努力しました。我々のプランにおいては、脅威をおおきく3種類に分類しました。Webアプリケーションの脆弱性、ブラウザとアドオンの脆弱性、ソーシャルエンジニアリングの脅威です。それぞれの脅威ごとに、多層防御による保護を提供するため、脅威を緩和するレイヤを開発しました。
Webアプリケーションの保護
クロスサイトスクリプティングの防御
過去数年にわたり、クロスサイトスクリプティング(XSS)攻撃は、バッファオーバーフローを凌ぐ、最多のソフトウェアの脆弱性となっています。XSS攻撃は、Cookieや他のデータを盗む、ページを書き換える、証明書ログイン情報を横取りする*1、よりエキゾチックな攻撃の開始さらなる外部攻撃の発動などを行います。
IE8では、もっとも一般的な形式のXSS攻撃(反射型と呼ばれる種類の攻撃)をブロックすることにより、XSS攻撃による脅威を軽減します。IE8のXSS Filter は、注入されたスクリプトをサニタイズし、スクリプトの実行を防ぐ、ヒューリスティックな軽減機構です。この防御について詳しく知るには、David のブログ IE8 Security Part IV - The XSS Filter を見てください*2。
XSS Filter は攻撃からの優れた保護機能ですが、この機能はIE8でのみ有効です。ですので、Webデベロッパはさらなる多層防御によりサイトからXSS脆弱性を取り除くことが重要です。サーバサイドでXSSを防ぐことは、ブラウザ側で防ぐよりもはるかに簡単なことです。とにかく、ユーザからの入力を信用しないということに尽きます*3。ほとんどのWebアプリケーションのプラットフォームでは、複数のサニタイズ機能が提供されています。ASP.NET を使っている開発者であれば、Microsoft Anti-Cross Site Scripting Library を使うことを考がえるべきです。さらに XSS による Cookie の漏えいを緩和するために、重要な Cookie (特に認証に使われるものなど)は HttpOnly 属性の付与により保護すべきです。
より安全なマッシュアップ
サーバ間のナビゲートにおいて、XSS Filter は Reflected XSS 攻撃を緩和しますが、Web 2.0 の時代においては、Webアプリケーションはますますクライアントサイドのマッシュアップ技術を使って構築されます。たいていのマッシュアップは、サードパーティからのスクリプトを直接マッシュアップするページ内に挿入する、単純な SCRIPT SRC のテクニックに頼っています。サードパーティのサイトへはDOMやHttpOnlyでないCookieへのフルアクセスを許したままで安全ではありません。
開発者がより安全なマッシュアップを作成できるよう、我々はIE8にてHTML5のクロスドキュメントメッセージング機能をサポートしました。これは、DOM間を隔離したままIFRAME間で安全に通信できます。また、ドメインを超えて「共有」データに安全にアクセスするのを可能にするため、XDomainRequest オブジェクト を導入しました。
クロスドキュメントメッセージングと XDomainRequestは安全にマッシュアップするのに役立ちますが、まだ重大な脅威は残っています。それらを使ってサードパーティのフレームやサーバから取り出した文字列データにスクリプトが含まれているかも知れません。呼び出し側が盲目的にアプリケーションのDOMにその文字列を挿入すると、スクリプトインジェクションが発生するでしょう。これらの理由により、我々がクロスドメインの通信メカニズムにおいて利用できるスクリプトインジェクション攻撃を軽減するための2つの新らしい技術を紹介できることを嬉しく思います。
より安全なマッシュアップ:HTMLのサニタイズ
IE8は、toStaticHTML という名前の、window オブジェクトの新しいメソッドを提供します。HTMLの文字列がこの関数を通ると、文字列が返される前に、実行可能なスクリプトを構成するすべての潜在的な部分が削除されます。この関数は、サーバサイドの Microsoft Anti-Cross Site Scripting Library と同じテクノロジーをベースにしています。
そして、例えば toStaticHTML を使うと、postMessage 呼び出しによって受け取ったHTMLにて、スクリプトを実行することなく基本的なHTML書式を利用できます。
document.attachEvent('onmessage',function(e) { if (e.domain == 'weather.example.com') { spnWeather.innerHTML = window.toStaticHTML(e.data); } }
呼び出し:
window.toStaticHTML("This is some <b>HTML</b> with embedded script following... <script>alert('bang!');</script>!");
結果:
This is some <b>HTML</b> with embedded script following... !
より安全なマッシュアップ:JSONのサニタイズ
JavaScript Object Notation (JSON) は、マッシュアップ部品の間でデータを受け渡しするのによく使われる、JavaScript オブジェクトの軽量なシリアライズされた文字列フォーマットです。残念ながら、マッシュアップの多くにおいてJSON文字列をJavaScriptオブジェクトに復元するにおいて、その過程でスクリプトが実行されるかも知れない可能性を含みつつ eval メソッドに頼るという、安全ではないJSONの使い方をしています。セキュリティを意識した開発者は、JSONオブジェクトが実行可能なスクリプトを含んでいないか確認するためにJSONパーサを使いますが、それにはパフォーマンス低下というペナルティがあります。
IE8は、JSONをネイティブに扱う機能(Douglas Crockford の json2.js を使います)として ECMAScript 3.1 提案を実装します。JSON.stringify メソッドはスクリプトのオブジェクトを与えると JSON 文字列を返し、JSON.parse メソッドに文字列を与えると、JavaScript オブジェクトを安全に復元します。新しいネイティブな JSON メソッドは、スクリプトエンジン自身と同じコードに基づいており、そのため非ネイティブな実装の性能を大きく上回りました。もし、生成されたオブジェクトにDOMへのインジェクションにつながる文字列が含まれているなら、前で説明した toStaticHTML 関数がスクリプトインジェクションからの保護に利用できます。
以下の例は、JSONとHTMLのサニタイズによりスクリプトインジェクションを防いでいます:
<html> <head><title>XDR+JSON Test Page</title> <script> if (window.XDomainRequest){ var xdr1 = new XDomainRequest(); xdr1.onload = function(){ var objWeather = JSON.parse(xdr1.responseText); var oSpan = window.document.getElementById("spnWeather"); oSpan.innerHTML = window.toStaticHTML("Tonight it will be <b>" + objWeather.Weather.Forecast.Tonight + "</b> in <u>" + objWeather.Weather.City+ "</u>."); }; xdr1.open("POST", "http://evil.weather.example.com/getweather.aspx"); xdr1.send("98052"); } </script></head> <body><span id="spnWeather"></span></body> </html>
もし Weather サービスが悪意ある応答を返したとしても:
HTTP/1.1 200 OK Content-Type: application/json XDomainRequestAllowed: 1 {"Weather": { "City": "Seattle", "Zip": 98052, "Forecast": { "Today": "Sunny", "Tonight": "<script defer>alert('bang!')</script>Dark", "Tomorrow": "Sunny" } }}
続く。