Backed out 6 changesets (bug 1740263) for causing bp-hybrid bustages on nsScriptSecurityManager. CLOSED TREE

Backed out changeset 2f5ec6ad0f81 (bug 1740263)
Backed out changeset a1e7766cdb94 (bug 1740263)
Backed out changeset 3978ccb95455 (bug 1740263)
Backed out changeset e34ba774b3f8 (bug 1740263)
Backed out changeset 8365b10be28e (bug 1740263)
Backed out changeset d923462c9cd0 (bug 1740263)
This commit is contained in:
Iulian Moraru
2022-05-19 03:28:08 +03:00
parent acf1a00d35
commit 979c59be19
47 changed files with 175 additions and 586 deletions

View File

@@ -20,11 +20,6 @@ interface nsIAddonPolicyService : nsISupports
*/
readonly attribute AString defaultCSP;
/**
* Same as above, but used for extensions using manifest v3.
*/
readonly attribute AString defaultCSPV3;
/**
* Returns the base content security policy which applies to all extension resources.
*/
@@ -84,14 +79,13 @@ interface nsIAddonContentPolicy : nsISupports
/* options to pass to validateAddonCSP
*
* Manifest V2 uses CSP_ALLOW_ANY.
* In Manifest V3, extension_pages would use CSP_ALLOW_LOCALHOST|CSP_ALLOW_WASM
* and sandbox would use CSP_ALLOW_EVAL.
* In Manifest V3, extension_pages would use CSP_ALLOW_LOCALHOST and
* sandbox would use CSP_ALLOW_EVAL.
*/
const unsigned long CSP_ALLOW_ANY = 0xFFFF;
const unsigned long CSP_ALLOW_LOCALHOST = (1<<0);
const unsigned long CSP_ALLOW_EVAL = (1<<1);
const unsigned long CSP_ALLOW_REMOTE = (1<<2);
const unsigned long CSP_ALLOW_WASM = (1<<3);
/**
* Checks a custom content security policy string, to ensure that it meets

View File

@@ -448,7 +448,7 @@ NS_IMPL_ISUPPORTS(nsScriptSecurityManager, nsIScriptSecurityManager)
///////////////// Security Checks /////////////////
bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
JSContext* cx, JS::RuntimeCode aKind, JS::Handle<JSString*> aCode) {
JSContext* cx, JS::HandleString aCode) {
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
// Get the window, if any, corresponding to the current global
@@ -484,14 +484,12 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
bool evalOK = true;
bool reportViolation = false;
nsAutoJSString scriptSample;
if (aKind == JS::RuntimeCode::JS) {
nsresult rv = csp->GetAllowsEval(&reportViolation, &evalOK);
// A little convoluted. We want the scriptSample for a) reporting a
// violation or b) passing it to AssertEvalNotUsingSystemPrincipal or c)
// we're in the parent process. So do the work to get it if either of those
// cases is true.
// A little convoluted. We want the scriptSample for a) reporting a violation
// or b) passing it to AssertEvalNotUsingSystemPrincipal or c) we're in the
// parent process. So do the work to get it if either of those cases is true.
nsAutoJSString scriptSample;
if (reportViolation || subjectPrincipal->IsSystemPrincipal() ||
XRE_IsE10sParentProcess()) {
if (NS_WARN_IF(!scriptSample.init(cx, aCode))) {
@@ -511,11 +509,6 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
NS_WARNING("CSP: failed to get allowsEval");
return true; // fail open to not break sites.
}
} else {
if (NS_FAILED(csp->GetAllowsWasmEval(&reportViolation, &evalOK))) {
return false;
}
}
if (reportViolation) {
JS::AutoFilename scriptFilename;
@@ -529,12 +522,7 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
} else {
MOZ_ASSERT(!JS_IsExceptionPending(cx));
}
uint16_t violationType =
aKind == JS::RuntimeCode::JS
? nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL
: nsIContentSecurityPolicy::VIOLATION_TYPE_WASM_EVAL;
csp->LogViolationDetails(violationType,
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
nullptr, // triggering element
cspEventListener, fileName, scriptSample, lineNum,
columnNum, u""_ns, u""_ns);

View File

@@ -90,8 +90,7 @@ class nsScriptSecurityManager final : public nsIScriptSecurityManager {
// Decides, based on CSP, whether or not eval() and stuff can be executed.
static bool ContentSecurityPolicyPermitsJSAction(JSContext* cx,
JS::RuntimeCode kind,
JS::Handle<JSString*> aCode);
JS::HandleString aCode);
static bool JSPrincipalsSubsume(JSPrincipals* first, JSPrincipals* second);

View File

@@ -165,7 +165,7 @@ interface nsIContentSecurityPolicy : nsISerializable
in boolean aEnforceWhitelist);
/**
* Whether this policy allows eval and eval-like functions
* whether this policy allows eval and eval-like functions
* such as setTimeout("code string", time).
* @param shouldReportViolations
* Whether or not the use of eval should be reported.
@@ -178,20 +178,6 @@ interface nsIContentSecurityPolicy : nsISerializable
*/
boolean getAllowsEval(out boolean shouldReportViolations);
/**
* Whether this policy allows the evaluation (and compilation) of
* WASM code from functions like `WebAssembly.compile`.
* @param shouldReportViolations
* Whether or not the use of WASM evaluation should be reported.
* This function returns "true" when violating report-only policies, but
* when any policy (report-only or otherwise) is violated,
* shouldReportViolations is true as well.
* @return
* Whether or not the effects of the WASM evaluation should be allowed
* (block the call if false).
*/
boolean getAllowsWasmEval(out boolean shouldReportViolations);
/**
* Delegate method called by the service when the protected document is loaded.
* Returns the union of all the sandbox flags contained in CSP policies. This is the most
@@ -249,7 +235,6 @@ interface nsIContentSecurityPolicy : nsISerializable
const unsigned short VIOLATION_TYPE_HASH_STYLE = 7;
const unsigned short VIOLATION_TYPE_REQUIRE_SRI_FOR_STYLE = 8;
const unsigned short VIOLATION_TYPE_REQUIRE_SRI_FOR_SCRIPT = 9;
const unsigned short VIOLATION_TYPE_WASM_EVAL = 10;
/**
* Called after the CSP object is created to fill in appropriate request

View File

@@ -36,7 +36,6 @@ nsresult CheckInternal(nsIContentSecurityPolicy* aCSP,
// The value is set at any "return", but better to have a default value here.
*aAllowed = false;
// This is the non-CSP check for gating eval() use in the SystemPrincipal
#if !defined(ANDROID)
JSContext* cx = nsContentUtils::GetCurrentJSContext();
if (!nsContentSecurityUtils::IsEvalAllowed(

View File

@@ -40,7 +40,6 @@
#include "nsStringStream.h"
#include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
#include "mozilla/StaticPrefs_security.h"
#include "mozilla/dom/CSPReportBinding.h"
#include "mozilla/dom/CSPDictionariesBinding.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
@@ -118,10 +117,6 @@ static void BlockedContentSourceToString(
case nsCSPContext::BlockedContentSource::eSelf:
aString.AssignLiteral("self");
break;
case nsCSPContext::BlockedContentSource::eWasmEval:
aString.AssignLiteral("wasm-eval");
break;
}
}
@@ -476,36 +471,6 @@ nsCSPContext::GetAllowsEval(bool* outShouldReportViolation,
return NS_OK;
}
NS_IMETHODIMP
nsCSPContext::GetAllowsWasmEval(bool* outShouldReportViolation,
bool* outAllowsWasmEval) {
EnsureIPCPoliciesRead();
*outShouldReportViolation = false;
*outAllowsWasmEval = true;
if (!StaticPrefs::security_csp_wasm_unsafe_eval_enabled()) {
// Allow and don't report when wasm-unsafe-eval isn't supported.
return NS_OK;
}
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
// Either 'unsafe-eval' or 'wasm-unsafe-eval' can allow this
if (!mPolicies[i]->allows(SCRIPT_SRC_DIRECTIVE, CSP_WASM_UNSAFE_EVAL,
u""_ns, false) &&
!mPolicies[i]->allows(SCRIPT_SRC_DIRECTIVE, CSP_UNSAFE_EVAL, u""_ns,
false)) {
// policy is violated: must report the violation and allow the inline
// script if the policy is report-only.
*outShouldReportViolation = true;
if (!mPolicies[i]->getReportOnlyFlag()) {
*outAllowsWasmEval = false;
}
}
}
return NS_OK;
}
// Helper function to report inline violations
void nsCSPContext::reportInlineViolation(
CSPDirective aDirective, Element* aTriggeringElement,
@@ -754,11 +719,6 @@ nsCSPContext::GetAllowsNavigateTo(nsIURI* aURI, bool aIsFormSubmission,
bool reportSample = false; \
mPolicies[p]->getDirectiveStringAndReportSampleForContentType( \
directive##_SRC_DIRECTIVE, violatedDirective, &reportSample); \
if (aViolationType == nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL || \
aViolationType == \
nsIContentSecurityPolicy::VIOLATION_TYPE_WASM_EVAL) { \
violatedDirective = u"script-src"_ns; \
} \
AsyncReportViolation(aTriggeringElement, aCSPEventListener, nullptr, \
blockedContentSource, nullptr, violatedDirective, \
p, NS_LITERAL_STRING_FROM_CSTRING(observerTopic), \
@@ -805,9 +765,6 @@ nsCSPContext::LogViolationDetails(
BlockedContentSource blockedContentSource = BlockedContentSource::eUnknown;
if (aViolationType == nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL) {
blockedContentSource = BlockedContentSource::eEval;
} else if (aViolationType ==
nsIContentSecurityPolicy::VIOLATION_TYPE_WASM_EVAL) {
blockedContentSource = BlockedContentSource::eWasmEval;
} else if (aViolationType ==
nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT ||
aViolationType ==
@@ -834,8 +791,6 @@ nsCSPContext::LogViolationDetails(
SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC);
CASE_CHECK_AND_REPORT(HASH_STYLE, STYLE, aContent, CSP_UNSAFE_INLINE,
STYLE_HASH_VIOLATION_OBSERVER_TOPIC);
CASE_CHECK_AND_REPORT(WASM_EVAL, SCRIPT, u""_ns, CSP_WASM_UNSAFE_EVAL,
WASM_EVAL_VIOLATION_OBSERVER_TOPIC);
default:
NS_ASSERTION(false, "LogViolationDetails with invalid type");

View File

@@ -115,7 +115,6 @@ class nsCSPContext : public nsIContentSecurityPolicy {
eInline,
eEval,
eSelf,
eWasmEval,
};
nsresult AsyncReportViolation(

View File

@@ -381,8 +381,7 @@ nsCSPHostSrc* nsCSPParser::host() {
return new nsCSPHostSrc(mCurValue);
}
// keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'" /
// "'wasm-unsafe-eval'"
// keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'"
nsCSPBaseSrc* nsCSPParser::keywordSource() {
CSPPARSERLOG(("nsCSPParser::keywordSource, mCurToken: %s, mCurValue: %s",
NS_ConvertUTF16toUTF8(mCurToken).get(),
@@ -441,11 +440,6 @@ nsCSPBaseSrc* nsCSPParser::keywordSource() {
return new nsCSPKeywordSrc(CSP_UTF16KeywordToEnum(mCurToken));
}
if (StaticPrefs::security_csp_wasm_unsafe_eval_enabled() &&
CSP_IsKeyword(mCurToken, CSP_WASM_UNSAFE_EVAL)) {
return new nsCSPKeywordSrc(CSP_UTF16KeywordToEnum(mCurToken));
}
if (CSP_IsKeyword(mCurToken, CSP_UNSAFE_ALLOW_REDIRECTS)) {
if (!CSP_IsDirective(mCurDir[0],
nsIContentSecurityPolicy::NAVIGATE_TO_DIRECTIVE)) {

View File

@@ -880,12 +880,11 @@ bool nsCSPKeywordSrc::allows(enum CSPKeyword aKeyword,
}
// either the keyword allows the load or the policy contains 'strict-dynamic',
// in which case we have to make sure the script is not parser created before
// allowing the load and also eval & wasm-eval should be blocked even if
// 'strict-dynamic' is present. Should be allowed only if 'unsafe-eval' is
// present.
// allowing the load and also eval should be blocked even if 'strict-dynamic'
// is present. Should be allowed only if 'unsafe-eval' is present.
return ((mKeyword == aKeyword) ||
((mKeyword == CSP_STRICT_DYNAMIC) && !aParserCreated &&
aKeyword != CSP_UNSAFE_EVAL && aKeyword != CSP_WASM_UNSAFE_EVAL));
aKeyword != CSP_UNSAFE_EVAL));
}
bool nsCSPKeywordSrc::visit(nsCSPSrcVisitor* aVisitor) const {

View File

@@ -51,9 +51,6 @@ void CSP_LogMessage(const nsAString& aMessage, const nsAString& aSourceName,
"violated base restriction: Inline Scripts will not execute"
#define EVAL_VIOLATION_OBSERVER_TOPIC \
"violated base restriction: Code will not be created from strings"
#define WASM_EVAL_VIOLATION_OBSERVER_TOPIC \
"violated base restriction: WebAssembly code will not be created from " \
"dynamically"
#define SCRIPT_NONCE_VIOLATION_OBSERVER_TOPIC "Inline Script had invalid nonce"
#define STYLE_NONCE_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid nonce"
#define SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC "Inline Script had invalid hash"
@@ -116,8 +113,7 @@ inline CSPDirective CSP_StringToCSPDirective(const nsAString& aDir) {
MACRO(CSP_NONCE, "'nonce-") \
MACRO(CSP_REPORT_SAMPLE, "'report-sample'") \
MACRO(CSP_STRICT_DYNAMIC, "'strict-dynamic'") \
MACRO(CSP_UNSAFE_ALLOW_REDIRECTS, "'unsafe-allow-redirects'") \
MACRO(CSP_WASM_UNSAFE_EVAL, "'wasm-unsafe-eval'")
MACRO(CSP_UNSAFE_ALLOW_REDIRECTS, "'unsafe-allow-redirects'")
enum CSPKeyword {
#define KEYWORD_ENUM(id_, string_) id_,

View File

@@ -150,13 +150,9 @@ nsresult runTestSuite(const PolicyTest* aPolicies, uint32_t aPolicyCount,
nsresult rv;
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
bool navigateTo = false;
bool wasmUnsafeEval = false;
if (prefs) {
prefs->GetBoolPref("security.csp.enableNavigateTo", &navigateTo);
prefs->SetBoolPref("security.csp.enableNavigateTo", true);
prefs->GetBoolPref("security.csp.wasm-unsafe-eval.enabled",
&wasmUnsafeEval);
prefs->SetBoolPref("security.csp.wasm-unsafe-eval.enabled", true);
}
for (uint32_t i = 0; i < aPolicyCount; i++) {
@@ -167,7 +163,6 @@ nsresult runTestSuite(const PolicyTest* aPolicies, uint32_t aPolicyCount,
if (prefs) {
prefs->SetBoolPref("security.csp.enableNavigateTo", navigateTo);
prefs->SetBoolPref("security.csp.wasm-unsafe-eval.enabled", wasmUnsafeEval);
}
return NS_OK;
@@ -250,8 +245,6 @@ TEST(CSPParser, Keywords)
"script-src 'unsafe-inline' 'unsafe-eval'" },
{ "script-src 'none'",
"script-src 'none'" },
{ "script-src 'wasm-unsafe-eval'",
"script-src 'wasm-unsafe-eval'" },
{ "img-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; default-src 'self'",
"img-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; default-src 'self'" },
// clang-format on

View File

@@ -1759,9 +1759,7 @@ nsresult ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
// Default CSP permissions for now. These will be overrided if necessary
// based on the script CSP headers during load in ScriptLoader.
info.mEvalAllowed = true;
info.mReportEvalCSPViolations = false;
info.mWasmEvalAllowed = true;
info.mReportWasmEvalCSPViolations = false;
info.mReportCSPViolations = false;
WorkerPrivate::OverrideLoadInfoLoadGroup(info, info.mPrincipal);

View File

@@ -448,20 +448,17 @@ bool InterruptCallback(JSContext* aCx) {
}
class LogViolationDetailsRunnable final : public WorkerMainThreadRunnable {
uint16_t mViolationType;
nsString mFileName;
uint32_t mLineNum;
uint32_t mColumnNum;
nsString mScriptSample;
public:
LogViolationDetailsRunnable(WorkerPrivate* aWorker, uint16_t aViolationType,
const nsString& aFileName, uint32_t aLineNum,
uint32_t aColumnNum,
LogViolationDetailsRunnable(WorkerPrivate* aWorker, const nsString& aFileName,
uint32_t aLineNum, uint32_t aColumnNum,
const nsAString& aScriptSample)
: WorkerMainThreadRunnable(aWorker,
"RuntimeService :: LogViolationDetails"_ns),
mViolationType(aViolationType),
mFileName(aFileName),
mLineNum(aLineNum),
mColumnNum(aColumnNum),
@@ -475,36 +472,22 @@ class LogViolationDetailsRunnable final : public WorkerMainThreadRunnable {
~LogViolationDetailsRunnable() = default;
};
bool ContentSecurityPolicyAllows(JSContext* aCx, JS::RuntimeCode aKind,
JS::Handle<JSString*> aCode) {
bool ContentSecurityPolicyAllows(JSContext* aCx, JS::Handle<JSString*> aCode) {
WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
worker->AssertIsOnWorkerThread();
bool evalOK;
bool reportViolation;
uint16_t violationType;
nsAutoJSString scriptSample;
if (aKind == JS::RuntimeCode::JS) {
if (NS_WARN_IF(!scriptSample.init(aCx, aCode))) {
JS_ClearPendingException(aCx);
return false;
}
if (!nsContentSecurityUtils::IsEvalAllowed(
aCx, worker->UsesSystemPrincipal(), scriptSample)) {
if (!nsContentSecurityUtils::IsEvalAllowed(aCx, worker->UsesSystemPrincipal(),
scriptSample)) {
return false;
}
evalOK = worker->IsEvalAllowed();
reportViolation = worker->GetReportEvalCSPViolations();
violationType = nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL;
} else {
evalOK = worker->IsWasmEvalAllowed();
reportViolation = worker->GetReportWasmEvalCSPViolations();
violationType = nsIContentSecurityPolicy::VIOLATION_TYPE_WASM_EVAL;
}
if (reportViolation) {
if (worker->GetReportCSPViolations()) {
nsString fileName;
uint32_t lineNum = 0;
uint32_t columnNum = 0;
@@ -518,8 +501,8 @@ bool ContentSecurityPolicyAllows(JSContext* aCx, JS::RuntimeCode aKind,
}
RefPtr<LogViolationDetailsRunnable> runnable =
new LogViolationDetailsRunnable(worker, violationType, fileName,
lineNum, columnNum, scriptSample);
new LogViolationDetailsRunnable(worker, fileName, lineNum, columnNum,
scriptSample);
ErrorResult rv;
runnable->Dispatch(Killing, rv);
@@ -528,7 +511,7 @@ bool ContentSecurityPolicyAllows(JSContext* aCx, JS::RuntimeCode aKind,
}
}
return evalOK;
return worker->IsEvalAllowed();
}
void CTypesActivityCallback(JSContext* aCx, JS::CTypesActivityType aType) {
@@ -1966,12 +1949,14 @@ bool LogViolationDetailsRunnable::MainThreadRun() {
nsIContentSecurityPolicy* csp = mWorkerPrivate->GetCSP();
if (csp) {
csp->LogViolationDetails(mViolationType,
if (mWorkerPrivate->GetReportCSPViolations()) {
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
nullptr, // triggering element
mWorkerPrivate->CSPEventListener(), mFileName,
mScriptSample, mLineNum, mColumnNum, u""_ns,
u""_ns);
}
}
return true;
}

View File

@@ -90,9 +90,7 @@ WorkerLoadInfoData::WorkerLoadInfoData()
mPrincipalHashValue(0),
mFromWindow(false),
mEvalAllowed(false),
mReportEvalCSPViolations(false),
mWasmEvalAllowed(false),
mReportWasmEvalCSPViolations(false),
mReportCSPViolations(false),
mXHRParamsAllowed(false),
mPrincipalIsSystem(false),
mPrincipalIsAddonOrExpandedAddon(false),
@@ -120,8 +118,7 @@ nsresult WorkerLoadInfo::SetPrincipalsAndCSPOnMainThread(
mCSP = aCsp;
if (mCSP) {
mCSP->GetAllowsEval(&mReportEvalCSPViolations, &mEvalAllowed);
mCSP->GetAllowsWasmEval(&mReportWasmEvalCSPViolations, &mWasmEvalAllowed);
mCSP->GetAllowsEval(&mReportCSPViolations, &mEvalAllowed);
mCSPInfo = MakeUnique<CSPInfo>();
nsresult rv = CSPToCSPInfo(aCsp, mCSPInfo.get());
if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -129,9 +126,7 @@ nsresult WorkerLoadInfo::SetPrincipalsAndCSPOnMainThread(
}
} else {
mEvalAllowed = true;
mReportEvalCSPViolations = false;
mWasmEvalAllowed = true;
mReportWasmEvalCSPViolations = false;
mReportCSPViolations = false;
}
mLoadGroup = aLoadGroup;

View File

@@ -134,9 +134,7 @@ struct WorkerLoadInfoData {
OriginTrials mTrials;
bool mFromWindow;
bool mEvalAllowed;
bool mReportEvalCSPViolations;
bool mWasmEvalAllowed;
bool mReportWasmEvalCSPViolations;
bool mReportCSPViolations;
bool mXHRParamsAllowed;
bool mPrincipalIsSystem;
bool mPrincipalIsAddonOrExpandedAddon;

View File

@@ -1419,25 +1419,15 @@ nsresult WorkerPrivate::SetCSPFromHeaderValues(
NS_ENSURE_SUCCESS(rv, rv);
}
mLoadInfo.mCSP = csp;
// Set evalAllowed, default value is set in GetAllowsEval
bool evalAllowed = false;
bool reportEvalViolations = false;
rv = csp->GetAllowsEval(&reportEvalViolations, &evalAllowed);
NS_ENSURE_SUCCESS(rv, rv);
mLoadInfo.mCSP = csp;
mLoadInfo.mEvalAllowed = evalAllowed;
mLoadInfo.mReportEvalCSPViolations = reportEvalViolations;
// Set wasmEvalAllowed
bool wasmEvalAllowed = false;
bool reportWasmEvalViolations = false;
rv = csp->GetAllowsWasmEval(&reportWasmEvalViolations, &wasmEvalAllowed);
NS_ENSURE_SUCCESS(rv, rv);
mLoadInfo.mWasmEvalAllowed = wasmEvalAllowed;
mLoadInfo.mReportWasmEvalCSPViolations = reportWasmEvalViolations;
mLoadInfo.mReportCSPViolations = reportEvalViolations;
mLoadInfo.mCSPInfo = MakeUnique<CSPInfo>();
rv = CSPToCSPInfo(csp, mLoadInfo.mCSPInfo.get());

View File

@@ -822,28 +822,14 @@ class WorkerPrivate final
bool IsEvalAllowed() const { return mLoadInfo.mEvalAllowed; }
void SetEvalAllowed(bool aAllowed) { mLoadInfo.mEvalAllowed = aAllowed; }
bool GetReportEvalCSPViolations() const {
return mLoadInfo.mReportEvalCSPViolations;
void SetEvalAllowed(bool aEvalAllowed) {
mLoadInfo.mEvalAllowed = aEvalAllowed;
}
void SetReportEvalCSPViolations(bool aReport) {
mLoadInfo.mReportEvalCSPViolations = aReport;
}
bool GetReportCSPViolations() const { return mLoadInfo.mReportCSPViolations; }
bool IsWasmEvalAllowed() const { return mLoadInfo.mWasmEvalAllowed; }
void SetWasmEvalAllowed(bool aAllowed) {
mLoadInfo.mWasmEvalAllowed = aAllowed;
}
bool GetReportWasmEvalCSPViolations() const {
return mLoadInfo.mReportWasmEvalCSPViolations;
}
void SetReportWasmEvalCSPViolations(bool aReport) {
mLoadInfo.mReportWasmEvalCSPViolations = aReport;
void SetReportCSPViolations(bool aReport) {
mLoadInfo.mReportCSPViolations = aReport;
}
bool XHRParamsAllowed() const { return mLoadInfo.mXHRParamsAllowed; }

View File

@@ -568,7 +568,6 @@ void CacheLoadHandler::DataReceived() {
// Set Eval and ContentSecurityPolicy
mWorkerPrivate->SetCSP(parent->GetCSP());
mWorkerPrivate->SetEvalAllowed(parent->IsEvalAllowed());
mWorkerPrivate->SetWasmEvalAllowed(parent->IsWasmEvalAllowed());
}
}
}

View File

@@ -378,9 +378,7 @@ nsresult RemoteWorkerChild::ExecWorkerOnMainThread(RemoteWorkerData&& aData) {
// Default CSP permissions for now. These will be overrided if necessary
// based on the script CSP headers during load in ScriptLoader.
info.mEvalAllowed = true;
info.mReportEvalCSPViolations = false;
info.mWasmEvalAllowed = true;
info.mReportWasmEvalCSPViolations = false;
info.mReportCSPViolations = false;
info.mSecureContext = aData.isSecureContext()
? WorkerLoadInfo::eSecureContext
: WorkerLoadInfo::eInsecureContext;

View File

@@ -66,22 +66,11 @@ extern JS_PUBLIC_API void JS_DropPrincipals(JSContext* cx,
// engine when determining, e.g., which stack frames to display in a backtrace.
typedef bool (*JSSubsumesOp)(JSPrincipals* first, JSPrincipals* second);
namespace JS {
enum class RuntimeCode { JS, WASM };
} // namespace JS
/*
* Used to check if a CSP instance wants to disable eval() and friends.
* See JSContext::isRuntimeCodeGenEnabled() in vm/JSContext.cpp.
*
* `code` is the JavaScript source code passed to eval/Function, but nullptr
* for Wasm.
*
* Returning `false` from this callback will prevent the execution/compilation
* of the code.
* See GlobalObject::isRuntimeCodeGenEnabled() in vm/GlobalObject.cpp.
*/
typedef bool (*JSCSPEvalChecker)(JSContext* cx, JS::RuntimeCode kind,
JS::HandleString code);
typedef bool (*JSCSPEvalChecker)(JSContext* cx, JS::HandleString code);
struct JSSecurityCallbacks {
JSCSPEvalChecker contentSecurityPolicyAllows;

View File

@@ -180,7 +180,6 @@ MSG_DEF(JSMSG_TOO_MANY_ARGUMENTS, 0, JSEXN_RANGEERR, "too many arguments pr
// CSP
MSG_DEF(JSMSG_CSP_BLOCKED_EVAL, 0, JSEXN_EVALERR, "call to eval() blocked by CSP")
MSG_DEF(JSMSG_CSP_BLOCKED_FUNCTION, 0, JSEXN_EVALERR, "call to Function() blocked by CSP")
MSG_DEF(JSMSG_CSP_BLOCKED_WASM, 1, JSEXN_WASMCOMPILEERROR, "call to {0}() blocked by CSP")
// Wrappers
MSG_DEF(JSMSG_ACCESSOR_DEF_DENIED, 1, JSEXN_ERR, "Permission denied to define accessor property {0}")

View File

@@ -238,7 +238,7 @@ static bool EvalKernel(JSContext* cx, HandleValue v, EvalType evalType,
// Steps 3-4.
RootedString str(cx, v.toString());
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, str)) {
if (!GlobalObject::isRuntimeCodeGenEnabled(cx, str, cx->global())) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_CSP_BLOCKED_EVAL);
return false;

View File

@@ -672,6 +672,20 @@ bool GlobalObject::initStandardClasses(JSContext* cx,
return true;
}
/* static */
bool GlobalObject::isRuntimeCodeGenEnabled(JSContext* cx, HandleString code,
Handle<GlobalObject*> global) {
// If there are callbacks, make sure that the CSP callback is installed
// and that it permits runtime code generation.
JSCSPEvalChecker allows =
cx->runtime()->securityCallbacks->contentSecurityPolicyAllows;
if (allows) {
return allows(cx, code);
}
return true;
}
/* static */
JSFunction* GlobalObject::createConstructor(JSContext* cx, Native ctor,
JSAtom* nameArg, unsigned length,

View File

@@ -964,6 +964,9 @@ class GlobalObject : public NativeObject {
static JSObject* getOrCreateThrowTypeError(JSContext* cx,
Handle<GlobalObject*> global);
static bool isRuntimeCodeGenEnabled(JSContext* cx, HandleString code,
Handle<GlobalObject*> global);
static bool getOrCreateEval(JSContext* cx, Handle<GlobalObject*> global,
MutableHandleObject eval);

View File

@@ -1188,18 +1188,6 @@ bool JSContext::isThrowingDebuggeeWouldRun() {
JSEXN_DEBUGGEEWOULDRUN;
}
bool JSContext::isRuntimeCodeGenEnabled(JS::RuntimeCode kind,
HandleString code) {
// Make sure that the CSP callback is installed and that it permits runtime
// code generation.
if (JSCSPEvalChecker allows =
runtime()->securityCallbacks->contentSecurityPolicyAllows) {
return allows(this, kind, code);
}
return true;
}
size_t JSContext::sizeOfExcludingThis(
mozilla::MallocSizeOf mallocSizeOf) const {
/*

View File

@@ -818,10 +818,6 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext,
*/
inline bool runningWithTrustedPrincipals();
// Checks if the page's Content-Security-Policy (CSP) allows
// runtime code generation "unsafe-eval", or "wasm-unsafe-eval" for Wasm.
bool isRuntimeCodeGenEnabled(JS::RuntimeCode kind, js::HandleString code);
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;

View File

@@ -1621,7 +1621,8 @@ static bool CreateDynamicFunction(JSContext* cx, const CallArgs& args,
}
// Block this call if security callbacks forbid it.
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, functionText)) {
Handle<GlobalObject*> global = cx->global();
if (!GlobalObject::isRuntimeCodeGenEnabled(cx, functionText, global)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_CSP_BLOCKED_FUNCTION);
return false;

View File

@@ -1796,12 +1796,6 @@ bool WasmModuleObject::construct(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_CSP_BLOCKED_WASM, "WebAssembly.Module");
return false;
}
if (!callArgs.requireAtLeast(cx, "WebAssembly.Module", 1)) {
return false;
}
@@ -4735,12 +4729,6 @@ static bool WebAssembly_compile(JSContext* cx, unsigned argc, Value* vp) {
CallArgs callArgs = CallArgsFromVp(argc, vp);
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_CSP_BLOCKED_WASM, "WebAssembly.compile");
return RejectWithPendingException(cx, promise, callArgs);
}
auto task = cx->make_unique<CompileBufferTask>(cx, promise);
if (!task || !task->init(cx, callArgs.get(1), "WebAssembly.compile")) {
return false;
@@ -4802,13 +4790,6 @@ static bool WebAssembly_instantiate(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
} else {
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_CSP_BLOCKED_WASM,
"WebAssembly.instantiate");
return RejectWithPendingException(cx, promise, callArgs);
}
auto task = cx->make_unique<CompileBufferTask>(cx, promise, importObj);
if (!task || !task->init(cx, callArgs.get(2), "WebAssembly.instantiate")) {
return false;
@@ -5380,13 +5361,6 @@ static bool WebAssembly_compileStreaming(JSContext* cx, unsigned argc,
CallArgs callArgs = CallArgsFromVp(argc, vp);
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_CSP_BLOCKED_WASM,
"WebAssembly.compileStreaming");
return RejectWithPendingException(cx, promise, callArgs);
}
if (!ResolveResponse(cx, callArgs, promise)) {
return RejectWithPendingException(cx, promise, callArgs);
}
@@ -5410,13 +5384,6 @@ static bool WebAssembly_instantiateStreaming(JSContext* cx, unsigned argc,
CallArgs callArgs = CallArgsFromVp(argc, vp);
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_CSP_BLOCKED_WASM,
"WebAssembly.instantiateStreaming");
return RejectWithPendingException(cx, promise, callArgs);
}
RootedObject firstArg(cx);
RootedObject importObj(cx);
if (!GetInstantiateArgs(cx, callArgs, &firstArg, &importObj)) {

View File

@@ -265,12 +265,6 @@ JSObject* Module::createObject(JSContext* cx) const {
return nullptr;
}
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_CSP_BLOCKED_WASM, "WebAssembly.Module");
return nullptr;
}
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmModule));
return WasmModuleObject::create(cx, *this, proto);
}

View File

@@ -12032,12 +12032,6 @@
value: false
mirror: always
# wasm-unsafe-eval source keyword
- name: security.csp.wasm-unsafe-eval.enabled
type: bool
value: true
mirror: always
# No way to enable on Android, Bug 1552602
- name: security.webauth.u2f
type: bool

View File

@@ -3679,10 +3679,9 @@ pref("extensions.webcompat-reporter.newIssueEndpoint", "https://webcompat.com/is
#endif
// Add-on content security policies.
pref("extensions.webextensions.base-content-security-policy", "script-src 'self' https://* http://localhost:* http://127.0.0.1:* moz-extension: blob: filesystem: 'unsafe-eval' 'wasm-unsafe-eval' 'unsafe-inline'; object-src 'self' moz-extension: blob: filesystem:;");
pref("extensions.webextensions.base-content-security-policy.v3", "script-src 'self' 'wasm-unsafe-eval' http://localhost:* http://127.0.0.1:*; object-src 'self';");
pref("extensions.webextensions.default-content-security-policy", "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';");
pref("extensions.webextensions.default-content-security-policy.v3", "script-src 'self'; object-src 'self';");
pref("extensions.webextensions.base-content-security-policy", "script-src 'self' https://* http://localhost:* http://127.0.0.1:* moz-extension: blob: filesystem: 'unsafe-eval' 'unsafe-inline'; object-src 'self' moz-extension: blob: filesystem:;");
pref("extensions.webextensions.base-content-security-policy.v3", "script-src 'self' http://localhost:* http://127.0.0.1:*; object-src 'self';");
pref("extensions.webextensions.default-content-security-policy", "script-src 'self'; object-src 'self';");
pref("network.buffer.cache.count", 24);

View File

@@ -0,0 +1,18 @@
[default-src-blocks-wasm.any.serviceworker.html]
[default-src-blocks-wasm]
expected: FAIL
[default-src-blocks-wasm.any.html]
[default-src-blocks-wasm]
expected: FAIL
[default-src-blocks-wasm.any.sharedworker.html]
[default-src-blocks-wasm]
expected: FAIL
[default-src-blocks-wasm.any.worker.html]
[default-src-blocks-wasm]
expected: FAIL

View File

@@ -0,0 +1,18 @@
[script-src-blocks-wasm.any.sharedworker.html]
[script-src-blocks-wasm]
expected: FAIL
[script-src-blocks-wasm.any.html]
[script-src-blocks-wasm]
expected: FAIL
[script-src-blocks-wasm.any.worker.html]
[script-src-blocks-wasm]
expected: FAIL
[script-src-blocks-wasm.any.serviceworker.html]
[script-src-blocks-wasm]
expected: FAIL

View File

@@ -0,0 +1,22 @@
[script-src-spv-asynch.any.sharedworker.html]
expected: TIMEOUT
[Securitypolicyviolation event looks like it should]
expected: TIMEOUT
[script-src-spv-asynch.any.html]
expected: TIMEOUT
[Securitypolicyviolation event looks like it should]
expected: TIMEOUT
[script-src-spv-asynch.any.serviceworker.html]
expected: TIMEOUT
[Securitypolicyviolation event looks like it should]
expected: TIMEOUT
[script-src-spv-asynch.any.worker.html]
expected: TIMEOUT
[Securitypolicyviolation event looks like it should]
expected: TIMEOUT

View File

@@ -1,31 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>eval-in-iframe</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
</head>
<body>
<iframe src="/content-security-policy/wasm-unsafe-eval/support/iframe.html">
</iframe>
<script>
async_test(t => {
self.addEventListener('message', t.step_func_done(({data}) => {
assert_equals(data.violatedDirective, "script-src");
assert_equals(data.originalPolicy, "default-src 'unsafe-inline'")
assert_equals(data.blockedURI, "wasm-eval")
}));
}, "Got the expected securitypolicyviolation in the iframe");
const iframe = document.querySelector('iframe');
iframe.addEventListener('load', () => {
let m = new WebAssembly.Module(
new Uint8Array([0, 0x61, 0x73, 0x6d, 0x1, 0, 0, 0]));
iframe.contentWindow.postMessage(m);
});
</script>
</body>
</html>

View File

@@ -1,15 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>iframe</h1>
<script>
self.addEventListener('securitypolicyviolation', e => {
window.parent.postMessage({ violatedDirective: e.violatedDirective,
originalPolicy: e.originalPolicy, blockedURI: e.blockedURI });
});
</script>
</body>
</html>

View File

@@ -1 +0,0 @@
Content-Security-Policy: default-src 'unsafe-inline'

View File

@@ -47,12 +47,7 @@ using dom::Promise;
#define DEFAULT_CSP_PREF \
"extensions.webextensions.default-content-security-policy"
#define DEFAULT_DEFAULT_CSP \
"script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
#define DEFAULT_CSP_PREF_V3 \
"extensions.webextensions.default-content-security-policy.v3"
#define DEFAULT_DEFAULT_CSP_V3 "script-src 'self'; object-src 'self';"
#define DEFAULT_DEFAULT_CSP "script-src 'self'; object-src 'self';"
#define OBS_TOPIC_PRELOAD_SCRIPT "web-extension-preload-content-script"
#define OBS_TOPIC_LOAD_SCRIPT "web-extension-load-content-script"
@@ -94,7 +89,6 @@ ExtensionPolicyService::ExtensionPolicyService() {
MOZ_RELEASE_ASSERT(mObs);
mDefaultCSP.SetIsVoid(true);
mDefaultCSPV3.SetIsVoid(true);
RegisterObservers();
}
@@ -219,7 +213,6 @@ void ExtensionPolicyService::RegisterObservers() {
}
Preferences::AddStrongObserver(this, DEFAULT_CSP_PREF);
Preferences::AddStrongObserver(this, DEFAULT_CSP_PREF_V3);
}
void ExtensionPolicyService::UnregisterObservers() {
@@ -230,7 +223,6 @@ void ExtensionPolicyService::UnregisterObservers() {
}
Preferences::RemoveObserver(this, DEFAULT_CSP_PREF);
Preferences::RemoveObserver(this, DEFAULT_CSP_PREF_V3);
}
nsresult ExtensionPolicyService::Observe(nsISupports* aSubject,
@@ -252,8 +244,6 @@ nsresult ExtensionPolicyService::Observe(nsISupports* aSubject,
const char* pref = converted.get();
if (!strcmp(pref, DEFAULT_CSP_PREF)) {
mDefaultCSP.SetIsVoid(true);
} else if (!strcmp(pref, DEFAULT_CSP_PREF_V3)) {
mDefaultCSPV3.SetIsVoid(true);
}
}
return NS_OK;
@@ -531,19 +521,6 @@ nsresult ExtensionPolicyService::GetDefaultCSP(nsAString& aDefaultCSP) {
return NS_OK;
}
nsresult ExtensionPolicyService::GetDefaultCSPV3(nsAString& aDefaultCSP) {
if (mDefaultCSPV3.IsVoid()) {
nsresult rv = Preferences::GetString(DEFAULT_CSP_PREF_V3, mDefaultCSPV3);
if (NS_FAILED(rv)) {
mDefaultCSPV3.AssignLiteral(DEFAULT_DEFAULT_CSP_V3);
}
mDefaultCSPV3.SetIsVoid(false);
}
aDefaultCSP.Assign(mDefaultCSPV3);
return NS_OK;
}
nsresult ExtensionPolicyService::GetBaseCSP(const nsAString& aAddonId,
nsAString& aResult) {
if (WebExtensionPolicy* policy = GetByID(aAddonId)) {

View File

@@ -120,7 +120,6 @@ class ExtensionPolicyService final : public nsIAddonPolicyService,
nsCOMPtr<nsIObserverService> mObs;
nsString mDefaultCSP;
nsString mDefaultCSPV3;
};
} // namespace mozilla

View File

@@ -1141,14 +1141,13 @@ const FORMATS = {
},
contentSecurityPolicy(string, context) {
// Manifest V3 extension_pages allows localhost and WASM. When sandbox is
// Manifest V3 extension_pages allows localhost. When sandbox is
// implemented, or any other V3 or later directive, the flags
// logic will need to be updated.
let flags =
context.manifestVersion < 3
? Ci.nsIAddonContentPolicy.CSP_ALLOW_ANY
: Ci.nsIAddonContentPolicy.CSP_ALLOW_LOCALHOST |
Ci.nsIAddonContentPolicy.CSP_ALLOW_WASM;
: Ci.nsIAddonContentPolicy.CSP_ALLOW_LOCALHOST;
let error = contentPolicyService.validateAddonCSP(string, flags);
if (error != null) {
// The CSP validation error is not reported as part of the "choices" error message,

View File

@@ -43,15 +43,15 @@ static const char kBackgroundPageHTMLEnd[] =
#define BASE_CSP_PREF_V2 "extensions.webextensions.base-content-security-policy"
#define DEFAULT_BASE_CSP_V2 \
"script-src 'self' https://* http://localhost:* http://127.0.0.1:* " \
"moz-extension: blob: filesystem: 'unsafe-eval' 'wasm-unsafe-eval' " \
"'unsafe-inline'; object-src 'self' moz-extension: blob: filesystem:;"
"script-src 'self' https://* moz-extension: blob: filesystem: " \
"'unsafe-eval' 'unsafe-inline'; " \
"object-src 'self' https://* moz-extension: blob: filesystem:;"
#define BASE_CSP_PREF_V3 \
"extensions.webextensions.base-content-security-policy.v3"
#define DEFAULT_BASE_CSP_V3 \
"script-src 'self' 'wasm-unsafe-eval' http://localhost:* " \
"http://127.0.0.1:*; object-src 'self';"
"script-src 'self'; object-src 'self'; " \
"style-src 'self'; worker-src 'self';"
static const char kRestrictedDomainPref[] =
"extensions.webextensions.restrictedDomains";
@@ -196,11 +196,7 @@ WebExtensionPolicy::WebExtensionPolicy(GlobalObject& aGlobal,
InitializeBaseCSP();
if (mExtensionPageCSP.IsVoid()) {
if (mManifestVersion < 3) {
EPS().GetDefaultCSP(mExtensionPageCSP);
} else {
EPS().GetDefaultCSPV3(mExtensionPageCSP);
}
}
mWebAccessibleResources.SetCapacity(aInit.mWebAccessibleResources.Length());
@@ -258,7 +254,6 @@ void WebExtensionPolicy::InitializeBaseCSP() {
}
return;
}
// Version 3 or higher.
nsresult rv = Preferences::GetString(BASE_CSP_PREF_V3, mBaseCSP);
if (NS_FAILED(rv)) {

View File

@@ -75,7 +75,7 @@ add_task(async function test_policy_csp() {
policyData: {
manifestVersion: 3,
},
expectedPolicy: aps.defaultCSPV3,
expectedPolicy: aps.defaultCSP,
},
{
name: "manifest 3 version set, custom extensionPage policy",
@@ -143,7 +143,7 @@ add_task(async function test_extension_csp() {
{
name: "manifest_v2 allows https protocol",
manifest: {
manifest_version: 2,
manifest_version: 3,
content_security_policy: {
extension_pages: `script-src 'self' https://*; object-src 'self'`,
},
@@ -153,23 +153,13 @@ add_task(async function test_extension_csp() {
{
name: "manifest_v2 allows unsafe-eval",
manifest: {
manifest_version: 2,
manifest_version: 3,
content_security_policy: {
extension_pages: `script-src 'self' 'unsafe-eval'; object-src 'self'`,
},
},
expectedPolicy: aps.defaultCSP,
},
{
name: "manifest_v2 allows wasm-unsafe-eval",
manifest: {
manifest_version: 2,
content_security_policy: {
extension_pages: `script-src 'self' 'wasm-unsafe-eval'; object-src 'self'`,
},
},
expectedPolicy: aps.defaultCSP,
},
{
name: "manifest_v3 invalid csp results in default csp used",
manifest: {
@@ -178,7 +168,7 @@ add_task(async function test_extension_csp() {
extension_pages: `script-src 'none'`,
},
},
expectedPolicy: aps.defaultCSPV3,
expectedPolicy: aps.defaultCSP,
},
{
name: "manifest_v3 forbidden protocol results in default csp used",
@@ -188,7 +178,7 @@ add_task(async function test_extension_csp() {
extension_pages: `script-src 'self' https://*; object-src 'self'`,
},
},
expectedPolicy: aps.defaultCSPV3,
expectedPolicy: aps.defaultCSP,
},
{
name: "manifest_v3 forbidden eval results in default csp used",
@@ -198,7 +188,7 @@ add_task(async function test_extension_csp() {
extension_pages: `script-src 'self' 'unsafe-eval'; object-src 'self'`,
},
},
expectedPolicy: aps.defaultCSPV3,
expectedPolicy: aps.defaultCSP,
},
{
name: "manifest_v3 allows localhost",
@@ -220,16 +210,6 @@ add_task(async function test_extension_csp() {
},
expectedPolicy: `script-src 'self' https://127.0.0.1; object-src 'self'`,
},
{
name: "manifest_v3 allows wasm-unsafe-eval",
manifest: {
manifest_version: 3,
content_security_policy: {
extension_pages: `script-src 'self' 'wasm-unsafe-eval'; object-src 'self'`,
},
},
expectedPolicy: `script-src 'self' 'wasm-unsafe-eval'; object-src 'self'`,
},
{
name: "manifest_v2 csp",
manifest: {
@@ -250,7 +230,7 @@ add_task(async function test_extension_csp() {
manifest: {
manifest_version: 3,
},
expectedPolicy: aps.defaultCSPV3,
expectedPolicy: aps.defaultCSP,
},
{
name: "manifest_v3 syntax used",

View File

@@ -42,25 +42,6 @@ add_task(async function test_csp_validator_flags() {
"eval allowed"
);
checkPolicy(
"default-src 'self'; script-src 'self' 'wasm-unsafe-eval'",
0,
"\u2018script-src\u2019 directive contains a forbidden 'wasm-unsafe-eval' keyword",
"wasm disallowed"
);
checkPolicy(
"default-src 'self'; script-src 'self' 'wasm-unsafe-eval'",
flags.CSP_ALLOW_WASM,
null,
"wasm allowed"
);
checkPolicy(
"default-src 'self'; script-src 'self' 'unsafe-eval' 'wasm-unsafe-eval'",
flags.CSP_ALLOW_EVAL,
null,
"wasm and eval allowed"
);
checkPolicy(
"default-src 'self'; script-src 'self' https://example.com",
0,

View File

@@ -17,12 +17,10 @@ server.registerPathHandler("/worker.js", (request, response) => {
});
const baseCSP = [];
// Keep in sync with extensions.webextensions.base-content-security-policy
baseCSP[2] = {
"object-src": ["blob:", "filesystem:", "moz-extension:", "'self'"],
"script-src": [
"'unsafe-eval'",
"'wasm-unsafe-eval'",
"'unsafe-inline'",
"blob:",
"filesystem:",
@@ -33,21 +31,10 @@ baseCSP[2] = {
"'self'",
],
};
// Keep in sync with extensions.webextensions.base-content-security-policy.v3
baseCSP[3] = {
"object-src": ["'self'"],
"script-src": [
"http://localhost:*",
"http://127.0.0.1:*",
"'self'",
"'wasm-unsafe-eval'",
],
"worker-src": [
"http://localhost:*",
"http://127.0.0.1:*",
"'self'",
"'wasm-unsafe-eval'",
],
"script-src": ["http://localhost:*", "http://127.0.0.1:*", "'self'"],
"worker-src": ["http://localhost:*", "http://127.0.0.1:*", "'self'"],
};
/**
@@ -67,10 +54,6 @@ async function testPolicy(manifest_version = 2, customCSP = null) {
"script-src": ["'self'"],
};
if (manifest_version < 3) {
addonCSP["script-src"].push("'wasm-unsafe-eval'");
}
let content_security_policy = null;
if (customCSP) {
@@ -276,10 +259,4 @@ add_task(async function testCSP() {
"script-src": `'self'`,
"worker-src": `'self'`,
});
await testPolicy(3, {
"object-src": "'none'",
"script-src": `'self' 'wasm-unsafe-eval'`,
"worker-src": `'self' 'wasm-unsafe-eval'`,
});
});

View File

@@ -1,117 +0,0 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
add_task(async function test_wasm_v2() {
let extension = ExtensionTestUtils.loadExtension({
background() {
let wasm = new WebAssembly.Module(
new Uint8Array([0, 0x61, 0x73, 0x6d, 0x1, 0, 0, 0])
);
browser.test.assertEq(wasm.toString(), "[object WebAssembly.Module]");
browser.test.notifyPass("finished");
},
manifest: {
manifest_version: 2,
},
});
await extension.startup();
await extension.awaitFinish("finished");
await extension.unload();
});
add_task(async function test_wasm_v2_explicit() {
let extension = ExtensionTestUtils.loadExtension({
background() {
let wasm = new WebAssembly.Module(
new Uint8Array([0, 0x61, 0x73, 0x6d, 0x1, 0, 0, 0])
);
browser.test.assertEq(wasm.toString(), "[object WebAssembly.Module]");
browser.test.notifyPass("finished");
},
manifest: {
manifest_version: 2,
content_security_policy: "object-src; script-src 'self'",
},
});
await extension.startup();
await extension.awaitFinish("finished");
await extension.unload();
});
add_task(async function test_wasm_v2_blocked() {
let extension = ExtensionTestUtils.loadExtension({
background() {
browser.test.assertThrows(
() => {
new WebAssembly.Module(
new Uint8Array([0, 0x61, 0x73, 0x6d, 0x1, 0, 0, 0])
);
},
error => error instanceof WebAssembly.CompileError,
"WASM should be blocked"
);
browser.test.notifyPass("finished");
},
manifest: {
manifest_version: 2,
content_security_policy: "object-src; script-src 'self'",
},
});
await extension.startup();
await extension.awaitFinish("finished");
await extension.unload();
});
add_task(async function test_wasm_v3() {
Services.prefs.setBoolPref("extensions.manifestV3.enabled", true);
let extension = ExtensionTestUtils.loadExtension({
background() {
browser.test.assertThrows(
() => {
new WebAssembly.Module(
new Uint8Array([0, 0x61, 0x73, 0x6d, 0x1, 0, 0, 0])
);
},
error => error instanceof WebAssembly.CompileError,
"WASM should be blocked"
);
browser.test.notifyPass("finished");
},
manifest: {
manifest_version: 3,
},
});
await extension.startup();
await extension.awaitFinish("finished");
await extension.unload();
Services.prefs.clearUserPref("extensions.manifestV3.enabled");
});
add_task(async function test_wasm_v3_allowed() {
Services.prefs.setBoolPref("extensions.manifestV3.enabled", true);
let extension = ExtensionTestUtils.loadExtension({
background() {
let wasm = new WebAssembly.Module(
new Uint8Array([0, 0x61, 0x73, 0x6d, 0x1, 0, 0, 0])
);
browser.test.assertEq(wasm.toString(), "[object WebAssembly.Module]");
browser.test.notifyPass("finished");
},
manifest: {
manifest_version: 3,
content_security_policy: {
extension_pages: `script-src 'self' 'wasm-unsafe-eval'; object-src 'self'`,
},
},
});
await extension.startup();
await extension.awaitFinish("finished");
await extension.unload();
Services.prefs.clearUserPref("extensions.manifestV3.enabled");
});

View File

@@ -269,7 +269,6 @@ skip-if =
os == "linux" && fission # Bug 1762638
[test_ext_userScripts_telemetry.js]
skip-if = os == "android" # Bug 1700482
[test_ext_wasm.js]
[test_ext_webRequest_auth.js]
skip-if = os == "android" && debug
[test_ext_webRequest_cached.js]

View File

@@ -265,12 +265,6 @@ class CSPValidator final : public nsCSPSrcVisitor {
case CSP_NONE:
case CSP_SELF:
return true;
case CSP_WASM_UNSAFE_EVAL:
if (mPermittedPolicy & nsIAddonContentPolicy::CSP_ALLOW_WASM) {
return true;
}
// fall through to also check CSP_ALLOW_EVAL
[[fallthrough]];
case CSP_UNSAFE_EVAL:
if (mPermittedPolicy & nsIAddonContentPolicy::CSP_ALLOW_EVAL) {
return true;