Author’s Note: The following discussion assumes you’re using both relayd
and
httpd
for serving your site. httpd
by itself does not handle manipulating things
like response headers.
WebAssembly(wasm) is the new hotness if you’ve not heard. It provides a language-agnostic binary instruction format that can be run in browsers. This means we can finally escape the tyranny of JavaScript and its assorted transpiled offspring.
I’ve been doing my own exploration with wasm lately. I’m using Rust as the source language and yew.rs to produce a wasm frontend. This works great and has been a much nicer experience than anything like React.js or Vue.js.
Unfortunately, when I deployed my frontend app to my website, it wouldn’t load. After some digging, I ended up finding the culprit in the browser debugger:
Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-jLxI1VFLBFY9e7acBLasiHGwzA2Os8wzffVUjpu0bT0='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
Ah - it’s the Content Security Policy. I’d forgotten those exist. After some digging, I learn two things:
unsafe-inline
and unsafe-eval
for both style-src
and script-src
.wasm-unsafe-eval
.If you’re unfamiliar with unsafe-inline
and unsafe-eval
, they prevent unsafe execution
of styles and scripts. Things like dynamic uses of JavaScript’s eval(..)
function.
Generally, it’s a good practice to not set theses values for your Content Security Policy
but needs must in my case.
My original Content-Security-Policy
in my relayd.conf
file looked like this:
match response header set "Content-Security-Policy" value "default-src 'self';"
That’s a pretty restricted and barebones one. It basically says only trust things loaded on the local server, preventing sketchy XSS attacks and friends.
My updated Content-Security-Policy
now looks like:
match response header set "Content-Security-Policy" value "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-eval' 'unsafe-inline';"
This adds two new keys - script-src
and style-src
. For both, I’ve specified
that for self
(i.e. zacbrown.org), enable unsafe-inline
and unsafe-eval
for
content served by self
.
This will allow us to load the WASM binaries and also lets the WASM binaries utilize styles defined outside the WASM binary itself.
By the way - httpd.conf doesn’t natively know about application/wasm
as a MIME type.
You’ll want to upload your httpd.conf
’s type {}
block with something like:
# make all OpenBSD default mime types available
types {
include "/usr/share/misc/mime.types"
application/wasm wasm
}
This will serve your WASM binaries with a well-known MIME type that browsers can
optimize loading.
—–Posted on: 2022-05-04