There are many different avenues our sites can be attacked, including (but not limited to) XSS, SQL injection, and CSRF. Fortunately, there are several best-practices we can follow to help reduce the blast radius of a vulnerability.
Observatory by Mozilla
This free tool scans your website and produces a score and grade for your site based on your use of SRI, HSTS, CSP, CORS, HPKP, and various other headers. It also gives you many recommendations on how to improve your rating and better secure your site.
SRI
Subresource Integrity (SRI) provides the ability to validate that the contents of a file haven’t been changed either in flight or at rest. This is especially important when pulling resources from a Content Delivery Network (CDN). If the CDN were to be compromised and source files were to be manipulated, your site would refuse to execute the potentially malicious code.
While this is especially important for CDNs, it’s generally best practice to use SRI for any files sourced from different hostnames. Why’s it not as important for files on your own host? There’s a good chance if someone could compromise the script files, they would be able to manipulate the hash too.
HSTS
HTTP Strict Transport Security (HSTS) is used to notify a browser that a site should ONLY be served using HTTPS. It is configured using the Strict-Transport-Security
response header. When enabled, even if a user tries to access the site without using HTTPS, the browser will automatically redirect without the need of a 301.
Warning
Only enable this if you are absolutely ready to serve your site only through HTTPS, as it is very difficult to clear the cached value from a browser.
CSP
Per Mozilla, “Content Security Policy (CSP) is another layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks.” With CSP, you are given the ability to whitelist the domains for which your site can communicate to either pull resources or data.
In order to fully implement CSP, you need to full understand the source of your resources, including images, stylesheets, scripts, fonts, and APIs. Once you authorize those sources, any other attempts are blocked. As an example, if your site has a XSS vulnerability and an attacker tries to execute a malicious payload on your page that is located on an unauthorized host, the attempt will be blocked.
Tip
When working on your CSP policy, any violations are displayed in the console output of the browser, usually with decent messages to help debug and update your policy.
CORS
Cross-Origin Resource Sharing (CORS) provides a set of policies that authorize a web application at one origin (hostname) to communicate with resources located on another hostname. It uses a set of headers to describe the allowed hosts, whether credentials (cookies, Authorization header, etc.) should be shared, allowed methods, and more.
When an application is utilizing a remote API, CORS is implemented by the serving API. As such, it should only authorize origins for which it is expecting to communicate.
Note
Only on very rare circumstances should you use Access-Control-Allow-Origin: *
, even though it is the #1 answer to most questions on StackOverflow. In addition to being too open, browsers will NOT send credentials when using a wildcard host.
Sample Configurations
Note that the CSP policy for each will need to be updated based on the specifics of your application.
Nginx Configuration
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;" always;
add_header Content-Security-Policy "default-src 'self';";
add_header X-Frame-Options "DENY";
add_header X-Xss-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "same-origin";
Apache Configuration
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set Content-Security-Policy "default-src 'self';"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
Header always set Referrer-Policy "same-origin"