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 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.
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
Avoid mixed content
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.
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.
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.
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
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.
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
X-Content-Type-Options response header to
nosniff. This tells browsers to avoid guessing response types and to rely only on the
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.
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.
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.
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
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.