When you view a website page or make a request against an application api, HTTP headers allow the client and the server to pass additional information with the request, page content, or the response.
Typical HTTP headers sent are Host, Accept-Language, etc, while typical HTTP headers received are Content-Type, Server, Content-Security-Policy, etc
HTTP Security Headers are a subset of HTTP headers which can help increase the security of your web application and website. In many cases they are easy to implement and only require a slight web server configuration or application change.
For the additional security to be realized, the browser must support the HTTP Security Headers, which most modern browsers do. Can I Use and Mozilla are both good sites to see what features browsers support.
HTTP Security Headers to implement:
Indicates whether the response can be shared with requesting code from the given origin.
- allow requesting code from any origin to access the resource
- one domain
To allow Cross-origin resource sharing
Stops pages from loading when they detect reflected cross-site scripting (XSS) attacks
Non standard, deprecated by Content-Security-Policy, but maybe useful for older browsers
- disables XSS filtering; never use!
- enable XSS filtering, sanitize, usually default in browsers
- enable, block rendering of page
To silently filter XSS and not server as a simple test bed for XSS attacks
Prevents browser from MIME-type sniffing a response away from the declared ie trust the web server.
- prevents browser from MIME-type sniffing a response away from the declared content-type.
Good additional information on attacks mitigated (MIME Confusion Attack, Unauthorized Hotlinking) stackoverflow
Indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe> or <object>
Non standard, deprecated by Content-Security-Policy, but useful for older browsers
- no framessameorigin
- allow frame from origin
- one domain
If you have no iframes, then deny
If you want your content iframed in by multiple websites, then do not send this header
Strict-Transport-Security Key CDN
Restricts web browsers to access web servers solely over HTTPS; header only has effect when requested over HTTPS
- defines the time in seconds for which the web server should only deliver through HTTPS.
- optional, apply to subdomains
- optional, the site owner can submit their website to the preload list which is a list of sites hardcoded into Chrome as being HTTPS only; Additional details serverfault
Given that browser will cache this header for your site, to test implementation, bump max-age up incrementally over time eg 300s=5min, 86400s=1day, 63072000s=2years required for preload
Strict-Transport-Security: max-age=300; includeSubDomains
Determine what information about the origin the user came from is sent to the destination site
- not referrer sent
- do not send the referrer header when navigating from HTTPS to HTTP
- only set the referrer header on requests to the same origin
- set the referrer header to the origin, stripping any path information
- same as origin, but do not send HTTPS request on HTTP
- send the full URL to requests to the same origin but only send the origin when requests are cross-origin
- same as origin-when-cross-origin, but do not send when navigating from HTTPS to HTTP
- always send the referrer; do not use!
To prevent any HTTPS info (referrer url) being sent over HTTP
Content-Security-Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. It replaces several of the above X- headers, but support depends on browser and browser versions, so you should still the above headers.
CSP makes it possible for server administrators to reduce or eliminate the vectors by which XSS can occur by specifying the domains that the browser should consider to be valid sources of executable scripts. A CSP compatible browser will then only execute scripts loaded in source files received from those white listed domains, ignoring all other script.
Note: While searching for CSP policy values, remember CSP version 2 is currently defined, and CSP version 3 is in the works. Across the versions, policy values have been added and removed, thus support depends on browsers and browser's versions.
An example Content-Security-Policy:
Content-Security-Policy "base-uri 'self'; object-src 'none'"
Possible policy keys:
- default policy for all resources type that are not defined (fallback)
- which scripts the protected resource can execute
- from where the protected resource can load plugins (flash, java, etc)
- which styles (CSS) the user applies to the protected resource
- from where the protected resource can load images
- from where the protected resource can load video and audio
- from where the protected resource can embed frames
- valid parents that may embed a page using <frame>, <iframe>, <object>, <embed>, or <applet>
- from where the protected resource can load fonts
- which URIs the protected resource can load using script interfaces
- which URIs can be used as the action of HTML form elements
- script execution by requiring the presence of the specified nonce (cryptographic number used once) on script elements
- Specifies a URI to which the user agent sends reports about policy violation
Deprecated keys (you may run across in searches, but don't use)
- instructs a user agent to activate or deactivate any heuristics used to filter or block reflected cross-site scripting attacks, equivalent to the effects of the non-standard X-XSS-Protection header
- determine what information about the origin the user came from is sent to the destination site
Possible values: blobfolio
– wildcard, i.e. anything goes
– load no resources
– same-origin is OK
– data-URI, such as a base64-encoded image
– any resource over HTTPS
domain.com, *.domain.com, https://domain.com
– domain.com (any protocol), all subdomains of domain.com (any protocol), domain.com (SSL) respectively
For scripts and stylesheets specifically, there are a few additional magic values:
– allow scripts to run eval().
– allow all inline scripts and/or styles.
– allow inline or linked assets with the nonce stackoverflow
For more options and information refer to Mozilla
A minimal CSP which should not break stuff is:
Content-Security-Policy base-uri 'self'; object-src 'none'
This ensures your base uri is not change via html injection, and that your site does not allow flash or applets
Adding CSP does require you know your application or websites resources, which may be non trivial.
Adding CSP can break you application or website, by preventing resources from loading.
For example, object-src 'none' disable embedded pdfs in Chrome.
Testing, as always, is important. To facilitate testing, consider adding one policy at a time.
Example Content-Security-Policy of a few domains:
header not set
header not set
header not set
script-src 'unsafe-inline' 'unsafe-eval' https: http:;object-src 'none';base-uri 'self';report-uri /cspreport
default-src 'self'; script-src 'self' cdnjs.cloudflare.com; img-src 'self'; style-src 'self' 'unsafe-inline' fonts.googleapis.com cdnjs.cloudflare.com; font-src 'self' fonts.gstatic.com cdnjs.cloudflare.com; form-action 'self'; report-uri https://scotthelme.report-uri.com/r/default/csp/enforce
default-src 'self' data: 'unsafe-inline' 'unsafe-eval' https: blob:; media-src 'self' https: blob:; worker-src 'self' https: blob:; block-all-mixed-content; connect-src 'self' data: 'unsafe-inline' 'unsafe-eval' https: blob: https://*.trouter.io:443 https://*.trouter.skype.com:443 wss://*.trouter.io:443 wss://*.trouter.skype.com:443;
Given that CSP is non trivial and policies can break the app, consider adding
or use the free service report-uri
and view the results in developer tools and/or log the results
"violated-directive": "style-src cdn.example.com",
"original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports",
To test your changes, load you application or website in a browser and view the developer tools network tab and review the headers.
For nicer graphical view, with a warm fuzzy grade system, which others might use, visit
Examples of how to add the HTTP Security Headers
header("Strict-Transport-Security: max-age=31536000s; includeSubDomains");
header("Content-Security-Policy: base-uri 'self'; object-src 'none'");
$response->headers->set('Strict-Transport-Security', 'max-age=31536000s; includeSubDomains');
$response->headers->set('Content-Security-Policy', "base-uri 'self'; object-src 'none'");
Header set X-Content-Type-Options nosniff
Header set X-XSS-Protection 1
Header set X-Frame-Options sameorigin
Header set Strict-Transport-Security max-age=31536000s; includeSubDomains
Header set Referrer-Policy no-referrer-when-downgrade
Header set Access-Control-Allow-Origin *
Header set Content-Security-Policy "base-uri 'self'; object-src 'none'"
add_header X-Content-Type-Options nosniff
add_header X-XSS-Protection 1
add_header X-Frame-Options sameorigin
add_header Strict-Transport-Security max-age=31536000s; includeSubDomains
add_header Referrer-Policy no-referrer-when-downgrade
add_header Access-Control-Allow-Origin *
add_header Content-Security-Policy "base-uri 'self'; object-src 'none'"
-End of Document-
Thanks for reading