O'REILLY JavaScript 第5版を飛ばし読む(13章 Webブラウザに組み込まれたJavaScript)
ここではDOMの構造やJavaアプレットの話が出てくるが、今回は割愛。
セキュリティ関係の話だけ少し取り出す。
JavaScript のセキュリティ
JavaScript ではできないこと
ユーザーの Web ブラウザ上で悪意のあるコードが実行されないよう、スクリプトの動作には以下のような制限がかけられている。
- クライアントのPC上のファイルやディレクトリに対して、読み出し、書き込み、作成、削除、表示ができない
- ソケットを開く、他のホストからの接続を受け付ける、といったネットワーク機能はサポートしていない
- クリック等のイベントなしに、ブラウザをオープンすることはできない
- そのプログラムがオープンしたウィンドウ以外は、ユーザーの確認なしにクローズできない
- リンクをマウスオーバーした際に、飛び先がステータス行に表示されるが、その内容をスクリプトで変更することはできない
- 1辺が100ピクセル以下のウィンドウ、画面サイズを超える大きさのウィンドウ、タイトルバーやステータス行のないウィンドウは作成できない
- 画面外にウィンドウを移動することはできない
- HTML の FileUpload 要素の Value プロバティには値を設定できない
- 同一出身ポリシー(後述)
同一出身ポリシー
同一出身ポリシーとは、以下のような内容である。
- あるスクリプトは、そのスクリプトを含むドキュメントと同じ出身のウィンドウやドキュメントのプロパティしか読み出せない
- 同様に、XMLHttpRequest オブジェクトで HTTP を制御する際も、リクエストを送信できるのはそのスクリプトを含むドキュメントがロードされた Web サーバーに対してのみ
- ドキュメントの「出身」は、そのドキュメントをロードした URL のプロトコルとホストとポート番号の組み合わせで決まる
これは、スクリプトを使って機密情報を盗めないようにする機構である。
例) 企業のイントラネット中のブラウザにロードされた悪意のあるスクリプトが空のウィンドウを開いたとする。 ユーザーがそのウィンドウからイントラネットのファイルを閲覧したとしても、同一出身ポリシーにより悪意のあるスクリプトはその内容を読み出すことはできない。
ただし、複数のサーバーを使用するような大規模な Web サービスでは、異なるサーバーからロードされたドキュメント間でプロパティを読み出さなければならない場合がある。
このような場合は各 Document
オブジェクトの domain
プロパティに同じ値を設定してやればよい。
document.domain
プロパティが同一である場合、2つのドキュメントは同一の出身とみなされ、相互にドキュメントのプロパティを読み出せるようになる。
デフォルトではドキュメントをロードしたサーバーのホスト名が設定されているが、この値は書き換えることができる。
例) orders.example.com と catalog.example.com からロードしたドキュメントの domain
プロパティを「example.com」に変更することで、同一出身ポリシーを回避できる。
クロスサイトスクリプティング
ある Web ページが、ユーザの入力したデータから HTML タグを削除せずに、ユーザの入力をそのまま利用してドキュメントのコンテンツを動的に生成していれば、クロスサイトスクリプトの脆弱性が存在する。 (HTML タグを削除する処理のことを「サニタイズ」と呼ぶ)
クロスサイトスクリプティングの流れは以下(一例)。
- クロスサイトスクリプトの脆弱性が含まれるサイトAがある。
- 悪意のあるユーザーがサイトAへのリンクを含むサイトBを用意する。サイトAへのリンクのクエリパラメータには、悪意のあるスクリプトをロードする script タグを含む値がセットされている。
- ユーザーが上記リンクからサイトAへアクセスすると、サイトAでクエリパラメータを用いてコンテンツが動的に生成され、悪意のあるスクリプトがロードされる。
- 悪意のあるスクリプトはクッキーの値等を読み出し、ユーザー情報等を取得することができてしまう。
感想
セキュリティの話はやっぱり変わらず大切。クロスサイトスクリプティングっていつも名前だけ覚えていて、内容なんだっけ。。。ってなる。