フロントエンドWeb戦略室

第1回 外部サイトに貼り付けるJavaScriptの作法―ポリシー,速度,セキュリティ,プライバシー(2)

この記事を読むのに必要な時間:およそ 4 分

速度に影響を与えないために

まずは外部サイト向けのJavaScriptが,そのサイトの読み込み速度へ与える影響を考えてみます。

Webページのレンダリングをブロックしないようにする

特別な配慮なく外部JavaScriptを提供すると,読み込み速度に影響を与えてしまいます。

外部JavaScriptの読み込みが遅れた場合,ページ全体の描画が停止してしまうのです。これはdocument.writeなど,読み込んだページに対してHTMLを出力するような命令が含まれていた場合には,ページ全体のレンダリング結果に影響を与えてしまうためです。ブラウザはscriptタグが記述されている順番でJavaScriptを実行しなくてはいけません注6)⁠これを回避するためには,次の2つの戦略が考えられます。

注6)
JavaScriptと違い画像やiframeであれば,ロードされた順番で表示されるだけですので,このような心配をする必要はありません。

defer属性やasync属性を活用する

Webページのレンダリングをブロックしないようにする1つ目の戦略は,あらかじめブログパーツやウィジェットを描画するエリアを指定しておいて,スクリプトのロードが終わりしだいコンテンツを描画する方法です。あるいはscriptタグの中で,appendChildやinsertBeforeを使って動的に描画エリアを作成するのもありでしょう。

scriptタグにdefer属性を付けると,そのスクリプトはページロード完了後に「遅れて」実行されます。

async属性を付けた場合は,スクリプトのロードが完了したタイミングで実行されます。async属性を使う場合,JavaScriptがどの順番で読み込み/実行が行われても影響がないように記述しなくてはいけません。

このように記述することで,もしスクリプトのロードが遅れても,ページ全体の描画をブロックすることがなくなります。ブログパーツやウィジェットであれば,この方法をお勧めします。ただしこの方式を採用する場合はスクリプト中でdocument.writeを使用すべきではありません。document.writeが含まれていてもスクリプトは実行されますが,Webページのレンダリングが完了した後にスクリプトが読み込まれた場合,document.writeは表示されたWebページの内容をクリアして,真っ白な状態のページに文字列を出力することになります。

document.write+ 追加のスクリプト

2つ目は,ローダとなるスクリプトと動的に生成されるスクリプトを分ける手法です。ブラウザは2段階に分けてスクリプトをロードします。defer属性やasync属性を使う方法と比べ,より幅広いブラウザをサポートしなくてはならないケースや,高速にレスポンスを返すことが保証できる場合は,この方法が選択肢となります。次の2段階に分けてスクリプトをロードさせます。

  • ① ブラウザに長期間キャッシュされる,ローダとなるjsファイル
  • ② ブラウザにキャッシュさせず,動的に生成されるjsファイルやiframe

これは広告配信などでよく使われる手法です。①については高速で読み込まれることを保証したうえでdocument.writeを使用し,その中から追加で読み込まれるjsファイルや,②の動的に生成されるコンテンツを追加でロードするようにします。

DOMDocument Object Modelをサポートしない古いブラウザ注7をサポートする必要がある場合,document.writeを使用しなくては動作しないことになります。しかし,そのような古いブラウザは現在ではサポート期限が終了していたり,セキュリティパッチが提供されていないなどの問題があるため,使用すること自体が望ましくありません。よって今ではdocument.writeに依存する必然性はほとんどありません。

注7)
Internet Explorer はver.4から,Netscape Navigatorはver.6からDOMに対応しています。

安全に提供するために─⁠─セキュリティ編

速度への影響がクリアになったところで,次に外部JavaScriptを安全に提供するためのセキュリティを考えます。具体例を見ていきましょう。

サンドボックスドメインを使う

外部JavaScriptのすべてが安全かどうか,利用者が確認・判断するのは容易ではありません。また「今は安全」と判断できても将来的に書き換えられてしまうことも考えられます。

外部に起因するJavaScriptを実行するなら,安全かどうかを慎重に確認するよりも,まずは「別ドメインで」実行することを考えましょう。検索エンジンやCGMConsumer Generated Mediaサイトなど,多くのサービスは任意のコンテンツをホスティングするための「サンドボックスドメイン」注8を持っています。

サンドボックスドメインとログイン情報を持つドメインを切り分けることができれば,セキュリティ上かなりのメリットがあります。任意のJavaScriptが実行されたとき,サンドボックスを使う場合と使わない場合でどのような差が生じるのか,表1にまとめました。

表1 任意のJavaScriptが実行された場合に何が起きるか

実行される場所何が起きるか
サンドボックスドメインの場合悪意のあるサイトへのリダイレクト,偽コンテンツの表示,ログインの有無に関係のない危険な操作
ログイン情報を持つドメインの場合そのドメインで行えるあらゆる操作

パスワード入力などの本人再確認がない範囲

注8)
隔離されたドメインのこと。ここでは外部JavaScriptを表示させるためのドメイン。サンドボックス(sandbox)とは,外部から受け取ったプログラムを保護された領域で動作させることにより,システムが不正に操作されるのを防ぐセキュリティモデルです。
サンドボックスドメインの例

たとえばlivedoorのサービスであれば,*.livedoor.comは主にlivedoorが提供するコンテンツで,ユーザがタグを自由に書くことはできません。一方,blog.livedoor.jpであれば,自由にHTMLタグを書くことができます。管理画面を提供するドメインと,ユーザが自由にコンテンツを置ける「表示用のドメイン」を分けているのです。

サンドボックスドメインの中では自由にJavaScriptを実行できるため,ブラクラや悪意のあるサイトへのリダイレクトを行うことができますが,ブログ管理用のドメインとはドメインが分かれているため,アカウントの乗っ取りなどを行うことができません。検索エンジンのキャッシュなどをホスティングしているドメインも,サンドボックスドメインと見なすことができます。

サンドボックスドメインを使わない場合

ブログサービスによっては,表示用のドメインと管理用のドメインが同一で,サービス事業者が許可したブログパーツの貼り付けのみ許可しているようなケースもあります。

このケースでは,ブログサービス事業者によって審査されたうえ,安全であると認められたブログパーツのみが利用可能です。しかし,ブログパーツやウィジェットの提供元が著名なサービスであるからといって安全だとは限りませんし,審査した段階では安全でも,ある日突然危険になる可能性もあります。この点,サンドボックスを使わないブログサービスは,利用者に観察力が求められています。

著者プロフィール

mala(マラ)

NHN Japan所属。livedoor Readerの開発で知られる。JavaScriptを使ったUI,非同期処理,Webアプリケーションセキュリティなどに携わる。

Twitter:@bulkneets

コメント

コメントの記入