HTML5.JP

Ads

W3C - 『Web Storage』日本語訳

一部、直訳ではなく意訳した部分がございます。原文と表現が異なることがございますので、ご了承ください。この日本語訳は、私が理解を深めるために、自分なりに日本語化したものです。本日本語訳には、翻訳上の誤りがある可能性があります。したがって、内容について一切保証をするものではありません。正確さを求める場合には、必ず原文を参照してください。当方は、この文書によって利用者が被るいかなる損害の責任を負いません。もし誤りなどを見つけたら、当サイトのお問い合わせより連絡いただければ幸いです。

概要

Web Storage とは、データをブラウザ側に蓄積する仕組みです。クッキーとよく似ていますが、多くの点で異なります。Web Storage は大きなデータを蓄積できますので、ユーザーエクスペリエンスの向上やサーバー負荷の低減に役立てることができます。

現在はW3CのHTML5仕様から分離されてしまいましたが、次世代のウェブアプリケーションの中核を担うテクノロジーとして期待されています。

日本語訳

目次

  1. 1 はじめに
  2. 2 準拠要件
    1. 2.1 依存関係
  3. 3 用語
  4. 4 API
    1. 4.1 Storage インタフェース
    2. 4.2 sessionStorage 属性
    3. 4.3 localStorage 属性
    4. 4.4 storage イベント
      1. 4.4.1 イベントの定義
    5. 4.5 スレッド
  5. 5 ディスクスペース
  6. 6 プライバシー
    1. 6.1 ユーザー追跡
    2. 6.2 クッキーの復活
    3. 6.3 データの機密性
  7. 7 セキュリティ
    1. 7.1 DNS スプーフィング・アタック
    2. 7.2 クロス・ディレクトリ・アタック
    3. 7.3 実装のリスク
  8. リファレンス

1 はじめに

このセクションは非準拠です。

この仕様では2つの関連メカニズムを紹介します。それは、HTTPセッションクッキーに似ていますが、クライアント側で構造化データを蓄積するものです。[COOKIES]

1つ目は、ユーザーが単一のトランザクションを実行しているところを想定して設計されたものですが、異なるウィンドウで複数のトランザクションを同時に実行することができます。

クッキーでは、この場合をうまく扱うことができません。例えば、ユーザーが、同じサイトを使って、2つの異なるウィンドウで飛行機のチケットを購入しようとする場合です。そのユーザーがどのチケットを購入しようとしていたのかを保持するために、そのサイトがクッキーを使っていた場合、そのユーザーが両方のウィンドウにあるそれぞれのページをクリックしたら、その時点で購入しようとしているチケットは、一方のウィンドウからもう一方のウィンドウに "漏れて" しまうでしょう。ユーザーはそれに全く気づかない可能性があり、同じフライトのチケットを2つ購入してしまうことになりかねません。

この問題に対処するために、この仕様は sessionStorage DOM 属性を取り入れています。サイトは、セッション・ストレージにデータを加えることができ、そのウィンドウで開かれている同じサイトのどんなページからでもアクセスすることができるようになります。

例えば、保険が欲しい場合にユーザーがチェックを入れるチェックボックスをページに入れることができるでしょう:

<label>
 <input type="checkbox" onchange="sessionStorage.insurance = checked">
 私はこの旅行で保険が欲しいです。
</label>

その後のページでは、ユーザーがチェックボックスをチェックしたかどうかをスクリプトから判別することができるようになります:

if (sessionStorage.insurance) { ... }

ユーザーがそのサイトでいくつもウィンドウを開いていたなら、それぞれのページごとに、セッション・ストレージ・オブジェクトのコピーを別々に持つことになります。

2つ目のストレージ・メカニズムは、複数のウィンドウをまたがり、そして、カレントのセッションが終了しても存続するストレージを想定したものです。特に、パフォーマンスの理由で、クライアント側に、ユーザーが編集したドキュメントを丸ごと、とか、ユーザーのメールボックスのように、何メガバイトものユーザーデータを蓄積したいと考えるウェブアプリケーションがあるでしょう。

何度も言うようですが、クッキーでは、この場合をうまく対処できません。なぜなら、リクエストの度に送信されてしまうからです。

localStorage IDL 属性を使って、ページのローカルストレージ領域にアクセスします。

example.com にあるサイトは、ユーザーがそのページを何回ロードしたかを表示することができます。そのページの最後に次のコードを入れます:

<p>
  You have viewed this page
  <span id="count">an untold number of</span>
  time(s).
</p>
<script>
  if (!localStorage.pageLoadCount)
    localStorage.pageLoadCount = 0;
  localStorage.pageLoadCount = parseInt(localStorage.pageLoadCount, 10) + 1;
  document.getElementById('count').textContent = localStorage.pageLoadCount;
</script>

ストレージ API は文字列ベースのため、数字(この場合は整数)を扱うなら parseInt() を使う必要があります。

各サイトは、それぞれ別々のストレージ領域を持ちます。

ストレージ領域(セッション・ストレージとローカル・ストレージの両方)は文字列を蓄積します。ストレージ領域に構造化データを蓄積するには、最初にそれを文字列に変換しなければいけません。

2 準拠要件

この仕様では、それぞれの節で非規定と記載されていれば、その節にある図表や例や注意事項はすべて非規定です。それ以外はすべて規定です。

この仕様の規定部分にある "しなければいけない(MUST)", "してはいけない(MUST NOT)", "する必要がある(REQUIRED)", "するべきである(SHOULD)", "すべきではない(SHOULD NOT)", "推奨される(RECOMMENDED)", "しても構わない(MAY)", "オプションで(OPTIONAL)" というキーワードは、RFC2119の規定通りに解釈してください。 [RFC2119]

アルゴリズムの一部として規定の中で述べられる要件("strip any leading space characters" や "return false and abort these steps" など)は、そのアルゴリズムの紹介で使われるキーワード("must", "should", "may", など)の意味で解釈するべきです。

いくつかの準拠要件は、属性、メソッド、オブジェクトでの要件として述べられています。このような要件は、ユーザーエージェントでの要件として解釈するべきです。

アルゴリズムや特定の手順として述べられている準拠要件は、最終的な結果が同じ限り、どのような方法で実装しても構いません。(特に、この仕様で定義されるアルゴリズムは追随のしやすさを考慮したもので、パフォーマンスを考慮しているわけではありません。)

この仕様で定義される準拠クラスは、ユーザーエージェントのみです。

ユーザーエージェントは、他の入力に関する実装仕様制限を自発的に課しても構いません。例えば、DoS攻撃を防止するためや、メモリーオーバーを防ぐためや、プラットフォーム依存の制限でも動作させるためです。

2.1 依存関係

この仕様は、いくつかの下層の仕様に依存しています。

HTML5

HTML5から多くの基本的な概念がこの仕様で使われています。 [HTML5]

WebIDL

この仕様の IDL ブロックには WebIDL 仕様を採用しています。 [WEBIDL]

3 用語

構文 "Foo オブジェクト" は、実際は Foo はインタフェースなのですが、より正確な "インタフェース Foo を実装するオブジェクト" の代わりに使われることがあります。

DOM という用語は、ウェブアプリケーションでスクリプトから利用することができる API セットを指すものとして使われます。必ずしも、実在の Document や、DOM Core 仕様で定義されているような Node オブジェクトの存在を意味しているわけではありません。 [DOMCORE]

DOM 属性は、その値が取り出されているとき、取得されているといいます(例えば、ウェブ制作者のスクリプトによって)。

"JavaScript" という用語は ECMA262 を指すものとして使われます。公式な用語である ECMAScript を使わないのは、JavaScript という用語のほうが広く知れ渡っているからです。[ECMA262]

4 API

4.1 Storage インタフェース

interface Storage {
  readonly attribute unsigned long length;
  getter any key(in unsigned long index);
  getter any getItem(in DOMString key);
  setter creator void setItem(in DOMString key, in any data);
  deleter void removeItem(in DOMString key);
  void clear();
};

それぞれの Storage オブジェクトは、key/value ペアのリストへのアクセスを提供します。key/value ペアのことを項目と呼ぶこともあります。key は文字列です。どんな文字列でも(空文字列を含む)妥当な key です。value は、構造化クローンアルゴリズムによってサポートされたデータタイプなら、何でも構いません。

sessionStoragelocalStorage 属性のセクションで定義されている通り、それぞれの Storage オブジェクトは、key/value ペアのリストが生成されたとき、その key/value ペアと関連づけられます。Storage インタフェースを実装している複数の別々のオブジェクトに、同時に同じ key/value ペアのリストを関連づけることができます。

オブジェクトのインデックス付きプロパティのインデックスは、0 から、そのオブジェクトと関連づけられたリストにその時点で存在する key/value ペアの数より小さい範囲の数字となります。そのリストが空なら、インデックス付きプロパティはないということになります。

length 属性は、そのオブジェクトと関連づけられたリストにその時点に存在する key/value ペアの数を返さなければいけません。

key(n) メソッドは、リストにある n 番目の key の名前を返さなければいけません。key の順番はユーザーエージェントが定義するものとなりますが、key の数に変更がない限り、オブジェクト内で一貫性を保たなければいけません。(ゆえに、key を追加したり削除したら、key の順番が変わる可能性があります。しかし、実在の key の値を変更しただけなのであれば、そのようなことはありません。)n がオブジェクトにある key/value ペアの数より大きいか等しいなら、このメソッドは null を返さなければいけません。

Storage オブジェクトの名前付きプロパティの名前は、そのオブジェクトと関連づけられているリストにその時点で存在する各 key/value ペアの key となります。

getItem(key) メソッドは、指定の key と関連づけられているその時点の値の構造化クローンを返さなければいけません。指定の key がそのオブジェクトと関連づけられているリストに存在しないなら、このメソッドは null を返さなければいけません。

setItem(key, value) メソッドは、指定の value の構造化クローンを最初に生成しなければいけません。ここで例外が発出されたら、その例外が投げられなければいけません。そして、そのオブジェクトと関連づけられているリストは変更されないままでなければいけません。構造化クローンの生成が新規の ImageData オブジェクトの生成を含んでいたなら、代わりに NOT_SUPPORTED_ERR 例外を投げなければいけません。

そうでなければ、ユーザーエージェントは、指定の key を持つ key/value ペアが、そのオブジェクトと関連づけられているリストにすでに存在するかどうかをチェックしなければいけません。

もし存在しなければ、新規の key/value ペアがリストに加えられなければいけません。指定の key と、新規に得られた value のクローンにセットされた値を使います。

指定の key がリストに存在していれば、その値は、新規に得られた value のクローンにアップデートされなければいけません。

もし新規の値をセットすることができなかったら、このメソッドは QUOTA_EXCEEDED_ERR 例外を発出しなければいけません。(例えば、ユーザーが該当のサイト用のストレージを無効にしていたり、容量制限オーバーだったなら、その値はセットできなかった可能性があります。)

removeItem(key) メソッドは、指定の key を持つ key/value ペアが存在すれば、それを、そのオブジェクトと関連づけられているリストから削除します。その key を持つ項目が一つもなければ、このメソッドは何もしてはいけません。

setItem()removeItem()メソッドは、失敗に対してはアトミックでなければいけません。失敗した場合においては、このメソッドは何もしません。つまり、データストレージ領域への変更が成功する、または、データストレージ領域が全く変更されない、のいずれかでなければいけません。

clear() メソッドは、そのオブジェクトと関連づけられているリストがあれば、その key/value ペアのすべてを空にします。なければ、このメソッドは何もしてはいけません。

setItem(), removeItem(), clear()メソッドが呼び出されるとき、新たに蓄積される、または、削除されるデータにアクセスすることができる他の HTMLDocument オブジェクトでイベントが発出されます。sessionStoragelocalStorage 属性のセクションで定義されている通りです。

この仕様では、前述のメソッドに対して、データが物理的にディスクに書き込まれるまで待つことを要求しません。別々のスクリプトから同じ key/value ペアのリストにアクセスしても同じものが見えるという点だけが要求されます。

4.2 sessionStorage 属性

[Supplemental, NoInterfaceObject]
interface WindowSessionStorage {
  readonly attribute Storage sessionStorage;
};
Window implements WindowSessionStorage;

sessionStorage 属性は、トップレベルのブラウジングコンテキストに限定したストレージ領域のセットを表します。

それぞれのトップレベルのブラウジングコンテキストは、origin ごとに、固有のセッションストレージ領域を持ちます。

ユーザーエージェントは、ブラウジングコンテキストのセッションストレージ領域からデータを失効するべきではありません。しかし、ユーザーが削除を要求したときや、それがストレージ領域を限定したことをユーザーエージェントが検知したときや、セキュリティの理由があるときは、そうすることができます。ユーザーエージェントは、データにアクセスすることができるスクリプトが実行されている間は、常に、データの削除を避けるべきです。トップレベルのブラウジングコンテキストが無くなったとき(それゆえに、永久的にユーザーはアクセスできなくなります。)、セッションストレージ領域に蓄積されたデータは、それとともに破棄されることができます。この仕様で説明する API は、それ以降に、そのデータを取り出す手段をまったく提供しません。

ブラウジングコンテキストの生存期間は、実際のユーザーエージェントのプロセスの生存期間と連動する必要はありません。ユーザーエージェントは、再起動後のセッションのレジュームをサポートすることができます。

新規の HTMLDocument が生成されるとき、ユーザーエージェントは、そのドキュメントのトップレベルのブラウジングコンテキストが、そのドキュメントの origin 用のセッションストレージ領域を割り当てたかどうかをチェックしなければいけません。もし、そうでなければ、そのドキュメントの origin 用の新規のストレージ領域が生成されなければいけません。

sessionStorage 属性は、そのセッションストレージ領域と関連づけられた Storage オブジェクトを返さなければいけません。それぞれの Document オブジェクトは、その WindowsessionStorage 属性ごとに別々のオブジェクトを持たなければいけません。

新規のトップレベルのブラウジングコンテキストが既存のブラウジングコンテキストを複製することで生成されるとき、その新規のブラウジングコンテキストは、オリジナルと同じセッションストレージ領域を使って開始しなければいけません。しかし、この2つのセットは、その時点からは、別々のものとして見なされなければいけません。決してお互いに影響を及ぼしてはいけません。

既存のブラウジングコンテキストのスクリプトによって、または、既存のブラウジングコンテキストのリンクをユーザーがたどることによって、または、特定の HTMLDocument に関係した別の方法で、新規のトップレベルのブラウジングコンテキストが生成されるとき、その HTMLDocument の origin のセッションストレージ領域は、それが生成されるとき、新規のブラウジングコンテキストの中にコピーされなければいけません。しかし、その時点から、その2つのセッションストレージ領域は別々のものとして見なされなければならず、決してお互いに影響を及ぼしてはいけません。

下記の通り、setItem(), removeItem(), clear()メソッドがセッションストレージ領域と関連づけられている Storage オブジェクト x 上で呼び出されるとき、もしそのメソッドが何かをしたなら、x 以外で、Window オブジェクトの sessionStorage 属性の Storage オブジェクトが同じストレージ領域と関連づけられているすべての HTMLDocument オブジェクトの中で、storage イベントが発出されなければいけません。

4.3 localStorage 属性

[Supplemental, NoInterfaceObject]
interface WindowLocalStorage {
  readonly attribute Storage localStorage;
};
Window implements WindowLocalStorage;

localStorage オブジェクトは、origin 用の Storage オブジェクトを提供します。

ユーザーエージェントは、それぞれの origin ごとに、ローカルストレージ領域のセットを持たなければいけません。

ユーザーエージェントは、セキュリティの理由がある場合、または、ユーザーからのリクエストがあるときに限り、ローカルストレージ領域からデータを失効するべきです。ユーザーエージェントは、そのデータにアクセスすることができるスクリプトが実行している間は、常に、データの削除を避けるべきです。

localStorage 属性にアクセスがあるとき、ユーザーエージェントは、それが、そのメソッドが呼び出された Window オブジェクトの Document の origin 用のローカルストレージ領域を割り当てたかどうかを、チェックしなければいけません。もしそうでなければ、その origin 用に新規のストレージ領域が生成されなければいけません。

ユーザーエージェントは、その origin のローカルストレージ領域と関連づけられた Storage オブジェクトを返さなければいけません。それぞれの Document オブジェクトは、その WindowlocalStorage 属性に対して、別々のオブジェクトを持たなければいけません。

下記の通り、setItem(), removeItem(), clear()メソッドが、ローカルストレージ領域と関連づけられた Storage オブジェクト x 上で呼び出されるとき、x 以外で、Window オブジェクトの localStorage 属性の Storage オブジェクトが同じストレージ領域と関連づけられているすべての HTMLDocument の中で、storage イベントが発出されなければいけません。

直接のプロパティアクセスの一部としてかどうかに関わらず、localStorage 属性の Storage オブジェクトのプロパティが調査される、返される、セットされる、削除されるときは常に、また、プロパティの列挙中、プロパティの存在をチェックするとき、また、Storage インタフェース上に定義されているメソッドや属性の実行の一部として、存在するプロパティの数を調査するとき、ユーザーエージェントは、まず最初に、ストレージのミューテックスを取得しなければいけません。

4.4 storage イベント

storage イベントは、前の2つのセクション(セッション・ストレージローカル・ストレージ)で説明した通り、ストレージ領域が変化したときに発出されます。

これが起こるとき、ユーザーエージェントは、Document オブジェクトが、影響を受ける Storage オブジェクトを持つ Window オブジェクトそれぞれで、storage という名前を持ったイベントを発出するタスクをキューイングしなければいけません。このイベントは、名前空間を持たず、バブリングせず、キャンセラブルではありません。そして、StorageEvent インタフェースを使います。

これは、完全にアクティブでない Document オブジェクトを含みます。しかし、それらの上で発出されたイベントは、その Document オブジェクトが再び完全にアクティブになるまで、イベント・ループによって無視されます。

このタスク用のタスクソースは、DOM 操作タスクソースです。

イベントが setItem()removeItem()メソッドの起動によって発出されているなら、そのイベントは、その key 属性に、該当の key の名前をセットし、その oldValue 属性に、該当の key の古い value の構造化クローンをセットします。その key が新規に追加されるなら null をセットします。そして、その newValue 属性に、該当の key の新規の value の構造化クローンをセットします。

そうでなければ、そのイベントが clear() メソッドの起動によって発出されているなら、そのイベントは、その key, oldValue, newValue 属性に null をセットしなければいけません。

さらに、そのイベントは、その url 属性に、Storage オブジェクトが影響を受けたドキュメントのアドレスをセットしなければいけません;2つのドキュメントが同じユニットの関連のブラウジングコンテキストの中にあるなら、その source 属性に、そのドキュメントのブラウジングコンテキストの WindowProxy オブジェクトをセットしなければいけません。そうでなければ null をセットしなければいけません。;その storageArea 属性に、影響を受けたのと同じ種類(つまり、セッション、または、ローカル)の Storage 領域を表すターゲットの DocumentWindow オブジェクトからの Storage オブジェクトをセットしなければいけません。

4.4.1 イベントの定義

interface StorageEvent : Event {
  readonly attribute DOMString key;
  readonly attribute any oldValue;
  readonly attribute any newValue;
  readonly attribute DOMString url;
  readonly attribute WindowProxy source;
  readonly attribute Storage storageArea;
  void initStorageEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString keyArg, in any oldValueArg, in any newValueArg, in DOMString urlArg, in WindowProxy sourceArg, in Storage storageAreaArg);
  void initStorageEventNS(in DOMString namespaceURI, in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString keyArg, in any oldValueArg, in any newValueArg, in DOMString urlArg, in WindowProxy sourceArg, in Storage storageAreaArg);
};

initStorageEvent()initStorageEventNS() メソッドは、DOM Event インタフェースの同名のメソッドと同じように、イベントを初期化しなければいけません。[DOMEVENTS]

key 属性は、変更があった key を表します。

oldValue 属性は、key の変更があった古い値を表します。

newValue 属性は、key の変更があった新しい値を表します。

url 属性は、key に変更があったドキュメントのアドレスを表します。

source 属性は、key に変更があったドキュメントのブラウジングコンテキストの WindowProxy オブジェクトを表します。

storageArea 属性は、影響を受けた Storage オブジェクトを表します。

4.5 スレッド

ストレージのミューテックスの利用のため、複数のブラウジングコンテキストは、同時にローカルストレージ領域にアクセスすることができるでしょう。このとき、スクリプトは、並列にスクリプトが実行されていることにまったく気づくことはできません。

ゆえに、Storage オブジェクトの length 属性と、そのオブジェクトの各種プロパティの値は、スクリプト自身によって予測可能な方法を除いて、スクリプト実行中に変更することができません。

5 ディスクスペース

ユーザーエージェントは、ストレージ領域用に許可するスペースの総量を制限するべきです。

ユーザーエージェントは、サイトが origin のもとで他のアフィリエイトサイトのデータを蓄積することを防ぐべきです。例えば、a1.example.com, a2.example.com, a3.example.com などでのリミットまで蓄積し、メインとなるexample.com のストレージリミットを回避するといったことです。

ユーザーエージェントは、クォータ制限に達したときユーザーに通知して、ユーザーがサイトに追加のスペースを許可できるようにすることができます。これによって、例えば、サイトは、ユーザーのコンピュータ上に、多くのユーザー生成ドキュメントを蓄積できるようになります。

ユーザーエージェントは、各ドメインがどれくらいスペースを使っているのかをユーザーに見せることができます。

ほとんど任意ではありますが、origin ごとに 5 MB の任意リミットが推奨されます。実装のフィードバックは歓迎です。将来的には、この提案を更新するために使われるでしょう。

6 プライバシー

6.1 ユーザー追跡

サードパーティの広告主(または、複数のサイトにコンテンツを配布することができるもの)は、複数のセッションをまたいでユーザーを追跡するために、そのローカルストレージ領域に蓄積されるユニークな識別子を使うということが考えられます。精度の高いターゲッティング広告を可能にするために、ユーザー興味のプロファイルを構築するのです。ユーザーの実際の身元を知っているサイト(例えば、身分証明書を要求するeコマースサイト)と連動すれば、これは、不当なグループに、純粋に匿名のウェブ利用を前提とした世界と比べて相当な精度で個人を標的にすることを許してしまうことになります。

ユーザー追跡のリスクを軽減するのに使うことができる数多くのテクニックがあります:

サードパーティのストレージをブロックする

ユーザーエージェントは、ブラウジングコンテキストのトップレベルのドキュメントのドメインからのスクリプトに対して、localStorage オブジェクトへのアクセスを制限することができます。例えば、iframe で実行する別ドメインからのページに対して、API へのアクセスを拒否します。

蓄積データを失効する

ユーザーエージェントは、ある期間の経過後に蓄積データを自動的に削除することができます。

例えば、ユーザーエージェントは、サードパーティのローカルストレージ領域を、セッション専用ストレージとして扱うことができるでしょう。ユーザーが、それにアクセスできるブラウジングコンテキストをすべて閉じたら、削除するのです。

これによって、ユーザーを追跡するサイトの能力を制限することができます。そのサイトは、ユーザーがそのサイトで認証(購入したり、サービスにログインする)しない限り、複数のセッションをまたいで、そのユーザーを追跡することができないからです。

しかし、これは、ユーザーのデータをリスクにさらすことにもなります。

永続的なストレージをクッキーとして扱う

ユーザーエージェントは、HTTP セッションクッキーと区別せずに、ユーザーに永続ストレージ機能を提供するべきです。[COOKIES]

こうすることで、ユーザーは健全性に疑念をもって見ることができるようになります。

ローカルストレージ領域にアクセスできるサイトのホワイトリスト

ユーザーエージェントは、サイトが制限なしにセッションストレージ領域にアクセスすることができるようにすることができますが、ユーザーに、ローカルストレージ領域へのアクセスを承認することを要求します。

蓄積データの origin 追跡

ユーザーエージェントは、データを蓄積することになるサードパーティの origin からのコンテンツを含んだサイトの origin を記録することができます。

この情報が永続ストレージにあるデータのビューを提供するために使われるなら、その情報によって、ユーザーは、永続ストレージのどの部分を切り取るべきかについて判断を下すことができるようになるでしょう。ブラックリスト("このデータを削除し、このドメインからのデータを二度と蓄積しないようにする")と組み合わせることで、ユーザーは、自分が信頼するサイトの永続ストレージの利用を限定することができます。

共有ブラックリスト

ユーザーエージェントは、ユーザーが永続的なストレージドメインのブラックリストを共有することができるようにすることができます。

これによって、コミュニティーがプライバシーを守るためにともに行動することができるようになります。

これらの提案によって、ユーザー追跡のためにこの API をある程度は利用できないようになりますが、完全にブロックするわけではありません。単一ドメイン内では、サイトはセッションが続く間、ユーザーを追跡し続けることができます。そして、サードパーティにこの情報を、何かしらの識別情報(名前、クレジットカード番号、住所)とともに、引き渡すことができます。もし、そのような情報を取得するために、サーボパーティが複数のサイトと協力しあっているなら、プロファイルを生成することができてしまいます。

しかし、ユーザー追跡は、ユーザーエージェントの助けがまったく無くても、ある程度は可能となるのです。例えば、URL にセッション識別子を入れたり、害のない目的で一般的に使われているテクニックを、ユーザー追跡用に目的を変えて使うのです(過去にさかのぼってすら)。この情報を他のサイトと共有することができるのです。訪問者の IP アドレスや、そのほかユーザー固有データ(例えば、ユーザーエージェントのヘッダーや設定情報)を使って、別々のセッションを統合して、一貫したユーザープロファイルに仕立てるのです。

永続ストレージ用のユーザーインタフェースで、HTTP セッションクッキーにあるデータと、この仕様で説明されている永続ストレージ機能にあるデータとを、別々に提供する場合、ユーザーは、一方のデータを削除しても、もう一方を削除しないということが考えられます。これによって、サイトは、お互いの冗長バックアップとして2つの機能を使うことができてしまいます。ユーザーが自分のプライバシーを守ろうとしても、意味が無くなってしまいます。

6.3 データの機密性

ユーザーエージェントは、永続的に蓄積したデータを、機密性が高くセンシティブである可能性があるとして扱うべきです。それは、e-mail かもしれないし、アポイントのスケジュールや健康管理記録かもしれないし、そのほか、このメカニズムに蓄積される秘密の文書かもしれません。

そのため、ユーザーエージェントは、データを削除するとき、確実に該当のストレージから速やかに削除されるようにするべきです。

7 セキュリティ

7.1 DNS スプーフィング・アタック

DNS スプーフィング・アタックの可能性があるため、ある特定のドメインにあると宣言しているホストが、本当にそのドメインからのものなのかを、誰も保証することはできません。これを低減するために、ページに SSL を使うことができます。SSL を使ったページであれば、確実に、同じドメインであることを確認できる証明書を持つ SSL を使ったページだけに、そのストレージ領域にアクセスできるようにすることができます。

7.2 クロス・ディレクトリ・アタック

ひとつのホスト名を別々のウェブ制作者で共有する場合、例えば、geocities.com にコンテンツをホスティングするユーザーは、全員、ひとつの永続ストレージオブジェクトを共有することになります。パス名でアクセスを制限する機能はありません。そのため、共有ホストのウェブ制作者は、これらの機能を使わないことが推奨されます。他のウェブ制作者にデータを読まれたり上書きされたりしてしまうかもしれないからです。

たとえ、パス制限機能が使えるようにしたとしても、DOM スクリプティング・セキュリティ・モデルでは、その防御をバイパスでき、どんなパスのデータでもアクセスできてしまいます。

7.3 実装のリスク

これらの永続ストレージ機能実装時には、主に2つのリスクが伴います。ひとつは、危険なサイトに別のドメインの情報を読まれてしまうこと、もう一つは、危険なサイトに、別のドメインから読まれた情報を書き換えられてしまうことです。

サードパーティのサイトに、彼らのドメインから読まれることになっていないデータを読まれてしまうというのは、情報漏洩を引き起こすことになります。例えば、あるドメインのユーザーのショッピング・ウィッシュリストが、ターゲッティング広告のために、別のドメインによって使われてしまうことが考えられます。また、文書処理サイトによって蓄積された制作中の機密文書を、競合の会社のサイトによって調べ上げられるかもしれません。

サードパーティのサイトによって別のドメインの永続ストレージにデータを書き込まれると、情報なりすましという結果となる可能性があります。例えば、危険なサイトがユーザーのウィッシュリストに商品を追加することが考えられます。また、危険なサイトが、餌食となるサイト上で、ユーザーのセッション識別子を、ユーザーアクション追跡可能な既知の ID にセットしてしまうことが考えられます。

そのため、この仕様で説明されている origin モデルに厳密に従うことが、ユーザーのセキュリティ上、重要なのです。

リファレンス

すべてのリファレンスは、"非規定" と記されていない限り、規定です。

[COOKIES]
HTTP State Management Mechanism, A. Barth. IETF, 2009年8月
[DOMCORE]
Document Object Model (DOM) Level 3 Core Specification, A. Le Hors, P. Le Hegaret, L. Wood, G. Nicol, J. Robie, M. Champion, S. Byrnes. W3C, 2004年4月
[DOMEVENTS]
Document Object Model (DOM) Level 3 Events Specification, D. Schepers. W3C, 2009年7月
[ECMA262]
ECMAScript Language Specification. ECMA, 1999年12月
[HTML5]
HTML 5, I. Hickson. WHATWG, August 2009.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF, 1997年3月
[WEBIDL]
Web IDL, C. McCormack. W3C, 2009年7月
サイト運営者情報 | プライバシーポリシー | 当サイトのご利用条件 | お問い合わせ | サイトマップ
Copyright © 2007 Futomi Hatano All Rights Reserved.