WebSQL databases should not openable in private browsing.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Mar 2017 19:06:31 +0000 (19:06 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Mar 2017 19:06:31 +0000 (19:06 +0000)
<rdar://problem/30383335> and https://bugs.webkit.org/show_bug.cgi?id=170013

Reviewed by Alex Christensen.

Source/WebCore:

Test: storage/websql/private-browsing-open-disabled.html

* Modules/webdatabase/DatabaseManager.cpp:
(WebCore::DatabaseManager::openDatabaseBackend):
(WebCore::DatabaseManager::tryToOpenDatabaseBackend): Throw an exception if in private browsing.
* Modules/webdatabase/DatabaseManager.h:

LayoutTests:

* storage/websql/private-browsing-open-disabled-expected.txt: Added.
* storage/websql/private-browsing-open-disabled.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@214309 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/storage/websql/private-browsing-open-disabled-expected.txt [new file with mode: 0644]
LayoutTests/storage/websql/private-browsing-open-disabled.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/webdatabase/DatabaseManager.cpp
Source/WebCore/Modules/webdatabase/DatabaseManager.h

index 4398d1a..eba22a2 100644 (file)
@@ -1,3 +1,13 @@
+2017-03-23  Brady Eidson  <beidson@apple.com>
+
+        WebSQL databases should not openable in private browsing.
+        <rdar://problem/30383335> and https://bugs.webkit.org/show_bug.cgi?id=170013
+
+        Reviewed by Alex Christensen.
+
+        * storage/websql/private-browsing-open-disabled-expected.txt: Added.
+        * storage/websql/private-browsing-open-disabled.html: Added.
+
 2017-03-23  Ryan Haddad  <ryanhaddad@apple.com>
 
         Remove pass expectation for fast/forms/range/range-remove-on-drag.html as it relies on touch events.
diff --git a/LayoutTests/storage/websql/private-browsing-open-disabled-expected.txt b/LayoutTests/storage/websql/private-browsing-open-disabled-expected.txt
new file mode 100644 (file)
index 0000000..a9c8cde
--- /dev/null
@@ -0,0 +1 @@
+Caught exception opening a WebSQL database in private browsing: SecurityError (DOM Exception 18): The operation is insecure.
diff --git a/LayoutTests/storage/websql/private-browsing-open-disabled.html b/LayoutTests/storage/websql/private-browsing-open-disabled.html
new file mode 100644 (file)
index 0000000..70a7783
--- /dev/null
@@ -0,0 +1,23 @@
+<body>
+<div id="logger"></div>
+<script>
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+    testRunner.setPrivateBrowsingEnabled(true);
+}
+
+var logger = document.getElementById("logger");
+try {
+    openDatabase("PrivateBrowsingOpenDisabled", "1.0", "Test that you can't open databases in private browsing mode", 1);
+    logger.innerHTML = "Successfully opened a WebSQL database in private browsing"
+} catch(e) {
+    logger.innerHTML = "Caught exception opening a WebSQL database in private browsing: " + e;
+}
+
+if (window.testRunner)
+    testRunner.notifyDone();
+
+</script>
+</body>
index 1f314b2..3cf0343 100644 (file)
@@ -1,3 +1,17 @@
+2017-03-23  Brady Eidson  <beidson@apple.com>
+
+        WebSQL databases should not openable in private browsing.
+        <rdar://problem/30383335> and https://bugs.webkit.org/show_bug.cgi?id=170013
+
+        Reviewed by Alex Christensen.
+
+        Test: storage/websql/private-browsing-open-disabled.html
+
+        * Modules/webdatabase/DatabaseManager.cpp:
+        (WebCore::DatabaseManager::openDatabaseBackend):
+        (WebCore::DatabaseManager::tryToOpenDatabaseBackend): Throw an exception if in private browsing.
+        * Modules/webdatabase/DatabaseManager.h:
+
 2017-03-22  Dean Jackson  <dino@apple.com>
 
         NeverDestroyed<MediaQueryEvaluator> must explicitly construct with a String
index 2e992b9..deb8788 100644 (file)
@@ -121,9 +121,7 @@ static void logOpenDatabaseError(ScriptExecutionContext& context, const String&
 
 ExceptionOr<Ref<Database>> DatabaseManager::openDatabaseBackend(ScriptExecutionContext& context, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize, bool setVersionInNewDatabase)
 {
-    auto databaseContext = this->databaseContext(context);
-
-    auto backend = tryToOpenDatabaseBackend(databaseContext, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase, FirstTryToOpenDatabase);
+    auto backend = tryToOpenDatabaseBackend(context, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase, FirstTryToOpenDatabase);
 
     if (backend.hasException()) {
         if (backend.exception().code() == QUOTA_EXCEEDED_ERR) {
@@ -133,9 +131,9 @@ ExceptionOr<Ref<Database>> DatabaseManager::openDatabaseBackend(ScriptExecutionC
             {
                 // FIXME: What guarantees context.securityOrigin() is non-null?
                 ProposedDatabase proposedDatabase { *this, *context.securityOrigin(), name, displayName, estimatedSize };
-                databaseContext->databaseExceededQuota(name, proposedDatabase.details());
+                this->databaseContext(context)->databaseExceededQuota(name, proposedDatabase.details());
             }
-            backend = tryToOpenDatabaseBackend(databaseContext, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase, RetryOpenDatabase);
+            backend = tryToOpenDatabaseBackend(context, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase, RetryOpenDatabase);
         }
     }
 
@@ -149,9 +147,22 @@ ExceptionOr<Ref<Database>> DatabaseManager::openDatabaseBackend(ScriptExecutionC
     return backend;
 }
 
-ExceptionOr<Ref<Database>> DatabaseManager::tryToOpenDatabaseBackend(DatabaseContext& backendContext, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize, bool setVersionInNewDatabase,
+ExceptionOr<Ref<Database>> DatabaseManager::tryToOpenDatabaseBackend(ScriptExecutionContext& scriptContext, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize, bool setVersionInNewDatabase,
     OpenAttempt attempt)
 {
+    if (is<Document>(&scriptContext)) {
+        auto* page = downcast<Document>(scriptContext).page();
+        if (!page || page->usesEphemeralSession())
+            return Exception { SECURITY_ERR };
+    }
+
+    if (scriptContext.isWorkerGlobalScope()) {
+        ASSERT_NOT_REACHED();
+        return Exception { SECURITY_ERR };
+    }
+
+    auto backendContext = this->databaseContext(scriptContext);
+
     ExceptionOr<void> preflightResult;
     switch (attempt) {
     case FirstTryToOpenDatabase:
@@ -171,7 +182,7 @@ ExceptionOr<Ref<Database>> DatabaseManager::tryToOpenDatabaseBackend(DatabaseCon
         return openResult.releaseException();
 
     // FIXME: What guarantees backendContext.securityOrigin() is non-null?
-    DatabaseTracker::singleton().setDatabaseDetails(backendContext.securityOrigin(), name, displayName, estimatedSize);
+    DatabaseTracker::singleton().setDatabaseDetails(backendContext->securityOrigin(), name, displayName, estimatedSize);
     return WTFMove(database);
 }
 
index 1834263..2ca2d07 100644 (file)
@@ -76,7 +76,7 @@ private:
 
     enum OpenAttempt { FirstTryToOpenDatabase, RetryOpenDatabase };
     ExceptionOr<Ref<Database>> openDatabaseBackend(ScriptExecutionContext&, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize, bool setVersionInNewDatabase);
-    static ExceptionOr<Ref<Database>> tryToOpenDatabaseBackend(DatabaseContext&, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize, bool setVersionInNewDatabase, OpenAttempt);
+    ExceptionOr<Ref<Database>> tryToOpenDatabaseBackend(ScriptExecutionContext&, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize, bool setVersionInNewDatabase, OpenAttempt);
 
     class ProposedDatabase;
     void addProposedDatabase(ProposedDatabase&);