Diff
Modified: trunk/LayoutTests/ChangeLog (125334 => 125335)
--- trunk/LayoutTests/ChangeLog 2012-08-10 22:52:41 UTC (rev 125334)
+++ trunk/LayoutTests/ChangeLog 2012-08-10 23:13:37 UTC (rev 125335)
@@ -1,3 +1,26 @@
+2012-08-09 Jeffrey Pfau <jp...@apple.com>
+
+ Allow blocking of third-party localStorage and sessionStorage
+ https://bugs.webkit.org/show_bug.cgi?id=93390
+
+ Reviewed by Adam Barth.
+
+ Created tests for testing accessing localStorage and selfStorage from a third party and first party when third-party blocking is on and off.
+
+ * http/tests/security/cross-origin-local-storage-allowed-expected.txt: Added.
+ * http/tests/security/cross-origin-local-storage-allowed.html: Added.
+ * http/tests/security/cross-origin-local-storage-expected.txt: Added.
+ * http/tests/security/cross-origin-local-storage.html: Added.
+ * http/tests/security/cross-origin-session-storage-allowed-expected.txt: Added.
+ * http/tests/security/cross-origin-session-storage-allowed.html: Added.
+ * http/tests/security/cross-origin-session-storage-expected.txt: Added.
+ * http/tests/security/cross-origin-session-storage.html: Added.
+ * http/tests/security/same-origin-document-domain-storage-allowed-expected.html: Added.
+ * http/tests/security/same-origin-document-domain-storage-allowed.html: Added.
+ * http/tests/security/resources/document-domain-iframe-for-local-storage.html: Added.
+ * http/tests/security/resources/cross-origin-iframe-for-local-storage.html: Added.
+ * http/tests/security/resources/cross-origin-iframe-for-session-storage.html: Added.
+
2012-08-10 Arko Saha <a...@motorola.com>
REGRESSION(r125159): ASSERTION FAILED: m_listsInvalidatedAtDocument.contains(list) in Document::unregisterNodeListCache.
Added: trunk/LayoutTests/http/tests/security/cross-origin-local-storage-allowed-expected.txt (0 => 125335)
--- trunk/LayoutTests/http/tests/security/cross-origin-local-storage-allowed-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/cross-origin-local-storage-allowed-expected.txt 2012-08-10 23:13:37 UTC (rev 125335)
@@ -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
Added: trunk/LayoutTests/http/tests/security/cross-origin-local-storage-allowed.html (0 => 125335)
--- trunk/LayoutTests/http/tests/security/cross-origin-local-storage-allowed.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/cross-origin-local-storage-allowed.html 2012-08-10 23:13:37 UTC (rev 125335)
@@ -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=""
+<p>This iframe should not return any errors:</p>
+<iframe src=""
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/security/cross-origin-local-storage-expected.txt (0 => 125335)
--- trunk/LayoutTests/http/tests/security/cross-origin-local-storage-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/cross-origin-local-storage-expected.txt 2012-08-10 23:13:37 UTC (rev 125335)
@@ -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
Added: trunk/LayoutTests/http/tests/security/cross-origin-local-storage.html (0 => 125335)
--- trunk/LayoutTests/http/tests/security/cross-origin-local-storage.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/cross-origin-local-storage.html 2012-08-10 23:13:37 UTC (rev 125335)
@@ -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="" _onload_="decrement()"></iframe>
+<p>This iframe should not return any errors:</p>
+<iframe src="" _onload_="decrement()"></iframe>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/security/cross-origin-session-storage-allowed-expected.txt (0 => 125335)
--- trunk/LayoutTests/http/tests/security/cross-origin-session-storage-allowed-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/cross-origin-session-storage-allowed-expected.txt 2012-08-10 23:13:37 UTC (rev 125335)
@@ -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
Added: trunk/LayoutTests/http/tests/security/cross-origin-session-storage-allowed.html (0 => 125335)
--- trunk/LayoutTests/http/tests/security/cross-origin-session-storage-allowed.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/cross-origin-session-storage-allowed.html 2012-08-10 23:13:37 UTC (rev 125335)
@@ -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=""
+<p>This iframe should not return any errors:</p>
+<iframe src=""
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/security/cross-origin-session-storage-expected.txt (0 => 125335)
--- trunk/LayoutTests/http/tests/security/cross-origin-session-storage-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/cross-origin-session-storage-expected.txt 2012-08-10 23:13:37 UTC (rev 125335)
@@ -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
Added: trunk/LayoutTests/http/tests/security/cross-origin-session-storage.html (0 => 125335)
--- trunk/LayoutTests/http/tests/security/cross-origin-session-storage.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/cross-origin-session-storage.html 2012-08-10 23:13:37 UTC (rev 125335)
@@ -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="" _onload_="decrement()"></iframe>
+<p>This iframe should not return any errors:</p>
+<iframe src="" _onload_="decrement()"></iframe>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-local-storage.html (0 => 125335)
--- trunk/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-local-storage.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-local-storage.html 2012-08-10 23:13:37 UTC (rev 125335)
@@ -0,0 +1,14 @@
+<html>
+<head>
+<script>
+try {
+ var c = window.localStorage;
+ document.write('No exception');
+} catch (exception) {
+ document.write(exception.name);
+}
+</script>
+</head>
+<body>
+</body>
+</head>
Added: trunk/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-session-storage.html (0 => 125335)
--- trunk/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-session-storage.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-session-storage.html 2012-08-10 23:13:37 UTC (rev 125335)
@@ -0,0 +1,14 @@
+<html>
+<head>
+<script>
+try {
+ var c = window.sessionStorage;
+ document.write('No exception');
+} catch (exception) {
+ document.write(exception.name);
+}
+</script>
+</head>
+<body>
+</body>
+</head>
Added: trunk/LayoutTests/http/tests/security/resources/document-domain-iframe-for-local-storage.html (0 => 125335)
--- trunk/LayoutTests/http/tests/security/resources/document-domain-iframe-for-local-storage.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/resources/document-domain-iframe-for-local-storage.html 2012-08-10 23:13:37 UTC (rev 125335)
@@ -0,0 +1,15 @@
+<html>
+<head>
+<script>
+try {
+ document.domain = document.domain;
+ var c = window.localStorage;
+ document.write('No exception');
+} catch (exception) {
+ document.write(exception.name);
+}
+</script>
+</head>
+<body>
+</body>
+</head>
Added: trunk/LayoutTests/http/tests/security/same-origin-document-domain-storage-allowed-expected.txt (0 => 125335)
--- trunk/LayoutTests/http/tests/security/same-origin-document-domain-storage-allowed-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/same-origin-document-domain-storage-allowed-expected.txt 2012-08-10 23:13:37 UTC (rev 125335)
@@ -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
Added: trunk/LayoutTests/http/tests/security/same-origin-document-domain-storage-allowed.html (0 => 125335)
--- trunk/LayoutTests/http/tests/security/same-origin-document-domain-storage-allowed.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/same-origin-document-domain-storage-allowed.html 2012-08-10 23:13:37 UTC (rev 125335)
@@ -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 not return any errors:</p>
+<iframe src="" _onload_="decrement()"></iframe>
+<p>This iframe should not return any errors:</p>
+<iframe src="" _onload_="decrement()"></iframe>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (125334 => 125335)
--- trunk/Source/WebCore/ChangeLog 2012-08-10 22:52:41 UTC (rev 125334)
+++ trunk/Source/WebCore/ChangeLog 2012-08-10 23:13:37 UTC (rev 125335)
@@ -1,3 +1,38 @@
+2012-08-09 Jeffrey Pfau <jp...@apple.com>
+
+ Allow blocking of third-party localStorage and sessionStorage
+ https://bugs.webkit.org/show_bug.cgi?id=93390
+
+ Reviewed by Adam Barth.
+
+ Add checks for if a page is third-party and third-party storage blocking is enabled while accessing storage.
+
+ Tests: http/tests/security/cross-origin-local-storage-allowed.html
+ http/tests/security/cross-origin-local-storage.html
+ http/tests/security/cross-origin-session-storage-allowed.html
+ http/tests/security/cross-origin-session-storage.html
+ http/tests/security/same-origin-document-domain-storage-allowed.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::initSecurityContext): Initialize securityOrigin with knowledge of if we should block third-party storage.
+ * page/DOMWindow.cpp: Check if the origin trying to access storage is third-party relative to the top document.
+ (WebCore::DOMWindow::sessionStorage):
+ (WebCore::DOMWindow::localStorage):
+ * page/SecurityOrigin.cpp: Add a call in Security origin to see if another origin counts as a third-party.
+ (WebCore::SecurityOrigin::SecurityOrigin):
+ (WebCore::SecurityOrigin::canAccessLocalStorage):
+ (WebCore):
+ (WebCore::SecurityOrigin::isThirdParty):
+ * page/SecurityOrigin.h:
+ (WebCore::SecurityOrigin::blockThirdPartyStorage):
+ (SecurityOrigin):
+ * testing/InternalSettings.cpp: Add an internals.settings hook for setting third-party storage blocking enabled.
+ (WebCore::InternalSettings::setThirdPartyStorageBlockingEnabled):
+ (WebCore):
+ * testing/InternalSettings.h:
+ (InternalSettings):
+ * testing/InternalSettings.idl:
+
2012-08-10 Arko Saha <a...@motorola.com>
REGRESSION(r125159): ASSERTION FAILED: m_listsInvalidatedAtDocument.contains(list) in Document::unregisterNodeListCache.
Modified: trunk/Source/WebCore/dom/Document.cpp (125334 => 125335)
--- trunk/Source/WebCore/dom/Document.cpp 2012-08-10 22:52:41 UTC (rev 125334)
+++ trunk/Source/WebCore/dom/Document.cpp 2012-08-10 23:13:37 UTC (rev 125335)
@@ -5015,6 +5015,8 @@
securityOrigin()->enforceFilePathSeparation();
}
}
+ if (settings->thirdPartyStorageBlockingEnabled())
+ securityOrigin()->blockThirdPartyStorage();
}
Document* parentDocument = ownerElement() ? ownerElement()->document() : 0;
Modified: trunk/Source/WebCore/page/DOMWindow.cpp (125334 => 125335)
--- trunk/Source/WebCore/page/DOMWindow.cpp 2012-08-10 22:52:41 UTC (rev 125334)
+++ trunk/Source/WebCore/page/DOMWindow.cpp 2012-08-10 23:13:37 UTC (rev 125335)
@@ -743,7 +743,7 @@
if (!document)
return 0;
- if (!document->securityOrigin()->canAccessLocalStorage()) {
+ if (!document->securityOrigin()->canAccessLocalStorage(document->topDocument()->securityOrigin())) {
ec = SECURITY_ERR;
return 0;
}
@@ -770,7 +770,7 @@
if (!document)
return 0;
- if (!document->securityOrigin()->canAccessLocalStorage()) {
+ if (!document->securityOrigin()->canAccessLocalStorage(document->topDocument()->securityOrigin())) {
ec = SECURITY_ERR;
return 0;
}
Modified: trunk/Source/WebCore/page/SecurityOrigin.cpp (125334 => 125335)
--- trunk/Source/WebCore/page/SecurityOrigin.cpp 2012-08-10 22:52:41 UTC (rev 125334)
+++ trunk/Source/WebCore/page/SecurityOrigin.cpp 2012-08-10 23:13:37 UTC (rev 125335)
@@ -133,6 +133,7 @@
, m_isUnique(false)
, m_universalAccess(false)
, m_domainWasSetInDOM(false)
+ , m_blockThirdPartyStorage(false)
, m_enforceFilePathSeparation(false)
, m_needsDatabaseIdentifierQuirkForFiles(false)
{
@@ -158,6 +159,7 @@
, m_universalAccess(false)
, m_domainWasSetInDOM(false)
, m_canLoadLocalResources(false)
+ , m_blockThirdPartyStorage(false)
, m_enforceFilePathSeparation(false)
, m_needsDatabaseIdentifierQuirkForFiles(false)
{
@@ -174,6 +176,7 @@
, m_universalAccess(other->m_universalAccess)
, m_domainWasSetInDOM(other->m_domainWasSetInDOM)
, m_canLoadLocalResources(other->m_canLoadLocalResources)
+ , m_blockThirdPartyStorage(other->m_blockThirdPartyStorage)
, m_enforceFilePathSeparation(other->m_enforceFilePathSeparation)
, m_needsDatabaseIdentifierQuirkForFiles(other->m_needsDatabaseIdentifierQuirkForFiles)
{
@@ -388,6 +391,17 @@
return true;
}
+bool SecurityOrigin::canAccessLocalStorage(const SecurityOrigin* topOrigin) const
+{
+ if (isUnique())
+ return false;
+
+ if (m_blockThirdPartyStorage && topOrigin->isThirdParty(this))
+ return false;
+
+ return true;
+}
+
SecurityOrigin::Policy SecurityOrigin::canShowNotifications() const
{
if (m_universalAccess)
@@ -397,6 +411,20 @@
return Ask;
}
+bool SecurityOrigin::isThirdParty(const SecurityOrigin* child) const
+{
+ if (child->m_universalAccess)
+ return false;
+
+ if (this == child)
+ return false;
+
+ if (isUnique() || child->isUnique())
+ return true;
+
+ return !isSameSchemeHostPort(child);
+}
+
void SecurityOrigin::grantLoadLocalResources()
{
// Granting privileges to some, but not all, documents in a SecurityOrigin
Modified: trunk/Source/WebCore/page/SecurityOrigin.h (125334 => 125335)
--- trunk/Source/WebCore/page/SecurityOrigin.h 2012-08-10 22:52:41 UTC (rev 125334)
+++ trunk/Source/WebCore/page/SecurityOrigin.h 2012-08-10 23:13:37 UTC (rev 125335)
@@ -121,8 +121,10 @@
// WARNING: This is an extremely powerful ability. Use with caution!
void grantUniversalAccess();
+ void blockThirdPartyStorage() { m_blockThirdPartyStorage = true; }
+
bool canAccessDatabase() const { return !isUnique(); }
- bool canAccessLocalStorage() const { return !isUnique(); }
+ bool canAccessLocalStorage(const SecurityOrigin* topOrigin) const;
bool canAccessCookies() const { return !isUnique(); }
bool canAccessPasswordManager() const { return !isUnique(); }
bool canAccessFileSystem() const { return !isUnique(); }
@@ -189,6 +191,7 @@
// FIXME: Rename this function to something more semantic.
bool passesFileCheck(const SecurityOrigin*) const;
+ bool isThirdParty(const SecurityOrigin*) const;
String m_protocol;
String m_host;
@@ -200,6 +203,7 @@
bool m_universalAccess;
bool m_domainWasSetInDOM;
bool m_canLoadLocalResources;
+ bool m_blockThirdPartyStorage;
bool m_enforceFilePathSeparation;
bool m_needsDatabaseIdentifierQuirkForFiles;
};
Modified: trunk/Source/WebCore/testing/InternalSettings.cpp (125334 => 125335)
--- trunk/Source/WebCore/testing/InternalSettings.cpp 2012-08-10 22:52:41 UTC (rev 125334)
+++ trunk/Source/WebCore/testing/InternalSettings.cpp 2012-08-10 23:13:37 UTC (rev 125335)
@@ -620,4 +620,10 @@
settings()->setMemoryInfoEnabled(enabled);
}
+void InternalSettings::setThirdPartyStorageBlockingEnabled(bool enabled, ExceptionCode& ec)
+{
+ InternalSettingsGuardForSettings();
+ settings()->setThirdPartyStorageBlockingEnabled(enabled);
}
+
+}
Modified: trunk/Source/WebCore/testing/InternalSettings.h (125334 => 125335)
--- trunk/Source/WebCore/testing/InternalSettings.h 2012-08-10 22:52:41 UTC (rev 125334)
+++ trunk/Source/WebCore/testing/InternalSettings.h 2012-08-10 23:13:37 UTC (rev 125335)
@@ -139,6 +139,7 @@
void setEnableMockPagePopup(bool, ExceptionCode&);
String configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode&);
void setMemoryInfoEnabled(bool, ExceptionCode&);
+ void setThirdPartyStorageBlockingEnabled(bool, ExceptionCode&);
private:
explicit InternalSettings(Page*);
virtual void hostDestroyed() OVERRIDE { m_page = 0; }
Modified: trunk/Source/WebCore/testing/InternalSettings.idl (125334 => 125335)
--- trunk/Source/WebCore/testing/InternalSettings.idl 2012-08-10 22:52:41 UTC (rev 125334)
+++ trunk/Source/WebCore/testing/InternalSettings.idl 2012-08-10 23:13:37 UTC (rev 125335)
@@ -78,6 +78,7 @@
boolean shouldDisplayTrackKind(in DOMString trackKind) raises (DOMException);
#endif
void setMemoryInfoEnabled(in boolean enabled) raises(DOMException);
+ void setThirdPartyStorageBlockingEnabled(in boolean enabled) raises(DOMException);
};
}