зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
283a88b45c
Коммит
4d59317ca4
|
@ -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
|
||||
|
|
|
@ -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,37 +484,30 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
|
|||
|
||||
bool evalOK = true;
|
||||
bool reportViolation = false;
|
||||
nsAutoJSString scriptSample;
|
||||
if (aKind == JS::RuntimeCode::JS) {
|
||||
nsresult rv = csp->GetAllowsEval(&reportViolation, &evalOK);
|
||||
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.
|
||||
if (reportViolation || subjectPrincipal->IsSystemPrincipal() ||
|
||||
XRE_IsE10sParentProcess()) {
|
||||
if (NS_WARN_IF(!scriptSample.init(cx, aCode))) {
|
||||
JS_ClearPendingException(cx);
|
||||
return false;
|
||||
}
|
||||
// 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))) {
|
||||
JS_ClearPendingException(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(ANDROID)
|
||||
if (!nsContentSecurityUtils::IsEvalAllowed(
|
||||
cx, subjectPrincipal->IsSystemPrincipal(), scriptSample)) {
|
||||
return false;
|
||||
}
|
||||
if (!nsContentSecurityUtils::IsEvalAllowed(
|
||||
cx, subjectPrincipal->IsSystemPrincipal(), scriptSample)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
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 (NS_FAILED(rv)) {
|
||||
NS_WARNING("CSP: failed to get allowsEval");
|
||||
return true; // fail open to not break sites.
|
||||
}
|
||||
|
||||
if (reportViolation) {
|
||||
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -115,7 +115,6 @@ class nsCSPContext : public nsIContentSecurityPolicy {
|
|||
eInline,
|
||||
eEval,
|
||||
eSelf,
|
||||
eWasmEval,
|
||||
};
|
||||
|
||||
nsresult AsyncReportViolation(
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
@ -108,16 +105,15 @@ inline CSPDirective CSP_StringToCSPDirective(const nsAString& aDir) {
|
|||
return nsIContentSecurityPolicy::NO_DIRECTIVE;
|
||||
}
|
||||
|
||||
#define FOR_EACH_CSP_KEYWORD(MACRO) \
|
||||
MACRO(CSP_SELF, "'self'") \
|
||||
MACRO(CSP_UNSAFE_INLINE, "'unsafe-inline'") \
|
||||
MACRO(CSP_UNSAFE_EVAL, "'unsafe-eval'") \
|
||||
MACRO(CSP_NONE, "'none'") \
|
||||
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'")
|
||||
#define FOR_EACH_CSP_KEYWORD(MACRO) \
|
||||
MACRO(CSP_SELF, "'self'") \
|
||||
MACRO(CSP_UNSAFE_INLINE, "'unsafe-inline'") \
|
||||
MACRO(CSP_UNSAFE_EVAL, "'unsafe-eval'") \
|
||||
MACRO(CSP_NONE, "'none'") \
|
||||
MACRO(CSP_NONCE, "'nonce-") \
|
||||
MACRO(CSP_REPORT_SAMPLE, "'report-sample'") \
|
||||
MACRO(CSP_STRICT_DYNAMIC, "'strict-dynamic'") \
|
||||
MACRO(CSP_UNSAFE_ALLOW_REDIRECTS, "'unsafe-allow-redirects'")
|
||||
|
||||
enum CSPKeyword {
|
||||
#define KEYWORD_ENUM(id_, string_) id_,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
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 (NS_WARN_IF(!scriptSample.init(aCx, aCode))) {
|
||||
JS_ClearPendingException(aCx);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reportViolation) {
|
||||
if (!nsContentSecurityUtils::IsEvalAllowed(aCx, worker->UsesSystemPrincipal(),
|
||||
scriptSample)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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,11 +1949,13 @@ bool LogViolationDetailsRunnable::MainThreadRun() {
|
|||
|
||||
nsIContentSecurityPolicy* csp = mWorkerPrivate->GetCSP();
|
||||
if (csp) {
|
||||
csp->LogViolationDetails(mViolationType,
|
||||
nullptr, // triggering element
|
||||
mWorkerPrivate->CSPEventListener(), mFileName,
|
||||
mScriptSample, mLineNum, mColumnNum, u""_ns,
|
||||
u""_ns);
|
||||
if (mWorkerPrivate->GetReportCSPViolations()) {
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
||||
nullptr, // triggering element
|
||||
mWorkerPrivate->CSPEventListener(), mFileName,
|
||||
mScriptSample, mLineNum, mColumnNum, u""_ns,
|
||||
u""_ns);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -568,7 +568,6 @@ void CacheLoadHandler::DataReceived() {
|
|||
// Set Eval and ContentSecurityPolicy
|
||||
mWorkerPrivate->SetCSP(parent->GetCSP());
|
||||
mWorkerPrivate->SetEvalAllowed(parent->IsEvalAllowed());
|
||||
mWorkerPrivate->SetWasmEvalAllowed(parent->IsWasmEvalAllowed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
|
@ -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>
|
|
@ -1 +0,0 @@
|
|||
Content-Security-Policy: default-src 'unsafe-inline'
|
|
@ -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)) {
|
||||
|
|
|
@ -120,7 +120,6 @@ class ExtensionPolicyService final : public nsIAddonPolicyService,
|
|||
nsCOMPtr<nsIObserverService> mObs;
|
||||
|
||||
nsString mDefaultCSP;
|
||||
nsString mDefaultCSPV3;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -42,16 +42,16 @@ static const char kBackgroundPageHTMLEnd[] =
|
|||
</html>";
|
||||
|
||||
#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:;"
|
||||
#define DEFAULT_BASE_CSP_V2 \
|
||||
"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';"
|
||||
#define DEFAULT_BASE_CSP_V3 \
|
||||
"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);
|
||||
}
|
||||
EPS().GetDefaultCSP(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)) {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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'`,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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");
|
||||
});
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче