Implement HTTP Strict Transport Security (HSTS)

HTTP Strict Transport Security (HSTS) prevents attacks based on circumventing SSL protection and is one of the components we test and monitor as part of every technical website audit.

What is HSTS?

HTTP Strict Transport Security tells a web browser that it should never load your site using HTTP and should automatically convert all requests to HTTPS instead. HSTS consists of the Strict-Transport-Security HTTP header sent by the server with the resource. It tells the browser that changing the protocol from HTTP to HTTPS in a URL will function correctly, is more secure and asks the browser to do it for every future request, until a specified expiry time.

How does HSTS work?

If your website accepts a connection through HTTP and redirects to HTTPS, visitors might initially communicate with the non-encrypted version of your site before being redirected. If, for example, the visitor types http://www.yourwebsite.com/ or even just yourwebsite.com this creates an opportunity for a man-in-the-middle attack. An exploited redirect can divert visitors to a malicious site instead of the secure version of your website.

Example scenario

You may be thinking "I already 301 redirect from HTTP to HTTPS. Isn't that safe enough?" Not necessarily. Let's say, for example, that you're in a café and have connected your laptop to a free WiFi access point so that you can check your bank account balance and pay a few bills. Unbeknown to you, the access point is a hacker's laptop, and they are intercepting your initial HTTP request and redirecting you to a clone of your bank's website instead of the real thing. When you attempt to log in, your private data is exposed to the hacker and captured.

HTTP Strict Transport Security solves this problem as long as you have visited your bank's website once using HTTPS and provided they use Strict Transport Security. If so, your web browser will know to use HTTPS automatically. It will prevent any potential man-in-the-middle attack that could have exploited an initial HTTP request.

How the web browser manages HSTS

It's important to understand that HSTS only works on a browser after your website is accessed using HTTPS. The first time your site is accessed using HTTPS, it returns the Strict-Transport-Security header. The web browser records this information so that all future attempts to load the site will automatically use HTTPS instead of HTTP. It remains so until the expiry time specified in the HSTS header elapses. After that time, the next attempt to load your website using HTTP will proceed normally instead of using HTTPS. If Strict Transport Security is still in place, the web browser will receive the header with a new expiry time, and all future requests will once again be via HTTPS only until the new expiry has been reached.

Should I implement HSTS?

In general, we'd recommend always implementing HSTS on your website if you're an e-commerce store or if your site has a secure login area for customers. It's essential to consider the use of HSTS in combination with a TLS/SSL certificate to protect cardholder data, logins and private information. If you're running a small blog or personal website with no personal data stored, then HSTS isn't essential. However, Google uses many factors to decide where a site should rank in search results. Among these are security and load time — HSTS is beneficial for both. Given the relative simplicity of enabling HSTS on your website, we recommend that website owners implement it as part of their standard website configuration.

What you need to know about HTTP Strict Transport Security (HSTS)

The Strict-Transport-Security header contains three possible directives, two of which are optional.

max-age=<expire-time>
The time, in seconds, that the browser should remember that a site is only to be accessed using HTTPS.
includeSubDomains | Optional
If this optional parameter is specified, this rule applies to all of the site's subdomains as well.
preload | Optional
Not officially part of the specification. See Preloading Strict Transport Security for details.

Preloading Strict Transport Security

The preload directive can potentially cause a lot of problems, so it's essential to understand what this directive does before adding Strict Transport Security headers on your website. It's great to support HSTS preloading as a best practice. However, site operators who enable HSTS should know about the long-term consequences of preloading before they enable it for a given domain.

HSTS preloading is a function built into web browsers based on a global list of HSTS-enabled hosts. The file is compiled by The Chromium Projects and embedded into the Google Chrome web browser. Other browsers maintain records based on the Chrome list, including Firefox, Safari, Opera, Edge and Internet Explorer.

If a domain is on the HSTS Preload List, the web browser does not depend on the HSTS headers to enforce the Strict Transport Security policy. Instead, the browser is immediately aware of the requirement to use HTTPS before the connection even takes place. HTTPS gets enforced regardless of any headers that might be served by the website.

Benefits of preloading HSTS

Remember the earlier example about connecting to your bank using a WiFi hotspot at a café? You might recall that HSTS is only valid until the expiry time in the HSTS header elapses. Once it has passed, an HTTP connection to a website is possible before being redirected to HTTPS and obtaining the HSTS header with a new expiry time. See the problem? It provides a window of opportunity for your traffic to be intercepted during the HTTP connection and redirected to a malicious site. The HSTS preload list addresses this by enforcing only HTTPS connections domains in the list, without the need to first check for HSTS headers.

Cautions about preloading HSTS

Undoing inclusion in the HSTS preload list is not simple. Domains are removable, but records are embedded into web browsers and can take months for the change to reach users. We recommend that you do not include the preload directive by default without carefully considering the implications of this. Removal is slow and could render non-SSL subdomains inaccessible to users until the removal process is complete. Don't request inclusion unless you're sure that you can support HTTPS for your entire site and all its subdomains in the long term.

Removing a domain from the HSTS preload list

If a preloaded site sends a valid HSTS header without the preload directive, it is requesting removal from the preload list. Once you've removed the preload directive, we'd also suggest using the removal form if you have satisfied the following requirements:

  1. Be preloaded or pending preload through hstspreload.org.
  2. Serve HTTPS with a valid certificate.
  3. Send a valid HSTS header. The header must not contain the preload directive.

Note that a preload list domain removal may take 6-12 weeks to reach most Chrome users, and may take longer for other browsers.

HSTS requirements

Your website must:

  1. Serve a valid SSL certificate.
  2. Redirect from HTTP to HTTPS on the same host, if you are listening on port 80.
  3. Serve all subdomains over HTTPS. In particular, you must support HTTPS for the www subdomain if a DNS record for that exists.

Note that the Strict Transport Security specification is for HTTPS connections only. Do not specify HSTS headers on HTTP connections — the HSTS headers will get picked up when the 301 redirect instructs the web browser to connect using HTTPS.

If you are considering adding your domain to the HSTS preload list then you must serve an HSTS header on the base domain for HTTPS requests:

  1. The max-age must be at least 31536000 seconds (1 year).
  2. The includeSubDomains directive must be specified.
  3. The preload directive must be specified.
  4. If you are serving an additional redirect from your HTTPS site, that redirect must still have the HSTS header (rather than the page it redirects to).

Deployment recommendations

  1. Due to the includeSubDomains directive, we recommend that your primary domain be a non-www domain. It ensures that all subdomains, including the www domain, are covered by the HSTS policy. HSTS implementation becomes more difficult if you redirect from a non-www domain to a www domain.
  2. Test all subdomains on your website and ensure they work properly over HTTPS. This would include testing to ensure that both HTTP and HTTPS versions of your root URL, as well as www and non-www versions of each, all correctly redirect to the HTTPS version of your default URL.
  3. Add the Strict-Transport-Security header to all HTTPS responses and ramp up the max-age in stages, using the following header values:
    • 5 minutes: max-age=300; includeSubDomains
    • 1 week: max-age=604800; includeSubDomains
    • 1 month: max-age=2592000; includeSubDomains
  4. During each stage above, test for broken pages and monitor your site metrics (traffic, revenue). Having a technical website audit running against your site is a simple way to identify any problems without having to test every page on your site manually.
  5. Once you are confident there are no issues, increase max-age to 2 years (this is the maximum time that can be specified) and submit your site to the preload list: max-age=63072000; includeSubDomains; preload

How to implement HTTP Strict Transport Security (HSTS)

As per the Strict Transport Security specification, do not specify HSTS headers on HTTP connections — the HSTS headers will get picked up when the 301 redirect instructs the web browser to connect using HTTPS.

Also, ensure that your 301 redirects perform the HTTP to HTTPS redirection before the www to non-www redirection.

Example HSTS implementation for the Apache HTTP Server

Some suggest specifying env=HTTPS at the end of the header to ensure HSTS is only on HTTPS connections, like this:

Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" env=HTTPS

However, we've found this method to be unreliable in many instances. We recommend wrapping the header in <if "%{HTTPS} == 'on'">...</if> instead. Add the following to the .htaccess file, usually found in the root folder of your website:

# BEGIN: Enable HSTS for HTTPS connections
<if "%{HTTPS} == 'on'">
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
</if>
# END: Enable HSTS for HTTPS connections

Connect to Amazon Lightsail using SFTP

If you're running an Amazon Lightsail instance, chances are that you'll want to edit files directly on the server. To do that, you need to connect to your Lightsail instance using SFTP (SSH File Transfer Protocol or Secure File Transfer Protocol), which is a more secure option than traditional FTP (File Transfer Protocol). It allows server-to-server transfers between your and your Lightsail instance in a safe way, allowing you to upload, download or edit files securely on your Lightsail server.

Choosing an SFTP Client

There's many different clients available and most support SFTP. Two of our favourites are Cyberduck (Mac OS and Windows) and Nova (Mac OS).

Cyberduck is available for free, so it tends to be a popular option if all you're looking for is an SFTP client. It supports other protocols and cloud storage systems as well, such as FTP, WebDAV, Amazon S3, OpenStack Swift, Backblaze B2, Microsoft Azure, Files.com, OneDrive, Google Drive, and DropBox. However, it's not a text editor, so you'll need to edit your files in another application.

Nova is a text editor with built-in support for many programming languages - 27 to be exact, plus plain text.  The huge time-saver with this software is that you can edit files all within the Nova interface, without needing to switch to another application. It includes support for SSH/SFTP, FTP, Amazon S3, WebDAV HTTPS, Amazon S3 with IAM Role, Backblaze B2, Box, DreamObjects, DropBox, FTP with Implicit SSL, FTP with TLS/SSL, Google Drive, Microsoft Azure, Microsoft OneDrive, Microsoft OneDrive for Business, OpenStack Swift, Rackpsace Cloud Files and WebDAV. Do you really need anything more?

If you're looking for an excellent way to write code and be connected to your server environment at the same time, then Nova is an amazing choice, albeit not free. If you're just looking for a free SFTP client, then Cyberduck is hard to beat and easy on the wallet.

Connecting to Lightsail using SFTP

We're going to tell you how to connect to Lightsail using Nova and Cyberduck since they are both popular options, plus we'll be using the Terminal application in a Mac OS environment. The process is essentially the same for both, with just a few subtle differences between the Nova and Cyberduck interfaces.

Download the Lightsail private key

To connect to your server using SFTP, you'll first need to obtain the private key .pem file for your Lightsail instance. It is used in the SFTP client instead of a password and is a way to protect your connections from stolen passwords.

  1. Go to the Lightsail Account Page.
  2. Select the SSH keys tab.
  3. Click Download to obtain the .pem file.

Elevate permissions on the Lightsail private key

For the private key to work correctly, we need to elevate permissions on the file.

  1. Start the Terminal application on Mac OS from Finder under Applications > Utilities > Terminal.
  2. Type chmod 400  ensuring you include a space at the end of this command as shown - it's important!
  3. Drag and drop the .pem file you downloaded in the previous section onto the Terminal window.
  4. Hit return to run the command against the file.
  5. Type exit and hit return, then Cmd+Q to quit the Terminal application.

Move the private key to your .ssh folder

The .ssh folder in Mac OS is a designated location for storing private keys. You don't have to use this location, but most SFTP clients will automatically look here for a key when you first create a new connection. If you don't want to use the .ssh folder, you can add your private key .pem file from any location directly into the SFTP client. See more in the following section.

  1. From the Finder application, press Cmd+Shift+G on your keyboard.
  2. Enter ~/.ssh in the Go to folder field.
  3. Hit return or click Go.
  4. Drag your .pem file from its current location into the .ssh folder.

Connect to the Lightsail server using an SFTP client

Use Cyberduck to connect to Lightsail

  1. On the toolbar, click Open Connection.
  2. Select SFTP (SSH File Transfer Protocol) from the dropdown box.
  3. In the Server field, enter the Public IP address of your Lightsail instance.
  4. In Username enter bitnami - this is the default username for Lightsail installations and cannot be changed.
  5. From the SSH Private Key dropdown, select the .pem file you added to the .ssh folder earlier. If you've opted not to store your .pem file in the .ssh folder, select Choose then locate and select your .pem file and click the Choose button.
  6. Click the Connect button.
  7. Your SFTP connection is now open. To save this connection for future use, click Action on the toolbar, then New Bookmark.
  8. A new window will appear with the credentials you entered earlier.
  9. Set the Nickname field to a friendly name, such as your website domain name.
  10. Close the window.
  11. Double-click the new connection added to the Cyberduck interface.
  12. Your SFTP connection is now open, and you can add, remove and edit files.

Use Nova to connect to Lightsail

  1. Press Cmd+, on your keyboard to access Preferences.
  2. Click Servers.
  3. Click the + icon at the bottom left of the window.
  4. Set the Untitled Server field to a friendly name, such as your domain name.
  5. Ensure the selected Protocol is SSH/SFTP.
  6. In Address enter the Public IP of your Lightsail instance.
  7. In Username enter bitnami - this is the default username for Lightsail installations and cannot be changed.
  8. In the Password field, click the image of the key then Manage Keys.
  9. Click the + icon at the bottom left of the window then Import Keys.
  10. Find and select the .pem file you downloaded earlier. If you can't see the .pem file, you may not be in the .ssh folder. If so, navigate to Macintosh HD > Users > [username] > .ssh and you should see your private key .pem file. If you've opted not to store your .pem file in the .ssh folder, you can select the file from any other location.
  11. Click Import.
  12. Go back to the previous window by clicking the < icon in the toolbar.
  13. In the Password field, click the image of the key once again, then under Authenticate with Key select the .pem file you just imported.
  14. Set Remote Path to your preferred default location. For Bitnami WordPress installations, this will probably be the WordPress root folder at /opt/bitnami/apps/wordpress/htdocs.
  15. Set Remote URL to your website URL.
  16. Click Save.
  17. For quick access, you can now drag the server connection you created onto the Nova desktop.
  18. Close the Servers window.
  19. Double-click the new connection added to the Nova desktop.
  20. Your SFTP connection is now open, and you can add, remove and edit files.

Launch a WordPress website on Amazon Lightsail

Amazon Lightsail is an easy-to-use cloud platform that offers you everything needed to build an application or website, on a cost-effective, monthly plan. Lightsail is ideal for simpler workloads, quick deployments, and getting started on Amazon Web Services. It will help you start small, and then scale as you grow.

Lightsail derives its computing power from Amazon EC2, repackaged in a simple, intuitive interface that makes it easy to set up a virtual server, even for a complete novice. Lightsail comes with numerous pre-configured options, so you don't need to worry about complicated server settings. You can be up and running in minutes and start focusing on building your website right away.

Although Lightsail offers both Linux and Windows servers, we're going to discuss setting up a Linux virtual private server. Linux/Unix is the most popular option for running a website, and you don't need to know anything about Linux. Unless you have a compelling reason to do so, such as running applications built on Microsoft’s .NET Framework, you are likely to be well-served with a Linux host.

For this article, we're going to assume that you already have an AWS account. If you don't have one, you can create an AWS account for free. Amazon also publishes information on how to create and activate a new AWS account.

Set up a WordPress instance

Create instance

  1. Visit lightsail.aws.amazon.com.
  2. Click Create instance.
  3. The Instance location is where your server will be. It should default to the area nearest you, which is usually the most appropriate choice. If you want to host your server in a different location, choose Change AWS Region and Availability Zone to select from other places worldwide. We recommend choosing the server location nearest you since this is probably where most of your web traffic will be. If you need increased performance elsewhere in the world, you can set up load balancers in different geographic locations later on, but note that each load balancer incurs additional costs.
  4. Under Pick your instance image > Select a platform then choose Linux/Unix.
  5. Under Pick your instance image > Select a blueprint ensure the App+OS option is active and choose WordPress.
  6. Regardless of your backup plans, it's a great idea to activate the Enable automatic snapshots option. With automatic snapshots, Lightsail will automatically take a daily backup for you at the time you specify. Lightsail keeps the seven most recent snapshots, so you can rest easy knowing that you’ll have a full weeks' worth of backup history. Use snapshots to restore your instance to a previous state or to create multiple new ones that are replicas of the original. Enabling the feature is free, but you pay for the storage of your snapshots on Lightsail at very reasonable rates. Lightsail also optimises your snapshot storage so that for each consecutive backup, you’re charged only for the data that's changed from the previous one.
  7. If you choose Enable automatic snapshots, select a time and timezone for the daily backup. We suggest you choose a time when you think traffic will be at its lowest, such as 03:00.
  8. Select an Instance plan. Amazon Lightsail offers a variety of plans to meet different needs. For a simple WordPress site, the smallest should be just fine. If you're running a WordPress site with many plugins or complicated themes, then a 1GB or 2GB plan may be preferable, so you can increase the WordPress memory limit for optimal performance. If you're not sure, select the most basic one - you can create a replica instance on a larger plan at any time, then remove the smaller one. Note that you can not restore a snapshot from a larger plan to a smaller one because the disk image is already too large. If you want to go back to a cheaper option, you'll need to restore your WordPress site manually to the smaller instance - plugins such as All-in-One WP Migration are excellent for this.
  9. In Identify your instance enter a name using only letters, numbers, hyphens and underscores. We suggest using a name like MyBusinessName-512MB-Sydney-ZoneA-001 which is:
    • Your website/business name
    • Instance plan memory size
    • Location and Zone
    • A sequential number (this is useful for clearly differentiating between multiple instances)
  10. Click Create instance.

It will take a short while for your instance to build. When it's ready, it will show the status of Running.

Create a static IP

Your instance will have a Private IP used to communicate securely with other Amazon resources over a private network. It is also assigned a Public IP which makes your website accessible over the Internet. However, the Public IP will change every time you restart the instance. To ensure that your site is always available at the same IP address, you need to allocate a Static IP address. A Static IP is free of charge as long as it is attached to an instance.

  1. Go to the Networking tab.
  2. Choose Create Static IP.
  3. Verify that the Static IP location matches the AWS Region and Availability Zone you selected when creating your instance, or choose Change AWS Region and Availability Zone to correct it.
  4. In Attach to an instance, select the instance name you created earlier.
  5. Give the Static IP a suitable name. We suggest using a name like BusinessName-StaticIP-1, which is:
    1. Your website/business name
    2. The words "StaticIP" to identify what this object is
    3. A sequential number (an instance can have up to 5 IP addresses)
  6. Click Create.
  7. Note the Public IP address for later reference in steps below.
  8. Click Home.

Obtain password

  1. Go to the Instances tab.
  2. Select your instance.
  3. Click Connect using SSH to connect to the server using Lightsail's built-in SSH web interface.
  4. Type cat bitnami_application_password and hit return.
  5. Copy the password shown.
  6. Type exit and hit return to close the SSH connection.
  7. Close the SSH window.

Connect to WordPress

  1. In a web browser, visit your new WordPress website at your Public IP address with /wp-admin added to the end.  For example, if your Public IP address is 123.456.789.0 then you would visit 123.456.789.0/wp-admin in your web browser.
  2. Log in as username user with the bitnami_application_password obtained in the previous section.

You're now ready to start configuring and building your new WordPress site.


Remove Apple Pay and Google Pay buttons from WooCommerce

When using the Stripe payment gateway for WooCommerce, you may want to remove the Payment Request buttons (such as Apple Pay and Google Pay) from single product pages.

This method ensures the Payment Request buttons are still available during the checkout process — it disables them on single product pages only.

To remove the Payment Request buttons, add this line of code to the functions.php file located in the root folder of your WordPress theme:

add_filter( 'wc_stripe_hide_payment_request_on_product_page', '__return_true' );

To avoid overwriting the file during upgrades, ensure you are using a child theme so that your edits persist.


Calculate age from MySQL date of birth

Calculating age in years from a person's date of birth is a common requirement when working with database applications. MySQL provides several different functions to perform operations on date data types and calculating a person's age is achievable using a simple MySQL query.

Although there are several ways to do this, we like to keep SQL queries as efficient and straightforward as possible. Here's an elegant MySQL Select statement using a combination of just two of the date functions.

SELECT TIMESTAMPDIFF(YEAR, '1973-01-01', CURDATE())

Explanation

The syntax for TIMESTAMPDIFF() is:

TIMESTAMPDIFF(unit, begin_date, end_date)

In the unit argument, we're using YEAR in this example because we want our result expressed in years. You could modify this argument to any of the following values to return different time units:

  • YEAR
  • QUARTER
  • MONTH
  • WEEK
  • DAY
  • HOUR
  • MINUTE
  • SECOND
  • MICROSECOND

The begin_date argument contains the date of birth. It can either be specified as a date string as shown in the example, but in practice, you'll probably be using a column name here (without the single quotes) that references date of birth in a table. This value forms the start of our date range that we want to calculate.

The end_date argument represents the end of our date range. Since we want to know the person's current age, the end of the date range should be today. The CURDATE() function is a simple way to return the current date and requires no parameters between the parentheses.