Bug 1959370 - Add an ability to disable and enable security checks per user context for testing. r=keeler
Differential Revision: https://phabricator.services.mozilla.com/D247746
This commit is contained in:
committed by
aborovova@mozilla.com
parent
742b637921
commit
6a615f57fc
@@ -433,7 +433,14 @@ nsCertOverrideService::HasMatchingOverride(
|
||||
bool disableAllSecurityCheck = false;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
disableAllSecurityCheck = mDisableAllSecurityCheck;
|
||||
if (mUserContextIdsWithSecurityChecksOverride.has(
|
||||
aOriginAttributes.mUserContextId)) {
|
||||
auto p = mUserContextIdsWithSecurityChecksOverride.lookup(
|
||||
aOriginAttributes.mUserContextId);
|
||||
disableAllSecurityCheck = p->value();
|
||||
} else {
|
||||
disableAllSecurityCheck = mDisableAllSecurityCheck;
|
||||
}
|
||||
}
|
||||
if (disableAllSecurityCheck) {
|
||||
*aIsTemporary = false;
|
||||
@@ -665,6 +672,39 @@ nsCertOverrideService::
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCertOverrideService::
|
||||
SetDisableAllSecurityChecksAndLetAttackersInterceptMyDataForUserContext(
|
||||
uint32_t aUserContextId, bool aDisable) {
|
||||
if (!(PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR") || IsDebugger())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mozilla::Unused << mUserContextIdsWithSecurityChecksOverride.put(
|
||||
aUserContextId, aDisable);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCertOverrideService::
|
||||
ResetDisableAllSecurityChecksAndLetAttackersInterceptMyDataForUserContext(
|
||||
uint32_t aUserContextId) {
|
||||
if (!(PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR") || IsDebugger())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mUserContextIdsWithSecurityChecksOverride.remove(aUserContextId);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCertOverrideService::GetSecurityCheckDisabled(bool* aDisabled) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
@@ -118,6 +118,8 @@ class nsCertOverrideService final : public nsICertOverrideService,
|
||||
|
||||
mozilla::Mutex mMutex;
|
||||
bool mDisableAllSecurityCheck MOZ_GUARDED_BY(mMutex);
|
||||
mozilla::HashMap<uint32_t, bool> mUserContextIdsWithSecurityChecksOverride
|
||||
MOZ_GUARDED_BY(mMutex);
|
||||
nsCOMPtr<nsIFile> mSettingsFile MOZ_GUARDED_BY(mMutex);
|
||||
nsTHashtable<nsCertOverrideEntry> mSettingsTable MOZ_GUARDED_BY(mMutex);
|
||||
|
||||
|
||||
@@ -134,10 +134,43 @@ interface nsICertOverrideService : nsISupports {
|
||||
/**
|
||||
* NOTE: This function is used only for testing!
|
||||
*
|
||||
* @param aDisable If true, disable all security check and make
|
||||
* @param aDisable If true, disable all security checks and make
|
||||
* hasMatchingOverride always return true.
|
||||
*/
|
||||
void setDisableAllSecurityChecksAndLetAttackersInterceptMyData(in boolean aDisable);
|
||||
void setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
||||
in boolean aDisable);
|
||||
|
||||
/**
|
||||
* NOTE: This function is used only for webdriver!
|
||||
* Spec: https://www.w3.org/TR/webdriver-bidi/#command-browser-createUserContext.
|
||||
*
|
||||
* The method is designed to enable or disable all security checks
|
||||
* for the specified user context. This settings should override the global state,
|
||||
* e.g., the security checks can be disabled globally but with this method they can
|
||||
* be enabled for the specified user context.
|
||||
*
|
||||
* @param aUserContextId Enable or disable all security checks for this user context.
|
||||
* @param aDisable If true, disable all security checks and make
|
||||
* hasMatchingOverride always return true.
|
||||
*/
|
||||
void setDisableAllSecurityChecksAndLetAttackersInterceptMyDataForUserContext(
|
||||
in uint32_t aUserContextId,
|
||||
in boolean aDisable);
|
||||
|
||||
/**
|
||||
* NOTE: This function is used only for webdriver!
|
||||
* Spec: https://www.w3.org/TR/webdriver-bidi/#cleanup-the-session.
|
||||
*
|
||||
* This method is required to reset the status of security checks
|
||||
* for the specified user context and fallback to the global state.
|
||||
* E.g., the user context can have security checks enabled
|
||||
* but globally they are disabled. After calling this method the security checks
|
||||
* for the user context should be disabled as it is globally.
|
||||
*
|
||||
* @param aUserContextId Reset the status of security checks for this user context.
|
||||
*/
|
||||
void resetDisableAllSecurityChecksAndLetAttackersInterceptMyDataForUserContext(
|
||||
in uint32_t aUserContextId);
|
||||
|
||||
readonly attribute boolean securityCheckDisabled;
|
||||
};
|
||||
|
||||
@@ -52,3 +52,5 @@ skip-if = ["os == 'linux'"]
|
||||
["browser_exportP12_passwordUI.js"]
|
||||
|
||||
["browser_loadPKCS11Module_ui.js"]
|
||||
|
||||
["browser_setDisableAllSecurityChecksAndLetAttackersInterceptMyData.js"]
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const { ContextualIdentityListener } = ChromeUtils.importESModule(
|
||||
"chrome://remote/content/shared/listeners/ContextualIdentityListener.sys.mjs"
|
||||
);
|
||||
|
||||
const PAGE_URL = "https://example.com/";
|
||||
const PAGE_WITH_EXPIRED_CERT = "https://expired.example.com/";
|
||||
|
||||
add_task(async function test_disable_all_security_checks_globally() {
|
||||
const certOverrideService = Cc[
|
||||
"@mozilla.org/security/certoverride;1"
|
||||
].getService(Ci.nsICertOverrideService);
|
||||
|
||||
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, PAGE_URL);
|
||||
const browser = gBrowser.selectedBrowser;
|
||||
|
||||
info("Loading and waiting for the cert error");
|
||||
let errorPageLoaded = BrowserTestUtils.waitForErrorPage(browser);
|
||||
BrowserTestUtils.startLoadingURIString(browser, PAGE_WITH_EXPIRED_CERT);
|
||||
await errorPageLoaded;
|
||||
|
||||
Assert.ok(true, "Error page is loaded");
|
||||
|
||||
info("Disable security checks");
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
||||
true
|
||||
);
|
||||
|
||||
const loadedPromise = BrowserTestUtils.browserLoaded(browser);
|
||||
BrowserTestUtils.startLoadingURIString(browser, PAGE_WITH_EXPIRED_CERT);
|
||||
await loadedPromise;
|
||||
Assert.ok(true, "Normal page is loaded");
|
||||
|
||||
info("Enable security checks");
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
||||
false
|
||||
);
|
||||
|
||||
errorPageLoaded = BrowserTestUtils.waitForErrorPage(browser);
|
||||
BrowserTestUtils.startLoadingURIString(browser, PAGE_WITH_EXPIRED_CERT);
|
||||
await errorPageLoaded;
|
||||
Assert.ok(true, "Error page is loaded");
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function test_disable_all_security_checks_for_user_context() {
|
||||
const certOverrideService = Cc[
|
||||
"@mozilla.org/security/certoverride;1"
|
||||
].getService(Ci.nsICertOverrideService);
|
||||
|
||||
const userContext = ContextualIdentityService.create("test_name");
|
||||
const { userContextId } = userContext;
|
||||
|
||||
const tabInUserContext = BrowserTestUtils.addTab(gBrowser, PAGE_URL, {
|
||||
userContextId,
|
||||
});
|
||||
const browserInUserContext = tabInUserContext.linkedBrowser;
|
||||
|
||||
info("Loading and waiting for the cert error in user context");
|
||||
let errorPageLoaded = BrowserTestUtils.waitForErrorPage(browserInUserContext);
|
||||
BrowserTestUtils.startLoadingURIString(
|
||||
browserInUserContext,
|
||||
PAGE_WITH_EXPIRED_CERT
|
||||
);
|
||||
await errorPageLoaded;
|
||||
|
||||
Assert.ok(true, "Error page is loaded");
|
||||
|
||||
info("Disable security checks for user context");
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyDataForUserContext(
|
||||
userContextId,
|
||||
true
|
||||
);
|
||||
|
||||
let loadedPromise = BrowserTestUtils.browserLoaded(browserInUserContext);
|
||||
BrowserTestUtils.startLoadingURIString(
|
||||
browserInUserContext,
|
||||
PAGE_WITH_EXPIRED_CERT
|
||||
);
|
||||
await loadedPromise;
|
||||
Assert.ok(true, "Normal page is loaded in user context");
|
||||
|
||||
const tabInDefaultUserContext = BrowserTestUtils.addTab(gBrowser, PAGE_URL);
|
||||
const browserInDefaultUserContext = tabInDefaultUserContext.linkedBrowser;
|
||||
|
||||
info("Loading and waiting for the cert error in default user context");
|
||||
errorPageLoaded = BrowserTestUtils.waitForErrorPage(
|
||||
browserInDefaultUserContext
|
||||
);
|
||||
BrowserTestUtils.startLoadingURIString(
|
||||
browserInDefaultUserContext,
|
||||
PAGE_WITH_EXPIRED_CERT
|
||||
);
|
||||
await errorPageLoaded;
|
||||
Assert.ok(true, "Error page is loaded");
|
||||
|
||||
BrowserTestUtils.removeTab(tabInUserContext);
|
||||
BrowserTestUtils.removeTab(tabInDefaultUserContext);
|
||||
ContextualIdentityService.remove(userContextId);
|
||||
});
|
||||
|
||||
add_task(
|
||||
async function test_disable_all_security_checks_globally_enable_for_user_context() {
|
||||
const certOverrideService = Cc[
|
||||
"@mozilla.org/security/certoverride;1"
|
||||
].getService(Ci.nsICertOverrideService);
|
||||
|
||||
const tabInDefaultUserContext = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
PAGE_URL
|
||||
);
|
||||
const browser = gBrowser.selectedBrowser;
|
||||
|
||||
info("Disable security checks");
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
||||
true
|
||||
);
|
||||
|
||||
let loadedPromise = BrowserTestUtils.browserLoaded(browser);
|
||||
BrowserTestUtils.startLoadingURIString(browser, PAGE_WITH_EXPIRED_CERT);
|
||||
await loadedPromise;
|
||||
Assert.ok(true, "Normal page is loaded");
|
||||
|
||||
const userContext = ContextualIdentityService.create("test_name");
|
||||
const { userContextId } = userContext;
|
||||
|
||||
const tabInUserContext = BrowserTestUtils.addTab(gBrowser, PAGE_URL, {
|
||||
userContextId,
|
||||
});
|
||||
const browserInUserContext = tabInUserContext.linkedBrowser;
|
||||
|
||||
info("Enable security checks for user context");
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyDataForUserContext(
|
||||
userContextId,
|
||||
false
|
||||
);
|
||||
|
||||
info("Loading and waiting for the cert error in user context");
|
||||
const errorPageLoaded =
|
||||
BrowserTestUtils.waitForErrorPage(browserInUserContext);
|
||||
BrowserTestUtils.startLoadingURIString(
|
||||
browserInUserContext,
|
||||
PAGE_WITH_EXPIRED_CERT
|
||||
);
|
||||
await errorPageLoaded;
|
||||
|
||||
Assert.ok(true, "Error page is loaded");
|
||||
|
||||
BrowserTestUtils.removeTab(tabInDefaultUserContext);
|
||||
BrowserTestUtils.removeTab(tabInUserContext);
|
||||
ContextualIdentityService.remove(userContextId);
|
||||
|
||||
info("Reenable security checks");
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
||||
false
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
add_task(
|
||||
async function test_reset_disable_all_security_checks_for_user_context() {
|
||||
const certOverrideService = Cc[
|
||||
"@mozilla.org/security/certoverride;1"
|
||||
].getService(Ci.nsICertOverrideService);
|
||||
|
||||
const userContext = ContextualIdentityService.create("test_name");
|
||||
const { userContextId } = userContext;
|
||||
|
||||
const tabInUserContext = BrowserTestUtils.addTab(gBrowser, PAGE_URL, {
|
||||
userContextId,
|
||||
});
|
||||
const browserInUserContext = tabInUserContext.linkedBrowser;
|
||||
|
||||
info("Loading and waiting for the cert error in user context");
|
||||
let errorPageLoaded =
|
||||
BrowserTestUtils.waitForErrorPage(browserInUserContext);
|
||||
BrowserTestUtils.startLoadingURIString(
|
||||
browserInUserContext,
|
||||
PAGE_WITH_EXPIRED_CERT
|
||||
);
|
||||
await errorPageLoaded;
|
||||
|
||||
Assert.ok(true, "Error page is loaded");
|
||||
|
||||
info("Disable security checks for user context");
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyDataForUserContext(
|
||||
userContextId,
|
||||
true
|
||||
);
|
||||
|
||||
let loadedPromise = BrowserTestUtils.browserLoaded(browserInUserContext);
|
||||
BrowserTestUtils.startLoadingURIString(
|
||||
browserInUserContext,
|
||||
PAGE_WITH_EXPIRED_CERT
|
||||
);
|
||||
await loadedPromise;
|
||||
Assert.ok(true, "Normal page is loaded in user context");
|
||||
|
||||
info("Reset disable security checks for user context");
|
||||
certOverrideService.resetDisableAllSecurityChecksAndLetAttackersInterceptMyDataForUserContext(
|
||||
userContextId
|
||||
);
|
||||
|
||||
errorPageLoaded = BrowserTestUtils.waitForErrorPage(browserInUserContext);
|
||||
BrowserTestUtils.startLoadingURIString(
|
||||
browserInUserContext,
|
||||
PAGE_WITH_EXPIRED_CERT
|
||||
);
|
||||
await errorPageLoaded;
|
||||
|
||||
Assert.ok(true, "Error page is loaded");
|
||||
|
||||
BrowserTestUtils.removeTab(tabInUserContext);
|
||||
ContextualIdentityService.remove(userContextId);
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user