|Controls Content-Security-Policy header [Experimental]
|Introduced in version:||1.32.0 (Gerrit change 253969; git #70941efd)|
|Removed in version:||still in use|
|Allowed values:||(boolean or array)|
|Other settings: Alphabetical | By function|
This config variable allows you to enable the Content-Security-Policy header. This header can help to keep your site secure from XSS attacks, and reduce the risk of certain kind of privacy leaks. Support for this is still experimental in MediaWiki, and comes with many caveats that reduce the amount of protection this feature provides.
As an anti-XSS measure
If the nonce part of this feature is enabled (See below), it can make it much more challenging to exploit cross-site scripting (XSS) vulnerabilities in your site. Certain types of XSS may even be impossible to exploit with this feature enabled.
It works by requiring a secret value (a "nonce") that changes every request, in order to execute.
For example, consider if you had $wgRawHtml set to true (You would probably never combine this feature with raw html as it defeats the point, but it serves as a good example).
If you wanted to run a script, you would put
<html><script>alert( 'Do Evil!' );</script></html> on the page.
This feature prevents things like that from working, by requiring all
<script> tags to have a nonce attribute, e.g.
The nonce has to match the nonce supplied in an http header, and changes on every request.
Thus you would no longer be able to run a script by writing something on to a wikipage, as once you hit save, the nonce changes.
It also disables the
<img src=x onerror="alert('do evil');">.
All user and site JS (If $wgAllowUserJs and/or $wgUseSiteJs is true) are unaffected, as long as they don't use
- This won't protect against certain type of Dom-XSS. Whether or not it protects against a Dom-XSS depends on the specifics of the vulnerability
- If front-end caching (varnish) is used, logged out users will have nonces repeat on cached page views. This reduces the security provided by this feature. The feature still helps, as logged in users are the most likely to be attacked (Since they have valuable accounts) and they would have full protection of the feature. It would also still protect against persistent XSS for the most part, as the act of saving a page would change the nonce. However protection against reflected XSS for logged out users would be rather limited.
- It is not compatible with $wgUseFileCache
- For best security, it is recommended that you do not have Angular js files anywhere on your webserver or any of the domains that script-src is configured to allow, as it can be used to bypass CSP restrictions.
- JSONP endpoints can sometimes be used to bypass CSP restrictions. MediaWiki comes with one by default . It only allows ascii letters, numbers, _, ', ", ., [, ] in the callback name, which makes it very difficult to exploit, but in principle there could be situations where it could be used to bypass CSP.
- Some extensions might not be compatible with this feature, but most should just work.
As a data-leak prevention measure
CSP allows you to define what urls the page is allowed to access. This can be used to help protect user privacy. At this point in time, this is more against accidental mistakes, as there are bypasses that a malicious person could use to leak data cross-domain if they can execute scripts (phab:T238367).
If a domain is access not in the allow list, the browser stops the access and (optionally) sends a report.
Keep in mind, extensions may add their own things. MediaWiki should automatically add anything that it itself needs.
false - disable feature and do nothing.
true, equivalent to setting it to
At the moment, this means: require nonce, limit scripts to coming from the current domain, allow everything else (default-src of *)
If an array, the following keys are recognized
- 'default-src' If true or array (of additional urls) will set a default-src directive, which limits what places things can load from. If false or not set, will send a default-src directive allowing all sources. If you want a restrictive default, just set it to the empty array.
- 'includeCORS' If true or not set, will include urls from $wgCrossSiteAJAXdomains as an allowed load sources unless default-src is already *.
- 'unsafeFallback' Add unsafe-inline as a script source, as a fallback for browsers that do not understand nonce-sources [default on].
- 'useNonces' Require nonces on all inline scripts. If disabled and 'unsafeFallback' is on, then all inline scripts will be allowed [default true].
- 'script-src' Array of additional places that are allowed to have JS be loaded from.
- 'report-uri' true to use MW api [default], false to disable, string for alternate uri. Set $wgDebugLogGroups['csp'] to record these.
In any of the src directives, you can use domain names with or without protocols, and also wildcards as the leftmost subdomain.
For example, the following are valid for script-src and default-src:
If you want to enable this for security reasons (nonces), but still want to allow loading images, etc from anywhere:
$wgCSPHeader = true;
If you want to be more restrictive, enabling both the security features, and disallowing loading resources from third party domains
$wgCSPHeader = [ 'default-src' =>  ];
If you want to be restrictive, but have a friendly site friend.example.com that you want to allow loading resources (images, styles, fonts, etc) from but not scripts:
$wgCSPHeader = [ 'default-src' => [ 'friend.example.com' ] ];
If you want to be able to both load resources and scripts from any subdomain of example.com:
$wgCSPHeader = [ 'script-src' => [ '*.example.com' ], 'default-src' => [ '*.example.com' ] ];
If you want to restrict where you can load resources and scripts from, but you want to disable the anti-xss (nonce) feature:
$wgCSPHeader = [ 'useNonces' => false, 'default-src' =>  ];