1

I have a website developed using VueJS (i.e. its a single page application). I've been looking at implementing Content Security Policy headers. As I tested out the header values I would need, I realised I would have to allow 'unsafe-inline' scripts, as this is fundamentally what my website is.

I've read around this a fair bit and found plenty of comments indicating that if I need to apply 'unsafe-inline', the CSP header really isn't going to do much for me.

So my question is; does applying 'unsafe-inline' render CSP more or less pointless? Does anyone have any good ideas of how to handle CSP on an SPA?

  • Are you sure you cant avoid unsafe-inline? I have no experience with Vue, but with React apps I have been able to set a CSP without the unsafe-inline without any trouble. I figured the experience with Vue would be similar, but I don't know that for sure. – Anders May 28 at 9:48
  • 2
    I made a considerable error here in thinking my unsafe-inline error was related to VueJS, when in fact it was due to a google tag manager script. Im now looking to SHA that script an enable it as an exception. – F_SO_K May 28 at 10:19
  • 1
    BTW, part of the problem is that I was using Firefox, which does not provide particularly detailed error logs on CSP violation. When I tested in Chrome, the issue was much clearer. I've raised a feature request on Firefox to improve the error output. – F_SO_K May 28 at 11:14
  • 2
    You can use Content-Security-Policy-Report-Only together with a report URI and the script-sample tag to get a very detailed response what exactly tripped up the CSP. – MechMK1 May 28 at 11:18
1

I've read around this a fair bit and found plenty of comments indicating that if I need to apply 'unsafe-inline', the CSP header really isn't going to do much for me.So my question is; does applying 'unsafe-inline' render CSP more or less pointless?

True, Disallowing inline styles and inline scripts is one of the biggest security wins CSP provides. However, if you absolutely have to use it, there are a few mechanisms that will allow them. You can use a nonce-source to only allow specific inline script blocks:

Content-Security-Policy: script-src 'nonce-2726c7f26c'

You will have to set the same nonce on the element:

<script nonce="2726c7f26c">
  var inline = 1;
</script>

Does anyone have any good ideas of how to handle CSP on an SPA?

Hopefully this may help(change xx to tt): hxxps://developer.squareup.com/blog/content-security-policy-for-single-page-web-apps/

Credits: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src

| improve this answer | |
  • Thanks, I'm currently looking into the SHA approach. – F_SO_K May 28 at 10:20
1

does applying 'unsafe-inline' render CSP more or less pointless?

Preventing XSS is one of the main benefits of a CSP. If you need to allow inline scripts, that benefit is mostly gone.

But there are still some situations where a CSP can prevent exploitation of issues. Examples:

  • Clickjacking: a CSP can prevent it
  • HTML injection: Even if no XSS can be gained, HTML injections can be used to exfiltrate data. A CSP may be able to mitigate some of the impact (by restricting form actions, images sources, etc)
  • CSS injection: If you don't have inline CSS, you can prevent CSS injection via CSP
  • even with unsafe-inline, a CSP may make XSS more difficult to exploit. The easiest way to exploit XSS is to include a remote script, as an attacker doesn't have to worry about length or special character restrictions in the payload
  • enforce content to be loaded via HTTPS

Does anyone have any good ideas of how to handle CSP on an SPA?

The same way as with any application: Don't have inline scripts. Instead, you should have all your scripts in .js files, which you then include from a trusted origin (this actually seems easier to achieve in a SPA compared to a classic application which may have inline JavaScript all over the place).

You can also allow a specific script block using a nonce or hash source (which implemented correctly prevents XSS).

Even if you need to allow unsafe-inline for now, I'd still recommend implementing a CSP which is as restrictive as possible given the situation.

It will help you implement future features in a way compatible with a restrictive CSP. And when you get around to removing inline js, you just need to remove unsafe-inline from the CSP that you have in place already (instead of having multiple issues to worry about implementing a new CSP).

| improve this answer | |
1

Yes, it is worth setting up a CSP anyway. Here are a few benefits:

  • Many real world XSS vulnerabilities does not allow arbitrarily long payloads. A common technique is then to just have a small payload that loads the big payload from another server. This can be prevented with a CSP.
  • You can prevent clickjacking with a frame-ancestors directive.
  • There are other useful things you might want to set, such as object-src. MDN has a nice list.

But you are right that the biggest benefit is to be able to block unsafe-inline. I think this should be possible to accomplish with Vue.JS without to much work.

So if you can find a way to get rid of unsafe-inline, it would be good. But something is still better than nothing.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.