Govuk-frontend: Strict Content Security Policy (CSP) blocks inline script

Created on 20 Nov 2019  路  13Comments  路  Source: alphagov/govuk-frontend

We鈥檙e in the process on GOV.UK Pay of implementing CSP in our apps and the inline script here gets blocked.

We can whitelist it with the hash of it鈥檚 contents which works until it gets changed, which I am sure doesn鈥檛 happen too often. So maybe this is fine, it secure at least as it means, we鈥榬e not trusting GOV.UK Frontend without explicitly checking here. But it would also mean if no one noticed, this could get blocked and break some functionality.

But I wondered if we could wrap it a block so if we wanted to we could override it we could.

Option 1

{% block inlineJsCheck %}
    <script>document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');</script>
{% endblock %}

Option 2

    <script nonce="{{ inlineJsCspNonce }}">document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');</script>

Most helpful comment

@jonheslop I think GOV.UK Frontend should aim to support the most proper way of doing this, if that's adding a hash we should consider adding something to our documentation. What do you think?

All 13 comments

Some related pull requests on the older deprecated template that may help us figure this out:

@jonheslop is the only part of the template that would block implementing CSP?

I think based on the previous discussion I have two questions:

  1. can we hardcode a hash since this JavaScript does not change, so GOV.UK Pay (and others) do not need to add this themselves?
  2. are nonce attributes still recommended and considered best practice, David in that thread suggests there is some criticism of the approach

@nickcolley Yeah that鈥檚 the only thing CSP complained about from govuk-frontend. I am not sure how we get the hash if you include it, but this probs would be preferred .

I put the nonce option in as it鈥檚 valid, but we would prefer not to do it.

I assume since the JS never changes a hash should suffice?

Content-Security-Policy: default-src 'self'; script-src 'sha256-+6WnXIl4mbFTCARd8N3COQmT3bJJmo32N8q8ZSQAIcU='

Then setup some monitoring for CSP reports like you are doing with report-only mode at the moment.

It doesn't look like you can include an inline hash attribute like you can with nonce. But there is the integrity attribute available with Subresource Integrity, Content-Security-Policy: require-sri-for script; but that will require all scripts on the page to have a sha generated for them, so looks a bit more involved.

I've also heard that SRI is now considered and anti-pattern and may even impact perf, but I've yet to see any concrete evidence of that.

Alright maybe we can just close, this we already added the hash to our CSP but we worried about if and when it changes but perhaps thats not worth worrying about.

@jonheslop I think GOV.UK Frontend should aim to support the most proper way of doing this, if that's adding a hash we should consider adding something to our documentation. What do you think?

Yeah I guess, basically we had a console log telling us this was being blocked and it gives you the hash in the log so you can add it, we did so and then the warning went away. I guess you could put the hash in your docs somewhere maybe but I dunno if people are more likely to fix themselves than look in docs 馃し鈥嶁檪

@m-green do you think we should document this, or close this for now and re-open if other people run into it?

@nickcolley I'd probably close for now. If the console log helps those users who run into this, it should be ok to leave out of the docs. But yep, if we hear from more users we can re-open and take a look.

I was in the process of implementing nonces for our frontend project (we're using helmet to set CSP) which I believe should change for each request. For the call to initAll() this has been relatively simple in our app, creating the nonce with

res.locals.nonce = uuid.v4() 

and then accessing this from the template.

<script nonce={{nonce}}>window.GOVUKFrontend.initAll()</script>

However as with the OP I saw no easy way to add a nonce to the below line as I can't override without it being wrapped in a block.

   <script>document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');</script>

I wasn't actually aware you could whitelist with a hash (sigh), so I think this would definitely be worth documenting. Especially, as in the linked issues from govuk_template, the argument seems to be this is in fact the preferred way of doing things over nonces.

We're finding our way with the framework and beginning to build out our own prototype kit apps that have received a great response internally into something production ready and we're keen to get off to the best possible start with things like CSP, even if we find ultimately we have to dial it back.

As such, +1 to documenting this!

I've also heard that SRI is now considered and anti-pattern and may even impact perf, but I've yet to see any concrete evidence of that.

Updating this issue as we now have more information on this. Subresource Integrity (SRI) has an impact on HTTP/2 coalescing, which in turn can cause web performance issues. Personal blog post about it here and a RFC related to changes we made on GOV.UK

Updating this issue as we now have more information on this. Subresource Integrity (SRI) has an impact on HTTP/2 coalescing, which in turn can cause web performance issues. Personal blog post about it here and a RFC related to changes we made on GOV.UK

Great information thanks. I'll be interested to see how this shakes out and if you do get any comments from security experts around disabling SRI as mentioned in your blog.

I get the impression documentation around this going to be hard as it touches so many issues around how framework users are hosting and serving up their own projects, but I still think a basic introduction is going to be worthwhile.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

adamsilver picture adamsilver  路  6Comments

petergphillips picture petergphillips  路  9Comments

alex-ju picture alex-ju  路  4Comments

hannalaakso picture hannalaakso  路  6Comments

joelanman picture joelanman  路  3Comments