First you might want to yeet the Server
& X-Powered-By
headers (the latter being unofficial), preferably through the server configs, or check no_srv.go
.
Security through obscurity ain’t all that chief, but it's just a good complementary security measure.
To test that you've removed this entirely you can use curl:
➜ ~ curl -IsL https://https://www.google.com/ | grep -i server
server: gws
server: gws
Google doesn't hide this info, but guess who does ?
The feds
➜ ~ curl -IsL https://cia.gov/ | grep -i server
➜ ~
Don't use unsafe-inline
directive.
Use a nonce
Content-Security-Policy: script-src 'nonce-r4nD0mV41u3';
If you're using NextJS
Here's how you set the scripts
import Script from 'next/script'
export default function Page() {
const nonce = "" // get it depending on the nature of the app
return (
<Script
src="https://www.googletagmanager.com/gtag/js"
strategy="afterInteractive"
nonce={nonce}
/>
)
}
NextJS v13+
has a server implementation for homogeneous apps view ref
-
base-uri
Restrictbase-uri
to block the injection of tags. This prevents attackers from changing the locations of scripts loaded from relative URLs. -
img-src
you might add trusted sources
img-src 'self' blob: data: https://i.imgur.com https://fontawesome.com/;
font-src
you might add some trusted sources, or just download them already why bother, anyways here's an example
font-src https://fonts.gstatic.com
Here's a good ref
use Content-Security-Policy-Report-Only
. If it's all good, push the CSP changes to prod.
View the original Microsoft ref over why they had it promoted.
w.Header().Set("X-Content-Type-Options", "nosniff")
This whole header has been obsoleted in favor of frame-ancestors
directive of the CSP
But some older browsers don't support CSP so you might as well use this
w.Header().Set("X-Frame-Options", "DENY")
Note
Content-Security-Policy: frame-ancestors 'none';
==>X-Frame-Options: 'DENY;
Content-Security-Policy: frame-ancestors 'self';
==>X-Frame-Options: 'SAMEORIGIN;
Also
ALLOW-FROM
Directive is DEPRECATED for this header.
Do not use this so set it to 0
.
w.Header().Set("X-XSS-Protection", "0")
Only for ancient browsers that don't support CSP.
But if you're somehow trying to support legacy browsers set it to
X-XSS-Protection: 1; mode=block
Max age of two years is recommended.
Extreme care is needed when setting the includeSubDomains
flag, as it could disable sites on subdomains that don’t yet have HTTPS enabled.
Secure cookies G.
If you set preload
attribute after submission to HSTS preload list
then switch back to HTTP, you've fumbled the bag big time, ref.
w.Header().Set("Strict-Transport-Security", "max-age=63072000; includeSubDomains, preload")
View ref
w.Header().Set("Referrer-Policy", "no-referrer, strict-origin-when-cross-origin")
Popups and windows
w.Header().Set("Cross-Origin-Opener-Policy", "same-origin")
document fetching
w.Header().Set("Cross-Origin-Resource-Policy", "same-origin")
need to check in with the homie above first
w.Header().Set("Cross-Origin-Embedder-Policy", "require-corp")
For a good balance
w.Header().Set("Cache-Control", "no-cache")
This has been deprecated in favor for Permissions-policy
// w.Header().Set("Feature-Policy", "geolocation 'none'; microphone 'none'; camera 'none'")
You can pick and choose which ones to block or activate
View ref
w.Header().Set("Permissions-Policy", "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), clipboard-read=(), clipboard-write=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), gamepad=(), geolocation=(self 'https://trusted.com'), gyroscope=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), speaker=(), speaker-selection=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=()")
Out in the wild you might find occurrences where
HPKP is still being used, well it got deprecated in 2018. It was to be replaced with the CT framework w/ Expect-CT header, but as of today this header is obsolete.
View ref