Optimisation and utility

Optimisation and utility

This section contains directives which are of utilitarian value and bound to save you some time:

Force index.php parsing before index.html

Some servers attempt to serve index.html before index.php. This has the implication that trying to access your site's root, e.g. http://www.example.com, will attempt to serve an index.html first. If this file doesn't exist, it will try to serve index.php. However, all of our Joomla! sites only have the index.php, so this checking slows them down unnecessarily on each page request. This rule works around this problem. Do note that some servers do not allow this and will result in a blank page or Internal Server Error page.

Set a long expiration time for static media

Enabling this option will cause all files and pages served from the site to have an expiration time between 1 week or 1 month (depending from the media), which means that the browser will not try to load them over the network until that time has passed. This is a very desirable feature, as it speeds up your site.

Automatically compress static resources

Enabling this option instructs the server to send plain text, HTML, XML, CSS, XHTML, RSS and Javascript pages and files to the browser after compressing them with GZip. This significantly reduces the amount of data transferred and speeds up the site. On the downside some very old browsers, like Internet Explorer 6, might have trouble loading the site. We do add a directive which instructs NginX to not compress the output when accessed by IE6 but all bets are off with a browser that hasn't been updated for over a decade...

Redirect index.php to the site's root

Normally, accessing your site as http://www.example.com and http://www.example.com/index.php will result in the same page being loaded. Except for the cosmetic issue of this behaviour it may also be bad for search engine optimization as search engines understand this as two different pages with the same content ("duplicate content"). Enabling this option will redirect requests to index.php, without additional parameter, to your site's root overriding this issue.

Redirect www and non-www adresses

Most web servers are designed to treat www and non-www URLs in the same way. For example, if your site is http://www.example.com then most servers will also display it if called as http://example.com. This has many adverse effects. For starters, if a user accesses the www site, logs in and then visits the non-www site he's no longer logged in, causing a functional issue with your site's users. Moreover, the duplicate content rules also apply in this case. That's why we suggest that you enable on of the redirection settings of this option. The different settings are:

  • Do not redirect. It does no redirection (turns this feature off)

  • Redirect non-www to www. Requests to the non-www site will be redirected to the www site, e.g. http://example.com will be redirected to http://www.example.com.

  • Redirect www to non-www. Requests to the www site will be redirected to the non-www site, e.g. http://www.example.com will be redirected to http://example.com.

[Important]Important

If your configuration.php file has a non-empty $live_site this option becomes disabled and will be reset to Do not redirect upon saving. This is intentional. If you have $live_site = 'https://www.example.com'; and set this option to Redirect www to non-www you would end with an infinite redirection loop: the .htaccess file would redirect your site to example.com, and Joomla! would then redirect you back to www.example.com, until the browser gives up after 20 redirections.

This also means that if you are already using this feature, you must pay attention if you decide to change $live_site in your configuration.php (something which is NOT recommended!). If you set $live_site to do the opposite of what this option already does, you will end up with an infinite redirection loop. The solution to that problem is to edit configuration.php and set $live_site = '';

Redirect this (old) domain name to the new one

Sometimes you have to migrate your site to a new domain, as we did migrating from joomlapack.net to akeebabackup.com. Usually this is done transparently, having both domains attached to the same site on the hosting level. However, while a visitor can access the old domain name, the address bar on his browser will still show the old domain name and search engines will believe that you have set up a duplicate content site, sending to the darkest hole of search engine results. Not good! So, you'd better redirect the old domain to the new domain with a 301 redirection to alert both users and search engines about the name change. This is what this option does. You can include several old domains separated by commas. For example:

joomlapack.net, www.joomlapack.net

will redirect all access attempts to joomlapack.net and www.joomlapack.net to the new domain.

[Important]Important

Do NOT put the primary domain name you want your site to be accessed with in this setting. Doing so would cause an infinite redirection loop which makes your site inaccessible.

Force HTTPS for these URLs (do not include the domain name)

Under regular circumstances Joomla! should be able to automatically redirect certain menu items to a secure (HTTPS) address. However, this is not possible if the HTTPS domain name and the HTTP domain name are not the same, as is casual with many shared hosts. Since Admin Tools supports custom HTTPS domain names you can use this feature to make up for the lack of functionality in Joomla! itself. Use one URL per line and do not include http:// and your domain name. For example, if you want to redirect http://www.example.com/eshop.html to https://www.example.com/eshop.html you have to enter eshop.html in a new line of this field. Easy, isn't it?

HSTS Header (for HTTP-only sites)

Assuming that you have a site which is only supposed to be accessed over HTTPS, your visitor's web browser has no idea that the site should not be ever accessed over HTTP. Joomla! offers a Global Configuration setting to force SSL throughout the entire site, but this is merely a workaround: if it sees a request coming through HTTP it will forward it to HTTPS. There are two privacy implications for your users:

  • If you have not enabled the SSL option in Global Configuration a man-in-the-middle attack known as "SSL Stripping" is possible. In this case the user will access your site over plain HTTP without having any idea that they should be using HTTPS instead.

  • Even if Joomla! forwards your user to HTTPS the unencrypted (HTTP) request can still be logged by an attacker. With a moderate amount of sophistication on the part of the attacker (basically, some $200 hardware an widely available information) they can efficiently eavesdrop at the very least the URLs visited by your user –undetected but to the most vigilant geeks among your users– and probably infer information about them.

The HSTS header can fix SSL Stripping attacks by instructing the browser to always use HTTPS for this website, even if the protocol used in a URL is HTTP. The browser, having seen this header, will always use HTTPS for your site. An SSL Stripping and other man-in-the-middle attacks are possible only if your user visits your site for the first time in a hostile environment. This is usually not the case, therefore the HSTS header can provide real benefits to the privacy of your users.

For more information on what the HSTS header is and how it can protect your site visitors' privacy you can read the Wikipedia entry on HSTS.

[Tip]Tip

You should also set Force SSL to Entire Site in your site's Global Configuration. This tells Joomla! to set up the cookies on your site with the “HTTPS Only” flag, which helps you and your visitors avoid a number of attacks which could lead to cookies being stolen and/or spoofed.

Again, you will need to set BOTH the HSTS Header in Admin Tools to Basic or For HSTS Preload AND the Force SSL in Joomla's Global Configuration to Entire Site.

Doing both = improved security. Doing only one or neither of them = no security.

There are three possible settings:

  • None. No action is taken. The .htaccess Maker will not set the Strict-Transport-Security (HSTS) header, nor it will be redirecting from HTTPS to HTTPS.

  • Basic. The .htaccess Maker enables HSTS by sending a basic Strict-Transport-Security (HSTS) header which tells the browser that for the next year it should assume the site runs on HTTPS only.

  • For HSTS Preload. As above, but also includes the includeSubDomains and preload flags in the Strict-Transport-Security (HSTS) header which are required to submit your site on https://hstspreload.org/ to have web browsers only ever connect to your domain using HTTPS. Please note that this header does have a major implication: all subdomains of the site MUST be accessed over HTTPS only. DO NOT use this setting if you do not have control over all subdomains on the server, e.g. an organization where you are only responsible for and in control of a single subdomain but not the entire list of subdomains. DO NOT use this setting if you have subdomains which MUST be accessed over plain HTTP, even if they are hosted on external services, e.g. a CDN provider such as Amazon CloudFront, or CloudFlare. Remember that if you mess up, you mess up for an entire year. There is no way to fix your mess for any browser which has already seen the HSTS header. Think before you act, and be extremely careful with your choices.

Disable HTTP methods TRACE and TRACK (protect against XST)

Enabling this option will prevent remote clients from using the HTTP methods TRACE and TRACK to connect to your site. These can be used by hackers to perform privilege escalation attacks known as Cross Site Tracing (XST). To the best of our knowledge there are no side-effects to enabling this feature.

Cross-Origin Resource Sharing (CORS)

By default a third party site cannot load content from your site using an AJAX request since your content is in a different domain than the site hosting the Javascript performing the request. Using CORS you can circumvent this problem, allowing third party sites' Javascript to load content from your site.

There are three settings for this option. Explicitly disallowed will tell browsers that you do not with your site's resources to be accessible from any other domain name whatsoever. Let the browser decide (default) will not set any headers and let the browser decide whether to allow access to your site from a different domain name; this may work a bit differently in older browsers which MIGHT allow subdomains of your site to have access. Use this option if you plan on setting up CORS headers yourself, either in custom .htaccess code or through server-side scripting e.g. as part of the response of a component. Finally, Explicitly allowed will tell browsers that you want your site's resources to be accessible for any other domain.

When you use any of the explicit options the appropriate Access-Control-Allow-Origin and Timing-Allow-Origin HTTP headers will be set for all requests. For more information on CORS please consult the Enable CORS site.

Send ETag

Your web server sends an ETag header with each static file it serves. Browsers will ask the server in subsequent requests whether the file has a different ETag. If not, they will serve the same file therefore reducing the amount of data they need to transfer from the server (and making the site load faster). By default ETags are calculated based on the file size, last modified date and the inode number. The latter depends on the location of the file inside the filesystem of the server.

When you have a site hosted on a single server this is great. If your static files are, however, hosted on a server farm this may not be a good idea. The reason is that every static file is stored on different server and while the file size and last modified date might be the same the inode number will differ, therefore causing the browser to perform unnecessary file transfers. This is where this option comes in handy.

[Important]Important

Do NOT change this option if your site is hosted on just one server. If you are not sure or have no idea what that means then your site is hosted on just one server and you MUST NOT change this option. Please bear in mind that site speed analysers like YSlow are designed for gigantic sites running off hundreds or thousands of servers. Their site speed checklists DO NOT work well with the vast majority of sites you are working on, i.e. very small sites running off a single server. Treat these checklists as suggestions: you need to exercise common sense, not blindly follow them. If you disable ETags on a small site you are more likely to do harm than good!

The available options are:

  • Server default. Use whatever setting the server administrator has chosen. If you are not perfectly sure you know what you're doing choose this option.

  • None (no ETag sent). Disable ETags completely. Do keep in mind that if you do not also enable the Set default expiration option you will be hurting your site's performance!

[Note]Note

The lack of other options is intentional and has to do with an IIS limitation. IIS, unlike Apache, only offers a binary switch for ETags: you either send them or you don't.

Referrer Policy Header

While surfing, your browser will send out some information about the previous you were visiting (the Referrer that brought you to the new page). This is useful for analytics, for example you can easily track down how many visitors came from Twitter or any other page.

However, there are security implications about the Referrer header. What if on the private area of your website there are sensible information? Think about a private support area, where there is a ticket with the link www.example.com/private-support/help-my-site-www-foobar-com-is-hacked ; you post a reply with a link to a Stack Overflow reply, the user clicks on it and... whops! Now Stack Overflow knows that the site www.foobar.com was hacked.

The Referrer Policy header will instruct your browser when to send the Referrer header and how many information you want to share.

  • Do not set any policy You're not setting any instruction to the browser

  • (Empty) You do not want to set the Referrer Policy here (as header) and the browser should fallback to other mechanisms, for example using the <meta> element or the referrerpolicy attribute on <a> and <link> elelements.

  • no-referrer Never send the referer header

  • no-referrer-when-downgrade The browser will not send the referrer header when navigating from HTTPS to HTTP, but will always send the full URL in the referrer header when navigating from HTTP to any origin. It doesn't matter whether the source and destination are the same site or not, only the scheme.

    SourceDestinationReferrer
    https://www.yoursite.com/url1http://www.yoursite.com/url2NULL
    https://www.yoursite.com/url1https://www.yoursite.com/url2https://www.yoursite.com/url1
    http://www.yoursite.com/url1http://www.yoursite.com/url2http://www.yoursite.com/url1
    http://www.yoursite.com/url1http://www.example.comhttp://www.yoursite.com/url1
    http://www.yoursite.com/url1https://www.example.comhttp://www.yoursite.com/url1
    https://www.yoursite.com/url1http://www.example.comNULL
  • same-origin The browser will only set the referrer header on requests to the same origin. If the destination is another origin then no referrer information will be sent.

    SourceDestinationReferrer
    https://www.yoursite.com/url1https://www.yoursite.com/url2https://www.yoursite.com/url1
    https://www.yoursite.com/url1http://www.yoursite.com/url2NULL
    https://www.yoursite.com/url1http://www.example.comNULL
    https://www.yoursite.com/url1https://www.example.comNULL
  • origin The browser will always set the referrer header to the origin from which the request was made. This will strip any path information from the referrer information.

    SourceDestinationReferrer
    https://www.yoursite.com/url1https://www.yoursite.com/url2https://www.yoursite.com/
    https://www.yoursite.com/url1http://www.yoursite.com/url2https://www.yoursite.com/
    https://www.yoursite.com/url1http://www.example.comhttps://www.yoursite.com/
    [Warning]Warning

    Navigating from HTTPS to HTTP will disclose the secure origin in the HTTP request.

  • strict-origin This value is similar to origin above but will not allow the secure origin to be sent on a HTTP request, only HTTPS.

    SourceDestinationReferrer
    https://www.yoursite.com/url1https://www.yoursite.com/url2https://www.yoursite.com/
    https://www.yoursite.com/url1http://www.yoursite.com/url2NULL
    https://www.yoursite.com/url1http://www.example.comNULL
    http://www.yoursite.com/url1https://www.yoursite.com/url2http://www.yoursite.com/
    http://www.yoursite.com/url1http://www.yoursite.com/url2http://www.yoursite.com/
    http://www.yoursite.com/url1http://www.example.comhttp://www.yoursite.com/
  • origin-when-cross-origin The browser will send the full URL to requests to the same origin but only send the origin when requests are cross-origin.

    SourceDestinationReferrer
    https://www.yoursite.com/url1https://www.yoursite.com/url2https://www.yoursite.com/url1
    https://www.yoursite.com/url1https://www.example.comhttps://www.yoursite.com/
    https://www.yoursite.com/url1http://www.yoursite.com/url2https://www.yoursite.com/
    https://www.yoursite.com/url1http://www.example.comhttps://www.yoursite.com/
    http://www.yoursite.com/url1https://www.yoursite.com/url2http://www.yoursite.com/
    [Warning]Warning

    Navigating from HTTPS to HTTP will disclose the secure URL or origin in the HTTP request.

  • strict-origin-when-cross-origin Similar to origin-when-cross-origin above but will not allow any information to be sent when a scheme downgrade happens (the user is navigating from HTTPS to HTTP).

    SourceDestinationReferrer
    https://www.yoursite.com/url1https://www.yoursite.com/url2https://www.yoursite.com/url1
    https://www.yoursite.com/url1https://www.example.comhttps://www.yoursite.com/
    https://www.yoursite.com/url1http://www.yoursite.com/url2NULL
    https://www.yoursite.com/url1http://www.example.comNULL
  • unsafe-url The browser will always send the full URL with any request to any origin.