IIS custom header "Content-Security-Policy" is overwritten - iis

I have currently an issue with a SharePoint web application, where all websites return a response header content-security-policy: default-src 'self'; object-src 'none'; form-action 'self', which breaks the website's view using Chrome or Firefox, as styles won't be applied and Javascript won't be executed.
Console-Log
Refused to execute inline script because it violates the following Content Security Policy directive: default-src 'self'.
Either the 'unsafe-inline' keyword, a hash ('sha256-WFRyoBrQbrYtLpGIdyBszDzxQni3b0V/wUirab0OhKM='), or a nonce ('nonce-...') is required to enable inline execution.
Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
The problems only occurs if the websites are addressed using HTTPS. I already checked the HTTP Response Headers in IIS. content-security-policy is not specified. If I add it myself, it gets overwritten and is not sent in the response header. There are only two solutions installed, which do not mess with the response headers.
Has anyone an idea what else could change the custom response header and overwrite the one defined in the web.config? Or is there an other way to change the Content-Security-Policy?

I tested changing the IIS Response Headers by configuring the "CustomHeaders"-section in the web.config, by writing custom IIS modules, which modified the headers using the request lifecycle, and also by writing additional rules with the URL Rewriting tool. Nothing worked...
In the end we found out someone extended the firewall, which onwards would add new header and overwrite my changes of the HTTPS response. Mystery solved :)

In my case, I was asked by Network and Information Security Team to add the Content-Security-Policy: default-src 'self'; header in my IIS 8.5 SharePoint Server 2016 Publishing website which affects all the system pages and the browser refuses to execute the scripts and in console we got this error
Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-HU8dCwZsqh4m8QG0y6qanyzPx1d6YSGHuAN0QXmxZvw='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
I then change the header to Content-Security-Policy:frame-ancestors 'self'; and it resolves the issue.
I actually got this from the JohnC's Answer that helps me resolving the issue

Related

content-security-policy doesn't work; I want to have my website load in an iFrame on ONE other website only

How do you do this? I want only one other website to be able to load my main website in an iFrame but nothing is working.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors
Apparently as I understand it the protocol you set in .htaccess is this
So far I've tried:
1.
Header set Content-Security-Policy "frame-ancestors 'self' https://example.subdomain.co;"
2.
Header always set Content-Security-Policy "frame-ancestors 'self' 'https://example.subdomain.co';"
3.
Header set Content-Security-Policy "frame-ancestors 'self' 'https://example.subdomain.co';"
None of these work. When I try to load an iframe of example.com inside https://example.subdomain.co I get the following error:
Refused to display 'https://example.com/' in a frame because it set
'X-Frame-Options' to 'sameorigin'.
And then I get more confused because apparently you can only do DENY and SAMEORIGIN with this.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
The X-Frame-Options HTTP response header can be used to indicate
whether or not a browser should be allowed to render a page in a
<frame>, <iframe>, <embed> or <object>. Sites can use this to avoid
click-jacking attacks, by ensuring that their content is not embedded into other sites.
The added security is provided only if the user accessing the document
is using a browser that supports X-Frame-Options.
The one I would have wanted is ALLOW FROM but
ALLOW-FROM uri This is an obsolete directive that no longer works in
modern browsers. Don't use it. In supporting legacy browsers, a page
can be displayed in a frame only on the specified origin uri. Note
that in the legacy Firefox implementation this still suffered from the
same problem as SAMEORIGIN did — it doesn't check the frame ancestors
to see if they are in the same origin. The Content-Security-Policy
HTTP header has a frame-ancestors directive which you can use instead.
It's deprecated and it doesn't work.
Refused to display in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'
This answer doesn't help because they don't talk about what I want to do, they just explain what it is.
How to set 'X-Frame-Options' on iframe?
Again, not helpful because it's explaining to OP that the header is set on the website in the iframe source.
Is there a way to set it X-Frame-Options for frame-ancestors somehow to make this work so that I can load an iframe of my website on one other specific website? Or is this not possible?
When you set frame-ancestors correctly all browsers that understand it will disregard X-Frame-Options. This means that you can set both headers and use ALLOW-FROM as you will then server X-Frame-Options to IE and frame-ancestors to other browsers.
Have you checked if your Content-Security-Policy is present as a response header? Your first version is the most correct one, but you can drop the scheme as such: "frame-ancestors 'self' example.subdomain.co;", there should not be any single quotes around hosts in sources.

content security policy frame-ancestors

I'm trying to load my content into an IFrame, so I implemented the Content-Security-Policy header: Content-Security-Policy: frame-ancestors http://*.example.com/abc.html.
I am able to load the content on iframe when I give the header as
Content-Security-Policy: frame-ancestors http://*.example.com/.
But when I change the header to:
Content-Security-Policy: frame-ancestors self http://*.example.com/abc.html.
then the content on iframe is getting loaded for the first time but gives below error when I refresh the web page
Refused to display 'https://....' in a frame because an ancestor violates the following Content Security Policy directive: frame-ancestors self http://*.example.com/abc.html.
Can anyone tell why its giving error on refreshing the page.
Also does frame-ancestors considerers the full url (http://.example.com/abc.html) or only the hostname like http://.example.com?
Chrome browser has a bug - it's not support paths in the frame-ancestors directive. Safari nas the same bug, and only lasets Firefox supports paths in this directive.
So for frame-ancestors instead of http://.example.com/abc.html you have to use http://.example.com host-source.
For other directives you can use paths and filenames.
Without a working example it is hard to know exactly what the problem is. But based on the specification, https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors, some adjustments to your CSP can be advised:
Remove the path, it is not according to the specification to use more than the scheme, host and port.
Use the expected scheme (http/https) or remove the scheme.
Use wildcard https://*.example.com, not just https://.example.com
Use 'self', not self

Why is script-src-elem not using values from script-src as a fallback?

When implementing csp-header, I have specified my policy as:
default-src 'self'; script-src www.gstatic.com; Since I have not declared script-src-elem directive in my csp policy, as stated in this mdn documentation, I was expecting policy defined for script-src to be used for script-src-elem directive as well. However, I see violation being reported as "violated-directive":"script-src-elem" "blocked-uri":"https://www.gstatic.com/blah/blah".
Any idea why this behavior is happening?
After seeing this exact same pattern in some of my applications, I finally got to the root of this!
The weirdness we were seeing was that CSP reports were coming in for a hostname which was definitely in the script-src directive; and we know that script-src-elem is supposed to fall back to those directives. From that perspective, it should have been literally impossible for these reports to happen.
Here's what we found: the users these reports were coming from were using the PrivacyBadger browser extension, which was leading to false positive CSP reports for the hosts (Google) that it blocked. I didn't dig too far into it, but here's my theory on how that happens:
The Content Security Policy performs a pre-request check for the JavaScript include on the page (eg. gstatic.com or google-analytics.com). The pre-request check passes, because the hostname is allowed in the policy.
The browser initiates a request for the resource
PrivacyBadger intercepts the request via the browser's onBeforeRequest API (see PrivacyBadger source and Chrome documentation)
ProvacyBadger returns a surrogate data blob for the asset. It does this to ensure that code which relies on the real javascript (eg. window.ga) won't break.
The browser then performs a post-request check against the returned base64 blob
The post-request check fails - because the policy does not allow data: for script-src
The browser sends a CSP report for the blocked asset.
This seems like it might be a browser bug - because the report reflects the original asset's third party hostname; while the blocked content is actually a data: blob that was returned via the intercepted request.
From the documentation you linked to: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src-elem
The HTTP Content-Security-Policy (CSP) script-src-elem directive specifies valid sources for JavaScript elements, but not inline script event handlers like onclick.
Without seeing the rest of your code it is a safe assumption that you are seeing this error as a result of an inline event handler and will need to define script-src-elem in your CSP policy.
script-src-elem definitely does fallback to script-src in browsers on the Chromium engine. Check the Chrome console, the warn will looks like:
... Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
Gecko-browsers does not support script-src-elem and use script-src directly.
The CSP2-browsers in violation reports sends a violatied directive resulting after all fallback chain. But CSP3-browsers send a "theoretically" violated directive and than perform fallback if directive was omitted. This introduces some confusion.
script-src-elem have nothing to do with inline event handler like onClick() -this is noted in MDN docs. script-src-elem controls only <script>...</script> and <script src='...'> elements (and javascript-navigation).
"blocked-uri":"https://www.gstatic.com/blah/blah" says that https://www.gstatic.com host-source was blocked, not inline event handler.
Inline event handlers do lock in the script-src-attr directive and report will looks like "blocked-uri":"inline".
Looks like you edit a copy CSP, but server issues another as default. Please look the "original-policy" filed in the report's JSON. Is it contains you real CSP or some default one?
PS: To detail analyse what's going on it need to look a full violation report and a your full CSP (print screen of browser console messages will be very helpful). Because script-src www.gstatic.com; is totally enough for CSP3-browsers to allow any resources from 'https://www.gstatic.com'. (CSP2-browsers requires more rules but you shown violation report sent by CSP3-browser).
I know I'm late to this, but this thread brought me to the solution for my case:
Disable the NoScript-Addon in Chrome.

How can i resolve this content security policy error?

when i run my node index file my getting this error in the browser
Refused to load the image 'http://localhost:3000/favicon.ico' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.
can any help me how can i resolve this error ?
The most basic approach to solve this issue is not to send a Content-Security-Policy response header if the client requests /favicon.ico.
However, depending on your specific use case there might be better solutions, e.g. setting img-src 'self' for the file or all static images below the root path.
In all cases you should return a HTTP 404 Not Found status code if you don't have a /favicon.ico.

CSP form-action directive override not working in Chrome

I need to relax the CSP (Content Security Policy) in Chrome to enable a redirect with some get parameters to the Azure login page. When processing such redirects Chrome applies policy restrictions related to form submissions. The default policy in such cases amounts to
<meta http-equiv="Content-Security-Policy" content="form-action 'self' javascript:"/>
In this case the redirect to https://login.microsoftonline.com/...
wont' work. The MDN says that you can expand the list of allowed destinations, which I tried like so:
<meta http-equiv="Content-Security-Policy" content="form-action 'self' https://*.microsoftonline.com javascript:"/>
It appears to have no effect at all as still get the same error on the console:
Refused to send form data to 'https://login.microsoftonline.com' because it violates the following Content Security Policy directive: "form-action 'self' javascript:"
Note also that playing with the order of the attributes or removing the javascript: part does help. However, removing the self part is evidently paid some attention to by Chrome as in this case I'm not able to send data back to the origin. It is almost like they let you tighten up the policy but not relax it.
Any help will be greatly appreciated.
I think that it is caused because form-action (according to the documentation):
The HTTP Content-Security-Policy (CSP) form-action directive restricts the URLs which can be used as the target of a form submissions from a given context.
Maybe you could try the default-src directive:
default-src
The HTTP Content-Security-Policy (CSP) default-src directive serves as a fallback for the other CSP fetch directives.
Hope it helps!
Do not include the protocol (https) and i think it will work

Resources