Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Content-security-policy with ACE.js

So I'm setting up a helmet-csp(https://www.npmjs.com/package/helmet-csp), and are running ace. Here's my helmet-setup:

var csp = require("helmet-csp");

app.use(csp({
    directives: {
        defaultSrc: ["'self'", "https://localhost:8000"],
        styleSrc: ["'self'", "'unsafe-inline'"],
        sandbox: ["allow-forms", "allow-scripts", "allow-same-origin"],
        reportUri: "/report-violation",
        scriptSrc: ["'self'", "'unsafe-inline'",
        "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js",
        "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-monokai.js",
        "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-javascript.js"]
    }
}));

and the script is implemented like this(the src is linked to a local embedment of ace):

<script src="../../src-min-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script>

    var editor = ace.edit("editor");
    editor.getSession().setUseWorker(false);
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/javascript");

</script>

Which works with no devastating errors, but I keep getting this in browser-console:

Refused to create a worker from 'blob:https://localhost:8000/34145ece-2c95-403b-92b0-79d02a5b4edd' because it violates the following Content Security Policy directive: "default-src 'self' https://localhost:8000". Note that 'worker-src' was not explicitly set, so 'default-src' is used as a fallback.

and

Could not load worker DOMException: Failed to construct 'Worker': Access to the script at 'blob:https://localhost:8000/701e5193-c7f3-47b4-94da-c2086bfc2dd4' is denied by the document's Content Security Policy.
    at new u (https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js:1:305119)
    at createWorker (https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-javascript.js:1:22584)
    at p.$startWorker (https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js:1:159829)
    at p.$onChangeMode (https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js:1:159064)
    at p.<anonymous> (https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js:1:158825)
    at https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js:1:55143
    at Array.forEach (native)
    at https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js:1:55120
    at n (https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js:1:936)
    at a (https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js:1:1487)

Feels like I've tried everything google has to offer, but no result. Can anybody help me?

like image 741
Jesper Avatar asked Feb 01 '26 04:02

Jesper


1 Answers

I had to add child-srcpolicies for the worker to work. Since the worker sent some kind of blob, i allowed blobs from that origin.

app.use(csp({
    directives: {
        defaultSrc: ["'self'"],
        imgSrc: ["data: *"],
        childSrc: ["blob: *"],
        styleSrc: ["'self'", "'unsafe-inline'",
        "https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"],
        sandbox: ["allow-forms", "allow-scripts", "allow-same-origin"],
        scriptSrc: ["'self'", "'unsafe-inline'", "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js",
        "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-monokai.js",
        "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-javascript.js",
        "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/worker-javascript.js"],
        fontSrc: ["'self'", "https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/fonts/fontawesome-webfont.woff2?v=4.7.0",
        "https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/fonts/fontawesome-webfont.woff?v=4.7.0]",
        "https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/fonts/fontawesome-webfont.ttf?v=4.7.0",
        "https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/worker-javascript.js"]
    }
}));

Also I made some changes to the script for it to work. Why it worked after that, I don't know:

<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js"></script>
<script>
    var textarea = document.querySelector("#content");

    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/javascript");

    editor.getSession().on("change", function () {
        textarea.innerHTML = editor.getSession().getValue();
    });

    textarea.innerHTML = editor.getSession().getValue();
</script>
like image 111
Jesper Avatar answered Feb 03 '26 17:02

Jesper