[html5] r1140 - /
whatwg at whatwg.org
whatwg at whatwg.org
Mon Dec 10 17:14:17 PST 2007
Author: ianh
Date: 2007-12-10 17:14:16 -0800 (Mon, 10 Dec 2007)
New Revision: 1140
Modified:
header-whatwg
index
source
Log:
[ag] (2) Massive changes to globalStorage to remove the multi-domain security model and replace it with the much simpler same-origin model.
Modified: header-whatwg
===================================================================
--- header-whatwg 2007-12-05 05:48:38 UTC (rev 1139)
+++ header-whatwg 2007-12-11 01:14:16 UTC (rev 1140)
@@ -2,7 +2,7 @@
<html lang="en-GB-hixie">
<head>
<title>HTML 5</title>
- <link rel="stylesheet" type="text/css" href="/style/specification">
+ <link rel="stylesheet" href="/style/specification">
<link rel="icon" href="/images/icon">
<style type="text/css">
h4 + .element { margin-top: -2.5em; padding-top: 2em; }
@@ -12,8 +12,10 @@
table.matrix, table.matrix td { border: none; text-align: right; }
table.matrix { margin-left: 2em; }
</style>
+ <link rel="stylesheet" href="status.css">
+ <script src="status.js"></script>
</head>
- <body class="draft">
+ <body class="draft" onload="initAnnotations()">
<div class="head">
<p><a rel="home" href="http://www.whatwg.org/" class="logo"><img alt="WHATWG" src="/images/logo"></a></p>
@@ -34,6 +36,7 @@
<dd>Commit-Watchers mailing list: <a href="http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org">http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org</a></dd>
<dd>Interactive Web interface: <a href="http://html5.org/tools/web-apps-tracker">http://html5.org/tools/web-apps-tracker</a></dd>
<dd>Subversion interface: <a href="http://svn.whatwg.org/">http://svn.whatwg.org/</a></dd>
+ <dd>HTML diff with the last version in Subversion: <a href="index-diff">http://whatwg.org/specs/web-apps/current-work/index-diff</a></dd>
<dt>Editor:</dt>
<dd>Ian Hickson, Google, ian at hixie.ch</dd>
</dl>
Modified: index
===================================================================
--- index 2007-12-05 05:48:38 UTC (rev 1139)
+++ index 2007-12-11 01:14:16 UTC (rev 1140)
@@ -3,7 +3,7 @@
<html lang=en-GB-hixie>
<head>
<title>HTML 5</title>
- <link href="/style/specification" rel=stylesheet type="text/css">
+ <link href="/style/specification" rel=stylesheet>
<link href="/images/icon" rel=icon>
<style type="text/css">
@@ -14,15 +14,18 @@
table.matrix, table.matrix td { border: none; text-align: right; }
table.matrix { margin-left: 2em; }
</style>
+ <link href=status.css rel=stylesheet>
+ <script src=status.js></script>
- <body class=draft>
+ <body class=draft onload="initAnnotations()">
<div class=head>
<p><a class=logo href="http://www.whatwg.org/" rel=home><img alt=WHATWG
src="/images/logo"></a></p>
<h1 id=html-5>HTML 5</h1>
- <h2 class="no-num no-toc" id=working>Working Draft — 5 December 2007</h2>
+ <h2 class="no-num no-toc" id=working>Working Draft — 11 December
+ 2007</h2>
<p>You can take part in this work. <a
href="http://www.whatwg.org/mailing-list">Join the working group's
@@ -67,6 +70,9 @@
<dd>Subversion interface: <a
href="http://svn.whatwg.org/">http://svn.whatwg.org/</a>
+ <dd>HTML diff with the last version in Subversion: <a
+ href=index-diff>http://whatwg.org/specs/web-apps/current-work/index-diff</a>
+
<dt>Editor:
<dd>Ian Hickson, Google, ian at hixie.ch
@@ -1151,61 +1157,42 @@
<li><a href="#the-storage"><span class=secno>4.10.2. </span>The
<code>Storage</code> interface</a>
- <li><a href="#the-storageitem"><span class=secno>4.10.3. </span>The
- <code>StorageItem</code> interface</a>
-
- <li><a href="#the-sessionstorage"><span class=secno>4.10.4. </span>The
+ <li><a href="#the-sessionstorage"><span class=secno>4.10.3. </span>The
<code title=dom-sessionStorage>sessionStorage</code> attribute</a>
- <li><a href="#the-globalstorage"><span class=secno>4.10.5. </span>The
+ <li><a href="#the-globalstorage"><span class=secno>4.10.4. </span>The
<code title=dom-globalStorage>globalStorage</code> attribute</a>
- <li><a href="#the-storage0"><span class=secno>4.10.6. </span>The <code
+ <li><a href="#the-storage0"><span class=secno>4.10.5. </span>The <code
title=event-storage>storage</code> event</a>
- <li><a href="#miscellaneous0"><span class=secno>4.10.7.
+ <li><a href="#miscellaneous0"><span class=secno>4.10.6.
</span>Miscellaneous implementation requirements for storage
areas</a>
<ul class=toc>
- <li><a href="#disk-space"><span class=secno>4.10.7.1. </span>Disk
+ <li><a href="#disk-space"><span class=secno>4.10.6.1. </span>Disk
space</a>
- <li><a href="#threads0"><span class=secno>4.10.7.2.
+ <li><a href="#threads0"><span class=secno>4.10.6.2.
</span>Threads</a>
</ul>
- <li><a href="#security5"><span class=secno>4.10.8. </span>Security and
+ <li><a href="#security5"><span class=secno>4.10.7. </span>Security and
privacy</a>
<ul class=toc>
- <li><a href="#user-tracking"><span class=secno>4.10.8.1. </span>User
+ <li><a href="#user-tracking"><span class=secno>4.10.7.1. </span>User
tracking</a>
- <li><a href="#cookie"><span class=secno>4.10.8.2. </span>Cookie
+ <li><a href="#cookie"><span class=secno>4.10.7.2. </span>Cookie
resurrection</a>
- <li><a href="#integrity"><span class=secno>4.10.8.3.
- </span>Integrity of "public" storage areas</a>
-
- <li><a href="#cross-protocol"><span class=secno>4.10.8.4.
- </span>Cross-protocol and cross-port attacks</a>
-
- <li><a href="#dns-spoofing"><span class=secno>4.10.8.5. </span>DNS
+ <li><a href="#dns-spoofing"><span class=secno>4.10.7.3. </span>DNS
spoofing attacks</a>
- <li><a href="#cross-directory"><span class=secno>4.10.8.6.
+ <li><a href="#cross-directory"><span class=secno>4.10.7.4.
</span>Cross-directory attacks</a>
- <li><a href="#public"><span class=secno>4.10.8.7. </span>Public
- storage areas corresponding to hosts</a>
-
- <li><a href="#storage0"><span class=secno>4.10.8.8. </span>Storage
- areas in the face of untrusted higher-level domains that do not
- correspond to public storage areas</a>
-
- <li><a href="#storage1"><span class=secno>4.10.8.9. </span>Storage
- areas in the face of untrusted subdomains</a>
-
- <li><a href="#implementation"><span class=secno>4.10.8.10.
+ <li><a href="#implementation"><span class=secno>4.10.7.5.
</span>Implementation risks</a>
</ul>
</ul>
@@ -24804,8 +24791,8 @@
// the user agent
readonly attribute <a href="#clientinformation">ClientInformation</a> <a href="#navigator" title=dom-navigator>navigator</a>; <!-- XXX IE6 also has window.clientInformation pointing to this same object -->
- readonly attribute <a href="#storage2">Storage</a> <a href="#sessionstorage" title=dom-sessionStorage>sessionStorage</a>;
- readonly attribute <a href="#storagelist">StorageList</a> <a href="#globalstorage" title=dom-globalStorage>globalStorage</a>;
+ readonly attribute <a href="#storage0">Storage</a> <a href="#sessionstorage" title=dom-sessionStorage>sessionStorage</a>;
+ readonly attribute <a href="#storage0">Storage</a> <a href="#globalstorage" title=dom-globalStorage>globalStorage</a>;
<a href="#database0">Database</a> <a href="#opendatabase" title=dom-opendatabase>openDatabase</a>(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize);
// modal user prompts
@@ -29573,7 +29560,7 @@
title=dom-sessionStorage><a
href="#sessionstorage">sessionStorage</a></code> DOM attribute. Sites can
add data to the session storage, and it will be accessible to any page
- from that domain opened in that window.
+ from that <a href="#origin0">origin</a> opened in that window.
<div class=example>
<p>For example, a page could have a checkbox that the user ticks to
@@ -29617,7 +29604,7 @@
<p>The <code title=dom-globalStorage><a
href="#globalstorage">globalStorage</a></code> DOM attribute is used to
- access the global storage areas.
+ access a page's global storage area.
<div class=example>
<p>The site at example.com can display a count of how many times the user
@@ -29629,80 +29616,55 @@
time(s).
</p>
<script>
- var storage = globalStorage['example.com'];
- if (!storage.pageLoadCount)
- storage.pageLoadCount = 0;
- storage.pageLoadCount = parseInt(storage.pageLoadCount, 10) + 1;
- document.getElementById('count').textContent = storage.pageLoadCount;
+ if (!globalStorage.pageLoadCount)
+ globalStorage.pageLoadCount = 0;
+ globalStorage.pageLoadCount = parseInt(globalStorage.pageLoadCount, 10) + 1;
+ document.getElementById('count').textContent = globalStorage.pageLoadCount;
</script></pre>
</div>
- <p>Each domain and each subdomain has its own separate storage area.
- Subdomains can access the storage areas of parent domains, and domains can
- access the storage areas of subdomains.
+ <p>Each <a href="#origin0">origin</a> has its own separate storage area.
- <ul class=brief>
- <li><code>globalStorage['']</code> is accessible to all domains.
-
- <li><code>globalStorage['com']</code> is accessible to all .com domains
-
- <li><code>globalStorage['example.com']</code> is accessible to example.com
- and any of its subdomains
-
- <li><code>globalStorage['www.example.com']</code> is accessible to
- www.example.com and example.com, but not www2.example.com.
- </ul>
-
<p>Storage areas (both session storage and global storage) store strings.
To store structured data in a storage area, you must first convert it to a
string.
<h4 id=the-storage><span class=secno>4.10.2. </span>The <code><a
- href="#storage2">Storage</a></code> interface</h4>
+ href="#storage0">Storage</a></code> interface</h4>
<pre class=idl>
-interface <dfn id=storage2>Storage</dfn> {
+interface <dfn id=storage0>Storage</dfn> {
readonly attribute unsigned long <a href="#length8" title=dom-Storage-length>length</a>;
DOMString <a href="#keyn" title=dom-Storage-key>key</a>(in unsigned long index);
- <a href="#storageitem">StorageItem</a> <a href="#getitem" title=dom-Storage-getItem>getItem</a>(in DOMString key);
+ DOMString <a href="#getitem" title=dom-Storage-getItem>getItem</a>(in DOMString key);
void <a href="#setitem" title=dom-Storage-setItem>setItem</a>(in DOMString key, in DOMString data);
void <a href="#removeitem" title=dom-Storage-removeItem>removeItem</a>(in DOMString key);
};</pre>
- <p>Each <code><a href="#storage2">Storage</a></code> object provides access
- to a list of key/value pairs, which are sometimes called items. Keys are
- strings, and any string (including the empty string) is a valid key.
- Values are strings with associated metadata, represented by <code><a
- href="#storageitem">StorageItem</a></code> objects.
+ <p>Each <code><a href="#storage0">Storage</a></code> object provides access
+ to a list of key/value pairs, which are sometimes called items. Keys and
+ values are strings. Any string (including the empty string) is a valid
+ key.
- <p>Each <code><a href="#storage2">Storage</a></code> object is associated
+ <p class=note>To store more structured data, authors may consider using the
+ <a href="#sql">SQL interfaces</a> instead.
+
+ <p>Each <code><a href="#storage0">Storage</a></code> object is associated
with a list of key/value pairs when it is created, as defined in the
sections on the <code title=dom-sessionStorage><a
href="#sessionstorage">sessionStorage</a></code> and <code
title=dom-globalStorage><a href="#globalstorage">globalStorage</a></code>
attributes. Multiple separate objects implementing the <code><a
- href="#storage2">Storage</a></code> interface can all be associated with
+ href="#storage0">Storage</a></code> interface can all be associated with
the same list of key/value pairs simultaneously.
- <p>Key/value pairs have associated metadata. In particular, a key/value
- pair can be marked as either "safe only for secure content", or as "safe
- for both secure and insecure content".
-
- <p>A key/value pair is <dfn id=accessible title="accessible
- keys">accessible</dfn> if either it is marked as "safe for both secure and
- insecure content", or it is marked as "safe only for secure content" and
- the script in question is running in a <span>secure browsing
- context</span><!-- XXX xref -->.
-
<p>The <dfn id=length8 title=dom-Storage-length><code>length</code></dfn>
- attribute must return the number of key/value pairs currently present and
- <a href="#accessible" title="accessible keys">accessible</a> in the list
- associated with the object.
+ attribute must return the number of key/value pairs currently present in
+ the list associated with the object.
<p>The <dfn id=keyn title=dom-Storage-key><code>key(<var
title="">n</var>)</code></dfn> method must return the name of the <var
- title="">n</var>th <a href="#accessible" title="accessible
- keys">accessible</a> key in the list. The order of keys is user-agent
+ title="">n</var>th key in the list. The order of keys is user-agent
defined, but must be consistent within an object between changes to the
number of keys. (Thus, <a href="#setitem"
title=dom-Storage-setItem>adding</a> or <a href="#removeitem"
@@ -29717,18 +29679,10 @@
<code>INDEX_SIZE_ERR</code> exception.
<p>The <dfn id=getitem title=dom-Storage-getItem><code>getItem(<var
- title="">key</var>)</code></dfn> method must return the <code><a
- href="#storageitem">StorageItem</a></code> object representing the
- key/value pair with the given <var title="">key</var>. If the given <var
- title="">key</var> does not exist in the list associated with the object,
- or is not <a href="#accessible" title="accessible keys">accessible</a>,
- then this method must return null. Subsequent calls to this method with
- the same key from scripts running in the same <span>security
- context</span> must return the same instance of the <code><a
- href="#storageitem">StorageItem</a></code> interface. (Such instances must
- not be shared across security contexts, though.)</p>
- <!-- XXX define
- security context -->
+ title="">key</var>)</code></dfn> method must return the current value
+ associated with the given <var title="">key</var>. If the given <var
+ title="">key</var> does not exist in the list associated with the object
+ then this method must return null.
<p>The <dfn id=setitem title=dom-Storage-setItem><code>setItem(<var
title="">key</var>, <var title="">value</var>)</code></dfn> method must
@@ -29736,31 +29690,17 @@
already exists in the list associated with the object.
<p>If it does not, then a new key/value pair must be added to the list,
- with the given <var title="">key</var> and <var title="">value</var>, such
- that any current or future <code><a
- href="#storageitem">StorageItem</a></code> objects referring to this
- key/value pair will return the value given in the <var
- title="">value</var> argument. If the script setting the value is running
- in a <span>secure browsing context</span>, then the key/value pair must be
- marked as "safe only for secure content", otherwise it must be marked as
- "safe for both secure and insecure content".
+ with the given <var title="">key</var> and <var title="">value</var>.
<p>If the given <var title="">key</var> <em>does</em> exist in the list,
- then, if the key/value pair with the given <var title="">key</var> is <a
- href="#accessible" title="accessible keys">accessible</a>, it must have
- its value updated so that any current or future <code><a
- href="#storageitem">StorageItem</a></code> objects referring to this
- key/value pair will return the value given in the <var
- title="">value</var> argument. If it is <em>not</em> <a href="#accessible"
- title="accessible keys">accessible</a>, the method must raise a <a
- href="#security8">security exception</a>.
+ then it must have its value updated to the value given in the <var
+ title="">value</var> argument.
<p>When the <code title=dom-Storage-setItem><a
- href="#setitem">setItem()</a></code> method is successfully invoked (i.e.
- when it doesn't raise an exception), events are fired on other <code><a
- href="#htmldocument">HTMLDocument</a></code> objects that can access the
- newly stored data, as defined in the sections on the <code
- title=dom-sessionStorage><a
+ href="#setitem">setItem()</a></code> method is invoked, events are fired
+ on other <code><a href="#htmldocument">HTMLDocument</a></code> objects
+ that can access the newly stored data, as defined in the sections on the
+ <code title=dom-sessionStorage><a
href="#sessionstorage">sessionStorage</a></code> and <code
title=dom-globalStorage><a href="#globalstorage">globalStorage</a></code>
attributes.</p>
@@ -29772,11 +29712,8 @@
title=dom-Storage-removeItem><code>removeItem(<var
title="">key</var>)</code></dfn> method must cause the key/value pair with
the given <var title="">key</var> to be removed from the list associated
- with the object, if it exists and is <a href="#accessible"
- title="accessible keys">accessible</a>. If no item with that key exists,
- the method must do nothing. If an item with that key exists but is not <a
- href="#accessible" title="accessible keys">accessible</a>, the method must
- raise a <a href="#security8">security exception</a>.
+ with the object, if it exists. If no item with that key exists, the method
+ must do nothing.
<p>The <code title=dom-Storage-setItem><a
href="#setitem">setItem()</a></code> and <code
@@ -29786,14 +29723,13 @@
not be changed at all.
<p>In the ECMAScript DOM binding, enumerating a <code><a
- href="#storage2">Storage</a></code> object must enumerate through the
- currently stored and <a href="#accessible" title="accessible
- keys">accessible</a> keys in the list the object is associated with. (It
- must not enumerate the values or the actual members of the interface). In
- the ECMAScript DOM binding, <code><a href="#storage2">Storage</a></code>
+ href="#storage0">Storage</a></code> object must enumerate through the
+ currently stored keys in the list the object is associated with. (It must
+ not enumerate the values or the actual members of the interface). In the
+ ECMAScript DOM binding, <code><a href="#storage0">Storage</a></code>
objects must support dereferencing such that getting a property that is
not a member of the object (i.e. is neither a member of the <code><a
- href="#storage2">Storage</a></code> interface nor of <code
+ href="#storage0">Storage</a></code> interface nor of <code
title=dom-Object>Object</code>) must invoke the <code
title=dom-Storage-getItem><a href="#getitem">getItem()</a></code> method
with the property's name as the argument, and setting such a property must
@@ -29801,83 +29737,17 @@
href="#setitem">setItem()</a></code> method with the property's name as
the first argument and the given value as the second argument.
- <h4 id=the-storageitem><span class=secno>4.10.3. </span>The <code><a
- href="#storageitem">StorageItem</a></code> interface</h4>
-
- <p>Items in <code><a href="#storage2">Storage</a></code> objects are
- represented by objects implementing the <code><a
- href="#storageitem">StorageItem</a></code> interface.
-
- <pre class=idl>
-interface <dfn id=storageitem>StorageItem</dfn> {
- attribute boolean <a href="#secure" title=dom-StorageItem-secure>secure</a>;
- attribute DOMString <a href="#value7" title=dom-StorageItem-value>value</a>;
-};</pre>
-
- <p>In the ECMAScript DOM binding, <code><a
- href="#storageitem">StorageItem</a></code> objects must stringify to their
- <code title=dom-StorageItem-value><a href="#value7">value</a></code>
- attribute's value.
-
- <p>The <dfn id=value7 title=dom-StorageItem-value><code>value</code></dfn>
- attribute must return the current value of the key/value pair represented
- by the object. When the attribute is set, the user agent must invoke the
- <code title=dom-Storage-setItem><a href="#setitem">setItem()</a></code>
- method of the <code><a href="#storage2">Storage</a></code> object that the
- <code><a href="#storageitem">StorageItem</a></code> object is associated
- with, with the key that the <code><a
- href="#storageitem">StorageItem</a></code> object is associated with as
- the first argument, and the new given value of the attribute as the second
- argument.
-
- <p><code><a href="#storageitem">StorageItem</a></code> objects must be
- <em><a href="#live">live</a></em>, meaning that as the underlying <code><a
- href="#storage2">Storage</a></code> object has its key/value pairs
- updated, the <code><a href="#storageitem">StorageItem</a></code> objects
- must always return the actual value of the key/value pair they represent.
-
- <p>If the key/value pair has been deleted, the <code><a
- href="#storageitem">StorageItem</a></code> object must act as if its value
- was the empty string. On setting, the key/value pair will be recreated.
-
- <p>The <dfn id=secure
- title=dom-StorageItem-secure><code>secure</code></dfn> attribute must
- raise an <code>INVALID_ACCESS_ERR</code> exception when accessed or set
- from a script whose browsing context is not <span title="secure browsing
- context">considered secure</span><!--
- XXX xref -->. (Basically, if the
- page is not an SSL page.)
-
- <p>If the browsing context <em>is</em> secure, then the <code
- title=dom-StorageItem-secure><a href="#secure">secure</a></code> attribute
- must return true if the key/value pair is considered "safe only for secure
- content", and false if it is considered "safe for both secure and insecure
- content". If it is set to true, then the key/value pair must be flagged as
- "safe only for secure content". If it is set to false, then the key/value
- pair must be flagged as "safe for both secure and insecure content".
-
- <p>If a <code><a href="#storageitem">StorageItem</a></code> object is
- obtained by a script that is not running in a <span>secure browsing
- context</span>, and the item is then marked with the "safe only for secure
- content" flag by a script that <em>is</em> running in a secure context,
- the <code><a href="#storageitem">StorageItem</a></code> object must
- continue to be available to the first script, who will be able to read the
- value of the object. However, any attempt to <em>set</em> the value would
- then start raising exceptions as described in the previous section, and
- the key/value pair would no longer appear in the appropriate <code><a
- href="#storage2">Storage</a></code> object.
-
- <h4 id=the-sessionstorage><span class=secno>4.10.4. </span>The <code
+ <h4 id=the-sessionstorage><span class=secno>4.10.3. </span>The <code
title=dom-sessionStorage><a
href="#sessionstorage">sessionStorage</a></code> attribute</h4>
<p>The <dfn id=sessionstorage
title=dom-sessionStorage><code>sessionStorage</code></dfn> attribute
- represents the storage area specific to the current <a
+ represents the set of storage areas specific to the current <a
href="#top-level">top-level browsing context</a>.
<p>Each <a href="#top-level">top-level browsing context</a> has a unique
- set of session storage areas, one for each domain.
+ set of session storage areas, one for each <a href="#origin0">origin</a>.
<p>User agents should not expire data from a browsing context's session
storage areas, but may do so when the user requests that such data be
@@ -29896,14 +29766,15 @@
<p>When a new <code><a href="#htmldocument">HTMLDocument</a></code> is
created, the user agent must check to see if the document's <a
href="#top-level">top-level browsing context</a> has allocated a session
- storage area for that <a href="#domain0">document's domain</a>. If it has
- not, a new storage area for that document's domain must be created.
+ storage area for that document's <a href="#origin0">origin</a>. If it has
+ not, a new storage area for that document's origin must be created.
- <p>The <code><a href="#storage2">Storage</a></code> object for the
+ <p>The <code><a href="#storage0">Storage</a></code> object for the
document's associated <code><a href="#window">Window</a></code> object's
<code title=dom-sessionStorage><a
href="#sessionstorage">sessionStorage</a></code> attribute must then be
- associated with the domain's session storage area.
+ associated with that <a href="#origin0">origin</a>'s session storage area
+ for that <a href="#top-level">top-level browsing context</a>.
<p>When a new <a href="#top-level">top-level browsing context</a> is
created by cloning an existing <a href="#browsing0">browsing context</a>,
@@ -29917,54 +29788,40 @@
context, or in some other way related to a specific <code><a
href="#htmldocument">HTMLDocument</a></code>, then, if the new context's
first <code><a href="#htmldocument">HTMLDocument</a></code> has the same
- <a href="#domain0" title="document's domain">domain</a> as the <code><a
+ <a href="#origin0">origin</a> as the <code><a
href="#htmldocument">HTMLDocument</a></code> from which the new context
was created, the new browsing context must start with a single session
- storage area. That storage area must be a copy of that domain's session
- storage area in the original browsing context, which from that point on
- must be considered separate, with the two storage areas not affecting each
- other in any way.</p>
+ storage area. That storage area must be a copy of that origin's session
+ storage area in the original top-level browsing context, which from that
+ point on must be considered separate, with the two storage areas not
+ affecting each other in any way.</p>
<!-- XXX define the case for window.open() -->
<p id=sessionStorageEvent>When the <code title=dom-Storage-setItem><a
href="#setitem">setItem()</a></code> method is called on a <code><a
- href="#storage2">Storage</a></code> object <var title="">x</var> that is
- associated with a session storage area, then, if the method does not raise
- a <a href="#security8">security exception</a>, in every <code><a
+ href="#storage0">Storage</a></code> object <var title="">x</var> that is
+ associated with a session storage area, then in every <code><a
href="#htmldocument">HTMLDocument</a></code> object whose <code><a
href="#window">Window</a></code> object's <code
title=dom-sessionStorage><a
href="#sessionstorage">sessionStorage</a></code> attribute's <code><a
- href="#storage2">Storage</a></code> object is associated with the same
+ href="#storage0">Storage</a></code> object is associated with the same
storage area, other than <var title="">x</var>, a <code
- title=event-storage><a href="#storage3">storage</a></code> event must be
- fired, as <a href="#storage3" title=event-storage>described below</a>.
+ title=event-storage><a href="#storage1">storage</a></code> event must be
+ fired, as <a href="#storage1" title=event-storage>described below</a>.
- <h4 id=the-globalstorage><span class=secno>4.10.5. </span>The <code
+ <h4 id=the-globalstorage><span class=secno>4.10.4. </span>The <code
title=dom-globalStorage><a href="#globalstorage">globalStorage</a></code>
attribute</h4>
- <pre class=idl>interface <dfn id=storagelist>StorageList</dfn> {
- <a href="#storage2">Storage</a> <a href="#nameditem2" title=dom-Storagelist-namedItem>namedItem</a>(in DOMString domain);
-};</pre>
-
<p>The <dfn id=globalstorage
title=dom-globalStorage><code>globalStorage</code></dfn> object provides a
- <code><a href="#storage2">Storage</a></code> object for each domain.
+ <code><a href="#storage0">Storage</a></code> object for <a
+ href="#origin0">origin</a>.
- <p>In the ECMAScript DOM binding, <code><a
- href="#storagelist">StorageList</a></code> objects must support
- dereferencing such that getting a property that is not a member of the
- object (i.e. is neither a member of the <code><a
- href="#storagelist">StorageList</a></code> interface nor of <code
- title=dom-Object>Object</code>) must invoke the <code
- title=dom-Storagelist-namedItem><a
- href="#nameditem2">namedItem()</a></code> method with the property's name
- as the argument.
+ <p>User agents must have a set of global storage areas, one for each <a
+ href="#origin0">origin</a>.
- <p>User agents must have a set of global storage areas, one for each
- domain.
-
<p>User agents should only expire data from the global storage areas for
security reasons or when requested to do so by the user. User agents
should always avoid deleting data while a script that could access that
@@ -29972,209 +29829,74 @@
potentially user-critical. It is expected that Web applications will use
the global storage areas for storing user-written documents.
- <p>The <dfn id=nameditem2
- title=dom-Storagelist-namedItem><code>namedItem(<var
- title="">domain</var>)</code></dfn> method tries to returns a <code><a
- href="#storage2">Storage</a></code> object associated with the given
- domain, according to the rules that follow.
+ <p>When the <code title=dom-globalStorage><a
+ href="#globalstorage">globalStorage</a></code> attribute is accessed, the
+ user agent must check to see if it has allocated global storage area for
+ the <a href="#origin0">origin</a> of the <a href="#browsing0">browsing
+ context</a> within which the script is running. If it has not, a new
+ storage area for that origin must be created.
- <div id=splitDomain>
- <p>The <var title="">domain</var> must first be split into an array of
- strings, by splitting the string at "." characters (U+002E FULL STOP). If
- the <var title="">domain</var> argument is the empty string, then the
- array is empty as well. If the <var title="">domain</var> argument is not
- empty but has no dots, then the array has one item, which is equal to the
- <var title="">domain</var> argument. If the <var title="">domain</var>
- argument contains consecutive dots, there will be empty strings in the
- array (e.g. the string "hello..world" becomes split into the three
- strings "hello", "", and "world", with the middle one being the empty
- string).</p>
-
- <p>Each component of the array must then have the IDNA ToASCII algorithm
- applied to it, with both the AllowUnassigned and UseSTD3ASCIIRules flags
- set. <a href="#refsRFC3490">[RFC3490]</a> If ToASCII fails to convert one
- of the components of the string, e.g. because it is too long or because
- it contains invalid characters, then the user agent must raise a
- <code>SYNTAX_ERR</code> exception. <a href="#refsDOM3CORE">[DOM3CORE]</a>
- The components after this step consist of only US-ASCII characters.</p>
-
- <p>The components of the array must then be converted to lowercase. Since
- only US-ASCII is involved at this step, this only requires converting
- characters in the range A-Z to the corresponding characters in the range
- a-z.</p>
- </div>
-
- <p>The resulting array is used in a comparison with another array, as
- described below. In addition, its components are concatenated together,
- each part separated by a dot (U+002E), to form the <dfn
- id=normalised0>normalised requested domain</dfn>.
-
- <p class=example>If the original <var title="">domain</var> was
- "Åsgård.Example.Com", then the resulting array would have the
- three items "xn--sgrd-poac", "example", and "com", and the normalised
- requested domain would be "xn--sgrd-poac.example.com".
-
- <p>Next, the domain part of the tuple forming the calling script's <a
- href="#origin0">origin</a> is processed to find if it is allowed to access
- the requested domain.
-
- <p>If the script's origin has no domain part, e.g. if only the server's IP
- address is known, and the <a href="#normalised0">normalised requested
- domain</a> is not the empty string, then the user agent must raise a <a
- href="#security8">security exception</a>.
-
- <p class=note>If the <a href="#normalised0">normalised requested domain</a>
- is the empty string, then the rest of this algorithm can be skipped. This
- is because in that situation, the comparison of the two arrays below will
- always find them to be the same — the first array in such a
- situation is also empty and so permission to access that storage area will
- always be given.
-
- <p>If the domain part of the script's origin contains no dots (U+002E) then
- the string "<code>.localdomain</code>" must be appended to the script's
- domain.
-
- <p>Then, the domain part of the script's origin must be turned into an
- array, being split, converted to ASCII, and lowercased as described for
- the <var title="">domain</var> argument <a href="#splitDomain">above</a>.
-
- <p>Of the two arrays, the longest one must then be shortened to the length
- of the shorter one, by dropping items from the start of the array.
-
- <div class=example>
- <p>If the <var title="">domain</var> argument is "www.example.com" and the
- script origin's domain part is "example.com" then the first array will be
- a three item array ("www", "example", "com"), and the second will be a
- two item array ("example", "com"). The first array is therefore
- shortened, dropping the leading parts, making both into the same array
- ("example", "com").</p>
- </div>
-
- <p>If the two arrays are not component-for-component identical in literal
- string comparisons, then the user agent must then raise a <a
- href="#security8">security exception</a>.
-
- <p>Otherwise, the user agent must check to see if it has allocated global
- storage area for the <a href="#normalised0">normalised requested
- domain</a>. If it has not, a new storage area for that domain must be
- created.
-
<p>The user agent must then create a <code><a
- href="#storage2">Storage</a></code> object associated with that domain's
+ href="#storage0">Storage</a></code> object associated with that origin's
global storage area, and return it.
- <p>When the requested <var title="">domain</var> is a top level domain, or
- the empty string, or a country-specific sub-domain like "co.uk" or
- "ca.us", the associated global storage area is known as <dfn
- id=public0>public storage area</dfn>
+ <p id=globalStorageEvent>When the <code title=dom-Storage-setItem><a
+ href="#setitem">setItem()</a></code> method is called on a <code><a
+ href="#storage0">Storage</a></code> object <var title="">x</var> that is
+ associated with a global storage area, then in every <code><a
+ href="#htmldocument">HTMLDocument</a></code> object whose <code><a
+ href="#window">Window</a></code> object's <code title=dom-globalStorage><a
+ href="#globalstorage">globalStorage</a></code> attribute's <code><a
+ href="#storage0">Storage</a></code> object is associated with the same
+ storage area, other than <var title="">x</var>, a <code
+ title=event-storage><a href="#storage1">storage</a></code> event must be
+ fired, as <a href="#storage1" title=event-storage>described below</a>.
- <div id=globalStorageEvent>
- <p>The <code title=dom-Storage-setItem><a
- href="#setitem">setItem()</a></code> method might be called on a <code><a
- href="#storage2">Storage</a></code> object that is associated with a
- global storage area for a domain <var title="">d</var>, created by a
- <code><a href="#storagelist">StorageList</a></code> object associated
- with a <code><a href="#window">Window</a></code> object <var
- title="">x</var>. Whenever this occurs, if the method didn't raise an
- exception, a <code title=event-storage><a
- href="#storage3">storage</a></code> event must be fired, as described
- below, in every <code><a href="#htmldocument">HTMLDocument</a></code>
- object that matches the following conditions:</p>
+ <h4 id=the-storage0><span class=secno>4.10.5. </span>The <code
+ title=event-storage><a href="#storage1">storage</a></code> event</h4>
- <ul>
- <li>Its <code><a href="#window">Window</a></code> object is not <var
- title="">x</var>, and
-
- <li>Its <code><a href="#window">Window</a></code> object's <code
- title=dom-sessionStorage><a
- href="#sessionstorage">globalStorage</a></code> attribute's <code><a
- href="#storagelist">StorageList</a></code> object's <code
- title=dom-Storagelist-namedItem><a
- href="#nameditem2">namedItem()</a></code> method would not raise a <a
- href="#security8">security exception</a> according to the rules above if
- it was invoked with the domain <var title="">d</var>.
- </ul>
-
- <p>In other words, every other document that has access to that domain's
- global storage area is notified of the change.</p>
- </div>
-
- <h4 id=the-storage0><span class=secno>4.10.6. </span>The <code
- title=event-storage><a href="#storage3">storage</a></code> event</h4>
-
- <p>The <dfn id=storage3 title=event-storage><code>storage</code></dfn>
+ <p>The <dfn id=storage1 title=event-storage><code>storage</code></dfn>
event is fired in an <code><a href="#htmldocument">HTMLDocument</a></code>
when a storage area changes, as described in the previous two sections (<a
href="#sessionStorageEvent">for session storage</a>, <a
href="#globalStorageEvent">for global storage</a>).
- <p>When this happens, a <code><a href="#storage2">storage</a></code> event
- in no namespace, which bubbles, is not cancelable, has no default action,
- and which uses the <code><a href="#storageevent">StorageEvent</a></code>
- interface described below, must be fired on <a href="#the-body0">the body
- element</a>.
+ <p>When this happens, the user agent must <a href="#firing2">fire a simple
+ event</a> called <code><a href="#storage0">storage</a></code> on <a
+ href="#the-body0">the body element</a>.
<p>However, it is possible (indeed, for session storage areas, likely) that
- the target <code><a href="#htmldocument">HTMLDocument</a></code> object is
- not active at that time. For example, it might not be the <a
- href="#current0">current entry</a> in the session history; user agents
- typically stop scripts from running in pages that are in the history. In
- such cases, the user agent must instead delay the firing of the event
- until such time as the <code><a
- href="#htmldocument">HTMLDocument</a></code> object in question becomes
- active again.
+ the target's <code><a href="#htmldocument">HTMLDocument</a></code> object
+ is not an <a href="#active">active document</a> at that time. In such
+ cases, the user agent must instead delay the firing of the event until
+ such time as the <code><a href="#htmldocument">HTMLDocument</a></code>
+ object in question becomes an <a href="#active">active document</a> again.
<p>When there are multiple delayed <code><a
- href="#storage2">storage</a></code> events for the same <code><a
- href="#htmldocument">HTMLDocument</a></code> object, user agents should
- coalesce events with the same <code title=dom-Storageevent-domain><a
- href="#domain1">domain</a></code> value (dropping duplicates).
+ href="#storage0">storage</a></code> events for the same <code><a
+ href="#htmldocument">HTMLDocument</a></code> object, user agents must
+ coalesce those events such that only one event fires when the document
+ becomes active again.
<p>If the DOM of a page that has delayed <code><a
- href="#storage2">storage</a></code> events queued up is <a href="#discard"
- title=discard>discarded</a>, then the delayed events are dropped as well.
-
- <pre class=idl>interface <dfn id=storageevent>StorageEvent</dfn> : Event {
- readonly attribute DOMString <a href="#domain1" title=dom-StorageEvent-domain>domain</a>;
- void <a href="#initstorageevent" title=dom-StorageEvent-initStorageEvent>initStorageEvent</a>(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString domainArg);
- void <a href="#initstorageeventns" title=dom-StorageEvent-initStorageEventNS>initStorageEventNS</a>(in DOMString namespaceURIArg, in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString domainArg);
-};</pre>
-
- <p>The <dfn id=initstorageevent
- title=dom-StorageEvent-initStorageEvent><code>initStorageEvent()</code></dfn>
- and <dfn id=initstorageeventns
- title=dom-StorageEvent-initStorageEventNS><code>initStorageEventNS()</code></dfn>
- methods must initialise the event in a manner analogous to the
- similarly-named methods in the DOM3 Events interfaces. <a
- href="#refsDOM3EVENTS">[DOM3EVENTS]</a>
-
- <p>The <dfn id=domain1
- title=dom-StorageEvent-domain><code>domain</code></dfn> attribute of the
- <code><a href="#storageevent">StorageEvent</a></code> event object must be
- set to the name of the domain associated with the storage area that
- changed if that storage area is a global storage area, or the string
- "<code>#session</code>" if it was a session storage area.</p>
+ href="#storage0">storage</a></code> events queued up is <a href="#discard"
+ title=discard>discarded</a>, then the delayed events are dropped as well.</p>
<!-- XXX onstorage should be defined -->
- <h4 id=miscellaneous0><span class=secno>4.10.7. </span>Miscellaneous
+ <h4 id=miscellaneous0><span class=secno>4.10.6. </span>Miscellaneous
implementation requirements for storage areas</h4>
- <h5 id=disk-space><span class=secno>4.10.7.1. </span>Disk space</h5>
+ <h5 id=disk-space><span class=secno>4.10.6.1. </span>Disk space</h5>
- <p>User agents should limit the total amount of space allowed for a domain
- based on the domain of the page setting the value.
+ <p>User agents should limit the total amount of space allowed for a storage
+ area based on the domain of the page setting the value.
<p>User agents should not limit the total amount of space allowed on a
per-storage-area basis, otherwise a site could just store data in any
- number of subdomains, e.g. storing up to the limit in a1.example.com,
- a2.example.com, a3.example.com, etc, circumventing per-domain limits.
+ number of subdomains or ports, e.g. storing up to the limit in
+ a1.example.com, a2.example.com, a3.example.com, etc, circumventing
+ per-domain limits.
- <p>User agents should consider additional quota mechanisms (for example
- limiting the amount of space provided to a domain's subdomains as a group)
- so that hostile authors can't run scripts from multiple subdomains all
- adding data to the global storage area in an attempted denial-of-service
- attack.
-
<p>User agents may prompt the user when per-domain space quotas are
reached, allowing the user to grant a site more space. This enables sites
to store many user-created documents on the user's computer, for instance.
@@ -30191,7 +29913,7 @@
Implementation feedback is welcome and will be used to update this
suggestion in future.
- <h5 id=threads0><span class=secno>4.10.7.2. </span>Threads</h5>
+ <h5 id=threads0><span class=secno>4.10.6.2. </span>Threads</h5>
<p>Multiple browsing contexts must be able to access the global storage
areas simultaneously in a predictable manner. Scripts must not be able to
@@ -30199,41 +29921,35 @@
<p>This is required to guarentee that the <code title=dom-Storage-length><a
href="#length8">length</a></code> attribute of a <code><a
- href="#storage2">Storage</a></code> object never changes while a script is
+ href="#storage0">Storage</a></code> object never changes while a script is
executing, other than in a way that is predictable by the script itself.
<p>There are various ways of implementing this requirement. One is that if
a script running in one browsing context accesses a global storage area,
the UA blocks scripts in other browsing contexts when they try to access
- <em>any</em> global storage area until the first script has executed to
- completion. (Similarly, when a script in one browsing context accesses its
- session storage area, any scripts that have the same top level browsing
- context and the same domain would block when accessing their session
- storage area until the first script has executed to completion.) Another
- (potentially more efficient but probably more complex) implementation
- strategy is to use optimistic transactional script execution. This
- specification does not require any particular implementation strategy, so
- long as the requirement above is met.
+ the global storage area for the same origin until the first script has
+ executed to completion. (Similarly, when a script in one browsing context
+ accesses its session storage area, any scripts that have the same top
+ level browsing context and the same origin would block when accessing
+ their session storage area until the first script has executed to
+ completion.) Another (potentially more efficient but probably more
+ complex) implementation strategy is to use optimistic transactional script
+ execution. This specification does not require any particular
+ implementation strategy, so long as the requirement above is met.
- <h4 id=security5><span class=secno>4.10.8. </span>Security and privacy</h4>
+ <h4 id=security5><span class=secno>4.10.7. </span>Security and privacy</h4>
- <h5 id=user-tracking><span class=secno>4.10.8.1. </span>User tracking</h5>
+ <h5 id=user-tracking><span class=secno>4.10.7.1. </span>User tracking</h5>
<p>A third-party advertiser (or any entity capable of getting content
distributed to multiple sites) could use a unique identifier stored in its
- domain's global storage area to track a user across multiple sessions,
- building a profile of the user's interests to allow for highly targeted
- advertising. In conjunction with a site that is aware of the user's real
- identity (for example an e-commerce site that requires authenticated
- credentials), this could allow oppressive groups to target individuals
- with greater accuracy than in a world with purely anonymous Web usage.
+ global storage area to track a user across multiple sessions, building a
+ profile of the user's interests to allow for highly targeted advertising.
+ In conjunction with a site that is aware of the user's real identity (for
+ example an e-commerce site that requires authenticated credentials), this
+ could allow oppressive groups to target individuals with greater accuracy
+ than in a world with purely anonymous Web usage.
- <p>The <code title=dom-globalStorage><a
- href="#globalstorage">globalStorage</a></code> object also introduces a
- way for sites to cooperate to track users over multiple domains, by
- storing identifying data in "<a href="#public0" title="public storage
- area">public</a>" top-level domain storage area, accessible by any domain.
-
<p>There are a number of techniques that can be used to mitigate the risk
of user tracking:
@@ -30245,56 +29961,26 @@
originating at the domain of the top-level document of the <a
href="#browsing0">browsing context</a>.</p>
- <p>This blocks a third-party site from using its private storage area for
- tracking a user, but top-level sites could still cooperate with third
- parties to perferm user tracking by using the "<a href="#public0"
- title="public storage area">public</a>" storage area.</p>
-
<li>
<p>Expiring stored data: user agents may automatically delete stored data
after a period of time.</p>
- <p>For example, a user agent could treat the global storage area as
- session-only storage, deleting the data once the user had closed all the
- <span>browsing contexts</span> that could access it.</p>
+ <p>For example, a user agent could treat third-party global storage areas
+ as session-only storage, deleting the data once the user had closed all
+ the <span>browsing contexts</span> that could access it.</p>
<p>This can restrict the ability of a site to track a user, as the site
would then only be able to track the user across multiple sessions when
he authenticates with the site itself (e.g. by making a purchase or
logging in to a service).</p>
+
+ <p>However, this also puts the user's data at risk.</p>
<!-- XXX should there be an explicit way for sites to state when
data should expire? as in
- globalStorage['example.com'].expireData(365); ? -->
+ globalStorage.expireData(365); ? -->
<li>
- <p>Blocking access to the top-level domain ("<a href="#public0"
- title="public storage area">public</a>") storage areas: user agents may
- prevent domains from storing data in and reading data from the top-level
- domain entries in the <code title=dom-globalStorage><a
- href="#globalstorage">globalStorage</a></code> object.</p>
-
- <p>In practice this requires a detailed list of all the "public"
- second-level (and third-level) domains. For example, content at the
- domain <code>www.example.com</code> would be allowed to access
- <code>example.com</code> data but not <code>com</code> data; content at
- the domain <code>example.co.uk</code> would be allowed access to
- <code>example.co.uk</code> but not <code>co.uk</code> or
- <code>uk</code>; and content at <code>example.chiyoda.tokyo.jp</code>
- would be allowed access to <code>example.chiyoda.tokyo.jp</code> but not
- <code>chiyoda.tokyo.jp</code>, <code>tokyo.jp</code>, or
- <code>jp</code>, while content at <code>example.metro.tokyo.jp</code>
- would be allowed access to both <code>example.metro.tokyo.jp</code> and
- <code>metro.tokyo.jp</code> but not <code>tokyo.jp</code> or
- <code>jp</code>. The problem is even more convoluted when one considers
- private domains with third-party subdomains such as
- <code>dyndns.org</code> or <code>uk.com</code>.</p>
-
- <p>Blocking access to the "<a href="#public0" title="public storage
- area">public</a>" storage areas can also prevent innocent sites from
- cooperating to provide services beneficial to the user.</p>
-
- <li>
<p>Treating persistent storage as cookies: user agents may present the
persistent storage feature to the user in a way that does not
distinguish it from HTTP session cookies. <a
@@ -30304,21 +29990,15 @@
suspicion.</p>
<li>
- <p>Site-specific white-listing of access to "<a href="#public0"
- title="public storage area">public</a>" storage area: user agents may
- allow sites to access persistent storage for their own domain and
- subdomains in an unrestricted manner, but require the user to authorise
- access to the storage area of higher-level domains.</p>
+ <p>Site-specific white-listing of access to global storage areas: user
+ agents may allow sites to access session storage areas in an
+ unrestricted manner, but require the user to authorise access to global
+ storage areas.</p>
- <p>For example, code at <code>example.com</code> would be always allowed
- to read and write data for <code>www.example.com</code> and
- <code>example.com</code>, but if it tried to access <code>com</code>,
- the user agent could display a non-modal message informing the user that
- the page requested access to <code>com</code> and offering to allow it.</p>
-
<li>
<p>Origin-tracking of persistent storage data: user agents may record the
- domain of the script that caused data to be stored.</p>
+ origins of sites that contained content from third-party origins that
+ caused data to be stored.</p>
<p>If this information is then used to present the view of data currently
in persistent storage, it would allow the user to make informed
@@ -30336,11 +30016,11 @@
<p>While these suggestions prevent trivial use of this API for user
tracking, they do not block it altogether. Within a single domain, a site
- can continue to track the user across multiple sessions, and can then pass
- all this information to the third party along with any identifying
- information (names, credit card numbers, addresses) obtained by the site.
- If a third party cooperates with multiple sites to obtain such
- information, a profile can still be created.
+ can continue to track the user during a session, and can then pass all
+ this information to the third party along with any identifying information
+ (names, credit card numbers, addresses) obtained by the site. If a third
+ party cooperates with multiple sites to obtain such information, a profile
+ can still be created.
<p>However, user tracking is to some extent possible even with no
cooperation from the user agent whatsoever, for instance by using session
@@ -30351,7 +30031,7 @@
headers and configuration settings) to combine separate sessions into
coherent user profiles.
- <h5 id=cookie><span class=secno>4.10.8.2. </span>Cookie resurrection</h5>
+ <h5 id=cookie><span class=secno>4.10.7.2. </span>Cookie resurrection</h5>
<p>If the user interface for persistent storage presents data in the
persistent storage feature separately from data in HTTP session cookies,
@@ -30359,75 +30039,15 @@
allow sites to use the two features as redundant backup for each other,
defeating a user's attempts to protect his privacy.
- <h5 id=integrity><span class=secno>4.10.8.3. </span>Integrity of "public"
- storage areas</h5>
+ <h5 id=dns-spoofing><span class=secno>4.10.7.3. </span>DNS spoofing attacks</h5>
- <p>Since the "<a href="#public0" title="public storage area">public</a>"
- global storage areas are accessible by content from many different
- parties, it is possible for third-party sites to delete or change
- information stored in those areas in ways that the originating sites may
- not expect.
-
- <p>Authors must not use the "<a href="#public0" title="public storage
- area">public</a>" global storage areas for storing sensitive data. Authors
- must not trust information stored in "<a href="#public0" title="public
- storage area">public</a>" global storage areas.
-
- <h5 id=cross-protocol><span class=secno>4.10.8.4. </span>Cross-protocol and
- cross-port attacks</h5>
-
- <p>This API makes no distinction between content served over HTTP, FTP, or
- other host-based protocols, and does not distinguish between content
- served from different ports at the same host.
-
- <p>Thus, for example, data stored in the global persistent storage for
- domain "www.example.com" by a page served from HTTP port 80 will be
- available to a page served in <code>http://example.com:18080/</code>, even
- if the latter is an experimental server under the control of a different
- user.
-
- <p>Since the data is not sent over the wire by the user agent, this is not
- a security risk in its own right. However, authors must take proper steps
- to ensure that all hosts that have fully qualified host names that are
- subsets of hosts dealing with sensitive information are as secure as the
- originating hosts themselves.
-
- <p>Similarly, authors must ensure that all Web servers on a host,
- regardless of the port, are equally trusted if any of them are to use
- persistent storage. For instance, if a Web server runs a production
- service that makes use of the persistent storage feature, then other users
- that have access to that machine and that can run a Web server on another
- port will be able to access the persistent storage added by the production
- service (assuming they can trick a user into visiting their page).
-
- <p>However, if one is able to trick users into visiting a Web server with
- the same host name but on a different port as a production service used by
- these users, then one could just as easily fake the look of the site and
- thus trick users into authenticating with the fake site directly,
- forwarding the request to the real site and stealing the credentials in
- the process. Thus, the persistent storage feature is considered to only
- minimally increase the risk involved.
-
- <p class=big-issue>What about if someone is able to get a server up on a
- port, and can then send people to that URI? They could steal all the data
- with no further interaction. How about putting the port number at the end
- of the string being compared? (Implicitly.)
-
- <h5 id=dns-spoofing><span class=secno>4.10.8.5. </span>DNS spoofing attacks</h5>
-
<p>Because of the potential for DNS spoofing attacks, one cannot guarentee
that a host claiming to be in a certain domain really is from that domain.
- The <code title=dom-StorageItem-secure><a href="#secure">secure</a></code>
- attribute is provided to mark certain key/value pairs as only being
- accessible to pages that have been authenticated using secure certificates
- (or similar mechanisms).
+ To mitigate this, pages can use SSL. Pages using SSL can be sure that only
+ pages using SSL that have certificates identifying them as being from the
+ same domain can access their global storage areas.
- <p>Authors must ensure that they do not mark sensitive items as "safe for
- both secure and insecure content". (To prevent the risk of a race
- condition, data stored by scripts in secure contexts default to being
- marked as "safe only for secure content".)
-
- <h5 id=cross-directory><span class=secno>4.10.8.6. </span>Cross-directory
+ <h5 id=cross-directory><span class=secno>4.10.7.4. </span>Cross-directory
attacks</h5>
<p>Different authors sharing one host name, for example users hosting
@@ -30441,47 +30061,7 @@
usual DOM scripting security model would make it trivial to bypass this
protection and access the data from any path.
- <h5 id=public><span class=secno>4.10.8.7. </span>Public storage areas
- corresponding to hosts</h5>
-
- <p>If a "<a href="#public0" title="public storage area">public</a>" global
- storage area corresponds to a host, as it typically does if for private
- domains with third-party subdomains such as dyndns.org or uk.com, the host
- corresponding to the "public" domain has access to all the storage areas
- of its third-party subdomains. In general, authors are discouraged from
- using the <code title=dom-globalStorage><a
- href="#globalstorage">globalStorage</a></code> API for sensitive data
- unless the operators of all the domains involved are trusted.
-
- <p>User agents may mitigate this problem by preventing hosts corresponding
- to "<a href="#public0" title="public storage area">public</a>" global
- storage areas from accessing any storage areas other than their own.
-
- <h5 id=storage0><span class=secno>4.10.8.8. </span>Storage areas in the
- face of untrusted higher-level domains that do not correspond to public
- storage areas</h5>
-
- <p>Authors should not store sensitive data using the global storage APIs if
- there are hosts with fully-qualified domain names that are subsets of
- their own which they do not trust. For example, an author at
- <code>finance.members.example.net</code> should not store sensitive
- financial user data in the <code>finance.members.example.net</code>
- storage area if he does not trust the host that runs
- <code>example.net</code>.
-
- <h5 id=storage1><span class=secno>4.10.8.9. </span>Storage areas in the
- face of untrusted subdomains</h5>
-
- <p>If an author publishing content on one host, e.g.
- <code>example.com</code>, wishes to use the <code
- title=dom-globalStorage><a href="#globalstorage">globalStorage</a></code>
- API but does not wish any content on the host's subdomains to access the
- data, the author should use an otherwise non-existent subdomain name,
- e.g., <code>private.example.com</code>, to store the data. This will be
- accessible only to that host (and its parent domains), and not to any of
- the real subdomains (e.g. <code>upload.example.com</code>).
-
- <h5 id=implementation><span class=secno>4.10.8.10. </span>Implementation
+ <h5 id=implementation><span class=secno>4.10.7.5. </span>Implementation
risks</h5>
<p>The two primary risks when implementing this persistent storage feature
@@ -30502,25 +30082,9 @@
known ID that the hostile site can then use to track the user's actions on
the victim site.
- <p>A risk is also presented by servers on local domains having host names
- matching top-level domain names, for instance having a host called "com"
- or "net". Such hosts might, if implementations fail to correctly implement
- the <code>.localdomain</code> suffixing, <!-- XXX cross ref --> have full
- access to all the data stored in a UA's persistent storage for that top
- level domain.
-
<p>Thus, strictly following the model described in this specification is
important for user security.
- <p>In addition, a number of optional restrictions related to the "<a
- href="#public0" title="public storage area">public</a>" global storage
- areas are suggested in the previous sections. The design of this API is
- intended to be such that not supporting these restrictions, or supporting
- them less than perfectly, does not result in critical security problems.
- However, implementations are still encouraged to create and maintain a
- list of "<a href="#public0" title="public storage area">public</a>"
- domains, and apply the restrictions described above.
-
<h3 id=sql><span class=secno>4.11. </span>Client-side database storage</h3>
<!-- Feature requests for future versions (v2):
* deleting databases
@@ -34816,7 +34380,7 @@
<pre class=idl>interface <dfn id=messageevent>MessageEvent</dfn> : Event {
readonly attribute DOMString <a href="#data4" title=dom-MessageEvent-data>data</a>;
- readonly attribute DOMString <a href="#domain2" title=dom-MessageEvent-domain>domain</a>;
+ readonly attribute DOMString <a href="#domain1" title=dom-MessageEvent-domain>domain</a>;
readonly attribute DOMString <a href="#uri" title=dom-MessageEvent-uri>uri</a>;
readonly attribute <a href="#window">Window</a> <a href="#source1" title=dom-MessageEvent-source>source</a>;
void <a href="#initmessageevent" title=dom-MessageEvent-initMessageEvent>initMessageEvent</a>(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString dataArg, in DOMString domainArg, in DOMString uriArg, in Window sourceArg);
@@ -34834,7 +34398,7 @@
<p>The <dfn id=data4 title=dom-MessageEvent-data><code>data</code></dfn>
attribute represents the message being sent.
- <p>The <dfn id=domain2
+ <p>The <dfn id=domain1
title=dom-MessageEvent-domain><code>domain</code></dfn> attribute
represents, in <a href="#cross-document">cross-document messaging</a>, the
domain of the document from which the message came.
@@ -36287,7 +35851,7 @@
the <var title="">message</var> argument to the <code
title=dom-window-postMessage><a
href="#postmessage">postMessage()</a></code> method, the <code
- title=dom-MessageEvent-domain><a href="#domain2">domain</a></code>
+ title=dom-MessageEvent-domain><a href="#domain1">domain</a></code>
attribute must be set to the domain of the document that the script that
invoked the methods is associated with, the <code
title=dom-MessageEvent-uri><a href="#uri">uri</a></code> attribute must be
@@ -36311,7 +35875,7 @@
and event listeners have been executed as appropriate).
<p class=warning>Authors should check the <code
- title=dom-MessageEvent-domain><a href="#domain2">domain</a></code>
+ title=dom-MessageEvent-domain><a href="#domain1">domain</a></code>
attribute to ensure that messages are only accepted from domains that they
expect to receive messages from. Otherwise, bugs in the author's message
handling code could be exploited by hostile sites.
@@ -47077,5 +46641,3 @@
0x12 ('foo')
-->
- <script src="http://status.whatwg.org/annotate-web-apps.js"
- type="text/javascript"></script>
Modified: source
===================================================================
--- source 2007-12-05 05:48:38 UTC (rev 1139)
+++ source 2007-12-11 01:14:16 UTC (rev 1140)
@@ -22340,7 +22340,7 @@
// the user agent
readonly attribute <span>ClientInformation</span> <span title="dom-navigator">navigator</span>; <!-- XXX IE6 also has window.clientInformation pointing to this same object -->
readonly attribute <span>Storage</span> <span title="dom-sessionStorage">sessionStorage</span>;
- readonly attribute <span>StorageList</span> <span title="dom-globalStorage">globalStorage</span>;
+ readonly attribute <span>Storage</span> <span title="dom-globalStorage">globalStorage</span>;
<span>Database</span> <span title="dom-opendatabase">openDatabase</span>(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize);
// modal user prompts
@@ -27103,7 +27103,7 @@
<p>To address this, this specification introduces the <code
title="dom-sessionStorage">sessionStorage</code> DOM attribute.
Sites can add data to the session storage, and it will be accessible
- to any page from that domain opened in that window.</p>
+ to any page from that <span>origin</span> opened in that window.</p>
<div class="example">
@@ -27149,7 +27149,7 @@
transmitted with every request.</p>
<p>The <code title="dom-globalStorage">globalStorage</code> DOM
- attribute is used to access the global storage areas.</p>
+ attribute is used to access a page's global storage area.</p>
<div class="example">
@@ -27163,26 +27163,16 @@
time(s).
</p>
<script>
- var storage = globalStorage['example.com'];
- if (!storage.pageLoadCount)
- storage.pageLoadCount = 0;
- storage.pageLoadCount = parseInt(storage.pageLoadCount, 10) + 1;
- document.getElementById('count').textContent = storage.pageLoadCount;
+ if (!globalStorage.pageLoadCount)
+ globalStorage.pageLoadCount = 0;
+ globalStorage.pageLoadCount = parseInt(globalStorage.pageLoadCount, 10) + 1;
+ document.getElementById('count').textContent = globalStorage.pageLoadCount;
</script></pre>
</div>
- <p>Each domain and each subdomain has its own separate storage area.
- Subdomains can access the storage areas of parent domains, and
- domains can access the storage areas of subdomains.</p>
+ <p>Each <span>origin</span> has its own separate storage area.</p>
- <ul class="brief">
- <li><code>globalStorage['']</code> is accessible to all domains.</li>
- <li><code>globalStorage['com']</code> is accessible to all .com domains</li>
- <li><code>globalStorage['example.com']</code> is accessible to example.com and any of its subdomains</li>
- <li><code>globalStorage['www.example.com']</code> is accessible to www.example.com and example.com, but not www2.example.com.</li>
- </ul>
-
<p>Storage areas (both session storage and global storage) store
strings. To store structured data in a storage area, you must first
convert it to a string.</p>
@@ -27194,17 +27184,19 @@
interface <dfn>Storage</dfn> {
readonly attribute unsigned long <span title="dom-Storage-length">length</span>;
DOMString <span title="dom-Storage-key">key</span>(in unsigned long index);
- <span>StorageItem</span> <span title="dom-Storage-getItem">getItem</span>(in DOMString key);
+ DOMString <span title="dom-Storage-getItem">getItem</span>(in DOMString key);
void <span title="dom-Storage-setItem">setItem</span>(in DOMString key, in DOMString data);
void <span title="dom-Storage-removeItem">removeItem</span>(in DOMString key);
};</pre>
<p>Each <code>Storage</code> object provides access to a list of
- key/value pairs, which are sometimes called items. Keys are strings,
- and any string (including the empty string) is a valid key. Values
- are strings with associated metadata, represented by
- <code>StorageItem</code> objects.</p>
+ key/value pairs, which are sometimes called items. Keys and values
+ are strings. Any string (including the empty string) is a valid
+ key.</p>
+ <p class="note">To store more structured data, authors may consider
+ using the <a href="#sql">SQL interfaces</a> instead.</p>
+
<p>Each <code>Storage</code> object is associated with a list of
key/value pairs when it is created, as defined in the sections on
the <code title="dom-sessionStorage">sessionStorage</code> and <code
@@ -27213,25 +27205,13 @@
all be associated with the same list of key/value pairs
simultaneously.</p>
- <p>Key/value pairs have associated metadata. In particular, a
- key/value pair can be marked as either "safe only for secure
- content", or as "safe for both secure and insecure content".</p>
-
- <p>A key/value pair is <dfn title="accessible keys">accessible</dfn>
- if either it is marked as "safe for both secure and insecure
- content", or it is marked as "safe only for secure content" and the
- script in question is running in a <span>secure browsing
- context</span><!-- XXX xref -->.</p>
-
<p>The <dfn title="dom-Storage-length"><code>length</code></dfn>
attribute must return the number of key/value pairs currently
- present and <span title="accessible keys">accessible</span> in the
- list associated with the object.</p>
+ present in the list associated with the object.</p>
<p>The <dfn title="dom-Storage-key"><code>key(<var
title="">n</var>)</code></dfn> method must return the name of the
- <var title="">n</var>th <span title="accessible
- keys">accessible</span> key in the list. The order of keys is
+ <var title="">n</var>th key in the list. The order of keys is
user-agent defined, but must be consistent within an object between
changes to the number of keys. (Thus, <span
title="dom-Storage-setItem">adding</span> or <span
@@ -27245,17 +27225,10 @@
method must raise an <code>INDEX_SIZE_ERR</code> exception.</p>
<p>The <dfn title="dom-Storage-getItem"><code>getItem(<var
- title="">key</var>)</code></dfn> method must return the
- <code>StorageItem</code> object representing the key/value pair with
- the given <var title="">key</var>. If the given <var
- title="">key</var> does not exist in the list associated with the
- object, or is not <span title="accessible keys">accessible</span>,
- then this method must return null. Subsequent calls to this method
- with the same key from scripts running in the same <span>security
- context</span> must return the same instance of the
- <code>StorageItem</code> interface. (Such instances must not be
- shared across security contexts, though.)</p> <!-- XXX define
- security context -->
+ title="">key</var>)</code></dfn> method must return the current
+ value associated with the given <var title="">key</var>. If the
+ given <var title="">key</var> does not exist in the list associated
+ with the object then this method must return null.</p>
<p>The <dfn title="dom-Storage-setItem"><code>setItem(<var
title="">key</var>, <var title="">value</var>)</code></dfn> method
@@ -27265,29 +27238,16 @@
<p>If it does not, then a new key/value pair must be added to the
list, with the given <var title="">key</var> and <var
- title="">value</var>, such that any current or future
- <code>StorageItem</code> objects referring to this key/value pair
- will return the value given in the <var title="">value</var>
- argument. If the script setting the value is running in a
- <span>secure browsing context</span>, then the key/value pair must
- be marked as "safe only for secure content", otherwise it must be
- marked as "safe for both secure and insecure content".</p>
+ title="">value</var>.</p>
<p>If the given <var title="">key</var> <em>does</em> exist in the
- list, then, if the key/value pair with the given <var
- title="">key</var> is <span title="accessible
- keys">accessible</span>, it must have its value updated so that any
- current or future <code>StorageItem</code> objects referring to this
- key/value pair will return the value given in the <var
- title="">value</var> argument. If it is <em>not</em> <span
- title="accessible keys">accessible</span>, the method must raise a
- <span>security exception</span>.</p>
+ list, then it must have its value updated to the value given in the
+ <var title="">value</var> argument.</p>
<p>When the <code title="dom-Storage-setItem">setItem()</code>
- method is successfully invoked (i.e. when it doesn't raise an
- exception), events are fired on other <code>HTMLDocument</code>
- objects that can access the newly stored data, as defined in the
- sections on the <code
+ method is invoked, events are fired on other
+ <code>HTMLDocument</code> objects that can access the newly stored
+ data, as defined in the sections on the <code
title="dom-sessionStorage">sessionStorage</code> and <code
title="dom-globalStorage">globalStorage</code> attributes.</p> <!--
not normative, see the sections below for the normative statement
@@ -27296,11 +27256,8 @@
<p>The <dfn title="dom-Storage-removeItem"><code>removeItem(<var
title="">key</var>)</code></dfn> method must cause the key/value
pair with the given <var title="">key</var> to be removed from the
- list associated with the object, if it exists and is <span
- title="accessible keys">accessible</span>. If no item with that key
- exists, the method must do nothing. If an item with that key exists
- but is not <span title="accessible keys">accessible</span>, the
- method must raise a <span>security exception</span>.</p>
+ list associated with the object, if it exists. If no item with that
+ key exists, the method must do nothing.</p>
<p>The <code title="dom-Storage-setItem">setItem()</code> and <code
title="dom-Storage-removeItem">removeItem()</code> methods must be
@@ -27309,10 +27266,9 @@
changed at all.</p>
<p>In the ECMAScript DOM binding, enumerating a <code>Storage</code>
- object must enumerate through the currently stored and <span
- title="accessible keys">accessible</span> keys in the list the
- object is associated with. (It must not enumerate the values or the
- actual members of the interface). In the ECMAScript DOM binding,
+ object must enumerate through the currently stored keys in the list
+ the object is associated with. (It must not enumerate the values or
+ the actual members of the interface). In the ECMAScript DOM binding,
<code>Storage</code> objects must support dereferencing such that
getting a property that is not a member of the object (i.e. is
neither a member of the <code>Storage</code> interface nor of <code
@@ -27324,76 +27280,15 @@
as the second argument.</p>
- <h4>The <code>StorageItem</code> interface</h4>
-
- <p>Items in <code>Storage</code> objects are represented by objects
- implementing the <code>StorageItem</code> interface.</p>
-
- <pre class="idl">
-interface <dfn>StorageItem</dfn> {
- attribute boolean <span title="dom-StorageItem-secure">secure</span>;
- attribute DOMString <span title="dom-StorageItem-value">value</span>;
-};</pre>
-
- <p>In the ECMAScript DOM binding, <code>StorageItem</code> objects must
- stringify to their <code title="dom-StorageItem-value">value</code>
- attribute's value.</p>
-
- <p>The <dfn title="dom-StorageItem-value"><code>value</code></dfn>
- attribute must return the current value of the key/value pair
- represented by the object. When the attribute is set, the user agent
- must invoke the <code title="dom-Storage-setItem">setItem()</code>
- method of the <code>Storage</code> object that the
- <code>StorageItem</code> object is associated with, with the key
- that the <code>StorageItem</code> object is associated with as the
- first argument, and the new given value of the attribute as the
- second argument.</p>
-
- <p><code>StorageItem</code> objects must be <em>live</em>, meaning
- that as the underlying <code>Storage</code> object has its key/value
- pairs updated, the <code>StorageItem</code> objects must always
- return the actual value of the key/value pair they represent.</p>
-
- <p>If the key/value pair has been deleted, the
- <code>StorageItem</code> object must act as if its value was the
- empty string. On setting, the key/value pair will be recreated.</p>
-
- <p>The <dfn title="dom-StorageItem-secure"><code>secure</code></dfn>
- attribute must raise an <code>INVALID_ACCESS_ERR</code> exception
- when accessed or set from a script whose browsing context is not
- <span title="secure browsing context">considered secure</span><!--
- XXX xref -->. (Basically, if the page is not an SSL page.)</p>
-
- <p>If the browsing context <em>is</em> secure, then the <code
- title="dom-StorageItem-secure">secure</code> attribute must return
- true if the key/value pair is considered "safe only for secure
- content", and false if it is considered "safe for both secure and
- insecure content". If it is set to true, then the key/value pair
- must be flagged as "safe only for secure content". If it is set to
- false, then the key/value pair must be flagged as "safe for both
- secure and insecure content".</p>
-
- <p>If a <code>StorageItem</code> object is obtained by a script that
- is not running in a <span>secure browsing context</span>, and the
- item is then marked with the "safe only for secure content" flag by
- a script that <em>is</em> running in a secure context, the
- <code>StorageItem</code> object must continue to be available to the
- first script, who will be able to read the value of the
- object. However, any attempt to <em>set</em> the value would then
- start raising exceptions as described in the previous section, and
- the key/value pair would no longer appear in the appropriate
- <code>Storage</code> object.</p>
-
-
<h4>The <code title="dom-sessionStorage">sessionStorage</code> attribute</h4>
<p>The <dfn
title="dom-sessionStorage"><code>sessionStorage</code></dfn>
- attribute represents the storage area specific to the current
- <span>top-level browsing context</span>.</p>
+ attribute represents the set of storage areas specific to the
+ current <span>top-level browsing context</span>.</p>
<p>Each <span>top-level browsing context</span> has a unique set of
- session storage areas, one for each domain.</p>
+ session storage areas, one for each <span>origin</span>.</p>
<p>User agents should not expire data from a browsing context's
session storage areas, but may do so when the user requests that
@@ -27413,13 +27308,14 @@
<p>When a new <code>HTMLDocument</code> is created, the user agent
must check to see if the document's <span>top-level browsing
context</span> has allocated a session storage area for that
- <span>document's domain</span>. If it has not, a new storage area
- for that document's domain must be created.</p>
+ document's <span>origin</span>. If it has not, a new storage area
+ for that document's origin must be created.</p>
<p>The <code>Storage</code> object for the document's associated
<code>Window</code> object's <code
title="dom-sessionStorage">sessionStorage</code> attribute must then
- be associated with the domain's session storage area.</p>
+ be associated with that <span>origin</span>'s session storage area
+ for that <span>top-level browsing context</span>.</p>
<p>When a new <span>top-level browsing context</span> is created by
cloning an existing <span>browsing context</span>, the new browsing
@@ -27430,23 +27326,22 @@
<p>When a new <span>top-level browsing context</span> is created by
a script in an existing <span>browsing context</span>, or by the
user following a link in an existing browsing context, or in some
- other way related to a specific <code>HTMLDocument</code>, then,
- if the new context's first <code>HTMLDocument</code> has the same
- <span title="document's domain">domain</span> as the
- <code>HTMLDocument</code> from which the new context was created,
- the new browsing context must start with a single session storage
- area. That storage area must be a copy of that domain's session
- storage area in the original browsing context, which from that point
- on must be considered separate, with the two storage areas not
- affecting each other in any way.</p>
+ other way related to a specific <code>HTMLDocument</code>, then, if
+ the new context's first <code>HTMLDocument</code> has the same
+ <span>origin</span> as the <code>HTMLDocument</code> from which the
+ new context was created, the new browsing context must start with a
+ single session storage area. That storage area must be a copy of
+ that origin's session storage area in the original top-level
+ browsing context, which from that point on must be considered
+ separate, with the two storage areas not affecting each other in any
+ way.</p>
<!-- XXX define the case for window.open() -->
<p id="sessionStorageEvent">When the <code
title="dom-Storage-setItem">setItem()</code> method is called on a
<code>Storage</code> object <var title="">x</var> that is associated
- with a session storage area, then, if the method does not raise a
- <span>security exception</span>, in every <code>HTMLDocument</code>
+ with a session storage area, then in every <code>HTMLDocument</code>
object whose <code>Window</code> object's <code
title="dom-sessionStorage">sessionStorage</code> attribute's
<code>Storage</code> object is associated with the same storage
@@ -27457,24 +27352,12 @@
<h4>The <code title="dom-globalStorage">globalStorage</code> attribute</h4>
- <pre class="idl">interface <dfn>StorageList</dfn> {
- <span>Storage</span> <span title="dom-Storagelist-namedItem">namedItem</span>(in DOMString domain);
-};</pre>
-
<p>The <dfn
- title="dom-globalStorage"><code>globalStorage</code></dfn>
- object provides a <code>Storage</code> object for each domain.</p>
+ title="dom-globalStorage"><code>globalStorage</code></dfn> object
+ provides a <code>Storage</code> object for <span>origin</span>.</p>
- <p>In the ECMAScript DOM binding, <code>StorageList</code> objects
- must support dereferencing such that getting a property that is not
- a member of the object (i.e. is neither a member of the
- <code>StorageList</code> interface nor of <code
- title="dom-Object">Object</code>) must invoke the <code
- title="dom-Storagelist-namedItem">namedItem()</code> method with the
- property's name as the argument.</p>
-
<p>User agents must have a set of global storage areas, one for each
- domain.</p>
+ <span>origin</span>.</p>
<p>User agents should only expire data from the global storage areas
for security reasons or when requested to do so by the user. User
@@ -27484,144 +27367,28 @@
Web applications will use the global storage areas for storing
user-written documents.</p>
- <p>The <dfn title="dom-Storagelist-namedItem"><code>namedItem(<var
- title="">domain</var>)</code></dfn> method tries to returns a
- <code>Storage</code> object associated with the given domain,
- according to the rules that follow.</p>
+ <p>When the <code title="dom-globalStorage">globalStorage</code>
+ attribute is accessed, the user agent must check to see if it has
+ allocated global storage area for the <span>origin</span> of the
+ <span>browsing context</span> within which the script is running. If
+ it has not, a new storage area for that origin must be created.</p>
- <div id="splitDomain">
-
- <p>The <var title="">domain</var> must first be split into an array
- of strings, by splitting the string at "." characters (U+002E FULL
- STOP). If the <var title="">domain</var> argument is the empty
- string, then the array is empty as well. If the <var
- title="">domain</var> argument is not empty but has no dots, then
- the array has one item, which is equal to the <var
- title="">domain</var> argument. If the <var title="">domain</var>
- argument contains consecutive dots, there will be empty strings in
- the array (e.g. the string "hello..world" becomes split into the
- three strings "hello", "", and "world", with the middle one being
- the empty string).</p>
-
- <p>Each component of the array must then have the IDNA ToASCII
- algorithm applied to it, with both the AllowUnassigned and
- UseSTD3ASCIIRules flags set. <a href="#refsRFC3490">[RFC3490]</a>
- If ToASCII fails to convert one of the components of the string,
- e.g. because it is too long or because it contains invalid
- characters, then the user agent must raise a
- <code>SYNTAX_ERR</code> exception. <a
- href="#refsDOM3CORE">[DOM3CORE]</a> The components after this step
- consist of only US-ASCII characters.</p>
-
- <p>The components of the array must then be converted to lowercase.
- Since only US-ASCII is involved at this step, this only requires
- converting characters in the range A-Z to the corresponding
- characters in the range a-z.</p>
-
- </div>
-
- <p>The resulting array is used in a comparison with another array,
- as described below. In addition, its components are concatenated
- together, each part separated by a dot (U+002E), to form the
- <dfn>normalised requested domain</dfn>.</p>
-
- <p class="example">If the original <var title="">domain</var> was
- "Åsgård.Example.Com", then the resulting array would
- have the three items "xn--sgrd-poac", "example", and "com", and the
- normalised requested domain would be
- "xn--sgrd-poac.example.com".</p>
-
- <p>Next, the domain part of the tuple forming the calling script's
- <span>origin</span> is processed to find if it is allowed to access
- the requested domain.</p>
-
- <p>If the script's origin has no domain part, e.g. if only the
- server's IP address is known, and the <span>normalised requested
- domain</span> is not the empty string, then the user agent must
- raise a <span>security exception</span>.</p>
-
- <p class="note">If the <span>normalised requested domain</span> is
- the empty string, then the rest of this algorithm can be skipped.
- This is because in that situation, the comparison of the two arrays
- below will always find them to be the same — the first array
- in such a situation is also empty and so permission to access that
- storage area will always be given.</p>
-
- <p>If the domain part of the script's origin contains no dots
- (U+002E) then the string "<code>.localdomain</code>" must be
- appended to the script's domain.</p>
-
- <p>Then, the domain part of the script's origin must be turned into
- an array, being split, converted to ASCII, and lowercased as
- described for the <var title="">domain</var> argument <a
- href="#splitDomain">above</a>.</p>
-
- <p>Of the two arrays, the longest one must then be shortened to the
- length of the shorter one, by dropping items from the start of the
- array.</p>
-
- <div class="example">
-
- <p>If the <var title="">domain</var> argument is "www.example.com"
- and the script origin's domain part is "example.com" then the first
- array will be a three item array ("www", "example", "com"), and the
- second will be a two item array ("example", "com"). The first array
- is therefore shortened, dropping the leading parts, making both
- into the same array ("example", "com").</p>
-
- </div>
-
- <p>If the two arrays are not component-for-component identical in
- literal string comparisons, then the user agent must then raise a
- <span>security exception</span>.</p>
-
- <p>Otherwise, the user agent must check to see if it has allocated
- global storage area for the <span>normalised requested
- domain</span>. If it has not, a new storage area for that domain
- must be created.</p>
-
<p>The user agent must then create a <code>Storage</code> object
- associated with that domain's global storage area, and return
+ associated with that origin's global storage area, and return
it.</p>
- <p>When the requested <var title="">domain</var> is a top level
- domain, or the empty string, or a country-specific sub-domain like
- "co.uk" or "ca.us", the associated global storage area is known as
- <dfn>public storage area</dfn></p>
+ <p id="globalStorageEvent">When the <code
+ title="dom-Storage-setItem">setItem()</code> method is called on a
+ <code>Storage</code> object <var title="">x</var> that is associated
+ with a global storage area, then in every <code>HTMLDocument</code>
+ object whose <code>Window</code> object's <code
+ title="dom-globalStorage">globalStorage</code> attribute's
+ <code>Storage</code> object is associated with the same storage
+ area, other than <var title="">x</var>, a <code
+ title="event-storage">storage</code> event must be fired, as <span
+ title="event-storage">described below</span>.</p>
- <div id="globalStorageEvent">
- <p>The <code title="dom-Storage-setItem">setItem()</code> method
- might be called on a <code>Storage</code> object that is associated
- with a global storage area for a domain <var title="">d</var>,
- created by a <code>StorageList</code> object associated with a
- <code>Window</code> object <var title="">x</var>. Whenever this
- occurs, if the method didn't raise an exception, a <code
- title="event-storage">storage</code> event must be fired, as
- described below, in every <code>HTMLDocument</code> object that
- matches the following conditions:</p>
-
- <ul>
-
- <li>Its <code>Window</code> object is not <var
- title="">x</var>, and</li>
-
- <li>Its <code>Window</code> object's <code
- title="dom-sessionStorage">globalStorage</code> attribute's
- <code>StorageList</code> object's <code
- title="dom-Storagelist-namedItem">namedItem()</code> method would
- not raise a <span>security exception</span> according to the rules
- above if it was invoked with the domain <var
- title="">d</var>.</li>
-
- </ul>
-
- <p>In other words, every other document that has access to that
- domain's global storage area is notified of the change.</p>
-
- </div>
-
-
<h4>The <code title="event-storage">storage</code> event</h4>
<p>The <dfn title="event-storage"><code>storage</code></dfn> event
@@ -27630,51 +27397,26 @@
href="#sessionStorageEvent">for session storage</a>, <a
href="#globalStorageEvent">for global storage</a>).</p>
- <p>When this happens, a <code>storage</code> event in no namespace,
- which bubbles, is not cancelable, has no default action, and which
- uses the <code>StorageEvent</code> interface described below, must
- be fired on <span>the body element</span>.</p>
+ <p>When this happens, the user agent must <span>fire a simple
+ event</span> called <code>storage</code> on <span>the body
+ element</span>.</p>
<p>However, it is possible (indeed, for session storage areas,
- likely) that the target <code>HTMLDocument</code> object is not
- active at that time. For example, it might not be the <span>current
- entry</span> in the session history; user agents typically stop
- scripts from running in pages that are in the history. In such
- cases, the user agent must instead delay the firing of the event
- until such time as the <code>HTMLDocument</code> object in
- question becomes active again.</p>
+ likely) that the target's <code>HTMLDocument</code> object is not an
+ <span>active document</span> at that time. In such cases, the user
+ agent must instead delay the firing of the event until such time as
+ the <code>HTMLDocument</code> object in question becomes an
+ <span>active document</span> again.</p>
<p>When there are multiple delayed <code>storage</code> events for
- the same <code>HTMLDocument</code> object, user agents should
- coalesce events with the same <code
- title="dom-Storageevent-domain">domain</code> value (dropping
- duplicates).</p>
+ the same <code>HTMLDocument</code> object, user agents must coalesce
+ those events such that only one event fires when the document
+ becomes active again.</p>
<p>If the DOM of a page that has delayed <code>storage</code> events
queued up is <span title="discard">discarded</span>, then the
delayed events are dropped as well.</p>
- <pre class="idl">interface <dfn>StorageEvent</dfn> : Event {
- readonly attribute DOMString <span title="dom-StorageEvent-domain">domain</span>;
- void <span title="dom-StorageEvent-initStorageEvent">initStorageEvent</span>(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString domainArg);
- void <span title="dom-StorageEvent-initStorageEventNS">initStorageEventNS</span>(in DOMString namespaceURIArg, in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString domainArg);
-};</pre>
-
- <p>The <dfn
- title="dom-StorageEvent-initStorageEvent"><code>initStorageEvent()</code></dfn>
- and <dfn
- title="dom-StorageEvent-initStorageEventNS"><code>initStorageEventNS()</code></dfn>
- methods must initialise the event in a manner analogous to the
- similarly-named methods in the DOM3 Events interfaces. <a
- href="#refsDOM3EVENTS">[DOM3EVENTS]</a></p>
-
- <p>The <dfn
- title="dom-StorageEvent-domain"><code>domain</code></dfn> attribute
- of the <code>StorageEvent</code> event object must be set to the
- name of the domain associated with the storage area that changed if
- that storage area is a global storage area, or the string
- "<code>#session</code>" if it was a session storage area.</p>
-
<!-- XXX onstorage should be defined -->
@@ -27683,20 +27425,14 @@
<h5>Disk space</h5>
<p>User agents should limit the total amount of space allowed for a
- domain based on the domain of the page setting the value.</p>
+ storage area based on the domain of the page setting the value.</p>
<p>User agents should not limit the total amount of space allowed on
a per-storage-area basis, otherwise a site could just store data in
- any number of subdomains, e.g. storing up to the limit in
+ any number of subdomains or ports, e.g. storing up to the limit in
a1.example.com, a2.example.com, a3.example.com, etc, circumventing
per-domain limits.</p>
- <p>User agents should consider additional quota mechanisms (for
- example limiting the amount of space provided to a domain's
- subdomains as a group) so that hostile authors can't run scripts
- from multiple subdomains all adding data to the global storage area
- in an attempted denial-of-service attack.</p>
-
<p>User agents may prompt the user when per-domain space quotas are
reached, allowing the user to grant a site more space. This enables
sites to store many user-created documents on the user's computer,
@@ -27729,16 +27465,17 @@
<p>There are various ways of implementing this requirement. One is
that if a script running in one browsing context accesses a global
storage area, the UA blocks scripts in other browsing contexts when
- they try to access <em>any</em> global storage area until the first
- script has executed to completion. (Similarly, when a script in one
- browsing context accesses its session storage area, any scripts that
- have the same top level browsing context and the same domain would
- block when accessing their session storage area until the first
- script has executed to completion.) Another (potentially more
- efficient but probably more complex) implementation strategy is to
- use optimistic transactional script execution. This specification
- does not require any particular implementation strategy, so long as
- the requirement above is met.</p>
+ they try to access the global storage area for the same origin until
+ the first script has executed to completion. (Similarly, when a
+ script in one browsing context accesses its session storage area,
+ any scripts that have the same top level browsing context and the
+ same origin would block when accessing their session storage area
+ until the first script has executed to completion.) Another
+ (potentially more efficient but probably more complex)
+ implementation strategy is to use optimistic transactional script
+ execution. This specification does not require any particular
+ implementation strategy, so long as the requirement above is
+ met.</p>
<h4>Security and privacy</h4>
@@ -27747,20 +27484,14 @@
<p>A third-party advertiser (or any entity capable of getting
content distributed to multiple sites) could use a unique identifier
- stored in its domain's global storage area to track a user across
- multiple sessions, building a profile of the user's interests to
- allow for highly targeted advertising. In conjunction with a site
- that is aware of the user's real identity (for example an e-commerce
- site that requires authenticated credentials), this could allow
+ stored in its global storage area to track a user across multiple
+ sessions, building a profile of the user's interests to allow for
+ highly targeted advertising. In conjunction with a site that is
+ aware of the user's real identity (for example an e-commerce site
+ that requires authenticated credentials), this could allow
oppressive groups to target individuals with greater accuracy than
in a world with purely anonymous Web usage.</p>
- <p>The <code title="dom-globalStorage">globalStorage</code> object
- also introduces a way for sites to cooperate to track users over
- multiple domains, by storing identifying data in "<span
- title="public storage area">public</span>" top-level domain storage
- area, accessible by any domain.</p>
-
<p>There are a number of techniques that can be used to mitigate the
risk of user tracking:</p>
@@ -27773,11 +27504,6 @@
to scripts originating at the domain of the top-level document of
the <span>browsing context</span>.</p>
- <p>This blocks a third-party site from using its private storage
- area for tracking a user, but top-level sites could still
- cooperate with third parties to perferm user tracking by using the
- "<span title="public storage area">public</span>" storage area.</p>
-
</li>
<li>
@@ -27785,55 +27511,26 @@
<p>Expiring stored data: user agents may automatically delete
stored data after a period of time.</p>
- <p>For example, a user agent could treat the global storage area
- as session-only storage, deleting the data once the user had
- closed all the <span>browsing contexts</span> that could access
- it.</p>
+ <p>For example, a user agent could treat third-party global
+ storage areas as session-only storage, deleting the data once the
+ user had closed all the <span>browsing contexts</span> that could
+ access it.</p>
<p>This can restrict the ability of a site to track a user, as the
site would then only be able to track the user across multiple
sessions when he authenticates with the site itself (e.g. by
making a purchase or logging in to a service).</p>
+ <p>However, this also puts the user's data at risk.</p>
+
<!-- XXX should there be an explicit way for sites to state when
data should expire? as in
- globalStorage['example.com'].expireData(365); ? -->
+ globalStorage.expireData(365); ? -->
</li>
<li>
- <p>Blocking access to the top-level domain ("<span title="public storage area">public</span>") storage
- areas: user agents may prevent domains from storing data in and
- reading data from the top-level domain entries in the <code
- title="dom-globalStorage">globalStorage</code> object.</p>
-
- <p>In practice this requires a detailed list of all the "public"
- second-level (and third-level) domains. For example, content at
- the domain <code>www.example.com</code> would be allowed to access
- <code>example.com</code> data but not <code>com</code> data;
- content at the domain <code>example.co.uk</code> would be allowed
- access to <code>example.co.uk</code> but not <code>co.uk</code> or
- <code>uk</code>; and content at
- <code>example.chiyoda.tokyo.jp</code> would be allowed access to
- <code>example.chiyoda.tokyo.jp</code> but not
- <code>chiyoda.tokyo.jp</code>, <code>tokyo.jp</code>, or
- <code>jp</code>, while content at
- <code>example.metro.tokyo.jp</code> would be allowed access to
- both <code>example.metro.tokyo.jp</code> and
- <code>metro.tokyo.jp</code> but not <code>tokyo.jp</code> or
- <code>jp</code>. The problem is even more convoluted when one
- considers private domains with third-party subdomains such as
- <code>dyndns.org</code> or <code>uk.com</code>.</p>
-
- <p>Blocking access to the "<span title="public storage area">public</span>" storage areas can also prevent
- innocent sites from cooperating to provide services beneficial to
- the user.</p>
-
- </li>
-
- <li>
-
<p>Treating persistent storage as cookies: user agents may present
the persistent storage feature to the user in a way that does not
distinguish it from HTTP session cookies. <a
@@ -27846,25 +27543,18 @@
<li>
- <p>Site-specific white-listing of access to "<span title="public storage area">public</span>" storage
- area: user agents may allow sites to access persistent storage
- for their own domain and subdomains in an unrestricted manner, but
- require the user to authorise access to the storage area of
- higher-level domains.</p>
+ <p>Site-specific white-listing of access to global storage areas:
+ user agents may allow sites to access session storage areas in an
+ unrestricted manner, but require the user to authorise access to
+ global storage areas.</p>
- <p>For example, code at <code>example.com</code> would be always
- allowed to read and write data for <code>www.example.com</code>
- and <code>example.com</code>, but if it tried to access
- <code>com</code>, the user agent could display a non-modal message
- informing the user that the page requested access to
- <code>com</code> and offering to allow it.</p>
-
</li>
<li>
<p>Origin-tracking of persistent storage data: user agents may
- record the domain of the script that caused data to be stored.</p>
+ record the origins of sites that contained content from
+ third-party origins that caused data to be stored.</p>
<p>If this information is then used to present the view of data
currently in persistent storage, it would allow the user to make
@@ -27889,11 +27579,12 @@
<p>While these suggestions prevent trivial use of this API for user
tracking, they do not block it altogether. Within a single domain, a
- site can continue to track the user across multiple sessions, and
- can then pass all this information to the third party along with any
+ site can continue to track the user during a session, and can then
+ pass all this information to the third party along with any
identifying information (names, credit card numbers, addresses)
obtained by the site. If a third party cooperates with multiple
- sites to obtain such information, a profile can still be created.</p>
+ sites to obtain such information, a profile can still be
+ created.</p>
<p>However, user tracking is to some extent possible even with no
cooperation from the user agent whatsoever, for instance by using
@@ -27904,6 +27595,7 @@
data (e.g. user-agent headers and configuration settings) to combine
separate sessions into coherent user profiles.</p>
+
<h5>Cookie resurrection</h5>
<p>If the user interface for persistent storage presents data in the
@@ -27913,72 +27605,16 @@
backup for each other, defeating a user's attempts to protect his
privacy.</p>
- <h5>Integrity of "public" storage areas</h5>
- <p>Since the "<span title="public storage area">public</span>" global storage areas are accessible by content
- from many different parties, it is possible for third-party sites to
- delete or change information stored in those areas in ways that the
- originating sites may not expect.</p>
-
- <p>Authors must not use the "<span title="public storage area">public</span>" global storage areas for
- storing sensitive data. Authors must not trust information stored in
- "<span title="public storage area">public</span>" global storage areas.</p>
-
- <h5>Cross-protocol and cross-port attacks</h5>
-
- <p>This API makes no distinction between content served over HTTP,
- FTP, or other host-based protocols, and does not distinguish between
- content served from different ports at the same host.</p>
-
- <p>Thus, for example, data stored in the global persistent storage
- for domain "www.example.com" by a page served from HTTP port 80 will
- be available to a page served in
- <code>http://example.com:18080/</code>, even if the latter is an
- experimental server under the control of a different user.</p>
-
- <p>Since the data is not sent over the wire by the user agent, this
- is not a security risk in its own right. However, authors must take
- proper steps to ensure that all hosts that have fully qualified host
- names that are subsets of hosts dealing with sensitive information
- are as secure as the originating hosts themselves.</p>
-
- <p>Similarly, authors must ensure that all Web servers on a host,
- regardless of the port, are equally trusted if any of them are to
- use persistent storage. For instance, if a Web server runs a
- production service that makes use of the persistent storage feature,
- then other users that have access to that machine and that can run a
- Web server on another port will be able to access the persistent
- storage added by the production service (assuming they can trick a
- user into visiting their page).</p>
-
- <p>However, if one is able to trick users into visiting a Web server
- with the same host name but on a different port as a production
- service used by these users, then one could just as easily fake the
- look of the site and thus trick users into authenticating with the
- fake site directly, forwarding the request to the real site and
- stealing the credentials in the process. Thus, the persistent
- storage feature is considered to only minimally increase the
- risk involved.</p>
-
- <p class="big-issue">What about if someone is able to get a server
- up on a port, and can then send people to that URI? They could steal
- all the data with no further interaction. How about putting the port
- number at the end of the string being compared? (Implicitly.)</p>
-
<h5>DNS spoofing attacks</h5>
<p>Because of the potential for DNS spoofing attacks, one cannot
guarentee that a host claiming to be in a certain domain really is
- from that domain. The <code
- title="dom-StorageItem-secure">secure</code> attribute is provided
- to mark certain key/value pairs as only being accessible to pages
- that have been authenticated using secure certificates (or similar
- mechanisms).</p>
+ from that domain. To mitigate this, pages can use SSL. Pages using
+ SSL can be sure that only pages using SSL that have certificates
+ identifying them as being from the same domain can access their
+ global storage areas.</p>
- <p>Authors must ensure that they do not mark sensitive items as
- "safe for both secure and insecure content". (To prevent the risk of
- a race condition, data stored by scripts in secure contexts default
- to being marked as "safe only for secure content".)</p>
<h5>Cross-directory attacks</h5>
@@ -27996,48 +27632,6 @@
path.</p>
- <h5>Public storage areas corresponding to hosts</h5>
-
- <p>If a "<span title="public storage area">public</span>" global
- storage area corresponds to a host, as it typically does if for
- private domains with third-party subdomains such as dyndns.org or
- uk.com, the host corresponding to the "public" domain has access to
- all the storage areas of its third-party subdomains. In general,
- authors are discouraged from using the <code
- title="dom-globalStorage">globalStorage</code> API for sensitive
- data unless the operators of all the domains involved are
- trusted.</p>
-
- <p>User agents may mitigate this problem by preventing hosts
- corresponding to "<span title="public storage area">public</span>"
- global storage areas from accessing any storage areas other than
- their own.</p>
-
-
- <h5>Storage areas in the face of untrusted higher-level domains that do not correspond to public storage areas</h5>
-
- <p>Authors should not store sensitive data using the global storage
- APIs if there are hosts with fully-qualified domain names that are
- subsets of their own which they do not trust. For example, an author
- at <code>finance.members.example.net</code> should not store
- sensitive financial user data in the
- <code>finance.members.example.net</code> storage area if he does not
- trust the host that runs <code>example.net</code>.</p>
-
-
- <h5>Storage areas in the face of untrusted subdomains</h5>
-
- <p>If an author publishing content on one host,
- e.g. <code>example.com</code>, wishes to use the <code
- title="dom-globalStorage">globalStorage</code> API but does not wish
- any content on the host's subdomains to access the data, the author
- should use an otherwise non-existent subdomain name, e.g.,
- <code>private.example.com</code>, to store the data. This will be
- accessible only to that host (and its parent domains), and not to
- any of the real subdomains
- (e.g. <code>upload.example.com</code>).</p>
-
-
<h5>Implementation risks</h5>
<p>The two primary risks when implementing this persistent storage
@@ -28059,28 +27653,11 @@
identifier to a known ID that the hostile site can then use to track
the user's actions on the victim site.</p>
- <p>A risk is also presented by servers on local domains having
- host names matching top-level domain names, for instance having a
- host called "com" or "net". Such hosts might, if implementations
- fail to correctly implement the <code>.localdomain</code> suffixing,
- <!-- XXX cross ref --> have full access to all the data stored in a
- UA's persistent storage for that top level domain.</p>
-
<p>Thus, strictly following the model described in this
specification is important for user security.</p>
- <p>In addition, a number of optional restrictions related to the
- "<span title="public storage area">public</span>" global storage
- areas are suggested in the previous sections. The design of this API
- is intended to be such that not supporting these restrictions, or
- supporting them less than perfectly, does not result in critical
- security problems. However, implementations are still encouraged to
- create and maintain a list of "<span title="public storage
- area">public</span>" domains, and apply the restrictions described
- above.</p>
-
<h3 id="sql">Client-side database storage</h3>
<!-- Feature requests for future versions (v2):
@@ -42930,6 +42507,5 @@
-->
- <script src="http://status.whatwg.org/annotate-web-apps.js" type="text/javascript"></script>
</body>
</html>
More information about the Commit-Watchers
mailing list