Extension:Secure HTML

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manualManual:Extensions
Crystal Clear action run.png
Secure HTML

Release status:Extension status stable

SpecialSecureHTML screenshot.png
ImplementationTemplate:Extension#type Tag, User rights
DescriptionTemplate:Extension#description Lets you include arbitrary HTML in an authorized and secure way
Author(s)Template:Extension#username Ryan Finnie (Fo0bartalk)
Latest versionTemplate:Extension#version 3.0 (2016-07-29)
MediaWikiTemplate:Extension#mediawiki 1.23+
LicenseTemplate:Extension#license GNU General Public License 2.0 or later
Download Download latest stable release (3.0), or:
ExampleTemplate:Extension#example <shtml> tag (PayPal forms), Special:SecureHTML

$wgSecureHTMLSecrets, $wgSecureHTMLSpecialRight, $wgSecureHTMLSpecialDropdown, $wgSecureHTMLTag

<shtml> (configurable)

Translate the Secure HTML extension if it is available at translatewiki.net

Check usage and version matrix.

Occasionally you need to display HTML within a wiki, but allowing it site-wide opens you up to various XSS attacks. This extension solves that problem by letting you specify arbitrary HTML, but only if the HTML includes a corresponding hash that is created by signing the HTML input with a secret that only authorized people know.

The extension uses a special page, Special:SecureHTML which helps you build a tag, <shtml>, which acts as a wrapper around raw HTML. An example looks like:

><strong>Hello world!</strong></shtml>

If the user uses a valid shared secret to build the hashed <shtml> snippet and includes it in a wiki page, the snippet is rendered as the raw HTML contained within the tag. If the shared secret is invalid, the snippet is rendered as an error message (but not containing the HTML, obviously).


Secure HTML is compatible with MediaWiki 1.23 and later.

The extension can be retrieved directly from Git [?]:

  • Browse code
  • Some extensions have tags for stable releases.
  • Each branch is associated with a past MediaWiki release. There is also a "master" branch containing the latest alpha version (might require an alpha version of MediaWiki).

Extract the snapshot and place it in the extensions/SecureHTML/ directory of your MediaWiki installation.

If you are familiar with git and have shell access to your server, you can also obtain the extension as follows:

cd extensions/
git clone https://gerrit.wikimedia.org/r/p/mediawiki/extensions/SecureHTML.git
  • Download and place the file(s) in a directory called SecureHTML in your extensions/ folder.
  • Add the following code at the bottom of your LocalSettings.php:
wfLoadExtension( 'SecureHTML' );
$wgSecureHTMLSecrets = array(
    'keyname' => 'keysecret',
  • Modify $wgSecureHTMLSecrets as per below.
  • Go to Special:SecureHTML and use the page to create a hashed snippet of raw HTML using the key secrets defined.
  • Add the hashed snippet to your desired wiki page.
  • YesY Done - Navigate to Special:Version on your wiki to verify that the extension is successfully installed.

To users running MediaWiki 1.24 or earlier:

The instructions above describe the new way of installing extensions using wfLoadExtension(), since MediaWiki 1.25. If you need to install this extension in earlier versions, instead of wfLoadExtension( 'SecureHTML' );, you need to use:

require_once "$IP/extensions/SecureHTML/SecureHTML.php";


Secure HTML uses HMAC digests to sign a piece of raw HTML in a <shtml> tag, using a shared secret key. The $wgSecureHTMLSecrets configuration array may have multiple shared secrets, and is in the format:

$wgSecureHTMLSecrets = array(
    'Wiki admin' => 'zX6Zn2WRKlQt',
    'developers' => '7RCkFRjw68CL',
    'Support department' => 'NL9g5QntWNbC',

The first part of each pair is the key name, and the second part is the key secret. This way, you can logically segment shared secrets among several groups. If a keyname= parameter is not given to the <shtml> tag, the first entry in $wgSecureHTMLSecrets is assumed. So, for example:

<!-- Use the default key ("Wiki admin" in the above example), signed with "zX6Zn2WRKlQt" -->
<shtml hash="ab...cd">HTML</shtml>

<!-- Or specify the key name explicitly -->
<shtml keyname="Wiki admin" hash="ab...cd">HTML</shtml>

<!-- Use the "developers" key, signed with "7RCkFRjw68CL" -->
<shtml keyname="developers" hash="ef...01">HTML</shtml>

The default tag name is shtml, but may be changed by setting e.g.:

$wgSecureHTMLTag = 'securehtml';


The special page Special:SecureHTML is used to build the snippet, specifying the raw HTML, the key secret, and (optionally) the key name. If a key name is not specified, the first entry in $wgSecureHTMLSecrets is assumed. When the form is submitted, the signed snipped is displayed, and an attempt to render the snippet is made. If the key secret is incorrect, this will show you the results immediately, before you try to add the snippet to a page.

Special:SecureHTML is restricted to users who have the 'edit' right; the rationale being the user needs to be able to edit pages anyway to make use of this extension. If you would like to change this right, set $wgSecureHTMLSpecialRight to another right, or set to '' to allow anyone to use the special page.

Note that this restriction does not provide much extra security. If your MediaWiki installation requires users to be logged in to edit, it does provide superficial protection against anonymous dictionary attacks (checking the preview result) against a key. However, if a user already knows a key secret, he/she can build the signed snippet manually; the special page is not strictly needed.

By default, Special:SecureHTML presents a dropdown list of configured key names to select from. If you would rather not show all key names, set the following to turn the field into a freeform text input:

$wgSecureHTMLSpecialDropdown = False;

Hash algorithms[edit]

Beginning with version 3.0, HMAC hash algorithms are configurable per-key. The default is HMAC SHA256 when the key value is a string (the secret), but may be extended, for example:

$wgSecureHTMLSecrets = array(
    'default sha256' => 'vwJ2prl4B4bg',
    'custom sha512' => array(
        'algorithm' => 'sha512',
        'secret' => 'RZQ8R99C95Xn',
    'custom whirlpool' => array(
        'algorithm' => 'whirlpool',
        'secret' => 'FXtN2QHflVPf',

SHA256 should be secure for most purposes, but if you do pick a custom algorithm, be careful with which one you choose. For example, adler32 would be a very bad choice for hashing.

Version 1.0 used a simple data + secret MD5 hash which is now considered cryptographically insecure. This format was deprecated in version 2.0 in favor of HMAC SHA256 hashes, and removed in 3.0. Any existing version 1.0 hashes must be converted to new hashes.


Translation of the extension strings is managed by Translatewiki.net (direct extension link). Please contribute translations there.

See also[edit]