Extension:HSTS

MediaWiki extensions manual
HSTS
Release status: stable
Implementation MyWiki
Description Implements HSTS (HTTP Strict Transport Security) on a per-user basis.
Author(s) Sébastien Beyou (Seb35talk)
Latest version 1.1.1
Compatibility policy Snapshots releases along with MediaWiki. Master is not backward compatible.
MediaWiki >= 1.42.0
Database changes No
License WTFPL 2.0
Download
See Releases
  • $wgHSTSForAnons
  • $wgHSTSMaxAge
  • $wgHSTSIncludeSubdomains
  • $wgHSTSBetaFeature
  • $wgHSTSForUsers
Quarterly downloads 4 (Ranked 135th)
Translate the HSTS extension if it is available at translatewiki.net

The HSTS extension implements the HTTP Strict Transport Security feature (RFC 6797) as an opt-in (or opt-out) preference for each user, in order to be always redirected to the HTTPS version of the website, if the user agent (client browser) understands the HSTS functionality. The server administrator is also given the possibility to force the anonymous and/or logged-in users to have a STS header and thus stay on HTTPS.

This extension can be used either:

  • to let users the choice to deactivate HSTS/HTTPS if they prefer (frequent travellers, residents of countries where HTTPS is forbidden, etc.),
  • to let advanced users to choice to activate HSTS/HTTPS,
  • as a "beta" feature before a widespread deployment.

Installation

  • Download and move the extracted HSTS folder to your extensions/ directory.
    Developers and code contributors should install the extension from Git instead, using:cd extensions/
    git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/HSTS
  • Add the following code at the bottom of your LocalSettings.php file:
    wfLoadExtension( 'HSTS' );
    
  • Configure as required.
  •   Done – Navigate to Special:Version on your wiki to verify that the extension is successfully installed.


Usage

If the system administrator has made this possible, the (logged-in) users can modify their preferences for activation of the HSTS in the page "Special:Preferences", tab "User profile", section "Basic information", or as a Beta Feature in the specific tab.

It must be noted that, due to the nature of the HSTS specification, the user will absolutely have no access to the unencrypted HTTP version of the wiki, even in case of problem due to TLS/HTTPS (either a client or server problem); so any misconfiguration can be fatal for the remaining time HSTS is active. This is intended to really protect the user in the case an attacker try to defeat the HTTPS connection for an HTTP connection, but any "legitimate" HTTPS failure from the server will let the user unable to access the website (so the server must have a really stable HTTPS connection to propose HSTS).

Configuration

HSTS has five configuration variables which can be modified in LocalSettings.php.

  • $wgHSTSBetaFeature - (boolean) activate the HSTS preference as a Beta Feature or as a classical user preference
  • $wgHSTSForAnons - (boolean) whether to give the STS header to anonymous users.
  • $wgHSTSForUsers - (boolean) whether to force the STS header for logged-in users; if true, the users do no more have their preference available since it became unuseful due to the server adminstrator’s decision.
  • $wgHSTSIncludeSubdomains - (boolean) whether to include the "includeSubDomains" keyword in the STS header.
  • $wgHSTSMaxAge - max-age parameter for HSTS; can be either:
    • a number: (e.g. 3600) fixed number of seconds before expiration of HSTS (note that 0 will deactivate HSTS the next time the user visit the website), or
    • a date: (e.g. "2014-09-24T00:00:00Z") when HSTS will expire (e.g. just before certificate expiration); MediaWiki must understand the date (see the manual).
      Note that in this second case the header is dynamical, so you may want to configure accordingly your cache servers for a consistent user experience, particularly given the authoritative HSTS header is the last sent, even if shorter.
  • $wgDefaultUserOptions['hsts'] - default value of the preference for logged-in users (0 = opt-out or 1 = opt-in)

Examples:

  • STS header fixed to 30 days before expiration: $wgHSTSMaxAge = 30*86400;
  • The STS security will expire midday UTC on 18 August 2013: $wgHSTSMaxAge = '2013-08-18T12:00:00Z';

Deployment scenarios

Time

In the early tests you can try with small values as 1 minute or a near expiration date, then increase the time to 5 minutes in the tests. For the real deployment you can begin with 30 minutes so that the early adopters will notice if they encounter errors. When you are sure your website has been tested by your regular users on a variety of platforms, you can increase to a production value as 1 month. When you are absolutely sure of your HTTPS quality and in particular you have alerts before the certificate expiration, you can increase to 1 year or even 10 years (or more, there are no more big differences).

As an option to advanced users

Use the default configuration:

$wgHSTSBetaFeature = false;
$wgHSTSForAnons = false;
$wgHSTSForUsers = false;
$wgDefaultUserOptions['hsts'] = 0;

and propose to your users to use HSTS if they want.

As a beta feature for a planned widespread deployment

It is advised to install Extension:BetaFeatures and use $wgHSTSBetaFeature = true;, but you can also not install this extension and use $wgHSTSBetaFeature = false;.

You should previously set $wgSecureLogin = true; to force all your users to log in with HTTPS, warn your users about this, and have a mechanism where they can contact you in case of issue during the connection. Note that if your users are in an enterprise where HTTPS is forbidden, you can use the hook CanIPUseHTTPS to blacklist HTTPS for some IPs.

For the deployment of HSTS itself:

  1. You can first deploy the HSTS extension with the default settings (however with $wgHSTSBetaFeature = true; and a small $wgHSTSMaxAge value (see Time), propose it to your early adopters, and debug issues with HTTPS.
  2. Then make it the default for all users, however with a possible opt-out:
    $wgDefaultUserOptions['preferhttps'] = 1;
    $wgDefaultUserOptions['hsts'] = 1;
  3. When there are no more issues for nobody, you can deploy it for all users and even remove the opt-out:
    $wgHSTSForUsers = true;
  4. Then you can either switch on the HSTS for anonymous visitors:
    $wgHSTSForAnons = true;
    or uninstall the extension and add the STS header in your webserver configuration (the latter is probably more efficient).

Note the HSTS doesn’t make mandatory the use of HTTPS: some visitors (who don’t have a user account) can still visit the wiki with HTTP, and it is probably the case for bots/crawlers as well. It is an independent decision to make it available only with HTTPS, but a previous deployment of HSTS is probably a good advice to have a smoother deployment of the HTTPS for your visitors.

Releases

Version Release date Comments
0.1.0 2013-08-18 Initial version.
0.2.0 2013-08-18 Added two options to force the STS header for anonymous and/or logged-in users by server administrator’s decision (unversionned in git).
1.0.0 2014-09-16 Wrapped in a class, added comments, stable.
1.1.0 2014-09-17 Added a true BetaFeature hook, enforce a change of the preference with HTTPS activated.
1.1.1 2015-05-04 Add extension.json, add license-name in wgExtensionCredits

Testing

The versions 0.2, 1.0 et 1.1 have been tested by extension author Seb35 on a local test wiki and all works as expected:

  • the STS header is present if and only if (iff) we are on HTTPS and the wgHSTSForAnons/Users is true or (the preference is activated and wgHSTSForUsers is false),
  • the includeSubDomains is present iff the parameter is activated,
  • the fixed duration-before-expiration stays correctly,
  • the decreasing duration-before-expiration for a fixed date decreases,
  • the STS header is no more present after expiration,
  • the preference (or BetaFeatures preference) is displayed only if wgHSTSForUsers is false,
  • if wgHSTSForUsers is false, the preference is a classical preference (in User profile/Basic information tab) iff wgHSTSBetaFeature is false (and in the Beta features tab else).

Warnings

  • The STS header is not present on some specific pages (e.g. low-level error pages), although it is present on every reasonably-formed page. If the HSTS period is not expired, the user agent should still consider the HSTS as active and redirect to the HTTPS version, see section 8.6 in RFC 6797.
  • HSTS works only on some user agents, and users could experience differences in activation of the HSTS if they change their user agent (although the STS header is always present).

Bugs and improvements

  • It could be added a feature to immediately deactivate HSTS, although this could be used to facilitate hacking of a user. A similar idea is to let the user choose her/his HSTS expiration time.

See also