From c84994fb3c5d4665af9b83bc4f451d7d4be1a2d8 Mon Sep 17 00:00:00 2001 From: Michael Layzell Date: Wed, 15 Jul 2015 16:44:42 -0400 Subject: [PATCH] Bug 536509 - Update localStorage to use common StorageAllowedForWindow logic, r=ehsan --- dom/base/nsGlobalWindow.cpp | 9 +-- dom/storage/DOMStorage.cpp | 67 ++++++------------- dom/storage/DOMStorage.h | 3 +- .../frameLocalStorageCookieSettings.html | 20 ++++++ .../localstorage/interOriginFrame.js | 4 +- .../mochitest/localstorage/mochitest.ini | 1 + .../test_localStorageCookieSettings.html | 31 ++++++++- 7 files changed, 76 insertions(+), 59 deletions(-) create mode 100644 dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 4726af28b229..1c60038e246e 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -10910,7 +10910,7 @@ nsGlobalWindow::GetLocalStorage(ErrorResult& aError) } if (!mLocalStorage) { - if (!DOMStorage::CanUseStorage()) { + if (!DOMStorage::CanUseStorage(this)) { aError.Throw(NS_ERROR_DOM_SECURITY_ERR); return nullptr; } @@ -10928,13 +10928,6 @@ nsGlobalWindow::GetLocalStorage(ErrorResult& aError) return nullptr; } - // If the document has the sandboxed origin flag set - // don't allow access to localStorage. - if (mDoc && (mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN)) { - aError.Throw(NS_ERROR_DOM_SECURITY_ERR); - return nullptr; - } - nsString documentURI; if (mDoc) { mDoc->GetDocumentURI(documentURI); diff --git a/dom/storage/DOMStorage.cpp b/dom/storage/DOMStorage.cpp index 0b4f2b21e822..4e8e7b2fcf0c 100644 --- a/dom/storage/DOMStorage.cpp +++ b/dom/storage/DOMStorage.cpp @@ -13,13 +13,14 @@ #include "nsIPermissionManager.h" #include "nsIPrincipal.h" #include "nsICookiePermission.h" -#include "nsICookieService.h" +#include "nsPIDOMWindow.h" #include "mozilla/dom/StorageBinding.h" #include "mozilla/dom/StorageEvent.h" #include "mozilla/dom/StorageEventBinding.h" #include "mozilla/Services.h" #include "mozilla/Preferences.h" +#include "mozilla/EnumSet.h" #include "nsThreadUtils.h" #include "nsContentUtils.h" #include "nsServiceManagerUtils.h" @@ -70,7 +71,7 @@ DOMStorage::WrapObject(JSContext* aCx, JS::Handle aGivenProto) uint32_t DOMStorage::GetLength(ErrorResult& aRv) { - if (!CanUseStorage(this)) { + if (!CanUseStorage(nullptr, this)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return 0; } @@ -83,7 +84,7 @@ DOMStorage::GetLength(ErrorResult& aRv) void DOMStorage::Key(uint32_t aIndex, nsAString& aResult, ErrorResult& aRv) { - if (!CanUseStorage(this)) { + if (!CanUseStorage(nullptr, this)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -94,7 +95,7 @@ DOMStorage::Key(uint32_t aIndex, nsAString& aResult, ErrorResult& aRv) void DOMStorage::GetItem(const nsAString& aKey, nsAString& aResult, ErrorResult& aRv) { - if (!CanUseStorage(this)) { + if (!CanUseStorage(nullptr, this)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -106,7 +107,7 @@ void DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData, ErrorResult& aRv) { - if (!CanUseStorage(this)) { + if (!CanUseStorage(nullptr, this)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -139,7 +140,7 @@ DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData, void DOMStorage::RemoveItem(const nsAString& aKey, ErrorResult& aRv) { - if (!CanUseStorage(this)) { + if (!CanUseStorage(nullptr, this)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -158,7 +159,7 @@ DOMStorage::RemoveItem(const nsAString& aKey, ErrorResult& aRv) void DOMStorage::Clear(ErrorResult& aRv) { - if (!CanUseStorage(this)) { + if (!CanUseStorage(nullptr, this)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -236,60 +237,32 @@ static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy"; // static, public bool -DOMStorage::CanUseStorage(DOMStorage* aStorage) +DOMStorage::CanUseStorage(nsPIDOMWindow* aWindow, DOMStorage* aStorage) { // This method is responsible for correct setting of mIsSessionOnly. // It doesn't work with mIsPrivate flag at all, since it is checked // regardless mIsSessionOnly flag in DOMStorageCache code. - if (aStorage) { - aStorage->mIsSessionOnly = false; - } if (!mozilla::Preferences::GetBool(kStorageEnabled)) { return false; } - // chrome can always use aStorage regardless of permission preferences - nsCOMPtr subjectPrincipal = - nsContentUtils::SubjectPrincipal(); - if (nsContentUtils::IsSystemPrincipal(subjectPrincipal)) { - return true; + nsContentUtils::StorageAccess access = nsContentUtils::StorageAccess::eDeny; + if (aWindow) { + access = nsContentUtils::StorageAllowedForWindow(aWindow); + } else if (aStorage) { + access = nsContentUtils::StorageAllowedForPrincipal(aStorage->mPrincipal); } - nsCOMPtr permissionManager = - services::GetPermissionManager(); - if (!permissionManager) { + if (access == nsContentUtils::StorageAccess::eDeny) { return false; } - uint32_t perm; - permissionManager->TestPermissionFromPrincipal(subjectPrincipal, - kPermissionType, &perm); - - if (perm == nsIPermissionManager::DENY_ACTION) { - return false; - } - - if (perm == nsICookiePermission::ACCESS_SESSION) { - if (aStorage) { - aStorage->mIsSessionOnly = true; - } - } else if (perm != nsIPermissionManager::ALLOW_ACTION) { - uint32_t cookieBehavior = Preferences::GetUint(kCookiesBehavior); - uint32_t lifetimePolicy = Preferences::GetUint(kCookiesLifetimePolicy); - - // Treat "ask every time" as "reject always". - if (cookieBehavior == nsICookieService::BEHAVIOR_REJECT || - lifetimePolicy == nsICookieService::ASK_BEFORE_ACCEPT) { - return false; - } - - if (lifetimePolicy == nsICookieService::ACCEPT_SESSION && aStorage) { - aStorage->mIsSessionOnly = true; - } - } - if (aStorage) { + aStorage->mIsSessionOnly = access <= nsContentUtils::StorageAccess::eSessionScoped; + + nsCOMPtr subjectPrincipal = + nsContentUtils::SubjectPrincipal(); return aStorage->CanAccess(subjectPrincipal); } @@ -327,7 +300,7 @@ DOMStorage::CanAccess(nsIPrincipal* aPrincipal) void DOMStorage::GetSupportedNames(unsigned, nsTArray& aKeys) { - if (!CanUseStorage(this)) { + if (!CanUseStorage(nullptr, this)) { // return just an empty array aKeys.Clear(); return; diff --git a/dom/storage/DOMStorage.h b/dom/storage/DOMStorage.h index 8f25e14cfa11..ec75e86ee7da 100644 --- a/dom/storage/DOMStorage.h +++ b/dom/storage/DOMStorage.h @@ -18,6 +18,7 @@ class nsIPrincipal; class nsIDOMWindow; +class nsPIDOMWindow; namespace mozilla { namespace dom { @@ -122,7 +123,7 @@ public: // It is an optimization since the privileges check and session only // state determination are complex and share the code (comes hand in // hand together). - static bool CanUseStorage(DOMStorage* aStorage = nullptr); + static bool CanUseStorage(nsPIDOMWindow* aWindow, DOMStorage* aStorage = nullptr); bool IsPrivate() const { return mIsPrivate; } bool IsSessionOnly() const { return mIsSessionOnly; } diff --git a/dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html b/dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html new file mode 100644 index 000000000000..de42e6bb9049 --- /dev/null +++ b/dom/tests/mochitest/localstorage/frameLocalStorageCookieSettings.html @@ -0,0 +1,20 @@ + + +localStorage cookies settings test + + + + + + + + diff --git a/dom/tests/mochitest/localstorage/interOriginFrame.js b/dom/tests/mochitest/localstorage/interOriginFrame.js index c24ddc07d047..185ef8858168 100644 --- a/dom/tests/mochitest/localstorage/interOriginFrame.js +++ b/dom/tests/mochitest/localstorage/interOriginFrame.js @@ -49,7 +49,9 @@ function todo(a, b, message) function finishTest() { - localStorage.clear(); + try { + localStorage.clear(); + } catch (e) {} postMsg("done"); return false; } diff --git a/dom/tests/mochitest/localstorage/mochitest.ini b/dom/tests/mochitest/localstorage/mochitest.ini index aa0343261cfd..14b678e292dd 100644 --- a/dom/tests/mochitest/localstorage/mochitest.ini +++ b/dom/tests/mochitest/localstorage/mochitest.ini @@ -2,6 +2,7 @@ support-files = frameAppIsolation.html frameChromeSlave.html + frameLocalStorageCookieSettings.html frameKeySync.html frameMasterEqual.html frameMasterNotEqual.html diff --git a/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html b/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html index 5e3b36b3e519..d3a47611e1f6 100644 --- a/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html +++ b/dom/tests/mochitest/localstorage/test_localStorageCookieSettings.html @@ -3,8 +3,13 @@ localStorage cookies settings test + + + + + - -