mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out 6 changesets (bug 1145744, bug 536509, bug 1184973, bug 1147821) for B2G test_storagePermissionsAccept.html failures.
Backed out changeset 07f5717ac742 (bug 1184973) Backed out changeset d49d61e97fcb (bug 1184973) Backed out changeset e056e2d6b7e8 (bug 1145744) Backed out changeset f4806930c168 (bug 1147821) Backed out changeset 24c808f933e5 (bug 536509) Backed out changeset 03dc725619b8 (bug 1184973) CLOSED TREE
This commit is contained in:
parent
c56c27baf2
commit
98e8b38140
@ -192,10 +192,6 @@
|
||||
#include "xpcprivate.h" // nsXPConnect
|
||||
#include "HTMLSplitOnSpacesTokenizer.h"
|
||||
#include "nsContentTypeParser.h"
|
||||
#include "nsICookiePermission.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "mozilla/EnumSet.h"
|
||||
|
||||
#include "nsIBidiKeyboard.h"
|
||||
|
||||
@ -270,9 +266,6 @@ bool nsContentUtils::sSendPerformanceTimingNotifications = false;
|
||||
|
||||
uint32_t nsContentUtils::sHandlingInputTimeout = 1000;
|
||||
|
||||
uint32_t nsContentUtils::sCookiesLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
|
||||
uint32_t nsContentUtils::sCookiesBehavior = nsICookieService::BEHAVIOR_ACCEPT;
|
||||
|
||||
nsHtml5StringParser* nsContentUtils::sHTMLFragmentParser = nullptr;
|
||||
nsIParser* nsContentUtils::sXMLFragmentParser = nullptr;
|
||||
nsIFragmentContentSink* nsContentUtils::sXMLFragmentSink = nullptr;
|
||||
@ -566,14 +559,6 @@ nsContentUtils::Init()
|
||||
Preferences::AddBoolVarCache(&sSendPerformanceTimingNotifications,
|
||||
"dom.performance.enable_notify_performance_timing", false);
|
||||
|
||||
Preferences::AddUintVarCache(&sCookiesLifetimePolicy,
|
||||
"network.cookie.lifetimePolicy",
|
||||
nsICookieService::ACCEPT_NORMALLY);
|
||||
|
||||
Preferences::AddUintVarCache(&sCookiesBehavior,
|
||||
"network.cookie.cookieBehavior",
|
||||
nsICookieService::BEHAVIOR_ACCEPT);
|
||||
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
Preferences::AddBoolVarCache(&sDOMWindowDumpEnabled,
|
||||
"browser.dom.window.dump.enabled");
|
||||
@ -8070,135 +8055,3 @@ nsContentUtils::PushEnabled(JSContext* aCx, JSObject* aObj)
|
||||
|
||||
return workerPrivate->PushEnabled();
|
||||
}
|
||||
|
||||
// static, public
|
||||
nsContentUtils::StorageAccess
|
||||
nsContentUtils::StorageAllowedForWindow(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
MOZ_ASSERT(aWindow->IsInnerWindow());
|
||||
|
||||
nsIDocument* document = aWindow->GetExtantDoc();
|
||||
if (document) {
|
||||
nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
|
||||
return InternalStorageAllowedForPrincipal(principal, aWindow);
|
||||
}
|
||||
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
// static, public
|
||||
nsContentUtils::StorageAccess
|
||||
nsContentUtils::StorageAllowedForPrincipal(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
return InternalStorageAllowedForPrincipal(aPrincipal, nullptr);
|
||||
}
|
||||
|
||||
// static, private
|
||||
nsContentUtils::StorageAccess
|
||||
nsContentUtils::InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
|
||||
nsPIDOMWindow* aWindow)
|
||||
{
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(!aWindow || aWindow->IsInnerWindow());
|
||||
|
||||
StorageAccess access = StorageAccess::eAllow;
|
||||
|
||||
// We don't allow storage on the null principal, in general. Even if the
|
||||
// calling context is chrome.
|
||||
bool isNullPrincipal;
|
||||
if (NS_WARN_IF(NS_FAILED(aPrincipal->GetIsNullPrincipal(&isNullPrincipal))) ||
|
||||
isNullPrincipal) {
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
if (aWindow) {
|
||||
// If the document is sandboxed, then it is not permitted to use storage
|
||||
nsIDocument* document = aWindow->GetExtantDoc();
|
||||
if (document->GetSandboxFlags() & SANDBOXED_ORIGIN) {
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
// Check if we are in private browsing, and record that fact
|
||||
if (IsInPrivateBrowsing(document)) {
|
||||
access = StorageAccess::ePrivateBrowsing;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we should only allow storage for the session, and record that fact
|
||||
if (sCookiesLifetimePolicy == nsICookieService::ACCEPT_SESSION) {
|
||||
// Storage could be StorageAccess::ePrivateBrowsing or StorageAccess::eAllow
|
||||
// so perform a std::min comparison to make sure we preserve ePrivateBrowsing
|
||||
// if it has been set.
|
||||
access = std::min(StorageAccess::eSessionScoped, access);
|
||||
}
|
||||
|
||||
// If the caller is chrome privileged, then it is allowed to access any
|
||||
// storage it likes, no matter whether the storage for that window/principal
|
||||
// would normally be permitted.
|
||||
if (IsSystemPrincipal(SubjectPrincipal())) {
|
||||
return access;
|
||||
}
|
||||
|
||||
if (!SubjectPrincipal()->Subsumes(aPrincipal)) {
|
||||
NS_WARNING("A principal is attempting to access storage for a principal "
|
||||
"which it doesn't subsume!");
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
// About URIs are allowed to access storage, even if they don't have chrome
|
||||
// privileges. If this is not desired, than the consumer will have to
|
||||
// implement their own restriction functionality.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aPrincipal->GetURI(getter_AddRefs(uri))));
|
||||
bool isAbout = false;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(uri->SchemeIs("about", &isAbout)));
|
||||
if (isAbout) {
|
||||
return access;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> permissionManager =
|
||||
services::GetPermissionManager();
|
||||
if (!permissionManager) {
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
// check the permission manager for any allow or deny permissions
|
||||
// for cookies for the window.
|
||||
uint32_t perm;
|
||||
permissionManager->TestPermissionFromPrincipal(aPrincipal, "cookie", &perm);
|
||||
if (perm == nsIPermissionManager::DENY_ACTION) {
|
||||
return StorageAccess::eDeny;
|
||||
} else if (perm == nsICookiePermission::ACCESS_SESSION) {
|
||||
return std::min(access, StorageAccess::eSessionScoped);
|
||||
} else if (perm == nsIPermissionManager::ALLOW_ACTION) {
|
||||
return access;
|
||||
}
|
||||
|
||||
// We don't want to prompt for every attempt to access permissions, so we
|
||||
// treat the cookie ASK_BEFORE_ACCEPT as though it was a reject.
|
||||
if (sCookiesBehavior == nsICookieService::BEHAVIOR_REJECT ||
|
||||
sCookiesLifetimePolicy == nsICookieService::ASK_BEFORE_ACCEPT) {
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
|
||||
// In the absense of a window, we assume that we are first-party.
|
||||
if (aWindow && (sCookiesBehavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
|
||||
sCookiesBehavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN)) {
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
||||
MOZ_ASSERT(thirdPartyUtil);
|
||||
|
||||
bool thirdPartyWindow = false;
|
||||
if (NS_SUCCEEDED(thirdPartyUtil->IsThirdPartyWindow(
|
||||
aWindow, nullptr, &thirdPartyWindow)) && thirdPartyWindow) {
|
||||
// XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by
|
||||
// simply rejecting the request to use the storage. In the future, if we
|
||||
// change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense
|
||||
// for non-cookie storage types, this may change.
|
||||
|
||||
return StorageAccess::eDeny;
|
||||
}
|
||||
}
|
||||
|
||||
return access;
|
||||
}
|
||||
|
@ -2476,38 +2476,6 @@ public:
|
||||
|
||||
static bool PushEnabled(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
// The order of these entries matters, as we use std::min for total ordering
|
||||
// of permissions. Private Browsing is considered to be more limiting
|
||||
// then session scoping
|
||||
enum class StorageAccess {
|
||||
// Don't allow access to the storage
|
||||
eDeny = 0,
|
||||
// Allow access to the storage, but only if it is secure to do so in a
|
||||
// private browsing context.
|
||||
ePrivateBrowsing = 1,
|
||||
// Allow access to the storage, but only persist it for the current session
|
||||
eSessionScoped = 2,
|
||||
// Allow access to the storage
|
||||
eAllow = 3,
|
||||
};
|
||||
|
||||
/*
|
||||
* Checks if storage for the given window is permitted by a combination of
|
||||
* the user's preferences, and whether the window is a third-party iframe.
|
||||
*
|
||||
* This logic is intended to be shared between the different forms of
|
||||
* persistent storage which are available to web pages. Cookies don't use
|
||||
* this logic, and security logic related to them must be updated separately.
|
||||
*/
|
||||
static StorageAccess StorageAllowedForWindow(nsPIDOMWindow* aWindow);
|
||||
|
||||
/*
|
||||
* Checks if storage for the given principal is permitted by the user's
|
||||
* preferences. The caller is assumed to not be a third-party iframe.
|
||||
* (if that is possible, the caller should use StorageAllowedForWindow)
|
||||
*/
|
||||
static StorageAccess StorageAllowedForPrincipal(nsIPrincipal* aPrincipal);
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
@ -2548,18 +2516,6 @@ private:
|
||||
CallOnRemoteChildFunction aCallback,
|
||||
void* aArg);
|
||||
|
||||
/*
|
||||
* Checks if storage for a given principal is permitted by the user's
|
||||
* preferences. If aWindow is non-null, its principal must be passed as
|
||||
* aPrincipal, and the third-party iframe and sandboxing status of the window
|
||||
* are also checked.
|
||||
*
|
||||
* Used in the implementation of StorageAllowedForWindow and
|
||||
* StorageAllowedForPrincipal.
|
||||
*/
|
||||
static StorageAccess InternalStorageAllowedForPrincipal(nsIPrincipal* aPrincipal,
|
||||
nsPIDOMWindow* aWindow);
|
||||
|
||||
static nsIXPConnect *sXPConnect;
|
||||
|
||||
static nsIScriptSecurityManager *sSecurityManager;
|
||||
@ -2625,8 +2581,6 @@ private:
|
||||
static bool sGettersDecodeURLHash;
|
||||
static bool sPrivacyResistFingerprinting;
|
||||
static bool sSendPerformanceTimingNotifications;
|
||||
static uint32_t sCookiesLifetimePolicy;
|
||||
static uint32_t sCookiesBehavior;
|
||||
|
||||
static nsHtml5StringParser* sHTMLFragmentParser;
|
||||
static nsIParser* sXMLFragmentParser;
|
||||
|
@ -10910,7 +10910,7 @@ nsGlobalWindow::GetLocalStorage(ErrorResult& aError)
|
||||
}
|
||||
|
||||
if (!mLocalStorage) {
|
||||
if (!DOMStorage::CanUseStorage(this)) {
|
||||
if (!DOMStorage::CanUseStorage()) {
|
||||
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
@ -10928,6 +10928,13 @@ 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);
|
||||
@ -11073,16 +11080,9 @@ nsGlobalWindow::GetCaches(ErrorResult& aRv)
|
||||
bool forceTrustedOrigin =
|
||||
GetOuterWindowInternal()->GetServiceWorkersTestingEnabled();
|
||||
|
||||
nsContentUtils::StorageAccess access =
|
||||
nsContentUtils::StorageAllowedForWindow(this);
|
||||
|
||||
// We don't block the cache API when being told to only allow storage for the
|
||||
// current session.
|
||||
bool storageBlocked = access <= nsContentUtils::StorageAccess::ePrivateBrowsing;
|
||||
|
||||
mCacheStorage = CacheStorage::CreateOnMainThread(cache::DEFAULT_NAMESPACE,
|
||||
this, GetPrincipal(),
|
||||
storageBlocked,
|
||||
IsPrivateBrowsing(),
|
||||
forceTrustedOrigin, aRv);
|
||||
}
|
||||
|
||||
|
12
dom/cache/CacheStorage.cpp
vendored
12
dom/cache/CacheStorage.cpp
vendored
@ -145,15 +145,15 @@ IsTrusted(const PrincipalInfo& aPrincipalInfo, bool aTestingPrefEnabled)
|
||||
// static
|
||||
already_AddRefed<CacheStorage>
|
||||
CacheStorage::CreateOnMainThread(Namespace aNamespace, nsIGlobalObject* aGlobal,
|
||||
nsIPrincipal* aPrincipal, bool aStorageDisabled,
|
||||
nsIPrincipal* aPrincipal, bool aPrivateBrowsing,
|
||||
bool aForceTrustedOrigin, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aGlobal);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aStorageDisabled) {
|
||||
NS_WARNING("CacheStorage has been disabled.");
|
||||
if (aPrivateBrowsing) {
|
||||
NS_WARNING("CacheStorage not supported during private browsing.");
|
||||
nsRefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return ref.forget();
|
||||
}
|
||||
@ -189,12 +189,6 @@ CacheStorage::CreateOnWorker(Namespace aNamespace, nsIGlobalObject* aGlobal,
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
if (!aWorkerPrivate->IsStorageAllowed()) {
|
||||
NS_WARNING("CacheStorage is not allowed.");
|
||||
nsRefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
if (aWorkerPrivate->IsInPrivateBrowsing()) {
|
||||
NS_WARNING("CacheStorage not supported during private browsing.");
|
||||
nsRefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
|
||||
|
2
dom/cache/CacheStorage.h
vendored
2
dom/cache/CacheStorage.h
vendored
@ -49,7 +49,7 @@ class CacheStorage final : public nsIIPCBackgroundChildCreateCallback
|
||||
public:
|
||||
static already_AddRefed<CacheStorage>
|
||||
CreateOnMainThread(Namespace aNamespace, nsIGlobalObject* aGlobal,
|
||||
nsIPrincipal* aPrincipal, bool aStorageDisabled,
|
||||
nsIPrincipal* aPrincipal, bool aPrivateBrowsing,
|
||||
bool aForceTrustedOrigin, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<CacheStorage>
|
||||
|
@ -362,13 +362,8 @@ IDBFactory::AllowedForWindowInternal(nsPIDOMWindow* aWindow,
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
nsContentUtils::StorageAccess access =
|
||||
nsContentUtils::StorageAllowedForWindow(aWindow);
|
||||
|
||||
// the factory callsite records whether the browser is in private browsing.
|
||||
// and thus we don't have to respect that setting here. IndexedDB has no
|
||||
// concept of session-local storage, and thus ignores it.
|
||||
if (access == nsContentUtils::StorageAccess::eDeny) {
|
||||
nsIDocument* document = aWindow->GetExtantDoc();
|
||||
if (document->GetSandboxFlags() & SANDBOXED_ORIGIN) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
@ -378,21 +373,26 @@ IDBFactory::AllowedForWindowInternal(nsPIDOMWindow* aWindow,
|
||||
nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
|
||||
if (NS_WARN_IF(!principal)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
|
||||
}
|
||||
|
||||
if (nsContentUtils::IsSystemPrincipal(principal)) {
|
||||
bool isSystemPrincipal;
|
||||
if (!AllowedForPrincipal(principal, &isSystemPrincipal)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
if (isSystemPrincipal) {
|
||||
principal.forget(aPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// About URIs shouldn't be able to access IndexedDB unless they have the
|
||||
// nsIAboutModule::ENABLE_INDEXED_DB flag set on them.
|
||||
// Whitelist about:home, since it doesn't have a base domain it would not
|
||||
// pass the ThirdPartyUtil check, though it should be able to use indexedDB.
|
||||
bool skipThirdPartyCheck = false;
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(principal->GetURI(getter_AddRefs(uri))));
|
||||
MOZ_ASSERT(uri);
|
||||
|
||||
bool isAbout = false;
|
||||
bool isAbout;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(uri->SchemeIs("about", &isAbout)));
|
||||
|
||||
if (isAbout) {
|
||||
@ -400,13 +400,29 @@ IDBFactory::AllowedForWindowInternal(nsPIDOMWindow* aWindow,
|
||||
if (NS_SUCCEEDED(NS_GetAboutModule(uri, getter_AddRefs(module)))) {
|
||||
uint32_t flags;
|
||||
if (NS_SUCCEEDED(module->GetURIFlags(uri, &flags))) {
|
||||
if (!(flags & nsIAboutModule::ENABLE_INDEXED_DB)) {
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
skipThirdPartyCheck = flags & nsIAboutModule::ENABLE_INDEXED_DB;
|
||||
} else {
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
NS_WARNING("GetURIFlags failed!");
|
||||
}
|
||||
} else {
|
||||
NS_WARNING("NS_GetAboutModule failed!");
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipThirdPartyCheck) {
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
||||
MOZ_ASSERT(thirdPartyUtil);
|
||||
|
||||
bool isThirdParty;
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
thirdPartyUtil->IsThirdPartyWindow(aWindow,
|
||||
nullptr,
|
||||
&isThirdParty)))) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
if (isThirdParty) {
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
}
|
||||
|
@ -10,31 +10,11 @@
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
const BEHAVIOR_ACCEPT = 0;
|
||||
const BEHAVIOR_REJECTFOREIGN = 1;
|
||||
const BEHAVIOR_REJECT = 2;
|
||||
const BEHAVIOR_LIMITFOREIGN = 3;
|
||||
|
||||
const testData = [
|
||||
{ host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_ACCEPT, expectedResult: true },
|
||||
{ host: "http://example.com", cookieBehavior: BEHAVIOR_ACCEPT, expectedResult: true },
|
||||
{ host: "http://sub1.test2.example.org:8000", cookieBehavior: BEHAVIOR_ACCEPT, expectedResult: true },
|
||||
{ host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_ACCEPT, expectedResult: true },
|
||||
|
||||
{ host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_REJECT, expectedResult: false },
|
||||
{ host: "http://example.com", cookieBehavior: BEHAVIOR_REJECT, expectedResult: false },
|
||||
{ host: "http://sub1.test2.example.org:8000", cookieBehavior: BEHAVIOR_REJECT, expectedResult: false },
|
||||
{ host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_REJECT, expectedResult: false },
|
||||
|
||||
{ host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_REJECTFOREIGN, expectedResult: true },
|
||||
{ host: "http://example.com", cookieBehavior: BEHAVIOR_REJECTFOREIGN, expectedResult: false },
|
||||
{ host: "http://sub1.test2.example.org:8000", cookieBehavior: BEHAVIOR_REJECTFOREIGN, expectedResult: false },
|
||||
{ host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_REJECTFOREIGN, expectedResult: true },
|
||||
|
||||
{ host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_LIMITFOREIGN, expectedResult: true },
|
||||
{ host: "http://example.com", cookieBehavior: BEHAVIOR_LIMITFOREIGN, expectedResult: false },
|
||||
{ host: "http://sub1.test2.example.org:8000", cookieBehavior: BEHAVIOR_LIMITFOREIGN, expectedResult: false },
|
||||
{ host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_LIMITFOREIGN, expectedResult: true }
|
||||
{ host: "http://" + window.location.host, expectedResult: true },
|
||||
{ host: "http://example.com", expectedResult: false },
|
||||
{ host: "http://sub1.test2.example.org:8000", expectedResult: false },
|
||||
{ host: "http://" + window.location.host, expectedResult: true }
|
||||
];
|
||||
|
||||
const iframe1Path =
|
||||
@ -61,12 +41,8 @@
|
||||
testRunning = true;
|
||||
iframe.addEventListener("load", iframeLoaded, false);
|
||||
}
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [["network.cookie.cookieBehavior", testData[testIndex].cookieBehavior]]
|
||||
}, () => {
|
||||
iframe.src = testData[testIndex].host + iframe1Path;
|
||||
});
|
||||
// SpecialPowers.setIntPref("network.cookie.cookieBehavior", testData[testIndex].cookieBehavior);
|
||||
|
||||
iframe.src = testData[testIndex].host + iframe1Path;
|
||||
}
|
||||
|
||||
function messageListener(event) {
|
||||
|
@ -13,14 +13,13 @@
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsICookiePermission.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsICookieService.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"
|
||||
@ -71,7 +70,7 @@ DOMStorage::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
uint32_t
|
||||
DOMStorage::GetLength(ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(nullptr, this)) {
|
||||
if (!CanUseStorage(this)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return 0;
|
||||
}
|
||||
@ -84,7 +83,7 @@ DOMStorage::GetLength(ErrorResult& aRv)
|
||||
void
|
||||
DOMStorage::Key(uint32_t aIndex, nsAString& aResult, ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(nullptr, this)) {
|
||||
if (!CanUseStorage(this)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
@ -95,7 +94,7 @@ DOMStorage::Key(uint32_t aIndex, nsAString& aResult, ErrorResult& aRv)
|
||||
void
|
||||
DOMStorage::GetItem(const nsAString& aKey, nsAString& aResult, ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(nullptr, this)) {
|
||||
if (!CanUseStorage(this)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
@ -107,7 +106,7 @@ void
|
||||
DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(nullptr, this)) {
|
||||
if (!CanUseStorage(this)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
@ -140,7 +139,7 @@ DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData,
|
||||
void
|
||||
DOMStorage::RemoveItem(const nsAString& aKey, ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(nullptr, this)) {
|
||||
if (!CanUseStorage(this)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
@ -159,7 +158,7 @@ DOMStorage::RemoveItem(const nsAString& aKey, ErrorResult& aRv)
|
||||
void
|
||||
DOMStorage::Clear(ErrorResult& aRv)
|
||||
{
|
||||
if (!CanUseStorage(nullptr, this)) {
|
||||
if (!CanUseStorage(this)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
@ -237,32 +236,60 @@ static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
|
||||
|
||||
// static, public
|
||||
bool
|
||||
DOMStorage::CanUseStorage(nsPIDOMWindow* aWindow, DOMStorage* aStorage)
|
||||
DOMStorage::CanUseStorage(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;
|
||||
}
|
||||
|
||||
nsContentUtils::StorageAccess access = nsContentUtils::StorageAccess::eDeny;
|
||||
if (aWindow) {
|
||||
access = nsContentUtils::StorageAllowedForWindow(aWindow);
|
||||
} else if (aStorage) {
|
||||
access = nsContentUtils::StorageAllowedForPrincipal(aStorage->mPrincipal);
|
||||
// chrome can always use aStorage regardless of permission preferences
|
||||
nsCOMPtr<nsIPrincipal> subjectPrincipal =
|
||||
nsContentUtils::SubjectPrincipal();
|
||||
if (nsContentUtils::IsSystemPrincipal(subjectPrincipal)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (access == nsContentUtils::StorageAccess::eDeny) {
|
||||
nsCOMPtr<nsIPermissionManager> permissionManager =
|
||||
services::GetPermissionManager();
|
||||
if (!permissionManager) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aStorage) {
|
||||
aStorage->mIsSessionOnly = access <= nsContentUtils::StorageAccess::eSessionScoped;
|
||||
uint32_t perm;
|
||||
permissionManager->TestPermissionFromPrincipal(subjectPrincipal,
|
||||
kPermissionType, &perm);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> subjectPrincipal =
|
||||
nsContentUtils::SubjectPrincipal();
|
||||
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) {
|
||||
return aStorage->CanAccess(subjectPrincipal);
|
||||
}
|
||||
|
||||
@ -300,7 +327,7 @@ DOMStorage::CanAccess(nsIPrincipal* aPrincipal)
|
||||
void
|
||||
DOMStorage::GetSupportedNames(unsigned, nsTArray<nsString>& aKeys)
|
||||
{
|
||||
if (!CanUseStorage(nullptr, this)) {
|
||||
if (!CanUseStorage(this)) {
|
||||
// return just an empty array
|
||||
aKeys.Clear();
|
||||
return;
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
class nsIPrincipal;
|
||||
class nsIDOMWindow;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -123,7 +122,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(nsPIDOMWindow* aWindow, DOMStorage* aStorage = nullptr);
|
||||
static bool CanUseStorage(DOMStorage* aStorage = nullptr);
|
||||
|
||||
bool IsPrivate() const { return mIsPrivate; }
|
||||
bool IsSessionOnly() const { return mIsSessionOnly; }
|
||||
|
@ -1,22 +0,0 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>frame for storage allowed test</title>
|
||||
|
||||
<script type="text/javascript" src="//example.com/tests/dom/tests/mochitest/general/storagePermissionsUtils.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
task(function* () {
|
||||
// We should be able to access storage
|
||||
yield storageAllowed();
|
||||
|
||||
// We should be able to run a web worker which can access storage
|
||||
yield runWorker("workerStorageAllowed.js");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,19 +0,0 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>frame for storage allowed test</title>
|
||||
|
||||
<script type="text/javascript" src="//example.com/tests/dom/tests/mochitest/general/storagePermissionsUtils.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
task(function* () {
|
||||
// We just check if we can access storage as chrome using special powers!
|
||||
yield chromePower();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,36 +0,0 @@
|
||||
// This is a sjs file which reads in frameStoragePrevented.html, and writes it out as a data: URI, which this page redirects to.
|
||||
// This produces a URI with the null principal, which should be unable to access storage.
|
||||
// We append the #nullprincipal hash to the end of the data: URI to tell the script that it shouldn't try to spawn a webworker,
|
||||
// as it won't be allowed to, as it has a null principal.
|
||||
|
||||
function handleRequest(request, response) {
|
||||
// Get the nsIFile for frameStoragePrevented.html
|
||||
var file;
|
||||
getObjectState("SERVER_ROOT", function(serverRoot) {
|
||||
file = serverRoot.getFile("/tests/dom/tests/mochitest/general/frameStoragePrevented.html");
|
||||
});
|
||||
|
||||
// Set up the file streams to read in the file as UTF-8
|
||||
let fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
fstream.init(file, -1, 0, 0);
|
||||
let cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIConverterInputStream);
|
||||
cstream.init(fstream, "UTF-8", 0, 0);
|
||||
|
||||
// Read in the file, and concatenate it onto the data string
|
||||
let data = "";
|
||||
let str = {};
|
||||
let read = 0;
|
||||
do {
|
||||
read = cstream.readString(0xffffffff, str);
|
||||
data += str.value;
|
||||
} while (read != 0);
|
||||
|
||||
// No scheme is provided in data URIs, so explicitly provide one
|
||||
data = data.replace('//example.com', 'http://example.com');
|
||||
|
||||
// Write out the file as a data: URI, and redirect to it
|
||||
response.setStatusLine('1.1', 302, 'Found');
|
||||
response.setHeader('Location', 'data:text/html,' + encodeURIComponent(data) + "#nullprincipal");
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>frame for storage prevented test</title>
|
||||
|
||||
<script type="text/javascript" src="//example.com/tests/dom/tests/mochitest/general/storagePermissionsUtils.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
task(function* () {
|
||||
// We shouldn't be able to access storage
|
||||
yield storagePrevented();
|
||||
|
||||
// This hash of the URI is set to #nullprincipal by the test if the current page has a null principal,
|
||||
// and thus attempting to create a dedicated worker will throw
|
||||
if (location.hash == "#nullprincipal") {
|
||||
try {
|
||||
new Worker("workerStoragePrevented.js");
|
||||
ok(false, "Running workers should not have been allowed");
|
||||
} catch (e) {
|
||||
ok(true, "Running workers was prevented");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to run a worker, which shouldn't be able to access storage
|
||||
yield runWorker("workerStoragePrevented.js");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -37,13 +37,6 @@ support-files =
|
||||
resource_timing.js
|
||||
navigation_timing.html
|
||||
test_bug1012662_common.js
|
||||
frameStorageAllowed.html
|
||||
frameStoragePrevented.html
|
||||
frameStorageChrome.html
|
||||
frameStorageNullprincipal.sjs
|
||||
workerStorageAllowed.js
|
||||
workerStoragePrevented.js
|
||||
storagePermissionsUtils.js
|
||||
|
||||
[test_497898.html]
|
||||
skip-if = ((buildapp == 'mulet' || buildapp == 'b2g') && toolkit != 'gonk') || toolkit == 'android' #Bug 931116, b2g desktop specific, initial triage
|
||||
@ -112,7 +105,3 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet'
|
||||
[test_bug1012662_noeditor.html]
|
||||
[test_bug1161721.html]
|
||||
[test_bug1170911.html]
|
||||
[test_storagePermissionsAccept.html]
|
||||
[test_storagePermissionsRejectForeign.html]
|
||||
[test_storagePermissionsReject.html]
|
||||
[test_storagePermissionsLimitForeign.html]
|
||||
|
@ -1,256 +0,0 @@
|
||||
const BEHAVIOR_ACCEPT = 0;
|
||||
const BEHAVIOR_REJECT_FOREIGN = 1;
|
||||
const BEHAVIOR_REJECT = 2;
|
||||
const BEHAVIOR_LIMIT_FOREIGN = 3;
|
||||
|
||||
const kPrefName = "network.cookie.cookieBehavior";
|
||||
|
||||
// Check if we are in frame, and declare ok and finishTest appropriately
|
||||
const inFrame = ("" + location).match(/frame/);
|
||||
if (inFrame) {
|
||||
ok = function(a, message) {
|
||||
if (!a) {
|
||||
parent.postMessage("FAILURE: " + message, "http://mochi.test:8888");
|
||||
} else {
|
||||
parent.postMessage(message, "http://mochi.test:8888");
|
||||
}
|
||||
};
|
||||
|
||||
finishTest = function() {
|
||||
parent.postMessage("done", "http://mochi.test:8888");
|
||||
};
|
||||
} else {
|
||||
finishTest = function() {
|
||||
SimpleTest.finish();
|
||||
};
|
||||
}
|
||||
|
||||
function setCookieBehavior(behavior) {
|
||||
return new Promise((resolve, reject) => {
|
||||
SpecialPowers.pushPrefEnv({"set": [[kPrefName, behavior]]}, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
function runIFrame(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
function onMessage(e) {
|
||||
if (e.data == "done") {
|
||||
resolve();
|
||||
window.removeEventListener('message', onMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
ok(!e.data.match(/^FAILURE/), e.data + " (IFRAME = " + url + ")");
|
||||
}
|
||||
window.addEventListener('message', onMessage, false);
|
||||
|
||||
document.querySelector('iframe').src = url;
|
||||
});
|
||||
}
|
||||
|
||||
function runWorker(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var worker = new Worker(url);
|
||||
worker.addEventListener('message', function(e) {
|
||||
if (e.data == "done") {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
ok(!e.data.match(/^FAILURE/), e.data + " (WORKER = " + url + ")");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function chromePower() {
|
||||
try {
|
||||
SpecialPowers.wrap(window).localStorage.getItem("X");
|
||||
ok(true, "getting localStorage didn't throw");
|
||||
} catch (e) {
|
||||
ok(false, "getting localStorage should not throw");
|
||||
}
|
||||
|
||||
try {
|
||||
SpecialPowers.wrap(window).sessionStorage.getItem("X");
|
||||
ok(true, "getting sessionStorage didn't throw");
|
||||
} catch (e) {
|
||||
ok(false, "getting sessionStorage should not throw");
|
||||
}
|
||||
|
||||
try {
|
||||
SpecialPowers.wrap(window).indexedDB;
|
||||
ok(true, "getting indexedDB didn't throw");
|
||||
} catch (e) {
|
||||
ok(false, "getting indexedDB should not throw");
|
||||
}
|
||||
|
||||
try {
|
||||
var promise = SpecialPowers.wrap(window).caches.keys();
|
||||
ok(true, "getting caches didn't throw");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
promise.then(function() {
|
||||
ok(location.protocol == "https:", "The promise was not rejected");
|
||||
resolve();
|
||||
}, function(e) {
|
||||
ok(location.protocol != "https:", "The promise should not have been rejected: " + e);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
ok(false, "getting caches should not have thrown");
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
function storageAllowed() {
|
||||
try {
|
||||
localStorage.getItem("X");
|
||||
ok(true, "getting localStorage didn't throw");
|
||||
} catch (e) {
|
||||
ok(false, "getting localStorage should not throw");
|
||||
}
|
||||
|
||||
try {
|
||||
sessionStorage.getItem("X");
|
||||
ok(true, "getting sessionStorage didn't throw");
|
||||
} catch (e) {
|
||||
ok(false, "getting sessionStorage should not throw");
|
||||
}
|
||||
|
||||
try {
|
||||
indexedDB;
|
||||
ok(true, "getting indexedDB didn't throw");
|
||||
} catch (e) {
|
||||
ok(false, "getting indexedDB should not throw");
|
||||
}
|
||||
|
||||
try {
|
||||
var promise = caches.keys();
|
||||
ok(true, "getting caches didn't throw");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
promise.then(function() {
|
||||
ok(location.protocol == "https:", "The promise was not rejected");
|
||||
resolve();
|
||||
}, function() {
|
||||
ok(location.protocol != "https:", "The promise should not have been rejected");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
ok(false, "getting caches should not have thrown");
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
function storagePrevented() {
|
||||
try {
|
||||
localStorage.getItem("X");
|
||||
ok(false, "getting localStorage should have thrown");
|
||||
} catch (e) {
|
||||
ok(true, "getting localStorage threw");
|
||||
}
|
||||
|
||||
if (location.hash == "#thirdparty") {
|
||||
// No matter what the user's preferences are, we don't block
|
||||
// sessionStorage in 3rd-party iframes. We do block them everywhere
|
||||
// else however.
|
||||
try {
|
||||
sessionStorage.getItem("X");
|
||||
ok(true, "getting sessionStorage didn't throw");
|
||||
} catch (e) {
|
||||
ok(false, "getting sessionStorage should not have thrown");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
sessionStorage.getItem("X");
|
||||
ok(false, "getting sessionStorage should have thrown");
|
||||
} catch (e) {
|
||||
ok(true, "getting sessionStorage threw");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
indexedDB;
|
||||
ok(false, "getting indexedDB should have thrown");
|
||||
} catch (e) {
|
||||
ok(true, "getting indexedDB threw");
|
||||
}
|
||||
|
||||
try {
|
||||
var promise = caches.keys();
|
||||
ok(true, "getting caches didn't throw");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
promise.then(function() {
|
||||
ok(false, "The promise should have rejected");
|
||||
resolve();
|
||||
}, function() {
|
||||
ok(true, "The promise was rejected");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
ok(false, "getting caches should not have thrown");
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
function task(fn) {
|
||||
if (!inFrame) {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
}
|
||||
|
||||
var gen = fn();
|
||||
|
||||
function next_step(val, e) {
|
||||
var it;
|
||||
try {
|
||||
if (typeof e !== "undefined") {
|
||||
it = gen.throw(e);
|
||||
} else {
|
||||
it = gen.next(val);
|
||||
}
|
||||
} catch (e) {
|
||||
ok(false, "An error was thrown while stepping: " + e);
|
||||
ok(false, "Stack: " + e.stack);
|
||||
finishTest();
|
||||
}
|
||||
|
||||
if (it.done) {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
it.value.then(next_step, (e) => next_step(null, e));
|
||||
}
|
||||
|
||||
next_step();
|
||||
}
|
||||
|
||||
var thirdparty = "https://example.com/tests/dom/tests/mochitest/general/";
|
||||
|
||||
// XXX B2G HACK
|
||||
|
||||
var b2gOnly = (function() {
|
||||
function pref(name) {
|
||||
try {
|
||||
return SpecialPowers.getBoolPref(name);
|
||||
} catch (e) {
|
||||
// Out of an over-abundance of caution, don't use https
|
||||
// if we can't check the pref
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var isAndroid = !!navigator.userAgent.includes("Android");
|
||||
var isMulet = pref("b2g.is_mulet");
|
||||
var isB2g = isMulet || (!isAndroid && /Mobile|Tablet/.test(navigator.userAgent));
|
||||
return isB2g ? true : undefined;
|
||||
})();
|
||||
|
||||
// Switch to http:// in b2g because https:// in tests isn't supported
|
||||
if (b2gOnly) {
|
||||
thirdparty = "http://example.com/tests/dom/tests/mochitest/general/";
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Storage Permission Restrictions</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="storagePermissionsUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<iframe></iframe>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
task(function* () {
|
||||
yield setCookieBehavior(BEHAVIOR_ACCEPT);
|
||||
|
||||
// We should be able to access storage
|
||||
yield storageAllowed();
|
||||
|
||||
// Same origin iframes should be allowed, unless they redirect to a URI with the null principal
|
||||
yield runIFrame("frameStorageAllowed.html");
|
||||
yield runIFrame("frameStorageNullprincipal.sjs");
|
||||
yield runIFrame("frameStorageChrome.html");
|
||||
|
||||
// Sandboxed iframes should have the null principal, and thus can't access storage
|
||||
document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts');
|
||||
yield runIFrame("frameStoragePrevented.html#nullprincipal");
|
||||
yield runIFrame("frameStorageNullprincipal.sjs");
|
||||
document.querySelector('iframe').removeAttribute('sandbox');
|
||||
|
||||
// Thirdparty iframes should be allowed, unless they redirect to a URI with the null principal
|
||||
yield runIFrame(thirdparty + "frameStorageAllowed.html");
|
||||
yield runIFrame(thirdparty + "frameStorageNullprincipal.sjs");
|
||||
yield runIFrame(thirdparty + "frameStorageChrome.html");
|
||||
|
||||
// Workers should be able to access storage
|
||||
yield runWorker("workerStorageAllowed.js");
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,42 +0,0 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Storage Permission Restrictions</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="storagePermissionsUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<iframe></iframe>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
task(function* () {
|
||||
yield setCookieBehavior(BEHAVIOR_LIMIT_FOREIGN);
|
||||
|
||||
// We should be able to access storage
|
||||
yield storageAllowed();
|
||||
|
||||
// Same origin iframes should be prevented, unless they have chrome privileges
|
||||
yield runIFrame("frameStorageAllowed.html");
|
||||
yield runIFrame("frameStorageNullprincipal.sjs");
|
||||
yield runIFrame("frameStorageChrome.html");
|
||||
|
||||
// Sandboxed iframes should have the null principal, and thus can't access storage
|
||||
document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts');
|
||||
yield runIFrame("frameStoragePrevented.html#nullprincipal");
|
||||
yield runIFrame("frameStorageNullprincipal.sjs");
|
||||
document.querySelector('iframe').removeAttribute('sandbox');
|
||||
|
||||
// Thirdparty iframes should be blocked, unless they have chrome privileges
|
||||
yield runIFrame(thirdparty + "frameStoragePrevented.html#thirdparty");
|
||||
yield runIFrame(thirdparty + "frameStorageNullprincipal.sjs");
|
||||
yield runIFrame(thirdparty + "frameStorageChrome.html");
|
||||
|
||||
// Workers should be unable to access storage
|
||||
yield runWorker("workerStorageAllowed.js");
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,41 +0,0 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Storage Permission Restrictions</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="storagePermissionsUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<iframe></iframe>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
task(function* () {
|
||||
yield setCookieBehavior(BEHAVIOR_REJECT);
|
||||
|
||||
// We should be unable to access storage
|
||||
yield storagePrevented();
|
||||
|
||||
// Same origin iframes should be prevented, unless they have chrome privileges
|
||||
yield runIFrame("frameStoragePrevented.html");
|
||||
yield runIFrame("frameStorageNullprincipal.sjs");
|
||||
yield runIFrame("frameStorageChrome.html");
|
||||
|
||||
// Sandboxed iframes should have the null principal, and thus can't access storage
|
||||
document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts');
|
||||
yield runIFrame("frameStoragePrevented.html#nullprincipal");
|
||||
yield runIFrame("frameStorageNullprincipal.sjs");
|
||||
document.querySelector('iframe').removeAttribute('sandbox');
|
||||
|
||||
// thirdparty iframes should be blocked, unless they have chrome privileges
|
||||
yield runIFrame(thirdparty + "frameStoragePrevented.html");
|
||||
yield runIFrame(thirdparty + "frameStorageNullprincipal.sjs");
|
||||
|
||||
// Workers should be unable to access storage
|
||||
yield runWorker("workerStoragePrevented.js");
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,42 +0,0 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Storage Permission Restrictions</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="storagePermissionsUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<iframe></iframe>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
task(function* () {
|
||||
yield setCookieBehavior(BEHAVIOR_REJECT_FOREIGN);
|
||||
|
||||
// We should be able to access storage
|
||||
yield storageAllowed();
|
||||
|
||||
// Same origin iframes should be allowed, unless they redirect to a URI with the null principal
|
||||
yield runIFrame("frameStorageAllowed.html");
|
||||
yield runIFrame("frameStorageNullprincipal.sjs");
|
||||
yield runIFrame("frameStorageChrome.html");
|
||||
|
||||
// Sandboxed iframes should have the null principal, and thus can't access storage
|
||||
document.querySelector('iframe').setAttribute('sandbox', 'allow-scripts');
|
||||
yield runIFrame("frameStoragePrevented.html#nullprincipal");
|
||||
yield runIFrame("frameStorageNullprincipal.sjs");
|
||||
document.querySelector('iframe').removeAttribute('sandbox');
|
||||
|
||||
// thirdparty iframes should be blocked, unless they have chrome privileges
|
||||
yield runIFrame(thirdparty + "frameStoragePrevented.html#thirdparty");
|
||||
yield runIFrame(thirdparty + "frameStorageNullprincipal.sjs");
|
||||
yield runIFrame(thirdparty + "frameStorageChrome.html");
|
||||
|
||||
// Workers should be able to access storage
|
||||
yield runWorker("workerStorageAllowed.js");
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,61 +0,0 @@
|
||||
// Unfortunately, workers can't share the code from storagePermissionsUtils.
|
||||
// These are basic mechanisms for communicating to the test runner.
|
||||
|
||||
function ok(condition, text) {
|
||||
if (!condition) {
|
||||
self.postMessage("FAILURE: " + text);
|
||||
} else {
|
||||
self.postMessage(text);
|
||||
}
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
self.postMessage("done");
|
||||
self.close();
|
||||
}
|
||||
|
||||
// Workers don't have access to localstorage or sessionstorage
|
||||
ok(typeof self.localStorage == "undefined", "localStorage should be undefined");
|
||||
ok(typeof self.sessionStorage == "undefined", "sessionStorage should be undefined");
|
||||
|
||||
// Make sure that we can access indexedDB
|
||||
try {
|
||||
indexedDB;
|
||||
ok(true, "WORKER getting indexedDB didn't throw");
|
||||
} catch (e) {
|
||||
ok(false, "WORKER getting indexedDB should not throw");
|
||||
}
|
||||
|
||||
// Make sure that we can access caches
|
||||
try {
|
||||
var promise = caches.keys();
|
||||
ok(true, "WORKER getting caches didn't throw");
|
||||
|
||||
promise.then(function() {
|
||||
ok(location.protocol == "https:", "WORKER The promise was not rejected");
|
||||
workerTest();
|
||||
}, function() {
|
||||
ok(location.protocol != "https:", "WORKER The promise should not have been rejected");
|
||||
workerTest();
|
||||
});
|
||||
} catch (e) {
|
||||
ok(false, "WORKER getting caches should not have thrown");
|
||||
}
|
||||
|
||||
// Try to spawn an inner worker, and make sure that it can also access storage
|
||||
function workerTest() {
|
||||
if (location.hash == "#inner") { // Don't recurse infinitely, if we are the inner worker, don't spawn another
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
// Create the inner worker, and listen for test messages from it
|
||||
var worker = new Worker("workerStorageAllowed.js#inner");
|
||||
worker.addEventListener('message', function(e) {
|
||||
if (e.data == "done") {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
|
||||
ok(!e.data.match(/^FAILURE/), e.data + " (WORKER = workerStorageAllowed.js#inner)");
|
||||
});
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
// Unfortunately, workers can't share the code from storagePermissionsUtils.
|
||||
// These are basic mechanisms for communicating to the test runner.
|
||||
|
||||
function ok(condition, text) {
|
||||
if (!condition) {
|
||||
self.postMessage("FAILURE: " + text);
|
||||
} else {
|
||||
self.postMessage(text);
|
||||
}
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
self.postMessage("done");
|
||||
self.close();
|
||||
}
|
||||
|
||||
// Workers don't have access to localstorage or sessionstorage
|
||||
ok(typeof self.localStorage == "undefined", "localStorage should be undefined");
|
||||
ok(typeof self.sessionStorage == "undefined", "sessionStorage should be undefined");
|
||||
|
||||
// Make sure that we can't access indexedDB
|
||||
try {
|
||||
indexedDB;
|
||||
ok(false, "WORKER getting indexedDB should have thrown");
|
||||
} catch (e) {
|
||||
ok(true, "WORKER getting indexedDB threw");
|
||||
}
|
||||
|
||||
// Make sure that we can't access caches
|
||||
try {
|
||||
var promise = caches.keys();
|
||||
ok(true, "WORKER getting caches didn't throw");
|
||||
|
||||
promise.then(function() {
|
||||
ok(false, "WORKER The promise should have rejected");
|
||||
workerTest();
|
||||
}, function() {
|
||||
ok(true, "WORKER The promise was rejected");
|
||||
workerTest();
|
||||
});
|
||||
} catch (e) {
|
||||
ok(false, "WORKER getting caches should not have thrown");
|
||||
}
|
||||
|
||||
// Try to spawn an inner worker, and make sure that it also can't access storage
|
||||
function workerTest() {
|
||||
if (location.hash == "#inner") { // Don't recurse infinitely, if we are the inner worker, don't spawn another
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
// Create the inner worker, and listen for test messages from it
|
||||
var worker = new Worker("workerStoragePrevented.js#inner");
|
||||
worker.addEventListener('message', function(e) {
|
||||
if (e.data == "done") {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
|
||||
ok(!e.data.match(/^FAILURE/), e.data + " (WORKER = workerStoragePrevented.js#inner)");
|
||||
});
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>localStorage cookies settings test</title>
|
||||
|
||||
<script type="text/javascript" src="interOriginFrame.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
localStorage.setItem("contentkey", "test-value");
|
||||
ok(false, "Setting localStorageItem should throw a security exception");
|
||||
} catch(ex) {
|
||||
is(ex.name, "SecurityError");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -49,9 +49,7 @@ function todo(a, b, message)
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
try {
|
||||
localStorage.clear();
|
||||
} catch (e) {}
|
||||
localStorage.clear();
|
||||
postMsg("done");
|
||||
return false;
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
support-files =
|
||||
frameAppIsolation.html
|
||||
frameChromeSlave.html
|
||||
frameLocalStorageCookieSettings.html
|
||||
frameKeySync.html
|
||||
frameMasterEqual.html
|
||||
frameMasterNotEqual.html
|
||||
|
@ -3,13 +3,8 @@
|
||||
<title>localStorage cookies settings test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="interOriginTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<iframe></iframe>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
@ -42,33 +37,11 @@ function test2() {
|
||||
is(ex.name, "SecurityError");
|
||||
}
|
||||
|
||||
// Set cookies behavior to "reject 3rd party"
|
||||
SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 1]],
|
||||
"clear": [["network.cookie.lifetimePolicy"]]},
|
||||
test3);
|
||||
}
|
||||
|
||||
function test3() {
|
||||
try {
|
||||
localStorage.setItem("contentkey", "test-value");
|
||||
ok(true, "Setting localStorageItem should not throw a security exception");
|
||||
}
|
||||
catch(ex) {
|
||||
ok(false, "Setting localStorageItem should not throw a security exception");
|
||||
}
|
||||
|
||||
var fileTest = (location.protocol + "//example.com" + location.pathname)
|
||||
.replace("test_l", "frameL");
|
||||
|
||||
var myframe = document.querySelector("iframe");
|
||||
myframe.src = fileTest;
|
||||
}
|
||||
|
||||
// Called by interOriginTest.js
|
||||
function doNextTest() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/EnumSet.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
@ -4058,9 +4057,6 @@ ServiceWorkerManager::CreateServiceWorker(nsIPrincipal* aPrincipal,
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
// Ensure that the IndexedDatabaseManager is initialized
|
||||
NS_WARN_IF(!indexedDB::IndexedDatabaseManager::GetOrCreate());
|
||||
|
||||
WorkerLoadInfo info;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(info.mBaseURI), aInfo->ScriptSpec(),
|
||||
nullptr, nullptr);
|
||||
@ -4080,12 +4076,9 @@ ServiceWorkerManager::CreateServiceWorker(nsIPrincipal* aPrincipal,
|
||||
|
||||
info.mPrincipal = aPrincipal;
|
||||
|
||||
nsContentUtils::StorageAccess access =
|
||||
nsContentUtils::StorageAllowedForPrincipal(aPrincipal);
|
||||
info.mStorageAllowed =
|
||||
access > nsContentUtils::StorageAccess::ePrivateBrowsing;
|
||||
|
||||
info.mPrivateBrowsing = false;
|
||||
info.mIndexedDBAllowed =
|
||||
indexedDB::IDBFactory::AllowedForPrincipal(aPrincipal);
|
||||
info.mPrivateBrowsing = false;
|
||||
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = aPrincipal->GetCsp(getter_AddRefs(csp));
|
||||
|
@ -2181,7 +2181,7 @@ WorkerLoadInfo::WorkerLoadInfo()
|
||||
, mPrincipalIsSystem(false)
|
||||
, mIsInPrivilegedApp(false)
|
||||
, mIsInCertifiedApp(false)
|
||||
, mStorageAllowed(false)
|
||||
, mIndexedDBAllowed(false)
|
||||
, mPrivateBrowsing(true)
|
||||
, mServiceWorkersTestingInWindow(false)
|
||||
{
|
||||
@ -2240,7 +2240,7 @@ WorkerLoadInfo::StealFrom(WorkerLoadInfo& aOther)
|
||||
mPrincipalIsSystem = aOther.mPrincipalIsSystem;
|
||||
mIsInPrivilegedApp = aOther.mIsInPrivilegedApp;
|
||||
mIsInCertifiedApp = aOther.mIsInCertifiedApp;
|
||||
mStorageAllowed = aOther.mStorageAllowed;
|
||||
mIndexedDBAllowed = aOther.mIndexedDBAllowed;
|
||||
mPrivateBrowsing = aOther.mPrivateBrowsing;
|
||||
mServiceWorkersTestingInWindow = aOther.mServiceWorkersTestingInWindow;
|
||||
}
|
||||
@ -4807,16 +4807,13 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
|
||||
loadInfo.mDomain = aParent->Domain();
|
||||
loadInfo.mFromWindow = aParent->IsFromWindow();
|
||||
loadInfo.mWindowID = aParent->WindowID();
|
||||
loadInfo.mStorageAllowed = aParent->IsStorageAllowed();
|
||||
loadInfo.mIndexedDBAllowed = aParent->IsIndexedDBAllowed();
|
||||
loadInfo.mPrivateBrowsing = aParent->IsInPrivateBrowsing();
|
||||
loadInfo.mServiceWorkersTestingInWindow =
|
||||
aParent->ServiceWorkersTestingInWindow();
|
||||
} else {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
// Make sure that the IndexedDatabaseManager is set up
|
||||
NS_WARN_IF(!indexedDB::IndexedDatabaseManager::GetOrCreate());
|
||||
|
||||
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
||||
MOZ_ASSERT(ssm);
|
||||
|
||||
@ -4935,9 +4932,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
|
||||
loadInfo.mIsInCertifiedApp = (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED);
|
||||
loadInfo.mFromWindow = true;
|
||||
loadInfo.mWindowID = globalWindow->WindowID();
|
||||
nsContentUtils::StorageAccess access =
|
||||
nsContentUtils::StorageAllowedForWindow(globalWindow);
|
||||
loadInfo.mStorageAllowed = access > nsContentUtils::StorageAccess::eDeny;
|
||||
loadInfo.mIndexedDBAllowed = IDBFactory::AllowedForWindow(globalWindow);
|
||||
loadInfo.mPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(document);
|
||||
} else {
|
||||
// Not a window
|
||||
@ -4979,7 +4974,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
|
||||
loadInfo.mXHRParamsAllowed = true;
|
||||
loadInfo.mFromWindow = false;
|
||||
loadInfo.mWindowID = UINT64_MAX;
|
||||
loadInfo.mStorageAllowed = true;
|
||||
loadInfo.mIndexedDBAllowed = true;
|
||||
loadInfo.mPrivateBrowsing = false;
|
||||
}
|
||||
|
||||
|
@ -769,9 +769,9 @@ public:
|
||||
}
|
||||
|
||||
bool
|
||||
IsStorageAllowed() const
|
||||
IsIndexedDBAllowed() const
|
||||
{
|
||||
return mLoadInfo.mStorageAllowed;
|
||||
return mLoadInfo.mIndexedDBAllowed;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -358,9 +358,8 @@ WorkerGlobalScope::GetIndexedDB(ErrorResult& aErrorResult)
|
||||
nsRefPtr<IDBFactory> indexedDB = mIndexedDB;
|
||||
|
||||
if (!indexedDB) {
|
||||
if (!mWorkerPrivate->IsStorageAllowed()) {
|
||||
if (!mWorkerPrivate->IsIndexedDBAllowed()) {
|
||||
NS_WARNING("IndexedDB is not allowed in this worker!");
|
||||
aErrorResult = NS_ERROR_DOM_SECURITY_ERR;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,7 @@ struct WorkerLoadInfo
|
||||
bool mPrincipalIsSystem;
|
||||
bool mIsInPrivilegedApp;
|
||||
bool mIsInCertifiedApp;
|
||||
bool mStorageAllowed;
|
||||
bool mIndexedDBAllowed;
|
||||
bool mPrivateBrowsing;
|
||||
bool mServiceWorkersTestingInWindow;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user