Allow blocking of Web SQL databases in third-party documents
https://bugs.webkit.org/show_bug.cgi?id=94057

Reviewed by Adam Barth.

Source/WebCore:

Add a check for pages in third-party pages to allow third-party storage blocking of Web SQL databases.

Tests: http/tests/security/cross-origin-websql-allowed.html
       http/tests/security/cross-origin-websql.html

* Modules/webdatabase/DOMWindowWebDatabase.cpp:
(WebCore::DOMWindowWebDatabase::openDatabase): Pass top origin to canAccessDatabase
* page/SecurityOrigin.cpp:
(WebCore::SecurityOrigin::canAccessStorage): Common method for various types of storage that use the same criteria
* page/SecurityOrigin.h:
(WebCore::SecurityOrigin::canAccessDatabase): Use canAccessStorage
(WebCore::SecurityOrigin::canAccessLocalStorage): Change to using canAccessStorage
(SecurityOrigin):

LayoutTests:

Created tests for accessing openDatabase from a third party and first party context when third-party blocking is on and off.

* http/tests/security/cross-origin-websql-allowed-expected.txt: Added.
* http/tests/security/cross-origin-websql-allowed.html: Added.
* http/tests/security/cross-origin-websql-expected.txt: Added.
* http/tests/security/cross-origin-websql.html: Added.
* http/tests/security/resources/cross-origin-iframe-for-websql.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@125736 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index aa87b15..2bd6480 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,18 @@
+2012-08-14  Jeffrey Pfau  <jpfau@apple.com>
+
+        Allow blocking of Web SQL databases in third-party documents
+        https://bugs.webkit.org/show_bug.cgi?id=94057
+
+        Reviewed by Adam Barth.
+
+        Created tests for accessing openDatabase from a third party and first party context when third-party blocking is on and off.
+
+        * http/tests/security/cross-origin-websql-allowed-expected.txt: Added.
+        * http/tests/security/cross-origin-websql-allowed.html: Added.
+        * http/tests/security/cross-origin-websql-expected.txt: Added.
+        * http/tests/security/cross-origin-websql.html: Added.
+        * http/tests/security/resources/cross-origin-iframe-for-websql.html: Added.
+
 2012-08-15  Kiran Muppala  <cmuppala@apple.com>
 
         Fix TestExpectations line format for two fast/css tests failing on mac
diff --git a/LayoutTests/http/tests/security/cross-origin-websql-allowed-expected.txt b/LayoutTests/http/tests/security/cross-origin-websql-allowed-expected.txt
new file mode 100644
index 0000000..9946bb4
--- /dev/null
+++ b/LayoutTests/http/tests/security/cross-origin-websql-allowed-expected.txt
@@ -0,0 +1,16 @@
+This iframe should not return any errors:
+
+
+This iframe should not return any errors:
+
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+No exception
+
+--------
+Frame: '<!--framePath //<!--frame1-->-->'
+--------
+No exception
diff --git a/LayoutTests/http/tests/security/cross-origin-websql-allowed.html b/LayoutTests/http/tests/security/cross-origin-websql-allowed.html
new file mode 100644
index 0000000..089ef71
--- /dev/null
+++ b/LayoutTests/http/tests/security/cross-origin-websql-allowed.html
@@ -0,0 +1,16 @@
+<html>
+<head>
+<script>
+if (window.testRunner) {
+	testRunner.dumpAsText();
+	testRunner.dumpChildFramesAsText();
+}
+</script>
+</head>
+<body>
+<p>This iframe should not return any errors:</p>
+<iframe src="http://localhost:8000/security/resources/cross-origin-iframe-for-websql.html"></iframe>
+<p>This iframe should not return any errors:</p>
+<iframe src="http://127.0.0.1:8000/security/resources/cross-origin-iframe-for-websql.html"></iframe>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/cross-origin-websql-expected.txt b/LayoutTests/http/tests/security/cross-origin-websql-expected.txt
new file mode 100644
index 0000000..fa7bc1c
--- /dev/null
+++ b/LayoutTests/http/tests/security/cross-origin-websql-expected.txt
@@ -0,0 +1,16 @@
+This iframe should return a security error:
+
+
+This iframe should not return any errors:
+
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+SECURITY_ERR
+
+--------
+Frame: '<!--framePath //<!--frame1-->-->'
+--------
+No exception
diff --git a/LayoutTests/http/tests/security/cross-origin-websql.html b/LayoutTests/http/tests/security/cross-origin-websql.html
new file mode 100644
index 0000000..dc039a6
--- /dev/null
+++ b/LayoutTests/http/tests/security/cross-origin-websql.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<script>
+var frames = 2;
+if (window.testRunner) {
+	testRunner.dumpAsText();
+	testRunner.dumpChildFramesAsText();
+	internals.settings.setThirdPartyStorageBlockingEnabled(true);
+}
+
+function decrement() {
+	--frames;
+	if (!frames && window.testRunner)
+		internals.settings.setThirdPartyStorageBlockingEnabled(false);
+}
+</script>
+</head>
+<body>
+<p>This iframe should return a security error:</p>
+<iframe src="http://localhost:8000/security/resources/cross-origin-iframe-for-websql.html" onload="decrement()"></iframe>
+<p>This iframe should not return any errors:</p>
+<iframe src="http://127.0.0.1:8000/security/resources/cross-origin-iframe-for-websql.html" onload="decrement()"></iframe>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-websql.html b/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-websql.html
new file mode 100644
index 0000000..8487677
--- /dev/null
+++ b/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-websql.html
@@ -0,0 +1,14 @@
+<html>
+<head>
+<script>
+try {
+	var c = window.openDatabase('testdb', '1.0', 'Testing database', 512 * 1024);
+	document.write('No exception');
+} catch (exception) {
+	document.write(exception.name);
+}
+</script>
+</head>
+<body>
+</body>
+</head>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 7bc5936..cb1852c 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,24 @@
+2012-08-14  Jeffrey Pfau  <jpfau@apple.com>
+
+        Allow blocking of Web SQL databases in third-party documents
+        https://bugs.webkit.org/show_bug.cgi?id=94057
+
+        Reviewed by Adam Barth.
+
+        Add a check for pages in third-party pages to allow third-party storage blocking of Web SQL databases.
+
+        Tests: http/tests/security/cross-origin-websql-allowed.html
+               http/tests/security/cross-origin-websql.html
+
+        * Modules/webdatabase/DOMWindowWebDatabase.cpp:
+        (WebCore::DOMWindowWebDatabase::openDatabase): Pass top origin to canAccessDatabase
+        * page/SecurityOrigin.cpp:
+        (WebCore::SecurityOrigin::canAccessStorage): Common method for various types of storage that use the same criteria
+        * page/SecurityOrigin.h:
+        (WebCore::SecurityOrigin::canAccessDatabase): Use canAccessStorage
+        (WebCore::SecurityOrigin::canAccessLocalStorage): Change to using canAccessStorage
+        (SecurityOrigin):
+
 2012-08-15  Nikhil Bhargava  <nbhargava@google.com>
 
         Improve Document.h compile time - reduce includes of ScriptCallStack.h
diff --git a/Source/WebCore/Modules/webdatabase/DOMWindowWebDatabase.cpp b/Source/WebCore/Modules/webdatabase/DOMWindowWebDatabase.cpp
index 85e7104..7848759 100644
--- a/Source/WebCore/Modules/webdatabase/DOMWindowWebDatabase.cpp
+++ b/Source/WebCore/Modules/webdatabase/DOMWindowWebDatabase.cpp
@@ -46,7 +46,7 @@
         return 0;
 
     RefPtr<Database> database = 0;
-    if (AbstractDatabase::isAvailable() && window->document()->securityOrigin()->canAccessDatabase())
+    if (AbstractDatabase::isAvailable() && window->document()->securityOrigin()->canAccessDatabase(window->document()->topDocument()->securityOrigin()))
         database = Database::openDatabase(window->document(), name, version, displayName, estimatedSize, creationCallback, ec);
 
     if (!database && !ec)
diff --git a/Source/WebCore/page/SecurityOrigin.cpp b/Source/WebCore/page/SecurityOrigin.cpp
index 6f7e344..bb79e55 100644
--- a/Source/WebCore/page/SecurityOrigin.cpp
+++ b/Source/WebCore/page/SecurityOrigin.cpp
@@ -391,11 +391,15 @@
     return true;
 }
 
-bool SecurityOrigin::canAccessLocalStorage(const SecurityOrigin* topOrigin) const
+bool SecurityOrigin::canAccessStorage(const SecurityOrigin* topOrigin) const
 {
     if (isUnique())
         return false;
 
+    // FIXME: This check should be replaced with an ASSERT once we can guarantee that topOrigin is not null.
+    if (!topOrigin)
+        return true;
+
     if (m_blockThirdPartyStorage && topOrigin->isThirdParty(this))
         return false;
 
diff --git a/Source/WebCore/page/SecurityOrigin.h b/Source/WebCore/page/SecurityOrigin.h
index 93b8681..fb8e036 100644
--- a/Source/WebCore/page/SecurityOrigin.h
+++ b/Source/WebCore/page/SecurityOrigin.h
@@ -123,8 +123,8 @@
 
     void blockThirdPartyStorage() { m_blockThirdPartyStorage = true; }
 
-    bool canAccessDatabase() const { return !isUnique(); }
-    bool canAccessLocalStorage(const SecurityOrigin* topOrigin) const;
+    bool canAccessDatabase(const SecurityOrigin* topOrigin = 0) const { return canAccessStorage(topOrigin); };
+    bool canAccessLocalStorage(const SecurityOrigin* topOrigin) const { return canAccessStorage(topOrigin); };
     bool canAccessCookies() const { return !isUnique(); }
     bool canAccessPasswordManager() const { return !isUnique(); }
     bool canAccessFileSystem() const { return !isUnique(); }
@@ -192,6 +192,7 @@
     // FIXME: Rename this function to something more semantic.
     bool passesFileCheck(const SecurityOrigin*) const;
     bool isThirdParty(const SecurityOrigin*) const;
+    bool canAccessStorage(const SecurityOrigin*) const;
 
     String m_protocol;
     String m_host;