Content-Security-Policy htaccess block all iframes but one - .htaccess

My objective is to block my site from being accessed in an iFrame, with the exception of defend.net. I'm able to successfully do it with this line:
Header append X-Frame-Options: "ALLOW-FROM https://*.defend.net/"
However, I read that that's been depreciated.
<IfModule mod_headers.c>
Header set X-XSS-Protection "1; mode=block"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-Content-Type-Options "nosniff"
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header add Content-Security-Policy "frame-src 'self' 'https://*.defend.net';"
Header set Referrer-Policy "same-origin"
</IfModule>
What is the most effective, secure way I can achieve my objective?
Can I safely remove this and have the same protection?
Header set X-Frame-Options "SAMEORIGIN"

This is what I came up with that seems to work as intended:
<IfModule mod_headers.c>
Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options "nosniff"
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header set Content-Security-Policy "frame-src 'self' https://www.google.com https://www.youtube.com; frame-ancestors 'self' https://*.defend.net;"
Header set Referrer-Policy "same-origin"
</IfModule>

Related

CSP for mapbox gl js , App created with dockerize nodejs and nginx

I'm trying to include CSP for Mapbox gl js in my nodejs app, where the map tile works properly on localhost but throw's issues in issues tab in chrome developer tool. And throw error on hosted website blob:https://example.com/ violates the Content-Security-Policy.
Issues tab in chrome developer tool in local environment
Indicate whether to send a cookie in a cross-site request by specifying its SameSite
attribute
Because a cookie’s SameSite attribute was not set or is invalid, it defaults to
SameSite=Lax, which prevents the cookie from being sent in a cross-site request.
This behavior protects user data from accidentally leaking to third parties and
cross-site request forgery.
Resolve this issue by updating the attributes of the cookie:
Specify SameSite=None and Secure if the cookie should be sent in cross-site requests.
This enables third-party use.
Specify SameSite=Strict or SameSite=Lax if the cookie should not be sent in
cross-site requests.
8 cookies
Name Domain & Path
_mkto_trk .mapbox.com/
_ga .mapbox.com/
mkjs_group_id .mapbox.com/
optimizelyEndUserId .mapbox.com/
mkjs_user_id .mapbox.com/
_uetvid .mapbox.com/
_cioid .mapbox.com/
_gid .mapbox.com/
Error in console
web_worker.js:9 Refused to create a worker from
'blob:https://example.com/20d2ed71-b218-4a21-b74d-8913226b398e' because it violates
the following Content Security Policy directive: "default-src * data: 'unsafe-eval'
'unsafe-inline'".Note that 'worker-src' was not explicitly set, so 'default-src'
is used as a fallback.
web_worker.js:9 Uncaught (in promise) DOMException: Failed to construct
'Worker': Access to the script at
'blob:https://example.com/20d2ed71-b218-4a21-b74d-8913226b398e'
is denied by the document's Content Security Policy.
nginx-conf file
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
server_tokens off;
#SSL configuration here
resolver 8.8.8.8;
location / {
try_files $uri #nodejs;
}
location #nodejs {
proxy_pass http://nodejs:8080;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
#here is the CSP header
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
}
I've tried several dozen thing's but nothing work's. Include helmet js and also csp header in server function in server side but find no success.
You need to add blob: to your "all allowed" Content-Security-Policy.
The below should fix the issue for you:
add_header Content-Security-Policy "default-src * data: blob: 'unsafe-eval' 'unsafe-inline'" always;
(I am assuming this is not the CSP you are actually going to run, because what would be the point?)

Content Security Policy directive: "default-src 'self'". Note that 'frame-src' was not explicitly set, so 'default-src' is used as a fallback

I have integrated the single-sign-on in our application using WsFedration(ADFS)
after the sign-out, it's redirecting to the page as successfully log out and back to the login page.
this follow is working correctly after hosting in the windows server, but after the hosting, to the Nginx server I'm having a problem, it's not redirecting to the login page, console error says,
Refused to frame 'https://xxx-yyy.zzz.rr/' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'frame-src' was not explicitly set, so 'default-src' is used as a fallback
then I search regarding this and added the Content Security Policy (CSP) to the Nginx config file like below.
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options SAMEORIGIN always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Content-Security-Policy "style-src-elem 'unsafe-inline' 'self' https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css https://fonts.googleapis.com/css";
add_header Content-Security-Policy "style-src 'unsafe-inline' 'self' https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css https://fonts.googleapis.com/css";
add_header Content-Security-Policy "frame-src 'unsafe-inline' 'self' none";
add_header Content-Security-Policy "default-src 'unsafe-inline' 'self'; https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css https://fonts.googleapis.com/css ";
add_header Content-Security-Policy "frame-ancestors 'self' 'unsafe-inline' none";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "font-src 'self' 'unsafe-inline' https://netdna.bootstrapcdn.com https://fonts.gstatic.com";
I tried several ways, but I couldn't figure it out , if anyone can help me to fix this issue much appreciated.
thanks in advance.
You publish a several CSPs at the same time, they work not as you think. If multiple CSP published, they are combined with logical 'AND'.
But you trickely use unique directives in each CSP, therefore the whole set would work as intended if not the default-src directive. If it's issued in a separate CSP, the default-src overrides all other fallback-directives. As result you have 'unsafe-inline' 'self' rule for all directives.
You have to place all directives in the one add_header Content-Security-Policy.
You have some errors in rules, for example:
https://fonts.googleapis.com/css source should have trailing /, because it;s a folder name, not file name.
none token should be single quoted - 'none', and it will be ignored if it's combined with the other sources.
"frame-src 'unsafe-inline' 'self' none" - the frame-src is not support 'unsafe-inline' token.
"frame-ancestors 'self' 'unsafe-inline' none" - the frame-ancestors is not support 'unsafe-inline' token.
"font-src 'self' 'unsafe-inline' https://netdna.bootstrapcdn.com https://fonts.gstatic.com" - the font-src is not support 'unsafe-inline' token.
"default-src 'unsafe-inline' 'self'; https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css https://fonts.googleapis.com/css " - the ;(semicolon) after 'self' does finish the default-src rules set, therefore https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css is counted as directive name.
Here your rules:
add_header Content-Security-Policy " \
default-src 'self' 'unsafe-inline' https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css https://fonts.googleapis.com/css/; \
font-src 'self' https://netdna.bootstrapcdn.com https://fonts.gstatic.com; \
frame-ancestors 'self'; \
frame-src 'self'; \
style-src 'self' 'unsafe-inline' https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css https://fonts.googleapis.com/css/; \
style-src-elem 'self' 'unsafe-inline' https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css https://fonts.googleapis.com/css/; \
"
In my case I follow the tip of #granty about first topic
You publish a several CSPs at the same time, they work not as you think. If multiple CSP published, they are combined with logical 'AND'.
And I "remove" the Header in my Nginx configuration:
add_header X-Frame-Options "";
In my Keycloak the Headers of Security Defenses are:
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-src 'self'; frame-ancestors 'self'; object-src 'none';

why I got 'strict-dynamic' is present?

I want to create CSP for my site and I used CSP mitigator extension in the Chrome browser
My app was written with Elixir and phoenix-framework and I use nginx for the web server
nginx headers are:
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
I've written many rules for CSP such as:
default-src 'none';
base-uri 'none';
form-action 'none';
frame-ancestors 'none';
script-src 'unsafe-inline' https://www.googletagmanager.com https://example.com https://www.google.com https://www.gstatic.com https://www.google-analytics.com 'nonce-hZwUTOrpRdsdlZmODf631g==';
style-src 'self' 'nonce-hZwUTOrpRdsdlZmODf631g==' https://example.com 'unsafe-inline' https://www.googletagmanager.com https://fonts.googleapis.com https://www.google.com/recaptcha;
img-src 'self' https://example.com:443 https://ssl.gstatic.com https://stats.g.doubleclick.net https://www.google-analytics.com;
frame-src https://www.gstatic.com https://www.google.comhttps://www.googletagmanager.com/ns.html;
font-src 'self' 'unsafe-inline' https://example.com https://fonts.gstatic.com;
connect-src www.google-analytics.com https://www.google-analytics.com https://stats.g.doubleclick.net ;
object-src 'none';
report-uri https://my_code.report-uri.com/r/d/csp/reportOnly;
and continuously my console has errors:
https://gist.github.com/mojtaba-naserei/da75abac20c94a655dd2ab2e652dab8d
=============================
My questions are:
1) Why did I receive
'strict-dynamic' is present, so host-based whitelisting is disabled
when I never define 'strict-dynamic' in my CSP?
2) Why do I get this error:
[Report Only] Refused to load the image 'https://example.com/images/smal-trangell-logo.png' because it violates the following Content Security Policy directive: "default-src * 'unsafe-inline' 'strict-dynamic' data: filesystem: blob: ws: wss: ". 'strict-dynamic' is present, so host-based whitelisting is disabled. Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.
when I defined a rule for this: img-src 'self' https://example.com:443?

How to set HttpOnly response header using nginx?

We are using node js and nginx as Web Server.
We want to restrict XSS attack by mitigating script execution that uses Cookies.
How can I secure Cookies by adding HttpOnly flags in nginx settings?
From Nginx version 1.19.3 you can use proxy_cookie_flags to add additional flags for your cookies.
For all cookie use:
proxy_cookie_flags ~ secure samesite=strict;
For some of the cookies you can use (or regex):
proxy_cookie_flags one httponly;
Check more in documentation: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_flags
Edit your virtualhost file:-
sudo vim /etc/nginx/sites-enable/example.conf
Add Below Line under server block:-
add_header X-XSS-Protection "1; mode=block";
Example:-
server {
server_name a.com;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
root /var/www/a/;
}

How to Override Content-Security-Policy of Site A while using nginx proxy_pass on Site B for serving content?

Is there a way to override Content-Security-Policy set by the domain/site A while i am using nginx proxy_pass on Site B.
Site A defined Content-Security-Policy on their domain.
Site B acts as a reverse proxy for site A.
How can i override Content-Security-Policy while serve content from site B ?
how can i achieve this in nginx proxy pass ?
my current nginx server block looks like this
server {
server_name proxy-domain.com.;
location / {
proxy_pass http://www.target-site.com/;
proxy_set_header Accept-Encoding "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
i have tried adding
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval'
e.g.
server {
server_name proxy-domain.com.;
location / {
proxy_pass http://www.target-site.com/;
proxy_set_header Accept-Encoding "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval'
}
but if i check headers of site B, then it shows modified Content-Security-Policy of site B but the content from other sources does not gets loaded., only headers are set.
why is that ?
update:
when i check headers i get 2 Content-Security-Policy headers , first are set by site A and then later one Content-Security-Policy headers set be my i.e. site B.
e.g.
Content-Security-Policy: default-src 'self' 'unsafe-inline' 'unsafe-eval' apis.google.com www.google.com;
Content-Security-Policy: default-src 'self' 'unsafe-inline' 'unsafe-eval' *.cloudflare.com;
This problem seems similar to the Nginx as reverse Proxy, remove X-Frame-Options header thread on the Nginx mailing list. That solution was proxy_hide_header
By default, nginx does not pass the header fields “Date”, “Server”,
“X-Pad”, and “X-Accel-...” from the response of a proxied server to a
client. The proxy_hide_header directive sets additional fields that
will not be passed. If, on the contrary, the passing of fields needs
to be permitted, the proxy_pass_header directive can be used.

Resources