Last active
July 3, 2024 09:47
-
-
Save oscarduignan/47540a9fc1b0c45015df23866701ca93 to your computer and use it in GitHub Desktop.
Example showing how default platform CSP is incompatible with some ways of loading scripts
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
http://127.0.0.1 { | |
vars { | |
platformCSP "script-src 'nonce-abc123' 'unsafe-inline' 'strict-dynamic' https: http: ; object-src 'none'; base-uri 'none';" | |
} | |
route / { | |
header Content-Type text/html | |
header Content-Security-Policy {vars.platformCSP} | |
respond <<HTML | |
<html> | |
<body> | |
<script nonce="abc123" src="/inject-script/which-succeeds/directly.js"></script> | |
<script nonce="abc123" src="/inject-script/which-succeeds/via-iframe.js"></script> | |
<script nonce="abc123" src="/inject-script/which-fails.js"></script> | |
</body> | |
</html> | |
HTML 200 | |
} | |
route /inject-script/which-fails.js { | |
header Content-Type text/javascript | |
header Content-Security-Policy {vars.platformCSP} | |
respond <<JS | |
var iframe = document.createElement("iframe"); | |
iframe.srcdoc = 'Create script in iframe via a html string <script src="/alert.js"></script>'; | |
document.body.appendChild(iframe); | |
JS 200 | |
} | |
route /inject-script/which-succeeds/directly.js { | |
header Content-Type text/javascript | |
header Content-Security-Policy {vars.platformCSP} | |
respond <<JS | |
var script = document.createElement("script"); | |
script.src = '/alert.js'; | |
document.body.appendChild(script); | |
JS 200 | |
} | |
route /inject-script/which-succeeds/via-iframe.js { | |
header Content-Type text/javascript | |
header Content-Security-Policy {vars.platformCSP} | |
respond <<JS | |
var iframe = document.createElement("iframe"); | |
document.body.appendChild(iframe); | |
var iframeDocument = iframe.contentWindow.document; | |
iframeDocument.body.innerText = 'Create script in iframe via document.createElement'; | |
var script = iframeDocument.createElement("script"); | |
script.src = '/alert.js'; | |
iframeDocument.body.appendChild(script); | |
JS 200 | |
} | |
route /alert.js { | |
header Content-Type text/javascript | |
header Content-Security-Policy {vars.iframeCSP} | |
respond <<JS | |
alert("a script was injected by another script successfully because nonce granted it permission via strict-dynamic"); | |
JS 200 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Try it out by running this command (prerequisite is you have caddy installed) and then opening http://127.0.0.1 you should see two alerts and in browser console one error where the CSP has blocked the injection one of the scripts via the incompatible method.