jenkinz
jenkinz

Reputation: 139

Why can't I get around my CSP blocking my javascript code in nunjucks when I use a nonce

I’m trying to allow the user to return to their previous screen when they get a 404 not found, but my CSP is stopping me.

Using nonce seems to be the way around it, but I can’t get the blessed thing to work.

Ideally, I’d like to add the nonce to my href, but I’m not sure that’s do-able. Alternatively, I’d like to run some javascript from the 404 file, but it doesn’t seem to be picking up the value of my nonce.

This is how I set up the nonce in helmet-csp:

app.locals.nonce = crypto.randomBytes(16).toString("hex");

app.use(csp({
  directives: {
    defaultSrc: ["'self'"],
    styleSrc: ["'self'"],
    scriptSrc: ["'self'", `'nonce-${app.locals.nonce}'`],
    imgSrc: ["'self'"],
    fontSrc: ["'self'"]
  }
}));

In the nunjucks 404 page, I’m trying to go back to previous page:

{% set n = "nonce-"+nonce %}

<a nonce={{n}} href="javascript:history.go(-1);">{{ t('404:goBack')</a>

And at the bottom, I have my script tags set up thusly:

<style nonce=app.locals.nonce>
    console.log('inside 404')
  </style>

On landing on my 404 page, Chrome spews up the following error: eligibilixxxty-sf-debt:38 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-a8ff45c6cc9b12df8111202f13d1c000'". Either the 'unsafe-inline' keyword, a hash ('sha256-+6WnXIl4mbFTCARd8N3COQmT3bJJmo32N8q8ZSQAIcU='), or a nonce ('nonce-...') is required to enable inline execution.

And clicking the href link gets this response: Refused to run the JavaScript URL because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-a8ff45c6cc9b12df8111202f13d1c000'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.

Any ideas where I’m going wrong?

Upvotes: 2

Views: 1794

Answers (1)

granty
granty

Reputation: 8546

<a href="javascript:history.go(-1);"> it's an javascript-naviagtion, it (as well as inline event handlers in the tags) requires mandatory 'unsafe-inline' and cannot be allowed via 'nonce-value' token. 'unsafe-hashes' token provided for such purposes, but it's not implemented into browsers yet it's implemented now! Pls see update below.

You have only one way - remove the handler from the tag:

<a id="elem" href='#'>go back</a>

<script nonce=app.locals.nonce>  // place 'nonce' here
  elem.onclick = function() {
    history.go(-1);
    };
<script>

To your taste you can use addEventListener() with arrow funct:

<script nonce=app.locals.nonce>
 elem.addEventListener( "click" , () => history.go(-1));
</script>

or with anonymous:

<script nonce=app.locals.nonce>
 elem.addEventListener("click", function() { history.go(-1); });
</script>

UPDATED

Chrome 85 and Firefox 81 do support 'unsafe-hashes' token both for inline event handlers and for inline styles.

Upvotes: 2

Related Questions