Created
August 13, 2018 19:12
-
-
Save rezan/24bd9f1943debcfc1a6ba2ffd388c006 to your computer and use it in GitHub Desktop.
Generate CSP nonces for Javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
varnishtest "Generate CSP nonces for Javascript" | |
server s1 { | |
rxreq | |
txresp -hdr "Content-Type: text/html" -body { | |
<html> | |
<script> | |
var a=1; | |
</script> | |
</html> | |
} | |
expect req.url == "/1" | |
} -start | |
varnish v1 -vcl+backend { | |
import crypto; | |
import edgestash; | |
import xbody; | |
sub vcl_backend_response{ | |
if (beresp.http.Content-Type ~ "html") { | |
xbody.regsub("<script>", "<script nonce={{nonce}}>"); | |
edgestash.parse_response(); | |
} | |
} | |
sub vcl_deliver { | |
if (edgestash.is_edgestash()) { | |
set req.http.X-nonce = crypto.hex_encode(crypto.urandom(16)); | |
set resp.http.Content-Security-Policy = "script-src 'nonce-" + | |
req.http.X-nonce + "'"; | |
edgestash.add_json({" | |
{ | |
"nonce":""} + req.http.X-nonce + {"" | |
} | |
"}); | |
edgestash.execute(); | |
} | |
} | |
} -start | |
client c1 { | |
txreq -url /1 | |
rxresp | |
expect resp.status == 200 | |
expect resp.body ~ "<script nonce=\\S+>" | |
expect resp.http.Content-Security-Policy ~ "nonce-\\S+" | |
} -run |
Works great, many many thanks!
In case someone stumbles upon this as I just did: this implementation is vulnerable, do not do it this way. If someone includes a script
tag in your website, if Varnish is configured this way he will happily put the nonce where needed, hence the XSS is possible.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks a lot! This is great, but I can't get vmod xbody in Varnish Plus 4.1.10r4 (latest) ..
Docs do mention Varnish 6.. Yet I don't see a Varnish Plus 6 release