Version 4 supported
This version of Silverstripe CMS is still supported though will not receive any additional features. Go to documentation for the most recent stable version.


Security patches

This release contains security patches. Some of those patches might require some updates to your project.

CVE-2020-9309 script execution on protected files

Silverstripe can be susceptible to script execution from malicious upload contents under allowed file extensions (for example HTML code in a TXT file). When these files are stored as protected or draft files, the MIME detection can cause browsers to execute the file contents.

Risk factors

If your project already includes the silverstripe/mimevalidator module, it's already protected. CWP projects are already protected.

If your project includes the silverstripe/userforms module or allows anonymous users to upload files, it's at a higher risk because malicious users can create files without requiring a CMS access.

Actions you need to take

If your project already includes the silverstripe/mimevalidator module, you do not need to do anything. To check if the silverstripe/mimevalidator module is installed in your project, run this command from your project root.

composer show silverstripe/mimevalidator

If you get an error, the module is not installed.

Upgrading to silverstripe/recipe-cms 4.5.3 will NOT automatically install silverstripe/mimevalidator. You need to manually install the module silverstripe/mimevalidator. To add silverstripe/mimevalidator to your project, run this command.

composer require silverstripe/mimevalidator

After installing the mimevalidator module, you need to enable it by adding this code snippet to your YAML configuration.

    class: SilverStripe\MimeValidator\MimeUploadValidator

If your project overrides the defaults allowed file types, it's important that you take the time to review your configuration and adjust it as need be to work with silverstripe/mimevalidator.

Read the Allowed file types documentation for more details on controlling the type of files that can be stored in your Silverstrip CMS Project.

Special consideration when upgrading userforms

The silverstripe/userforms module now also includes silverstripe/mimevalidator in its dependencies. Upgrading to the following versions of userforms will automatically install silverstripe/mimevalidator:

  • 5.4.3 or later
  • 5.5.3 or later
  • 5.6.0 or later (requires CMS 4.6.0)

Userforms that include a file upload field will automatically use theMimeUploadValidator. Beware that this will NOT change the default upload validator for other file upload fields in the CMS. You'll need to update your YAML configuration for the MimeUploadValidator to be used everywhere.

CVE-2019-19326 web cache poisoning

Silverstripe sites using HTTP cache headers and HTTP caching proxies (e.g. CDNs) can be susceptible to web cache poisoning through the:

  • X-Original-Url HTTP header
  • X-HTTP-Method-Override HTTP header
  • _method POST variable.

In order to remedy this vulnerability, Silverstripe Framework 4.5.3 removes native support for these features. While this is technically a semantic versioning breakage, these features are inherently insecure and date back to a time when browsers didn't natively support the full range of HTTP methods. Sites who still require these features will have highly unusual requirements that are best served by a tailored solution.

Re-enabling the support for removed features

These features are best implemented by defining a Middleware.

The following example illustrates how to implement an HTTPMiddleware that restores support for the X-Original-Url header and the _method POST parameter for requests originating from a trusted proxy.

namespace App\Middleware;

use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\Middleware\HTTPMiddleware;

 * This is meant to illustrate how to implement an HTTPMiddleware. If you blindly
 * copy-paste this in in your code base, you'll simply replicate the vulnerability.
class InsecureHeaderMiddleware implements HTTPMiddleware
    public function process(HTTPRequest $request, callable $delegate)
        // Normally, you would validate that the request is coming from a trusted source at this point.
        // View SilverStripe\Control\Middleware\TrustedProxyMiddleware for an example.
        $trustedProxy = true;
        if ($trustedProxy) {
            $originalUrl = $request->getHeader('X-Original-Url');
            if ($originalUrl) {
                $_SERVER['REQUEST_URI'] = $originalUrl;
            $methodOverride = $request->postVar('_method');
            $validMethods = ['GET', 'POST', 'PUT', 'DELETE', 'HEAD'];
            if ($methodOverride && in_array(strtoupper($methodOverride), $validMethods)) {
        return $delegate($request);

To learn more about re-implementing support for the disabled features:

CVE-2020-6164 information disclosure on /interactive URL path

A specific URL path configured by default through the silverstripe/framework module can be used to disclose the fact that a domain is hosting a Silverstripe application. There is no disclosure of the specific version. The functionality on this URL path is limited to execution in a CLI context, and is not known to present a vulnerability through web-based access. As a side-effect, this preconfigured path also blocks the creation of other resources on this path (e.g. a page).

CVE-2020-6165 limited queries break CanViewPermissionChecker

The automatic permission checking mechanism in the silverstripe/graphql module does not provide complete protection against lists that are limited (e.g. through pagination), resulting in records that should fail the permission check being added to the final result set.

If your project implements custom GraphQL queries using the CanViewPermissionChecker, you should validate that they still work as expected after the upgrade.

Read Controlling who can view results in a GraphQL result set for more information on updating your GraphQL queries.

Change log


  • 2020-05-13 cce2b1630 Remove/deprecate unused controllers that can potentially give away some information about the underlying project. (Maxime Rainville) - See cve-2020-6164
  • 2020-05-11 8518987cb Stop honouring X-HTTP-Method-Override header, X-Original-Url header and _method POST variable. Add SS_HTTPRequest::setHttpMethod() (Maxime Rainville) - See cve-2019-19326
  • 2020-02-17 d3968ad Move the query resolution after the DataListQuery has been altered (Maxime Rainville) - See cve-2020-6165
  • 2020-02-11 107e6c9 Ensure canView() check is run on items (Steve Boyd) - See cve-2020-6165

API changes

  • 2020-06-30 ec83959f2 Remove UpgradeBootstrap (not part of our official API) (Maxime Rainville)

Features and enhancements

  • 2020-04-15 daa80d8 Add secure icons (Sacha Judd)


  • 2020-07-09 b780c4f50 Tweak DBHTMLText::Plain to avoid treating some chinese characters as line breaks. (Maxime Rainville)
  • 2020-06-23 e033f26 Fix external link setting text to undefined on text (#1059) (Andre Kiste)
  • 2020-06-01 3df2222 Prevent react-selectable from interfering with pagination (Maxime Rainville)
  • 2020-05-26 3e52b1a Vertically align form description contents (including icons) (bergice)
  • 2020-05-26 09d2061 Asset revision timestamps are no longer underlined in asset admin history tabs (Robbie Averill)
  • 2020-05-19 b9de9e6 Remove direct descendant selector to apply correct margins (Sacha Judd)
  • 2020-05-11 9dcc030 Resize address-card-warning (Sacha Judd)
  • 2020-05-08 afc1759 Page search form layout overflow issue (Mojmir Fendek)
  • 2020-05-05 2cc037b Fix merge conflict in Travis configuration (Robbie Averill)
  • 2020-05-01 b1f6e52 Remove grid view sorting hack to correct initial state (Garion Herman)
  • 2020-05-01 891f0682 Correct placement of 'Page location' field title (Garion Herman)
  • 2020-04-30 fff806ca Prevent Treeview from always reloading (Maxime Rainville)
  • 2020-04-18 216989165 Ensure realpath returns a string for stripos (mattclegg)
  • 2020-04-15 be80813 Campaign admin permission fix (Mojmir Fendek)
  • 2020-04-15 d7c76bdb Published pages filter correction (missing default filter) (Mojmir Fendek)
  • 2020-04-14 e2a6281 Legacy max upload size setting removal (Mojmir Fendek)
  • 2020-03-23 5002f514b Capitalisation fixes in welcome back message (#9439) (Robbie Averill)
  • 2020-03-23 e5aa94c "My profile" title in CMS is now vertical centered as other LeftAndMain screens are (Robbie Averill)
  • 2020-03-20 14fd29a Switch incorrect modified and draft state indicator colours (Sacha Judd)
  • 2020-03-17 7ad5f1bb1 Ensure diff arrays are one-dimensional (Aaron Carlino)
  • 2020-03-08 b269d8749 Register new sub tasks to fix files affected by CVE-2020-9280 and CVE-2019-12245 (Serge Latyntcev)
  • 2020-03-04 12ea7cd Create NormaliseAccessMigrationHelper to fix files affected by CVE-2019-12245 (Maxime Rainville)
  • 2020-02-24 bba0f2f72 Fixed issue where TimeField_Readonly would only show "(not set)" instead of the value (UndefinedOffset)
  • 2020-02-20 ff417ca Fix last file upload showing as errored when uploading multiple files. (bergice)
  • 2020-02-19 7455d14 Handle case where provided $context is null (Garion Herman)
  • 2020-02-19 8402966 Correct deprecated implode syntax for PHP 7.4 compat (Garion Herman)
  • 2020-02-18 9900d07 Tweak UsedOnTableTest ti dynamically switch protocol (Maxime Rainville)
  • 2020-02-05 c92e3b9d Prioritise same-level pages in OldPageRedirector (Klemen Dolinšek)
  • 2019-10-17 b62288cc9 Disabled the UpgradeBootstrap upgrader doctor task (Maxime Rainville)
  • 2019-09-02 6d8a4bc Make AbsoluteLink work with manipulated images (fixes #322) (Loz Calver)