From 6c901e5967b282893de9e57622f3436c9f05ffc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20J=C3=A4genstedt?= Date: Sat, 14 Nov 2015 11:21:38 +0100 Subject: [PATCH] Remove the storage mutex due to lack of implementation Add a stern warning for the racy document.cookies API. Fixes https://github.com/whatwg/html/issues/335 --- source | 129 +++++++-------------------------------------------------- 1 file changed, 15 insertions(+), 114 deletions(-) diff --git a/source b/source index 4fed104cf40..3124381e721 100644 --- a/source +++ b/source @@ -8282,24 +8282,31 @@ partial /*sealed*/ interface Document {

On getting, if the document is a cookie-averse Document object, then the user agent must return the empty string. Otherwise, if the Document's origin is not a scheme/host/port tuple, the user agent must - throw a SecurityError exception. Otherwise, the user agent must first obtain - the storage mutex and then return the cookie-string for the document's address - for a "non-HTTP" API, decoded using the UTF-8 decoder. - + throw a SecurityError exception. Otherwise, the user agent must return the + cookie-string for the document's address for a "non-HTTP" API, decoded + using the UTF-8 decoder.

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

+ Otherwise, the user agent must act as it would when receiving a set-cookie-string for the document's address + via a "non-HTTP" API, consisting of the new value encoded as UTF-8.

Since the cookie 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.

+

The cookie 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.

+
@@ -12878,8 +12885,6 @@ people expect to have work and what is necessary.
  • If the meta element has no content attribute, or if that attribute's value is the empty string, then abort these steps.

  • -
  • Obtain the storage mutex.

  • -
  • Act as if receiving a set-cookie-string for the document's address via a "non-HTTP" API, consisting of the value of the element's content @@ -79643,8 +79648,6 @@ x === this; // true

  • -
  • Release the storage mutex.

  • -
  • Set the attribute's value to new value.

    @@ -81438,8 +81441,6 @@ State: <OUTPUT NAME=I>1</OUTPUT> <INPUT VALUE="Increment" TYPE=BUTTON O
      -
    1. Release the storage mutex.

    2. -
    3. Decrease the event loop's termination nesting level by one.

    4. -
    5. Release the storage mutex.

    6. -
    7. If any event listeners were triggered by the earlier dispatch step, then set the Document's salvageable state to false.

    8. @@ -83125,8 +83124,6 @@ dictionary PageTransitionEventInit : EventInit {
    9. Decrease the event loop's termination nesting level by one.

    10. -
    11. Release the storage mutex.

    12. -
    13. If any event listeners were triggered by the earlier unload event step, then set the Document object's salvageable state to false and set the Document's fired unload flag to true.

    14. @@ -86645,34 +86642,6 @@ dictionary PromiseRejectionEventInit : EventInit { microtask checkpoint flag, which must initially be false. It is used to prevent reentrant invocation of the perform a microtask checkpoint algorithm.

      -
      - -

      A user agent may have one storage mutex. This mutex is used to control access to - shared state like cookies. At any one point, the storage mutex is either free, or - owned by a particular event loop or instance of the fetching algorithm.

      - -

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

      - -

      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.

      - -

      So far, all browsers faced with this decision have opted to not implement the - storage mutex.

      - -

      Whenever a script calls into a plugin, and - whenever a plugin calls into a script, the user - agent must release the storage mutex.

      - -
      Processing model

      An event loop must continually run through the following steps for as long as it @@ -86702,9 +86671,6 @@ dictionary PromiseRejectionEventInit : EventInit {

    15. Set the event loop's currently running task back to null.

    16. -
    17. If the storage mutex is now owned by the event loop, release it - so that it is once again free.

    18. -
    19. Remove the task that was run in the run step above from its task queue.

    20. @@ -86865,9 +86831,6 @@ dictionary PromiseRejectionEventInit : EventInit {
    21. Set the event loop's currently running task back to null.

    22. -
    23. If the storage mutex is now owned by the event loop, release it - so that it is once again free.

    24. -
    25. Remove the microtask run in the step above from the microtask queue, and return to the microtask queue handling step.

    26. @@ -86994,28 +86957,6 @@ dictionary PromiseRejectionEventInit : EventInit {
    -
    - -

    When a user agent is to obtain the storage mutex as part of running a task, it must run through the following steps:

    - -
      - -
    1. If the storage mutex is already owned by this task's event loop, then abort these steps.

    2. - -
    3. Otherwise, pause until the storage mutex can be taken by the - event loop.

    4. - -
    5. Take ownership of the storage mutex.

    6. - -
    - - - - -
    -
    Generic task sources

    The following task sources are used by a number of mostly @@ -88218,8 +88159,6 @@ interface WindowBase64 {

  • -
  • Release the storage mutex.

  • -
  • Set the Document's salvageable state to false.

  • @@ -88952,8 +88891,6 @@ scheduleWork(); // queues a task to do lots of work
  • If the event loop's termination nesting level is non-zero, optionally abort these steps.

  • -
  • Release the storage mutex.

  • -
  • If the active sandboxing flag set of the active document of the responsible browsing context specified by the incumbent settings object has the sandboxed modals flag set, then abort these @@ -88982,8 +88919,6 @@ scheduleWork(); // queues a task to do lots of work

  • If the event loop's termination nesting level is non-zero, optionally abort these steps, returning false.

  • -
  • Release the storage mutex.

  • -
  • If the active sandboxing flag set of the active document of the responsible browsing context specified by the incumbent settings object has the sandboxed modals flag set, then return false and abort these @@ -89010,8 +88945,6 @@ scheduleWork(); // queues a task to do lots of work

  • If the event loop's termination nesting level is non-zero, optionally abort these steps, returning null.

  • -
  • Release the storage mutex.

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

  • -
  • - -

    The user agent must release the storage mutex.

    - -
  • -
  • The user agent should offer the user the opportunity to obtain a physical form @@ -89181,12 +89108,6 @@ scheduleWork(); // queues a task to do lots of work

  • If the event loop's termination nesting level is non-zero, optionally abort these steps, returning the empty string.

  • -
  • - -

    Release the storage mutex.

    - -
  • -
  • If the user agent is configured such that this invocation of WindowLocalStorage { Window object's localStorage attribute's Storage object is associated with the same storage area, other than x, send a storage notification. -

    Whenever the properties of a localStorage attribute's Storage 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 - Storage interface, the user agent must first obtain the storage - mutex.

    -

    The storage event

    @@ -96699,18 +96612,6 @@ dictionary StorageEventInit : EventInit { initialised to null. It represents the Storage object that was affected.

    - -

    Threads

    - -

    Because of the use of the storage mutex, 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.

    - -

    Thus, the length attribute of a Storage - 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.

    - -

    Disk space

    User agents should limit the total amount of space allowed for storage areas, because hostile