Socket.IO blocked by Content Security Policy - html

I am trying to create a super simple website just to show content and have another page be able to change said content on the page. (Security is of 0 concern so feel free to post really sketchy answers).
But when I visit the site (hosted on a digital ocean server behind NGINX), I get the following error:
Refused to connect to wss://subdomain.domain.online/socket.io/?EIO=4&transport=websocket&sid=SIDHERE because it appears in neither the connect-src directive nor the default-src directive of the Content Security Policy.
I have looked everywhere and got to this policy of:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' wss: ws: *; connect-src 'self' ws: wss: *;">
But still get the error, I was wondering if anyone would know a fix.
Cheers, Sam.

Look like you have publish 2 CSPs - one via <meta http-equiv='Content-Security-Policy'> tag and the second one via CSP HTTP header. In this case the most stringent policy apply.
The second CSP is published on server by Helmet middleware, Helmet version 4 have CSP swiched on with default rules.
Disable CSP in helmet.contentSecurityPolicy(options) if you wish to use tag:
app.use(
helmet({
contentSecurityPolicy: false,
})
);
or configure CSP header in Helmet and do not use meta tag.

Related

Unexpected blocked page when called from link in iframe to PDF file with chrome based browsers

I have a webpage in an iframe which contains a link to a foreign page with attributes target="_blank" rel="noopener". This link works well from the page itself and also from the iframe but only when called via context menu with the option open in new tab. A regular click opens a new tab and shows the correct URL but results in This page has been blocked by Opera ERR_BLOCKED_BY_CLIENT.
I looked around for help, disabled all addons to no avail and played the scenario in incognito mode as well, no change. The console on the error page shows VM589:1460 crbug/1173575, non-JS module files deprecated. This hint left me in the dark, however. I manipulated the attributes to target="_blank" rel="noopener" rel="noreferrer" or rel="noopener noreferrer" with no success. This all applies to Opera.
I tried Brave with the same result and error message, except Brave instead of Opera, of course. Edge joins the failure band. No surprise then to see This page has been blocked by Chrome proper as well.
This error applies to all PDF-file links from the iframe, normal external links work well. Firefox shows briefly PDF.js viewer in the new tab and then works normal. I had no chance to try links to YouTube or the like, but I guess there is ample evidence I hit a bug in the chrome PDF-rendering engine.
What to do? Who is interested in this bug and how to reach them? Or is there anything I can do in my code?
Browser use already longer time the Content Security Policy (CSP) to protect users from undesired content. The definition of undesired content can be made by the site owner. if the site owner hasn't done that, then some standard values are used, which are more restrictive.
The website https://content-security-policy.com/ explains it like this
What is Content-Security-Policy?
Content-Security-Policy is the name of a HTTP response header that modern browsers use to enhance the security of the document (or web page). The Content-Security-Policy header allows you to restrict how resources such as JavaScript, CSS, or pretty much anything that the browser loads.
Although it is primarily used as a HTTP response header, you can also apply it via a meta tag.
The term Content Security Policy is often abbreviated as CSP.
What types of attacks does Content-Security-Policy help mitigate?
CSP was first designed to reduce the attack surface of Cross Site Scripting (XSS) attacks, later versions of the spec also protect against other forms of attack such as Click Jacking.
In your case you have to configure two hurdles for the user:
The iframe, required rule:
frame-src 'self'
The PDF, required rule:
object-src 'self' blob;
Essentially it's relatively safe to allow most things with 'self' but it's always good to disallow elements that are not used at all on the site.
Your Content Security Policy should look similar to this, and should allow PDFs in iframes:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'self' blob:; style-src 'self'; frame-src 'self';
The best is to configure the CSP in the server configuration. This is not possible for every site owner though, and it's possible to configure the CSP in meta tags too. You could add this to your site inside the head-tag:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'self' blob:; style-src 'self'; frame-src 'self'">
Setting the CSP in the server configuration is the stronger approach though:
https://content-security-policy.com/examples/meta/
Here are more examples, including CSP related server configuration for Apache Web Server and Nginx Webserver:
https://content-security-policy.com/examples/
EDIT
If the PDF is hosted on another domain, then the CSP has to adjusted differently, more openly.
Different options for sources are explained here:
https://content-security-policy.com/#source_list
The iframe, required rule has to be adjusted.
It should be restricted either to a special domain with *.example.com or to a nonce with 'nonce-rAnd0m'.
The PDF, required rule has to be adjusted, the same advise like for point 1. is applying.
So even the PDF is external then, it doesn't mean that everything could be injected somehow in the website.
Assumed you use the option with the domain *.example.com it would look like or similar to this then:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src '*.example.com' blob:; style-src 'self'; frame-src '*.example.com'
Assumed you use the option with the nonce it would look like or similar to this then:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'nonce-rAnd0m' blob:; style-src 'self'; frame-src 'nonce-rAnd0m'
I didn't test it, so slight adjustments might be required.

How to disable content security policy in react

I have searched and I have seen many articles saying how the content security policy is for my benefit and it secures my application, but why is it so frustrating. Currently this is my meta tag and my content security policy settings
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none'; script-src 'self' 'unsafe-inline'; connect-src 'self' https://polygon-rpc.com/ https://ipfs.infura.io:5001/api/v0/add?stream-channels=true&progress=false https://ipfs.infura.io:5001/api/v0/* img-src 'self'; style-src 'self' 'unsafe-inline'; base-uri 'self'; form-action 'self'; font-src 'self' https://fonts.gstatic.com;
"
/>
In my application, I connect to the polygon network, and users can upload files to IPFS. Now the problem is that although the above allows the successful upload of files, IPFS sends the url of the uploaded image to show the file preview to the user and the url changes on every request but that is blocked by CSP. So what I wanna know now is how to disable the goddamn thing completely. I don't want it, because if I had to manually add all external websites I call to the meta tag. That just seems stupid
I tried setting the content security policy from the server side using this, but it does not seem to do anything and only the settings from the meta tag in the react html file that works.
app.use(
contentSecurityPolicy({
useDefaults: true,
directives: {
defaultSrc: ["'none'"],
connectSrc: [
"'self'",
"https://polygon-rpc.com/",
"https://ipfs.infura.io:5001",
"https://ipfs.infura.io:5001/api/v0",
"https://ipfs.infura.io",
],
upgradeInsecureRequests: [],
},
reportOnly: false,
})
);
Its a MERN application hosted on heroku. So any idea how to go about that? Thanks
I tried setting the content security policy from the server side using this, but it does not seem to do anything and only the settings from the meta tag in the react html file that works.
As a result, you have 2 CSPs acting simultaneously - from the meta tag and from the HTTP header. All sources must pass through both CSPs, so the strictest rules from both CSPs will be applied as a result.
Use either a meta tag or an HTTP header.
IPFS sends the url of the uploaded image to show the file preview to the user and the url changes on every request but that is blocked by CSP.
It's enough to set img-src * to allow images from any host.
Note you have 2 errors in the CSP in the meta tag:
is missed semicolon ; before img-src 'self';. Fix it as ; img-src * data: blob:; to allow images from any sources including data:-Urls and blob:-Urls.
the https://ipfs.infura.io:5001/api/v0/* source is wrong because CSP does not support * in the path-part. Remove *.

How to allow scripts in HTML in CSP

My script-src for my website continues to produce an error and refuses to load my scripts which lie within my Header.html file, and I have tried multiple websites, including reading the docs, however I am unsure of what I am doing wrong of if I just need to be patient and wait for it to take effect on my site.
I am currently using a Meta tag for my CSP policy,
<meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline' 'unsafe-eval'; script-src * 'unsafe-inline' 'unsafe-eval';">
<script src='https://th4rjdmmrjsz.statuspage.io/embed/script.js'></script>
However, regardless of what I do with it nothing seems to work, I have used sites like RapidSec and the CSP site itself, including an auto generator, and nothing seems to have worked. What am I doing wrong here?
Edit: Added an example script.
CSP has versions (or levels) with newly supported features extending the original spec. Serving the CSP through an html meta header is considered legacy and has some drawbacks/bugs. Try setting CSP via the HTTP headers of the request.
Also, if you're using RapidSec, you can use the integrations (Wordpress plugin, Node.js package) that do this automatically for you.

Adding google fonts (fonts.googleapis.com) to CSP header

I am hosting a personal project on gitHub pages, and using cloudflare to enforce https. Now I would like to implement a CSP policy.
I tried adding meta tag to the head of my page:
<meta HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'self' *.fonts.googleapis.com/* *.cloudflare.com/* *.fonts.googleapis.com/*;">
But I am getting the following error:
Refused to load the stylesheet
'https://fonts.googleapis.com/icon?family=Material+Icons' because it
violates the following Content Security Policy directive: "default-src
'self' .fonts.googleapis.com/ .cloudflare.com/
.fonts.googleapis.com/". Note that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
This are the scripts that I am including:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans|Roboto" rel="stylesheet">
won't setting *.fonts.googleapis.com/* allow everything from the page?
Since this is the first time I am setting a CSP is this the correct way to set it for github pages? I have not found any reading on this yet.
Won't setting *.fonts.googleapis.com/* allow everything from the page?
Although this would be intuitive, the answer is no.
See the pretty good HTML5rocks introduction to Content Security Policy on the topic of wildcards (section Implementation details):
Wildcards are accepted, but only as a scheme, a port, or in the leftmost position of the hostname: *://*.example.com:* would match all subdomains of example.com (but not example.com itself), using any scheme, on any port.
So a working CSP for the two fonts could look something like this:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://fonts.googleapis.com/ https://fonts.gstatic.com/ 'unsafe-inline';">
Note 1: It's a good practice to use the corresponding CSP directives. In your case you should use the font-src and style-src like so:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; font-src 'self' https://fonts.gstatic.com/; style-src 'self' https://fonts.googleapis.com/ 'unsafe-inline';">
The advantage of using the corresponding directives is that your CSP gets pretty restrictive now. E.g., you're not allowing 'unsafe-inline' for script sources anymore. This means inline javascript is now forbidden. It's also forbidden to load scripts from https://fonts.gstatic.com/, which was allowed before. And so on...
Note 2: You can get rid of the 'unsafe-inline' keyword at all by using a hash or a nonce. I have not been able to make this work for this example but if you're interested, just take a look at the HTML5rocks intro again.

because the document's frame is sandboxed and the 'allow-scripts' permission is not set

I wrote a program that generated an html file with this header:
but I don't have iframe at all, let alone in sandbox
When I open the page in the browser (hosted on a Jenkins server) I see no css.
These are the errors (security policy)
I have seen some posts on stockoverflow, saying the <meta> should be like:
<meta http-equiv="content-type" content="text/html; charset=utf-8 ;">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' http://onlineerp.solution.quebec 'unsafe-inline' 'unsafe-eval'; style-src 'self' maxcdn.bootstrapcdn.com">
but as you can see in my print screen that didn't help
any idea, how can I fix this?
You're serving an HTML page from Jenkins, so Jenkins controls the response headers, not your content. Recent security fixes in Jenkins imposed a strict default Content Security Policy. You should be able to see the Content-Security-Policy header inserted by Jenkins in the response headers.
One solution is to relax the Jenkins configuration, see the Configuring Content Security Policy wiki page for details:
The CSP header sent by Jenkins can be modified by setting the system property hudson.model.DirectoryBrowserSupport.CSP:
If its value is the empty string, e.g. java -Dhudson.model.DirectoryBrowserSupport.CSP= -jar jenkins.war then the header will not be sent at all.
(Warning!) This is potentially very unsafe and should only be used after reviewing the overall security setup.
You can experiment with different settings using the Jenkins Script Console. To enable CSS and images from external sites, you could use something like:
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "sandbox; default-src 'self'; img-src '*'; style-src '*' 'unsafe-inline';")
Another solution is to publish (deploy) the generated page(s) on another server where you can control the content security policy.