Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support wasm-eval csp behind WebAssemblyCSP flag #28576

Merged
merged 2 commits into from
Apr 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions patches/chromium/.patches
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,4 @@ cherry-pick-93ce5606cd9a.patch
cherry-pick-c6d6f7aee733.patch
cherry-pick-e1505713dc31.patch
cherry-pick-a66dbdcf6493.patch
blink_wasm_eval_csp.patch
101 changes: 101 additions & 0 deletions patches/chromium/blink_wasm_eval_csp.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: feat: support wasm-eval csp behind WebAssemblyCSP flag

This is a minimal backport of
https://chromium.googlesource.com/chromium/src/+/83913676803db53648b6a47d159102a7cf1dac36

The tracking issue in Chromium is
https://bugs.chromium.org/p/chromium/issues/detail?id=948834

diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
index 43c72ec32aef73b71f25aa3672f01ac098810432..869ce99f8800566c3ec46a0885933090608cdb95 100644
--- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
+++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
@@ -315,7 +315,8 @@ void ContentSecurityPolicy::CopyPluginTypesFrom(

void ContentSecurityPolicy::DidReceiveHeaders(
const ContentSecurityPolicyResponseHeaders& headers) {
- if (headers.ShouldParseWasmEval())
+ if (RuntimeEnabledFeatures::WebAssemblyCSPEnabled() ||
+ headers.ShouldParseWasmEval())
supports_wasm_eval_ = true;
if (!headers.ContentSecurityPolicy().IsEmpty()) {
AddAndReportPolicyFromHeaderValue(headers.ContentSecurityPolicy(),
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
index 5aec2cab35a7a615e2689b298f18487183c047c7..e76b7a2d99feaf0d7d0992ce79f322ab6b00fbc4 100644
--- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
+++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -272,8 +272,13 @@ bool CSPDirectiveList::CheckEval(SourceListDirective* directive) const {
return !directive || directive->AllowEval();
}

+bool SupportsWasmEval(const ContentSecurityPolicy* policy) {
+ return RuntimeEnabledFeatures::WebAssemblyCSPEnabled() ||
+ policy->SupportsWasmEval();
+}
+
bool CSPDirectiveList::CheckWasmEval(SourceListDirective* directive) const {
- return !directive || directive->AllowWasmEval();
+ return !directive || (SupportsWasmEval(policy_.Get()) && directive->AllowWasmEval());
}

bool CSPDirectiveList::IsMatchingNoncePresent(SourceListDirective* directive,
@@ -661,11 +666,15 @@ bool CSPDirectiveList::AllowWasmEval(
ContentSecurityPolicy::ExceptionStatus exception_status,
const String& content) const {
if (reporting_disposition == ReportingDisposition::kReport) {
+ String infix = SupportsWasmEval(policy_.Get())
+ ? "neither 'wasm-eval' nor 'unsafe-eval' is"
+ : "'unsafe-eval' is not";
return CheckWasmEvalAndReportViolation(
OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc),
- "Refused to compile or instantiate WebAssembly module because "
- "'wasm-eval' is not an allowed source of script in the following "
- "Content Security Policy directive: ",
+ "Refused to compile or instantiate WebAssembly module because " +
+ infix +
+ " an allowed source of script in the following "
+ "Content Security Policy directive: ",
exception_status, content);
}
return IsReportOnly() ||
diff --git a/third_party/blink/renderer/core/frame/csp/source_list_directive.cc b/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
index 063158759fbfdff4be9821aa4da30c6c6a094c57..68d159c98a3ad4de11fab330a190824f06209bb4 100644
--- a/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
+++ b/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
@@ -233,10 +233,15 @@ bool SourceListDirective::ParseSource(
return true;
}

- if (policy_->SupportsWasmEval() &&
- EqualIgnoringASCIICase("'wasm-eval'", token)) {
- AddSourceWasmEval();
- return true;
+ // Temporarily behind a runtime feature
+ if (EqualIgnoringASCIICase("'wasm-eval'", token)) {
+ if (RuntimeEnabledFeatures::WebAssemblyCSPEnabled() ||
+ policy_->SupportsWasmEval()) {
+ AddSourceWasmEval();
+ return true;
+ } else {
+ return false;
+ }
}

if (EqualIgnoringASCIICase("'strict-dynamic'", token) ||
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 4bd783c23496c9b499a5f809e9a00c141bb465b2..1ee6d8863c8c226e60dc2b733fd660cf32c190d6 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1989,6 +1989,9 @@
{
name: "WebAppManifestDisplayOverride",
},
+ {
+ name: "WebAssemblyCSP",
+ },
{
name: "WebAssemblySimd",
origin_trial_feature_name: "WebAssemblySimd",
38 changes: 38 additions & 0 deletions spec-main/chromium-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,44 @@ describe('web security', () => {
expect(response).to.equal('passed');
});

describe('wasm-eval csp', () => {
async function loadWasm (csp: string) {
const w = new BrowserWindow({
show: false,
webPreferences: {
sandbox: true,
enableBlinkFeatures: 'WebAssemblyCSP'
}
});
await w.loadURL(`data:text/html,<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' ${csp}">
</head>
<script>
function loadWasm() {
const wasmBin = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0])
return new Promise((resolve) => {
WebAssembly.instantiate(wasmBin).then(() => {
resolve('loaded')
}).catch((error) => {
resolve(error.message)
})
});
}
</script>`);
return await w.webContents.executeJavaScript('loadWasm()');
}

it('wasm codegen is disallowed by default', async () => {
const r = await loadWasm('');
expect(r).to.equal('WebAssembly.instantiate(): Wasm code generation disallowed by embedder');
});

it('wasm codegen is allowed with "wasm-eval" csp', async () => {
const r = await loadWasm("'wasm-eval'");
expect(r).to.equal('loaded');
});
});

it('does not crash when multiple WebContent are created with web security disabled', () => {
const options = { webPreferences: { webSecurity: false } };
const w1 = new BrowserWindow(options);
Expand Down