How to add HTTP security headers? - php

How can I add the following security headers to my website?
X-Frame-Options - Protects against Clickjacking attacks
X-XSS-Protection - Mitigates Cross-Site Scripting (XSS) attacks
X-Content-Type-Options - Prevents possible phishing or XSS attacks

Two ways you can add these headers:
Apache Conf or .htaccess File
<IfModule mod_headers.c>
Header set X-Frame-Options "DENY"
Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options "nosniff"
</IfModule>
The Apache/htaccess approach is most likely the preferred way. If you add it to your configuration file, which may be in your httpd.conf or it could be in a vhost configuration file (really depends on how the server is setup), you would place it within a <Directory> element. To use .htaccess the configuration for the site must have AllowOverride All. While it's pretty standard, you must have the mod_headers library installed in Apache as well.
PHP
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');
header('X-Content-Type-Options: nosniff');
With the PHP approach, you will need to write this to every response, so if you do not have a bootstrap that can do this, I'd recommend leveraging either your apache configuration file or the .htaccess file.

Related

Setting X-Frame-Options in PHP

How can I set X-Frame-Options in my PHP code so that it will be there in all the web pages from my server. Basically, I am trying to avoid iframe loading of my web app.
Use below in your php file which outputs response to client side.
header("X-Frame-Options: DENY");
DENY will fully block. You may try SAMEORIGIN option also.
header("X-Frame-Options: SAMEORIGIN");
If you are using apache web server, you can directly set in httpd.conf also.
<Directory />
...
Header always set X-Frame-Options "SAMEORIGIN"
</Directory>
The X-Frame-Options prevents your site content embedded into other sites. Browser allowed other sites to open web page in iframe. It also secure your Apache web server from clickjacking attack.
There are three options available to set with X-Frame-Options:
‘SAMEORIGIN’ – With this setting, you can embed pages on same origin. For example, add iframe of a page to site itself.
‘ALLOW-FROM uri – Use this setting to allow specific origin (website/domain) to embed pages of your site in iframe.
‘DENY – This will not allow any website to embed your site pages in an iframe.
We have two way to Setup X-Frame-Options
1. with Apache Configuration
2. with .htaccess
with Apache configuration:
Debian based systems: /etc/apache2/conf-enabled/security.conf
Redhat based systems: /etc/httpd/conf/httpd.conf
Header set X-Frame-Options: "SAMEORIGIN" #Allow for Same Origin (Default Action)
Header set X-Frame-Options: "ALLOW-FROM http://example.com/" #Allow from specific origin
Header set X-Frame-Options: "DENY" #Deny to everyone
with .htaccess
Header append X-Frame-Options: "SAMEORIGIN"

Apache / .htaccess : website optimizations

I make my website from scratch with PHP. In order to optimize performance, loading time and security I use a lot of online tools : google page speed insight, gtmetrix, dareboost.com, webpagetest etc...
Dareboost.com advises me to set headers in my .htaccess file like :
Content-Security-Policy
X-FRAME-OPTIONS
X-XSS-Protection
X-Content-Type-Options
I did :
Header set Content-Security-Policy "default-src 'self'; script-src 'self' www.googletagmanager.com ;"
Header always set X-FRAME-OPTIONS "DENY"
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Content-Type-Options "nosniff"
It seems to be a little bit inefficient : when I look into my waterfall timeline I see that all my assets (CSS, JS, fonts, IMG) use those directives but not my first GET request (on www.mydomain.com).
Why ? Due to that, Dareboost doesn't understand that I set properly my headers.

issue with htaccess not setting header

For some reason this new host isn't setting htaccess headers, I use 1and1. previously on 000webhost it worked fine.
Is there maybe a difference in apache versions?
This is my htaccess
Header set X-Frame-Options DENY
Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options "nosniff"
Header set Content-Security-Policy "script-src 'self' //ajax.googleapis.com"
The .htaccess file only works if it's behind the directory that I use for my website.
e.g.
htdocs/.htaccess
htdocs/folder1/index.php
will now correctly set HTTP headers on 1and1.

Give X-Content-Type-Options headers for Error Pages?

I'm using a security scanning tool to check for vulnerabilities of my web application.
One of the results was a low warning about X-Content-Type-Options header being missing.
After some digging around, I found this post on setting apache to emit nosniff headers and I put this code in to httpd.conf file;
<IfModule mod_headers.c>
Header unset ETag
Header set X-Frame-Options: deny
Header set X-XSS-Protection: "1; mode=block"
Header set X-Content-Type-Options: nosniff
Header set X-WebKit-CSP: "default-src 'self'"
Header set X-Permitted-Cross-Domain-Policies: "master-only"
</IfModule>
And it worked! But then, my security scanning tool discovered that the 404 Not Found page on my web server was still giving me this warning. I'm guessing that the 404 error page is set to ignore the above rule somehow..
Can someone explain to me how to change this code or suggest an alternative so that error pages are included?
Could someone also maybe explain what the code above is doing? I don't actually know what IfModule or mod_headers.c actually means. Maybe that's why I'm having trouble in the first place.

Forced HTTPS on osCommerce breaks sessions and logins

I have been trying to force HTTPS on my osCommerce site and it works. But when it switched to HTTPS, the session breaks and login doesn't work at all.
.htaccess code for forcing HTTP
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The way to force HTTPS on all your pages in an osCommerce site is to use what's already set up for you in the configuration instead of making .htaccess do the work.
Edit the includes/configure.php file and put the HTTPS version of your site in both of the following:
define('HTTP_SERVER', 'https://example.com');
define('HTTPS_SERVER', 'https://example.com');
Are you definitely using Apache?
Try this instead in your .htaccess...
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
I'm not sure if this is directly related to your problem, but I would suggest to make sure that all the forms, links and Location headers aimed within your site point to URLs using an https prefix, if those are absolute.
The rewrite rules that turn HTTP requests into HTTPS are only really useful for securing the "entry point": the first page that the user visits. It doesn't prevent data to be sent in clear if that data is sent to a URL that uses http://. Indeed, these rewrite rules only come into action after the browser has made the request in clear first (so all headers, including login cookies, unless secure cookies, and all the POSTed data, for example, will have been sent in clear).
You may be interested in these related questions:
How to redirect all HTTP requests to HTTPS
Tomcat session management - url rewrite and switching from http to https
There's a chance that the sessions break because there's a seemingly invisible plain HTTP connection in the process, which may cause some session-related data not to be transmitted correctly. If you're using Firefox, it can be useful to turn on the security.warn_leaving_secure option (via about:config URL) to track this sort of problems.
In /includes/configure.php modify the HTTP DOMAIN to have https:// That will make all sessions stay https only. Do the same in /admin/includes/configure.php
It builds upon the other answers for mod_rewrite which you should do.
I would also add the HTTP STRICT TRANSPORT SECURITY header and XSS protection, too.
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header unset X-Powered-By
Header unset Server
Header set X-Content-Type-Options "nosniff"
Header set X-XSS-Protection "1; mode=block"
<FilesMatch "\.(appcache|atom|bbaw|bmp|crx|css|cur|eot|f4[abpv]|flv|geojson|gif|htc|ico|jpe?g|js|json(ld)?|m4[av]|manifest|map|mp4|oex|og[agv]|opus|otf|pdf|png|rdf|rss|safariextz|svgz?|swf|topojson|tt[cf]|txt|vcard|vcf|vtt|webapp|web[mp]|woff2?|xloc|xml|xpi)$">
Header unset X-XSS-Protection
</FilesMatch>
</ifModule>

Categories