Web Security Best Practices
The Checkbot Web Security Guide will teach you how to harden the security of your website to reduce attack vectors, protect user privacy and prevent data leaks. Website security is critical whether you handle payments or not as succesful attacks can still damage your brand and lead to your site visitors being exploited. Browser vendors know that security is important to users as well because browsers are starting to show prominent warnings when insecure pages are detected. Search engines are also trying to encourage website owners to secure their sites by treating HTTPS as a ranking signal. This guide will teach you how to secure your website by setting up HTTPS and securing password forms as well as how to harden your site against common exploits known as XSS, clickjacking and content sniffing attacks.
Beyond our own stuff, we’re also working to make the Internet safer more broadly. A big part of that is making sure that websites people access from Google are secure.
HTTPS
HTTPS prevents attackers from reading and modifying data sent between your site and browsers. HTTPS should be considered a minimum security requirement for all websites.
HTTPS (Hypertext Transfer Protocol Secure) is an internet communication protocol that protects the integrity and confidentiality of data between the user’s computer and the site. Users expect a secure and private online experience when using a website. We encourage you to adopt HTTPS in order to protect your users' connection to your website, regardless of the content on the site.
Use HTTPS
All pages should use HTTPS to prevent attacks and protect the privacy of your visitors. When a browser loads a URL via HTTP, the data is sent unprotected: attackers can read and modify all data being sent without anyone knowing. Attackers can steal passwords and personal information, inject malware and ads into pages, redirect visitors to malicious sites and more. HTTPS adds encryption to the data sent between your website and browsers to stop attackers from reading or tampering with communications. How you enable HTTPS is specific to the server or hosting service you’re using. Once set up, you should make sure all http://
page requests are redirected to https://
URLs.
Learn more
- Why HTTPS Mattersdevelopers.google.com
- Communicating the Dangers of Non-Secure HTTPblog.mozilla.org
- HTTPS as a ranking signalwebmasters.googleblog.com
- Introduction to HTTP/2developers.google.com
- HTTPSen.wikipedia.org
Avoid mixed content
HTTPS pages should not include HTTP resources to prevent “mixed content” browser security warnings. Page resources such as JavaScript, images, CSS and iframes that aren’t secured with HTTPS can be tampered with which can allow attackers to compromise otherwise secure HTTPS pages. For example, if attackers could modify a JavaScript file as it is being sent to a browser, they could inject code to steal passwords or redirect users to a malicious site. To prevent this, browsers block HTTP resources from loading on HTTPS pages and will show visitors what are called “mixed content” security warnings. To avoid these problems, make sure all page resources are included using https://
URLs.
Learn more
- Mixed content - MDN web docsdeveloper.mozilla.org
- What Is Mixed Content? - Web Fundamentalsdevelopers.google.com
- Mixed Content - W3C Candidate Recommendationwww.w3.org
Use secure password forms
Password fields in forms should be sent securely by using POST requests via HTTPS. When a password is submitted from a form on a page to your server, several steps must be taken to send the password securely. Firstly, a page with a password field should be served via HTTPS URLs to stop attackers modifying the page to send the password to wherever they want. Secondly, the form action
attribute that says where the form submission is sent should be set to an HTTPS URL (<form action="https://…
) so an attacker cannot observe the password in transit. Lastly, the form method
attribute that sets the request method to use should be set to the POST method (<form method="POST"…
). This prevents passwords being visible in browser histories, browser address bars, server logs and in the Referer
request header that is sent when navigating to other sites.
Learn more
- Sending form datadeveloper.mozilla.org
- Avoiding the Not Secure Warning in Chromedevelopers.google.com
HSTS
HTTP Strict Transport Security (HSTS) is a response header that improves security by instructing browsers to always use HTTPS instead of HTTP when visiting your site.
We recommend that HTTPS sites support HSTS. HSTS tells the browser to request HTTPS pages automatically, even if the user enters http in the browser location bar. It also tells Google to serve secure URLs in the search results. All this minimizes the risk of serving unsecured content to your users.
Use HSTS
Configure HSTS (HTTP Strict Transport Security) response headers to force browsers to always use HTTPS instead of HTTP on your site. When a browser visits your site and sees the Strict-Transport-Security
response header, it tells the browser to transform all future http://
URL requests to your site into https://
requests. The header can include these options: 1) max-age=<seconds>
says how many seconds the HSTS policy should be followed for 2) includeSubDomains
says to apply the policy to all subdomains. For example, Strict-Transport-Security: max-age=31536000; includeSubDomains
tells browsers to use HTTPS for the next year and for all subdomains. Warning: Start with a low max-age
until you’re confident you can manage the HTTPS configuration of your site. If there are problems loading pages over HTTPS later, users will be locked out of accessing your site until the problems are fixed.
Learn more
- Strict-Transport-Securitydeveloper.mozilla.org
- HTTP Strict Transport Security Cheat Sheetwww.owasp.org
- HTTP Strict Transport Securityen.wikipedia.org
- Secure your site with HTTPSsupport.google.com
Use HSTS preload
Add your site to the HSTS preload list so HSTS is active for your site in browsers by default. Your HSTS policy is only active in a browser after that browser sees a response from your site with an HSTS response header. This means new visitors will be vulnerable to exploits if they initially visit your site using an insecure HTTP URL. To eliminate this attack vector, add your site to the “HSTS preload list” so browsers will apply HSTS to your site by default even before the first visit. To add your site to the list, your Strict-Transport-Security
header for all responses on all subdomains should have a max-age
setting of at least 1 year (31,536,000 seconds) and both the includeSubDomains
and preload
options should be set. The header Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
meets these requirements. Take care to get the capitalisation right for each option such as for includeSubDomains
. Once this is done, you can submit your site to https://hstspreload.org/ for inclusion in the HSTS preload list. Warning: As with enabling HSTS, you must be confident you won’t need to disable HTTPS in the future. Removing yourself from the HSTS preload list may take some time and browsers might not keep their list up to date.
Learn more
- HSTS Preload List Submissionhstspreload.org
- HTTP Strict Transport Securitywww.chromium.org
- Preloading HSTSblog.mozilla.org
- HTTP Strict Transport Securityen.wikipedia.org
- HTTP Strict Transport Security Cheat Sheetwww.owasp.org
- HSTS Preload List Removalhstspreload.org
Content sniffing
A content sniffing attack typically involve tricking a browser into executing a script that is disguised as another file type. These attacks can be protected against with correctly configured response headers.
The X-Content-Type-Options response HTTP header is a marker used by the server to indicate the MIME types advertised in the Content-Type headers should not be changed and be followed … This header was introduced by Microsoft in IE 8 as a way for webmasters to block content sniffing that was happening and could transform non-executable MIME types into executable MIME types.
Use content sniffing protection
Turn off browser content sniffing to protect against content sniffing exploits. When processing a response, browsers sometimes ignore the MIME type in the Content-Type
header and guess the type based on the contents of the response. This is called content sniffing and is done to improve the user experience when Content-Type
headers are inaccurate or missing. However, this behaviour can be exploited. For example, if your site allows users to share images, an attacker might be able to upload a specially crafted image file that contains JavaScript code. A browser performing content sniffing might then be tricked into executing the malicious file. To reduce content sniffing attacks, set the X-Content-Type-Options
response header to nosniff
. This tells browsers to avoid guessing response types and to rely only on the Content-Type
header.
Learn more
- Reducing MIME type security risksmsdn.microsoft.com
- OWASP Secure Headers Projectwww.owasp.org
- Content sniffingen.wikipedia.org
- X-Content-Type-Optionsdeveloper.mozilla.org
Set MIME types
All responses should accurately specify their MIME type so that browsers don’t have to rely on content sniffing. When the X-Content-Type-Options: nosniff
response header is used to disable content sniffing, browsers rely on the Content-Type
header to determine the type of each response. To avoid issues, set the Content-Type
header of all responses to an accurate MIME type.
Learn more
- X-Content-Type-Optionsdeveloper.mozilla.org
- Properly Configuring Server MIME Typesdeveloper.mozilla.org
- Content sniffingen.wikipedia.org
- Types (Section 7.2.1)www.w3.org
- Mitigating MIME Confusion Attacks in Firefoxblog.mozilla.org
Response headers
Response headers should be configured to restrict iframe usage, prevent XSS exploits and to hide server configuration data.
The Internet is a dangerous place! With great regularity we hear about websites becoming unavailable due to denial of service attacks, or displaying modified (and often damaging) information on their home pages. In other high-profile cases millions of passwords, email addresses and credit card details have been leaked into the public domain, exposing website users to both personal embarrassment and financial risk.
Use clickjack protection
Protect against clickjacking attacks by restricting how your pages can be embedded within iframes. Clickjacking attacks involve an attacker displaying your pages within an iframe on a site they control. For example, an attacker could overlay a UI layer over an iframe to trick visitors into triggering actions on your page as well overlaying form fields to steal data. Clickjacking has been used to exploit users into sharing links on social networks, clicking ads and stealing passwords. Protect against these attacks using the X-Frame-Options
response header to restrict which hosts are allowed to embed your pages. The possible options are 1) DENY
to restricts all URLs 2) SAMEORIGIN
to allow only URLs from the same origin as your page 3) ALLOW-FROM
to allow from a specific origin. For example, X-Frame-Options: DENY
will block all iframe usage. You should use a setting that’s as restrictive as possible.
Learn more
- X-Frame-Optionsdeveloper.mozilla.org
- Clickjacking - OWASPwww.owasp.org
- Clickjacking - Wikipediaen.wikipedia.org
Use XSS protection
Protect against XSS attacks by enabling browser XSS safeguards. XSS attacks involve an attacker injecting code into a page that is being sent to users. Some browsers have built-in XSS protection that is enabled by adding X-XSS-Protection: 1; mode=block
to the response header of each page. This setting will stop the page being rendered if the browser detects an XSS attack. Note that this should only be considered as a last resort defence against XSS attacks. Your site should be thoroughly reviewed and built with XSS safeguards in mind to prevent injection attempts from ever reaching the browser.
Learn more
- OWASP Secure Headers Project :X-XSS-Protectionwww.owasp.org
- X-XSS-Protectiondeveloper.mozilla.org
Hide server version data
Avoid leaking information to attackers by removing response headers that say what software is running on your web server. Many web servers give the name and versions of software that were used to respond to a request within the response headers. For example, a server might respond with the header Server: Apache/2.2.20 (Win32) PHP/5.3.10
when a page is requested. This can give hints to attackers on how to search for vulnerabilities. Response headers that can contain software version information include the Server
, Powered-by
, ASPNET
and ASPNETMVC
headers. You should configure your server to suppress headers like these. Note that a determined attacker can uncover details about your server configuration in other ways and can find exploits without knowing this information anyway. However, making life a little harder for an attacker by keeping this information hidden doesn’t usually require a lot of effort.
Learn more
- HTTP/1.1: Security Considerationswww.w3.org
- Fingerprint Web Application Frameworkowasp.org