Skip to content

Commit

Permalink
Remove the storage mutex due to lack of implementation
Browse files Browse the repository at this point in the history
Add a stern warning for the racy document.cookies API.

Fixes #335
  • Loading branch information
foolip committed Dec 15, 2015
1 parent eff2e1b commit 6c901e5
Showing 1 changed file with 15 additions and 114 deletions.
129 changes: 15 additions & 114 deletions source
Expand Up @@ -8282,24 +8282,31 @@ partial /*sealed*/ interface <dfn>Document</dfn> {
<p id="sandboxCookies">On getting, if the document is a <span>cookie-averse <code>Document</code>
object</span>, then the user agent must return the empty string. Otherwise, if the
<code>Document</code>'s <span>origin</span> is not a scheme/host/port tuple, the user agent must
throw a <code>SecurityError</code> exception. Otherwise, the user agent must first <span>obtain
the storage mutex</span> and then return the <span>cookie-string</span> for <span>the document's address</span>
for a "non-HTTP" API, decoded using the <span>UTF-8 decoder</span>. <ref spec=COOKIES>
<!--INSERT FINGERPRINT-->
throw a <code>SecurityError</code> exception. Otherwise, the user agent must return the
<span>cookie-string</span> for <span>the document's address</span> for a "non-HTTP" API, decoded
using the <span>UTF-8 decoder</span>. <ref spec=COOKIES> <!--INSERT FINGERPRINT-->
</p>

<p>On setting, if the document is a <span>cookie-averse <code>Document</code> object</span>, then
the user agent must do nothing. Otherwise, if the <code>Document</code>'s <span>origin</span> is
not a scheme/host/port tuple, the user agent must throw a <code>SecurityError</code> exception.
Otherwise, the user agent must <span>obtain the storage mutex</span> and then act as it would when
<span data-x="receives a set-cookie-string">receiving a set-cookie-string</span> for <span>the
document's address</span> via a "non-HTTP" API, consisting of the new value encoded as UTF-8. <ref
spec=COOKIES> <ref spec=ENCODING></p>
Otherwise, the user agent must act as it would when <span data-x="receives a
set-cookie-string">receiving a set-cookie-string</span> for <span>the document's address</span>
via a "non-HTTP" API, consisting of the new value encoded as UTF-8. <ref spec=COOKIES> <ref
spec=ENCODING></p>

<p class="note">Since the <code data-x="dom-document-cookie">cookie</code> attribute is accessible
across frames, the path restrictions on cookies are only a tool to help manage which cookies are
sent to which parts of the site, and are not in any way a security feature.</p>

<p class="warning">The <code data-x="dom-document-cookie">cookie</code> attribute's getter and
setter synchronously access shared state. Since there is no locking mechanism, other browsing
contexts in a multiprocess user agent can modify cookies while scripts are running. A site could,
for instance, try to read a cookie, increment its value, then write it back out, using the new
value of the cookie as a unique identifier for the session; if the site does this twice in two
different browser windows at the same time, it might end up using the same "unique" identifier for
both sessions, with potentially disastrous effects.</p>

<hr>

</div>
Expand Down Expand Up @@ -12878,8 +12885,6 @@ people expect to have work and what is necessary.
<li><p>If the <code>meta</code> element has no <code data-x="attr-meta-content">content</code>
attribute, or if that attribute's value is the empty string, then abort these steps.</p></li>

<li><p><span>Obtain the storage mutex</span>.</p></li>

<li><p>Act as if <span data-x="receives a set-cookie-string">receiving a
set-cookie-string</span> for <span>the document's address</span> via a "non-HTTP" API,
consisting of the value of the element's <code data-x="attr-meta-content">content</code>
Expand Down Expand Up @@ -79643,8 +79648,6 @@ x === this; // true</pre>

</li>

<li><p>Release the <span>storage mutex</span>.</p></li>

<li>

<p>Set the attribute's value to <var>new value</var>.</p>
Expand Down Expand Up @@ -81438,8 +81441,6 @@ State: &lt;OUTPUT NAME=I>1&lt;/OUTPUT> &lt;INPUT VALUE="Increment" TYPE=BUTTON O

<ol>

<li><p>Release the <span>storage mutex</span>.</p></li>

<li id="sandboxLinks">

<p>If the <span>source browsing context</span> is not <span>allowed to navigate</span> the
Expand Down Expand Up @@ -83016,8 +83017,6 @@ dictionary <dfn>PageTransitionEventInit</dfn> : <span>EventInit</span> {
<li><p>Decrease the <span>event loop</span>'s <span>termination nesting level</span> by
one.</p></li>

<li><p>Release the <span>storage mutex</span>.</p></li>

<li><p>If any event listeners were triggered by the earlier <i>dispatch</i> step, then set the
<code>Document</code>'s <i data-x="concept-document-salvageable">salvageable</i> state to
false.</p></li>
Expand Down Expand Up @@ -83125,8 +83124,6 @@ dictionary <dfn>PageTransitionEventInit</dfn> : <span>EventInit</span> {
<li><p>Decrease the <span>event loop</span>'s <span>termination nesting level</span> by
one.</p></li>

<li><p>Release the <span>storage mutex</span>.</p></li>

<li><p>If any event listeners were triggered by the earlier <i>unload event</i> step, then set
the <code>Document</code> object's <i data-x="concept-document-salvageable">salvageable</i> state
to false and set the <code>Document</code>'s <span>fired unload</span> flag to true.</p></li>
Expand Down Expand Up @@ -86645,34 +86642,6 @@ dictionary <dfn>PromiseRejectionEventInit</dfn> : <span>EventInit</span> {
microtask checkpoint</dfn> flag, which must initially be false. It is used to prevent reentrant
invocation of the <span>perform a microtask checkpoint</span> algorithm.</p>

<hr>

<p>A user agent may have one <dfn>storage mutex</dfn>. This mutex is used to control access to
shared state like cookies. At any one point, the <span>storage mutex</span> is either free, or
owned by a particular <span>event loop</span> or instance of the <span
data-x="concept-fetch">fetching</span> algorithm.</p>

<p>If a user agent does not implement a <span>storage mutex</span>, it is exempt from implementing
the requirements that require it to acquire or release it.</p>

<p class="note">User agent implementors have to make a choice between two evils. On the one hand,
not implementing the storage mutex means that there is a risk of data corruption: a site could,
for instance, try to read a cookie, increment its value, then write it back out, using the new
value of the cookie as a unique identifier for the session; if the site does this twice in two
different browser windows at the same time, it might end up using the same "unique" identifier for
both sessions, with potentially disastrous effects. On the other hand, implementing the storage
mutex has potentially serious performance implications: whenever a site uses Web Storage or
cookies, all other sites that try to use Web Storage or cookies are blocked until the first site
finishes.</p>

<p class="warning">So far, all browsers faced with this decision have opted to not implement the
<span>storage mutex</span>.</p>

<p>Whenever a <span data-x="concept-script">script</span> calls into a <span>plugin</span>, and
whenever a <span>plugin</span> calls into a <span data-x="concept-script">script</span>, the user
agent must release the <span>storage mutex</span>.</p>


<h5>Processing model</h5> <!-- EVENT LOOP -->

<p>An <span>event loop</span> must continually run through the following steps for as long as it
Expand Down Expand Up @@ -86702,9 +86671,6 @@ dictionary <dfn>PromiseRejectionEventInit</dfn> : <span>EventInit</span> {
<li><p>Set the <span>event loop</span>'s <span>currently running task</span> back to
null.</p></li>

<li><p>If the <span>storage mutex</span> is now owned by the <span>event loop</span>, release it
so that it is once again free.</p></li>

<li><p>Remove the task that was run in the <i>run</i> step above from its <span>task
queue</span>.</p></li>

Expand Down Expand Up @@ -86865,9 +86831,6 @@ dictionary <dfn>PromiseRejectionEventInit</dfn> : <span>EventInit</span> {
<li><p>Set the <span>event loop</span>'s <span>currently running task</span> back to
null.</p></li>

<li><p>If the <span>storage mutex</span> is now owned by the <span>event loop</span>, release it
so that it is once again free.</p></li>

<li><p>Remove the <span>microtask</span> run in the step above from the <span>microtask
queue</span>, and return to the <i>microtask queue handling</i> step.</p></li>

Expand Down Expand Up @@ -86994,28 +86957,6 @@ dictionary <dfn>PromiseRejectionEventInit</dfn> : <span>EventInit</span> {

</ol>

<hr>

<p>When a user agent is to <dfn>obtain the storage mutex</dfn> as part of running a <span
data-x="concept-task">task</span>, it must run through the following steps:</p>

<ol>

<li><p>If the <span>storage mutex</span> is already owned by this <span
data-x="concept-task">task</span>'s <span>event loop</span>, then abort these steps.</p></li>

<li><p>Otherwise, <span>pause</span> until the <span>storage mutex</span> can be taken by the
<span>event loop</span>.</p></li>

<li><p>Take ownership of the <span>storage mutex</span>.</p></li>

</ol>

</div>


<div w-nodev>

<h5>Generic task sources</h5>

<p>The following <span data-x="task source">task sources</span> are used by a number of mostly
Expand Down Expand Up @@ -88218,8 +88159,6 @@ interface <dfn>WindowBase64</dfn> {

</li>

<li><p>Release the <span>storage mutex</span>.</p></li>

<li><p>Set the <code>Document</code>'s <i
data-x="concept-document-salvageable">salvageable</i> state to false.</p></li>

Expand Down Expand Up @@ -88952,8 +88891,6 @@ scheduleWork(); // queues a task to do lots of work</pre>
<li><p>If the <span>event loop</span>'s <span>termination nesting level</span> is non-zero,
optionally abort these steps.</p></li>

<li><p>Release the <span>storage mutex</span>.</p></li>

<li><p>If the <span>active sandboxing flag set</span> of the <span>active document</span> of
the <span>responsible browsing context</span> specified by the <span>incumbent settings
object</span> has the <span>sandboxed modals flag</span> set, then abort these
Expand Down Expand Up @@ -88982,8 +88919,6 @@ scheduleWork(); // queues a task to do lots of work</pre>
<li><p>If the <span>event loop</span>'s <span>termination nesting level</span> is non-zero,
optionally abort these steps, returning false.</p></li>

<li><p>Release the <span>storage mutex</span>.</p></li>

<li><p>If the <span>active sandboxing flag set</span> of the <span>active document</span> of
the <span>responsible browsing context</span> specified by the <span>incumbent settings
object</span> has the <span>sandboxed modals flag</span> set, then return false and abort these
Expand All @@ -89010,8 +88945,6 @@ scheduleWork(); // queues a task to do lots of work</pre>
<li><p>If the <span>event loop</span>'s <span>termination nesting level</span> is non-zero,
optionally abort these steps, returning null.</p></li>

<li><p>Release the <span>storage mutex</span>.</p></li>

<li><p>If the <span>active sandboxing flag set</span> of the <span>active document</span> of
the <span>responsible browsing context</span> specified by the <span>incumbent settings
object</span> has the <span>sandboxed modals flag</span> set, then return null and abort these
Expand Down Expand Up @@ -89104,12 +89037,6 @@ scheduleWork(); // queues a task to do lots of work</pre>

</li>

<li>

<p>The user agent must release the <span>storage mutex</span>.</p>

</li>

<li>

<p>The user agent should offer the user the opportunity to <span>obtain a physical form</span>
Expand Down Expand Up @@ -89181,12 +89108,6 @@ scheduleWork(); // queues a task to do lots of work</pre>
<li><p>If the <span>event loop</span>'s <span>termination nesting level</span> is non-zero,
optionally abort these steps, returning the empty string.</p></li>

<li>

<p>Release the <span>storage mutex</span>.</p>

</li>

<li>

<p>If the user agent is configured such that this invocation of <code
Expand Down Expand Up @@ -96607,14 +96528,6 @@ interface <dfn>WindowLocalStorage</dfn> {
<code>Window</code> object's <code data-x="dom-localStorage">localStorage</code> attribute's
<code>Storage</code> object is associated with the same storage area, other than <var>x</var>, <span>send a storage notification</span>.

<p id="localStorageMutex">Whenever the properties of a <code
data-x="dom-localStorage">localStorage</code> attribute's <code>Storage</code> object are to be
examined, returned, set, or deleted, whether as part of a direct property access, when checking
for the presence of a property, during property enumeration, when determining the number of
properties present, or as part of the execution of any of the methods or attributes defined on the
<code>Storage</code> interface, the user agent must first <span>obtain the storage
mutex</span>.</p>


<h4>The <code data-x="event-storage">storage</code> event</h4>

Expand Down Expand Up @@ -96699,18 +96612,6 @@ dictionary <dfn>StorageEventInit</dfn> : <span>EventInit</span> {
initialised to null. It represents the <code>Storage</code> object that was affected.</p>



<h4>Threads</h4>

<p>Because of <a href="#localStorageMutex">the use</a> of the <span>storage mutex</span>, multiple
browsing contexts will be able to access the local storage areas simultaneously in such a manner
that scripts cannot detect any concurrent script execution.</p>

<p>Thus, the <code data-x="dom-Storage-length">length</code> attribute of a <code>Storage</code>
object, and the value of the various properties of that object, cannot change while a script is
executing, other than in a way that is predictable by the script itself.</p>


<h3>Disk space</h3>

<p>User agents should limit the total amount of space allowed for storage areas, because hostile
Expand Down

0 comments on commit 6c901e5

Please sign in to comment.