Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
eee3f9b
Adding CSP proposal.
flagxor Nov 1, 2017
d69bc5d
Update README.
flagxor Nov 6, 2017
7aa2d37
Provide background on CSP threat model and use cases
eholk Dec 6, 2017
14755e6
Add table detailing combinations.
flagxor Feb 21, 2018
0487ca8
Merge pull request #6 from eholk/threat-model
eholk Mar 2, 2018
ed2c962
Summarize API behavior and threats relative to CSP
eholk Mar 2, 2018
21342e3
Fix typos
eholk Mar 3, 2018
0659dc5
Reaffirm out of scope risks
eholk Mar 3, 2018
60c71ca
Merge branch 'master' of github.com:WebAssembly/spec into merge-master
eholk Mar 6, 2018
05341cd
Pull in latest changes from WebAssembly/spec repo
eholk Mar 6, 2018
7d3b908
Starting to define abstract operation hooks
eholk Mar 8, 2018
d2caac3
Add HostEnsureCanCompileWasmBytes hook for CSP
eholk Mar 8, 2018
e22a366
Add HostEnsureCanCompileWasmResponse for interacting with CSP
eholk Mar 9, 2018
87945e9
Delete spurious newline
eholk Mar 9, 2018
3eef43b
Add table entries for instantiation
Aug 24, 2018
529968a
Reword paragraph about CSP threat model
Sep 13, 2018
0acfec0
Merge branch 'master' into threat-summary
Sep 13, 2018
60bbf51
Rename \'wasm-eval\' to \'wasm-unsafe-eval\'
Oct 29, 2018
fca6045
Remove reference to mimetype hardening
Oct 29, 2018
55eae1b
Always allow WebAssembly.validate()
Oct 31, 2018
fe0e372
Merge pull request #17 from WebAssembly/rename_wasm_eval
Oct 31, 2018
53f60d4
Merge pull request #18 from WebAssembly/remove_mime_type
Oct 31, 2018
86a899f
Rework final table for clarity
Oct 31, 2018
f1cb729
Merge pull request #20 from WebAssembly/allow_validate
Oct 31, 2018
8fd4402
Fix table
Nov 12, 2018
e822b29
Add note about unsafe-eval implying wasm-unsafe-eval
Nov 13, 2018
edb4502
Merge branch 'master' into rework_final_table
Nov 13, 2018
0c9bce3
Merge pull request #21 from WebAssembly/rework_final_table
Nov 22, 2018
57b7b52
Merge pull request #16 from WebAssembly/threat-summary
Nov 22, 2018
ca8a1b3
fix typo
technohippy Jul 23, 2019
a29b53e
Merge pull request #24 from technohippy/patch-1
Jul 24, 2019
7b1980b
Merge pull request #13 from eholk/csp-hooks
fgmccabe Apr 16, 2021
c21513a
Revised and simplified note
fgmccabe May 10, 2021
cbf723a
Update proposals/CSP.md
fgmccabe May 11, 2021
a62b487
Update proposals/CSP.md
fgmccabe May 11, 2021
4ed70b2
Changed wasm-eval to wasm-unsafe-eval
fgmccabe May 11, 2021
55a48c3
Fixed error exception type when failing to compile
fgmccabe May 11, 2021
afddc88
Fix typo
fgmccabe May 12, 2021
d017c46
Merge pull request #31 from WebAssembly/fgm-patch-4
fgmccabe May 12, 2021
2081326
Refactored explainer to use regular script-src for streaming
fgmccabe Jul 20, 2021
57ed620
Slight tweak explaining streaming extension
fgmccabe Jul 20, 2021
b0e8b1e
Slight tweak explaining streaming extension
fgmccabe Jul 20, 2021
8242fc9
Merge branch 'fgm-patch-4' of github.com:WebAssembly/content-security…
fgmccabe Jul 20, 2021
3c888ab
Modified handling of compileStreaming
fgmccabe Aug 26, 2021
07af594
Removed funny dangling entry
fgmccabe Aug 30, 2021
3d3d959
Remove reference to iframe
fgmccabe Aug 30, 2021
e3977ba
Update proposals/CSP.md
fgmccabe Aug 31, 2021
58ff796
Merge pull request #32 from WebAssembly/fgm-patch-4
fgmccabe Aug 31, 2021
d89c8bc
Removed text relating to extending script-src to include wasm
fgmccabe Sep 9, 2021
097b397
Update proposals/CSP.md
fgmccabe Sep 10, 2021
fe56c79
Merge pull request #33 from WebAssembly/wasm-unsafe-eval
fgmccabe Sep 13, 2021
a43fa62
Remove reference to Response CSP policy algorithm
fgmccabe Oct 18, 2021
4c61db8
Merge remote-tracking branch 'upstream/main'
fgmccabe Oct 26, 2021
8cd593e
Merge pull request #39 from WebAssembly/merger
fgmccabe Nov 8, 2021
83c9f94
Merge remote-tracking branch 'upstream/main'
fgmccabe Mar 22, 2022
76c7781
Fixed up bikeshed errors
fgmccabe Mar 24, 2022
e15864d
[spec] Fix missing mention of vectype (#1436)
ngzhian Apr 4, 2022
74381a7
[spec] Fix single-table limitation in module instantiation (#1434)
keithw Apr 4, 2022
a5bd4b9
[spec] Fix missing immediate on table.set (#1441)
keithw Apr 5, 2022
0121c84
[docs] Update syntax in examples (#1442)
codefromthecrypt Apr 14, 2022
be2489e
Clarification in proposals README
rossberg Apr 14, 2022
e190ac3
[interpreter] Tweak start section AST to match spec
rossberg Apr 15, 2022
7e64d2c
[spec] Bump release to 2 (#1443)
rossberg Apr 16, 2022
7bcf319
Starting to define abstract operation hooks
eholk Mar 8, 2018
13fcaec
Add HostEnsureCanCompileWasmBytes hook for CSP
eholk Mar 8, 2018
c3996e8
Revised and simplified note
fgmccabe May 10, 2021
9247d8d
Changed wasm-eval to wasm-unsafe-eval
fgmccabe May 11, 2021
31ede6b
Removed funny dangling entry
fgmccabe Aug 30, 2021
c274959
Ensure compile as well as compile streaming guarded
fgmccabe Apr 18, 2022
2746eae
Remove duplicate text
fgmccabe Apr 18, 2022
dd75e5b
Merge pull request #41 from WebAssembly/curfuffle
fgmccabe Apr 18, 2022
ed5df37
Merge remote-tracking branch 'upstream/main' into curfuffle
fgmccabe Jul 16, 2025
011ae57
Take out use of HostEnsureCanCompileWasmBytes from web-api
fgmccabe Jul 16, 2025
63f01a2
Merge remote-tracking branch 'upstream/wasm-3.0' into curfuffle
fgmccabe Jul 16, 2025
cfa8673
Merge pull request #45 from WebAssembly/curfuffle
fgmccabe Jul 16, 2025
04b0388
Drop some spaces
fgmccabe Jul 16, 2025
9f09100
Drop more spaces
fgmccabe Jul 16, 2025
7c1478f
Add back section on implementation defined operations
fgmccabe Jul 16, 2025
2b81a76
Remove bytes argument from HostEnsureCanCompileWasmBytes
fgmccabe Jul 16, 2025
48feb4b
Fixed markdown indentation error
fgmccabe Jul 16, 2025
893da3b
Remove reference to HostEnsureWasmCanCompile
fgmccabe Jul 16, 2025
284adaf
Merge remote-tracking branch 'upstream/main'
fgmccabe Jun 23, 2026
8227401
Update README to remove CSP proposal details
fgmccabe Jun 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions document/js-api/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ Note:

<div algorithm>
To <dfn>compile a WebAssembly module</dfn> from source bytes |bytes|, perform the following steps:
1. Perform [$HostEnsureCanCompileWasmBytes()$].
Note: This operation terminates with a {{CompileError}} exception if the operation is not permitted.
1. Let |module| be [=module_decode=](|bytes|). If |module| is [=error=], return [=error=].
1. If [=module_validate=](|module|) is [=error=], return [=error=].
1. Return |module|.
Expand Down Expand Up @@ -652,6 +654,7 @@ The verification of WebAssembly type requirements is deferred to the
<div algorithm>
The <dfn method for="WebAssembly">instantiate(|bytes|, |importObject|, |options|)</dfn> method, when invoked, performs the following steps:
1. Let |stableBytes| be a [=get a copy of the buffer source|copy of the bytes held by the buffer=] |bytes|.
1. Perform [$HostEnsureCanCompileWasmBytes()$]
1. [=Asynchronously compile a WebAssembly module=] from |stableBytes| using |options| and let |promiseOfModule| be the result.
1. [=Instantiate a promise of a module|Instantiate=] |promiseOfModule| with imports |importObject| and return the result.
</div>
Expand Down Expand Up @@ -2204,6 +2207,18 @@ Note: ECMAScript doesn't specify any sort of behavior on out-of-memory condition
See [Issue 879](https://github.com/WebAssembly/spec/issues/879) for further discussion.
</div>

<h2>Implementation-defined Operations</h2>

<h3 id="host-ensure-can-compile-wasm-bytes">HostEnsureCanCompileWasmBytes()</h3>

<dfn abstract-op>HostEnsureCanCompileWasmBytes()</dfn> is an implementation-defined abstract operation
that allows host environments to block certain WebAssembly functions which
compile bytes into WebAssembly code.

An implementation of HostEnsureCanCompileWasmBytes may complete normally or
abruptly. Any abrupt completions will be propagated to its callers. The default
implementation of HostEnsureCanCompileWasmBytes is to unconditionally return an
empty normal completion.

<h2 id="limits">Implementation-defined Limits</h2>

Expand Down
24 changes: 0 additions & 24 deletions document/web-api/index.bs

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the deletions here expected? It seems it would be better to edit the "Security and Privacy Considerations" section rather than remove it.

Original file line number Diff line number Diff line change
Expand Up @@ -312,27 +312,3 @@ application/wasm
<dt>Author/Change Controller:</dt>
<dd>W3C</dd>
</dl></dd>
</dl>

<h2 id="security-considerations">Security and Privacy Considerations</h2>

<p><em>This section is non-normative.</em></p>
WebAssembly provides no access to the surrounding environment other than via the JavaScript API described in the [[WASMJS|JS API]] specification.
Therefore, WebAssembly cannot collect or expose any information (personal, sensitive or otherwise) to Web sites or other parties beyond what can be collected, exposed or processed with JavaScript.
WebAssembly memory has the same lifetime as the objects in the surrounding JavaScript environment and is not persisted or serialized (other than by copying it out to JavaScript and using existing serialization APIs).
No access is provided to the underlying platform or hardware, or to other devices, or to the user agent’s native UI.

WebAssembly is an additional program execution mechanism, and can be executed wherever JavaScript can be executed.
Therefore the threat model is essentially the same as for JavaScript code, and has similar considerations for delivery (e.g. WebAssembly code should be protected in transit from active and passive network attackers)
and policy (e.g. some loading mechanisms or execution are restricted via mechanisms such as the same-origin policy or Content Security Policy).

<h2 id="change-history">Change History</h2>

<p><em>This section is non-normative.</em></p>

<p>Since the original release 1.0 of the WebAssembly specification, a number of proposals for extensions have been integrated.
The following sections provide an overview of what has changed.</p>

<h3 id="release-20">Release 2.0</h3>
<h4 id="changes-registration" class="no-toc heading settled">Media-type Registraton Completed</h4>
The registration for the `application/wasm` media type has been successfully completed.
157 changes: 157 additions & 0 deletions proposals/CSP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# WebAssembly Content Security Policy

This note describes a recommendation to the WebAppSec WG to extend Content Security Policy (CSP) to support compiling and executing WebAssembly modules.

## Background: WebAssembly, Trust and Safety

In order for a user to experience the benefits of using a particular WebAssembly module there are three (at least) parties that must collaborate: the browser (or other host environment), the publisher (the author of the WebAssembly module) and the user. Each party seeks some form of guarantee from the other parties that allow that party to trust the others. This trust centric modeling allows us to paint a more accurate picture of WebAssembly security.

### WebAssembly Sandbox

WebAssembly has a sandbox-style security model which focuses on limiting the potential damage a WebAssembly module can do to its host environment. For example, a WebAssembly module is not permitted to access any functions from the host other than those explicitly passed to it via imports. Similarly, a WebAssembly module cannot directly access the evaluation stack; which also limits the potential for attacks based on manipulating return addresses and other important stack data.

By imposing this sandbox on the execution of a WebAssembly model, the browser (or other host) gains sufficient trust that browser is willing to permit the WebAssembly code to execute.

This does not, however, provide any guarantees that WebAssembly modules compute correct results: it is still possible that an incorrectly programmed module may corrupt data, produce invalid results and be subject to attacks such as SQL injection and even buffer overrun affecting data structures within an application. Since the memory used by a WebAssembly module may be shared via ArrayBuffers these faults may be visible to and affect other WebAssembly and JavaScript modules that also share the same memory. Other memory faults - such as use-after-free and accessing uninitialized memory - are also similarly not protected against by the engine.

We should also note that a malicious module may be completely safe in terms of the resources from the host that it uses and still cause significant harm to the user. A classic example of this would be a surruptiously loaded crypto-mining WebAssembly module.

In addition, the sandbox model does not manage _which_ WebAssembly modules are executed. Controlling which WebAssembly modules are executed is the primary focus of CSP.

### CSP Resource Control

CSP, broadly, allows a publisher to control what resources can be loaded as part
of a site. These resources can include images, audio, video, or scripts. In particular, a suitable CSP should allow the publisher to declare to the host which WebAssembly modules may be executed by the browser on behalf of the user.

It is important to manage this as malicious WebAssembly modules could exfiltrate data from the site. Images could display misleading or
incorrect information. Fetching resources leaks information about the user to
untrusted third parties.

Viewed in terms of _trust_ modeling, CSP allows the content publisher to establish a trust contract with the browser -- and therefore be willing to let the browser execute the publisher's code. It does not, however, address the trust that a user must express when accessing functionality from a WebAssembly module. This is crucially important; however, it is also beyond the scope of this note.

### WebAssembly Execution API

Executing WebAssembly has several steps.

1. First there are the raw WebAssembly
bytes, which typically are loaded using the [fetch
API](https://fetch.spec.whatwg.org/).

1. Next, the bytes are compiled using
`WebAssembly.compile` or `WebAssembly.compileStreaming` into a
`WebAssembly.Module`. This module is not yet executable, but WebAssembly
implementations may choose to translate the WebAssembly code into machine code
at this step.

1. Finally, a WebAssembly module
is combined with an _import object_ using `WebAssembly.instantiate` to create an
`WebAssembly.Instance` object. The import object, broadly, defines the
capabilities of the resulting instance, optionally including a
`WebAssembly.Memory`, bindings for the WebAssembly function imports, and an
indirect function call table.

Note that, via the `start` function, some functionality within a WebAssembly module may start executing at this point. However, for the most part, the host accesses WebAssembly functions through the instance's exports.

These steps provide the core of the WebAssembly API, but there are several other
methods provided as well. These are summarized below along with their risks that
are related to CSP.

### Risk Analysis of WebAssembly API

[**`WebAssembly.validate`**](https://webassembly.github.io/spec/js-api/index.html#dom-webassembly-validate)
checks whether the given bytes comprise a valid WebAssembly program. In other
words, it checks whether the bytes are syntactically correct and valid according
to the WebAssembly type system.

_Risks:_ Limited to certain denial of service style attacks. Currently the cost of validating a WebAssembly module is linear on the size of the module; however, certain anticipated changes to the WebAssembly type system may change that.

[**`new WebAssembly.Module`**](https://webassembly.github.io/spec/js-api/index.html#dom-module-module)
synchronously creates a `WebAssembly.Module` from WebAssembly bytes. This is a
synchronous version of `WebAssembly.compile`.

_Risks:_ many implementations will generate machine code at this step, even
though it is not yet exposed as executable code to the surrounding program.

[**`WebAssembly.compile`**](https://webassembly.github.io/spec/js-api/index.html#dom-webassembly-compile)
provides a `Promise` that resolves to a `WebAssembly.Module` generated from the
provided WebAssembly bytes. This is an asynchronous version of `new
WebAssembly.Module`.

_Risks:_ equivalent to `new WebAssembly.Module`.

[**`WebAssembly.compileStreaming`**](https://webassembly.github.io/spec/web-api/index.html#dom-webassembly-compilestreaming)
creates a `WebAssembly.Module` from the WebAssembly bytes contained in the
provided `Response` object.

_Risks:_ equivalent to `new WebAssembly.Module`.

[**`WebAssembly.instantiate`**](https://webassembly.github.io/spec/js-api/index.html#dom-webassembly-instantiate)
accepts either WebAssembly bytes or a `WebAssembly.Module` and an import object.
The function returns a `WebAssembly.Instance` that allows executing the
WebAssembly code. If WebAssembly bytes are provided, `instantiate` will first
perform the steps of `WebAssembly.compile`.

_Risks:_ loads executable code into the running program and execute any included `start` function.

As noted above, WebAssembly functions are only able to access objects reachable from the import object. The instance
does not have unrestricted access to the JavaScript global object.

[**`WebAssembly.instantiateStreaming`**](https://webassembly.github.io/spec/web-api/index.html#dom-webassembly-instantiatestreaming)
accepts a `Response` containing WebAssembly bytes and an import object, performs
the operations behind `WebAssembly.compileStreaming` on these bytes and then
creates a `WebAssembly.Instance`.

_Risks:_ equivalent to `WebAssembly.instantiate`.

### Out of Scope Threats

* **Bugs in the browser**. We assume correct implementations of image decoders,
script compilers, etc. CSP does not protect against malicious inputs that can,
for example, trigger buffer overflows.
* **Resource exhaustion**. Computation performed by scripts uses memory and CPU
time and can therefore cause a denial of service on the browser. Protecting
against this is one reason site owners use CSP, but denial of service is not a
first order consideration for CSP. Scripts are dangerous not because of their
resource consumption but because of other effects that can cause.

## WebAssembly and CSP

As noted earlier, CSP allows publishers to control what resources are loaded into a browser from a Web application. This includes resources that are dynamically created as well as those loaded directly. There is no direct equivalent of a `script` element for WebAssembly modules; although it is possible that such an feature may be specified in the future. Instead, WebAssembly modules are compiled and instantiated via a JavaScript API. Thus our focus on CSP for WebAssembly is on that API.

### The `HostEnsureCanCompileWasmBytes` Policy Point

It is proposed that the above APIs are _gated_ by a policy point: `HostEnsureCanCompileWasmBytes`. (This is sometimes referred to as an _abstract operation_ that must be performed by the host to permit the compilation.)

#### `HostEnsureCanCompileWasmBytes`

If `HostEnsureCanCompileWasmBytes` is not enabled, then the `WebAssembly.compile` and `WebAssembly.compileStreaming` functions fail with a `WebAssembly.CompileError` exception. Otherwise, these API functions return results depending on the internal integrity of the WebAssembly module being compiled.

### The `wasm-unsafe-eval` source directive

We recommend that a new CSP policy directive `wasm-unsafe-eval` be created. If set in the headers of a page, then the `HostEnsureCanCompileWasmBytes` policy point is enabled; which, in turn, allows the page to load, compile and instantiate WebAssembly code. This would apply to both the inline APIs (`WebAssembly.compile` etc.) and the streaming APIs (`WebAssembly.compileStreaming` et el.) The details of these abstract operations will be incorporated into a future version of the CSP specification.

Given the current usage of the CSP policy `unsafe-eval` to gate both JavaScript `eval` and instantiating WebAssembly modules, we propose that that behavior be allowed to continue; but that `wasm-unsafe-eval` should have no implication for JavaScript loading or evaluation or use of `eval` in JavaScript. NOTE: Providing a directive to allow JavaScript `eval` without WebAssembly doesn't seem immediately useful, and so has been left out intentionally.

#### Proposed Policy Behavior

With the `wasm-unsafe-eval` source, there are two options for managing WebAssembly execution: `unsafe-eval` and `wasm-unsafe-eval`. The former is primarily intended to govern JavaScript execution -- specifically those JS features that can be used to construct programs from text. However, it has been extended to allow WebAssembly execution. The second is a more targeted source keyword that only applies to WebAssembly.

* If the `unsafe-eval` source keyword is used, then this overrides any occurence of `wasm-unsafe-eval` in the CSP policy.

* If the `wasm-unsafe-eval` source keyword is used, and the `unsafe-eval` keyword is not present, then WebAssembly modules may be compiled and instantiated.

One advantage of this is that a website can permit WebAssembly modules to be used without also enabling JavaScript's `eval` keyword.

On the event of failure, then a `CompileError` should be thrown by the `WebAssembly.compile` and related API calls.

### Using existing CSP script-src policies

Currently, WebAssembly modules are anomolous within the Web platform because there is no specific HTML element that references WebAssembly modules. It is reasonable to suggest that the existing `script` element may one day be extended to also include WebAssembly modules. In that event, it is also reasonable to consider the use of the CSP `script-src` source keyword to include WebAssembly as well as JavaScript.

However, it may not be wise to extend the scope of CSP's `script-src` source in this way. The reasons for this are that it could break existing websites and that the specific rules for `script-src` are too tailored to the requirements of JavaScript.

* Extending `script-src` to include WebAssembly has the potential to compromise a website that currently uses a CSP policy for JavaScript that was not intended to support WebAssembly.

* Using a _white list_ approach for allowable domains to source executable can be shown to be difficult to manage in practice. This is especially true for JavaScript, but is also true for WebAssembly.

* The primary issue with white listing a domain is that it allows _all_ code from that domain. However, many domains -- such as CDNs -- host many code modules; many more than owners of websites can reasonably be aware of.
Loading