I want to deploy a Nuxt application but I have a problem with Csp. I added all the Sha256 to my Csp but some lines are still stuck. I think it's the lines with :style="". What would be the solution? Is it really risky to add an "unsafe-inline"?
Everything works if I add "unsafe-inline" but I'm not sure that's great for site security.
I also specify that all my other Headers are well configured
If you add hashes for event attributes such as onclick, onerror etc, it won't work. You can make it work if the browser has implemented full support for 'unsafe-hashes', but there are likely still a lot of users who are not at that level. Otherwise you'll need to rewrite the event attributes to event listeners if you don't want to add 'unsafe-inline'.
Related
Is there a way to make Vue.js to work with CSP properly?
When I run my spa application (resulting from npm run generate with Nuxt.js), I will get several warnings such as these:
Refused to apply inline style because it violates the following
Content Security Policy directive: "style-src 'self' 'strict-dynamic'
'nonce-124lk5fjOc4jn7qqLYEsG2jEvxYuqu8J' 'unsafe-inline' https:". Note
that 'unsafe-inline' is ignored if either a hash or nonce value is
present in the source list.
Knowing CSP, there are two correct ways of fixing this:
Using nonces, where Vue.js would have to sign all the generated scripts and styles with a nonce attribute. But I don't think this would solve anything, since it appears some CSS is added inline.
Using hashes, which is actually the preferred way of doing it, since the hash secures exactly what we want the client to execute on the browser.
However, in order to use hashes, Vue.js/Webpack must be able to calculate the hash for all its scripts and styles, and:
for each compilation, tell them to the developer that will then add these hashes to a NGINX configuration file,
or,
be able to generate meta tags containing the hashes, making this process 100% transparent to the developer, who doesn't need to configure anything else to guarantee a good CSP protection.
Does Vue.js support this in any way? Is there anyone in the world who was able to make CSP working with Vue.js without any 'unsafe-inline'?
According to the Vue.js docs, the runtime build is fully CSP-compliant.
Nuxt is supporting a csp config to create hashes via webpack sent as header on dynamic SSR mode and meta elements otherwise (see https://github.com/nuxt/nuxt.js/pull/5354)
you could use the --no-unsafe-inline option in your npm run build script
https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-build
Not sure if this is better as a comment or not but it kinda works so putting it here for now.
Our deployment strategy might be a bit different, but essentially we trigger a lambda to update the cloudfront csp with our CI/CD.
We noted that the inline scripting was static despite different app versions/bumps. Our current workaround is:
Deploy on a dev server - get the sha256 hash from the chrome dev tools (you could probably calculate it yourself to avoid deploying)
Updated our terraform cloudfront lambda CSP with the hash
On the new deploy the hash matches and we don't need unsafe-inline
Some big limitations re: if nuxt changes the inline script on new versions we'll have to manually update our hash in the CSP. Also, depending on your styling framework there may be a number of inline-styles which aren't captured here.
I want to add a sort of custom middleware in Traefik, where I can check user identity and after validating from the database, I want to route users to different versions of the application? Is it possible with Traefik?
For the time being, the only way to add a custom middleware to Traefik is to fork it and add your custom middleware into the source code and build it for yourself. Actually this is not too difficult but of course it comes with all the downsides of forking. There is an example here: https://github.com/negasus/traefik2-luascript. You need to edit it a bit because it is somewhat outdated but I was able to add my custom middleware by following it.
I'm new to CSP and my goal is to enable the simplest possible CSP header.
Based on reading the spec and MDN docs I thought my app should work but unfortunately no luck on Chrome Canary v70.
I setup a minimal repo to reproduce. Can you see where I've gone wrong?
Turns out I was misunderstanding the details a bit. I'll post my solution here in case it helps someone else in the same boat.
My goal is to serve a React SPA with CSP enabled. The app happens to use Material-UI, which uses JSS, which injects inline styles - which of course are blocked by default with CSP.
Because it's a static SPA for the frontend and modifying HTTP headers is out of scope of the SPA, I instead generate a nonce on the web server. The nonce gets injected into the CSP HTTP Header and also in the index.html tag consistent with what JSS expects.
The upside is CSP is protecting the SPA, and we don't have to use unsafe-inline escape hatch. The downside, but a small one, is that index.html is dynamic now and can't be cached. But seeing as the file is already tiny (<1kb) the benefits of CSP seem worth that tradeoff.
So I've been going through my forms recently to check my SQL queries are secure along with sanitizing any input and have just found that entering <? into a text box triggers a 403 before it even hits the processing file, I can only assume it must be related to mod_security??
My question is, is this something to just not worry about if it's controlled by the web host as I'm using shared hosting.
I recently ran into a problem with submitting form data via a GET request to the server after using jQuery's .serialize() function for the submitted variables. These were web apps that had worked flawlessly for years. It turned out that after a recent ModSecurity rule set update, I was triggering the 211700 (HTTP redirect) and 217280 (smuggling attack) rules in Comodo's WAF ruleset, which the server uses with ModSecurity. I wasn't getting a 403. My IP address got blocked by the firewall. :(
The fix was switching my AJAX code to use to POST instead of GET, and not using .serialize(). I still have some web apps that use .serialize() and GET requests via AJAX without triggering ModSecurity, so I believe it is also necessary to pass suspect characters, as you discovered, though in my testing, all I was using was parentheses.
Since you're on a shared server, it's probably not possible--or worth your time--to find out what rule set the host is using, so your best bet is most likely to switch your form submissions to using POST instead of GET, and not use .serialize(). I figure those rules are there for a reason, and a better approach is to avoid having my code look like it's doing something nefarious than to disable the rules.
What are the best practices (and how to go about doing it) to support offline mode when using html5 history api for url rewrites?
For example, (hypothetically) I have a PWA SPA application at https://abc.xyz which has internationalization built in. So when I visit this link, the Vue router (which ideally could be any framework - vue, react, angular etc.) redirect me to https://abc.xyz/en.
This works perfectly when I am online (ofcourse, the webserver is also handling this redirect so that app works even if you directly visit the said link).
However, its a different story when I am offline. The service worker caches all resources correctly so when I visit the URL https://abc.xyz everything loads up as expected. However, now if I manually type the URL to https://abc.xyz/en, the app fails to load up.
Any pointers on how to achieve this?
Link to same question in github: https://github.com/vuejs-templates/pwa/issues/188
Yes, this is possible quite trivially with Service Workers. All you have to do is to configure the navigateFallback property of sw-precache properly. It has to point to the cached asset you want the service worker to fetch if it encounters a cache miss.
In the template you posted, you should be good to go if you configure your SWPrecache Webpack Plugin as follows:
new SWPrecacheWebpackPlugin({
...
navigateFallback: '/index.html'
...
})
Again, it is absolutely mandatory that the thing you put inside navigateFallback is cached by the Service Worker already, otherwise this will fail silently.
You can verify if everything was configured correctly by checking two things in your webpack generated service-worker.js:
the precacheConfig Array contains ['/index.html', ...]
in the fetch interceptor of the service worker (at the bottom of the file), the variable navigateFallback is set to the value you configured
If your final App is hosted in a subdirectory, for example when hosting it on Github pages, you also have to configure the stripPrefix and replacePrefix Options correctly.