- Security: SQL information disclosure in MySQLDatabase
- Security: XSS in controller handling for missing actions
- Security: SQL injection with Translatable extension enabled
- Security: Version number information disclosure
- Security: Weak entropy in tokens for CSRF protection, autologin, "forgot password" emails and password salts
- Security: HTTP referer leakage on Security/changepassword
- Security: CSRF protection bypassed when handling form action requests through controller
- Improved security of PHPSESSID and byPassStaticCache cookies (setting them to 'httpOnly')
If you're using open_basedir in PHP:
There is a bug in 2.4.4 which breaks open_basedir restriction.
The issue has been fixed in the development 2.4 branch, but you'll need to patch your existing copy of SilverStripe 2.4.4 if this affects you. The error usually occurs when you try logging into the CMS.
It can be fixed by patching your working copy with this change: http://open.silverstripe.org/changeset/115314
Security: SQL information disclosure in MySQLDatabase
The 'showqueries' GET parameter shows all performed SQL queries in the page output. This is intended functionality, but should be limited websites not being in "live mode" (set through Director::set_environment_type(), checked through Director::isLive()). By adding an 'ajax' GET parameter you can circumvent this live check.
See Secunia Advisory: http://secunia.com/advisories/42346/
Don't circumvent Director::isLive() check in MySQLDatabase
Information disclosure of potentially sensitive information through SQL query strings.
Andrew Lord, Nathaniel McHugh
- trunk: http://open.silverstripe.org/changeset/114782
- 2.4: http://open.silverstripe.org/changeset/114783
Security: XSS in controller handling for missing actions
Controller routing in SilverStripe core doesn't encode error messages for missing URL actions before returning them to the user (see Controller->handleAction()).
This can be reproduced with any URL that doesn't have custom error handling defined through RequestHandler::$url_handlers, which includes all core controllers.
Reproduce with the following URL:
See Secunia Advisory: http://secunia.com/advisories/42346/
Force Content-Type: text/plain upon output.
Attackers can craft URLs to change the displayed website behaviour as well as gain access to authenticated cookie information. In case the victim has a permanent login cookie ("Remember me" checkbox), this can lead to CMS access for attackers.
Tim Suter, Andrew Horton (http://security-assessment.com)
- trunk: http://open.silverstripe.org/changeset/114444
- 2.4: http://open.silverstripe.org/changeset/114751
Security: SQL injection with Translatable extension enabled
Locale setter methods on i18n and Translatable classes are not sanitizing or whitelisting input, which can lead to SQL injection based on "locale" GET parameters. This behaviour is limited to websites having the (built-in) Translatable extension activated.
Sanitize locale values in Translatable->augmentSQL() and whitelist locale values in i18n setters.
- SilverStripe trunk
- SilverStripe 2.4.3 or older
- SilverStripe 2.3.9 or older
- trunk: http://open.silverstripe.org/changeset/114515
- 2.4: http://open.silverstripe.org/changeset/114516
- 2.3: http://open.silverstripe.org/changeset/114517
Security: Version number information disclosure
SilverStripe exposes version information through static files located in the webroot. As these files have no extension, they are served without processing by most webserver default configurations.
The files are: sapphire/silverstripe_version cms/silverstripe_version
Reject web requests to version information through .htaccess for Apache, and web.config for IIS.
Version Information about the product can be used to craft attacks more specifically.
Robert Mac Neil
- trunk: http://open.silverstripe.org/changeset/114774 http://open.silverstripe.org/changeset/114770
- 2.4: http://open.silverstripe.org/changeset/114774 http://open.silverstripe.org/changeset/114771
- 2.3: http://open.silverstripe.org/changeset/114776 http://open.silverstripe.org/changeset/114772
Security: Weak entropy in tokens for CSRF protection, autologin, "forgot password" emails and password salts
SilverStripe uses rand(), mt_rand() in combination with uniqid(), substr() and time() to create pseudo-random tokens. Due to the nature of these implementations, the entropy of tokens is low, potentially exposing them to brute force attacks.
- CSRF form protection
- Member Autologin
- "Forgot Password" emails
- Autogenerated salt values for hashed passwords in the Member table
Use the best available PRNG implementation on the current platform and PHP version (favouring MCRYPT_DEV_URANDOM and openssl_random_pseudo_bytes()).
Weak entropy can be used for more successful brute force attacks.
Andrew Horton (http://security-assessment.com)
- trunk: http://open.silverstripe.org/changeset/114497 http://open.silverstripe.org/changeset/114498 http://open.silverstripe.org/changeset/114503 http://open.silverstripe.org/changeset/114504 http://open.silverstripe.org/changeset/114505
- 2.4: http://open.silverstripe.org/changeset/114499 http://open.silverstripe.org/changeset/114500 http://open.silverstripe.org/changeset/114506 http://open.silverstripe.org/changeset/114507
- 2.3: http://open.silverstripe.org/changeset/114501 http://open.silverstripe.org/changeset/114502 http://open.silverstripe.org/changeset/114509
Security: HTTP referer leakage on Security/changepassword
The Security/changepassword URL action can be invoked with a temporary token stored against the member record ("AutoLoginHash"). This token is set when a member requests a new password by email through Security/lostpassword, and cleared upon successful password change.
The token is passed as a GET parameter, which can expose it to HTTP referer leakage, in case the member decides to navigate away from the "change password" form before submitting the form (which would invalidate the token). If the clicked link is an external page, the (still valid) GET parameter will appear in the external site's HTTP referer logs, enabling third parties to take over user accounts.
Note: This is only a problem when Security/changepassword is used without being logged-in.
Redirect from Security/changepassword/?h=XXX to Security/changepassword and store the token in session instead.
Takeover of user accounts by third parties with access to HTTP referer logs.
- trunk: http://open.silverstripe.org/changeset/114758
- 2.4: http://open.silverstripe.org/changeset/114760
- 2.3: http://open.silverstripe.org/changeset/114763
Security: CSRF protection bypassed when handling form action requests through controller
The built-in CSRF protection on forms in SilverStripe can be bypassed by routing the action through the controller instead of the form.
Note: Does not apply to manual CSRF protection in controller actions through SecurityToken->check().
Developers are encouraged to use Controller::$allowed_actions to limit the actions accessible through URL routing. Methods that need automatic CSRF protection (most form actions) should NOT be included in $allowed_actions, their protection is handled through request handling in the form class itself.
See security documentation for more details.
Exposes various administrative actions (creating a new page, reverting to draft) to CSRF attacks, in case attackers know the URL a victim has a valid CMS login for.
- trunk: http://open.silverstripe.org/changeset/115182 http://open.silverstripe.org/changeset/115185
- 2.4: http://open.silverstripe.org/changeset/115189 http://open.silverstripe.org/changeset/115188
- 2.3: http://open.silverstripe.org/changeset/115200 http://open.silverstripe.org/changeset/115191
Features and Enhancements
- [rev:114901] Allow setting secure session cookies when using SSL. Recent change r114567 made this impossible. (thanks simon_w!) (from r114900)
- [rev:114572] 'bypassStaticCache' cookie set in Versioned is limited to httpOnly flag (no access by JS) to improve clientside security (from r114568)
- [rev:114571] Session::start() forces PHPSESSID cookies to be httpOnly (no access by JS) to improve clientside security (from r114567)
- [rev:114499] Added !RandomGenerator for more secure CRSF tokens etc. (from r114497)
- [rev:114467] PHP requirements in installer now check for date.timezone correctly being set for PHP 5.3.0+. This option is required to be set starting with 5.3.0 and will cause an error during installation if not
- [rev:114083] Added SS_HTTPResponse->setStatusDescription() as equivalent to setStatusCode(). Added documentation.
- [rev:113963] Split temp directory check and writability into two checks
- [rev:113961] #6206 Installer additional checks for module existence by checking _config.php exists, in addition to the directory
- [rev:113919] Allowing i18nTextCollector to discover entities in templates stored in themes/ directory (thanks nlou) (from r113918)
- [rev:113871] Update Asset's left and right panels with filders and files after 'Look for new files' was triggered (open #5543)
- [rev:114474] Using i18n::validate_locale() in various Translatable methods to ensure the locale exists (as defined through i18n::$allowed_locales) (from r114470)
- [rev:115189] Removing form actions from $allowed_actions in !AssetAdmin, CMSMain, !LeftAndMain - handled through Form->httpSubmission() (from r115185)
- [rev:115188] Checking for existence of !FormAction in Form->httpSubmission() to avoid bypassing $allowed_actions definitions in controllers containing this form
- [rev:115188] Checking for $allowed_actions in Form class, through Form->httpSubmission() (from r115182)
- [rev:115169] Fixed conflicting check of mysite directory with recommendation of removal of _config.php in installer
- [rev:114941] #6162 CMSMain::publishall() fails when over 30 pages (thanks natmchugh!) (from r114940)
- [rev:114922] #6219 Director::direct() validation fails for doubly nested file fields (thanks ajshort!) (from r114921)
- [rev:114823] Installer should check asp_tags is disabled, as it can cause issues with !SilverStripe
- [rev:114783] Removed switch in !MySQLDatabase->query() to directly echo queries with 'showqueries' parameter when request is called via ajax (from r114782)
- [rev:114774] Disallow web access to sapphire/silverstripe_version to avoid information leakage (from r114773)
- [rev:114771] Disallow web access to cms/silverstripe_version to avoid information leakage (from r114770)
- [rev:114760] Avoid potential referer leaking in Security->changepassword() form by storing Member->!AutoLoginHash in session instead of 'h' GET parameter (from r114758)
- [rev:114719] Fallback text for "Password" in !ConfirmedPasswordField when no translation found
- [rev:114683] Populates the page with fake data in order to pass subsequent unit tests
- [rev:114654] Test if form is the right class (if a class decorates the content controller, this test would break ie sphinx)
- [rev:114516] Escaping $locale values in Translatable->augmentSQL() in addition to the i18n::validate_locale() input validation (from r114515)
- [rev:114512] Limiting usage of mcrypt_create_iv() in !RandomGenerator->generateEntropy() to *nix platforms to avoid fatal errors (specically in IIS) (from r114510)
- [rev:114507] Using !RandomGenerator class in Member->logIn(), Member->autoLogin() and Member->generateAutologinHash() for better randomization of tokens. Increased VARCHAR length of '!RememberLoginToken' and '!AutoLoginHash' fields to 1024 characters to support longer token strings. (from r114504)
- [rev:114506] Using !RandomGenerator class in !PasswordEncryptor->salt() (from r114503)
- [rev:114500] Using !RandomGenerator class in !SecurityToken->generate() for more random tokens
- [rev:114473] Check for valid locale in i18n::set_locale()/set_default_locale()/include_locale_file()/include_by_locale() (as defined in i18n::$allowed_locales). Implicitly sanitizes the data for usage in controllers. (from r114469)
- [rev:114445] Don't allow HTML formatting in !RequestHandler->httpError() by sending "Content-Type: text/plain" response headers. (from r114444)
- [rev:114208] Including template /lang folders in i18n::include_by_locale() (implementation started in r113919)
- [rev:114195] Added !SecurityToken to !PageCommentInterface->!DeleteAllLink() (fixes #6223, thanks Pigeon)
- [rev:114083] Strip newlines and carriage returns from SS_HTTPResponse->getStatusDescription() (fixes #6222, thanks mattclegg) (from r114082)
- [rev:114081] Removed double quoting of $where parameter in Translatable::get_existing_content_languages() (fixes #6203, thanks cloph) (from r114080)
- [rev:114036] Fixed case where !AssetAdmin would throw an error if $links was not an object in !AssetAdmin::getCustomFieldsFor()
- [rev:113976] #6201 Use of set_include_path() did not always include sapphire paths in some environments
- [rev:113962] Installer now checks temporary directory is writable, in addition to it being available.
- [rev:113809] #6197 simon_w: Fixed Internal Server Error when accessing assets on Apache without mod_php.
- [rev:113692] Avoid reloading CMS form twice after certain saving actions (fixes #5451, thanks muzdowski)
- [rev:114916] Ensure php5-required.html template shows correct minimum and recommended PHP versions (thanks mattcleg!) (from r114915)
- [rev:114751] Setting Content-Type to text/plain in various error responses for !RestfulServer (from r114750)
- [rev:114749] Reverting Member "!AutoLoginHash", "!RememberLoginToken" and "Salt" to their original VARCHAR length to avoid problems with invalidated hashes due to shorter field length (from r114748)
- [rev:114745] Partially reverted r114744
- [rev:114744] Reduced VARCHAR length from 1024 to 40 bytes, which fits the sha1 hashes created by !RandomGenerator. 1024 bytes caused problems with index lengths on MySQL (from r114743)
- [rev:114720] Code formatting change in !ConfirmedPasswordField::__construct()
- [rev:114454] Added exception handling if !ClassName is null in search results
- [rev:114334] Checking for class_exists() before !SapphireTest::is_running_tests() to avoid including the whole testing framework, and triggering PHPUnit to run a performance-intensive directory traversal for coverage file blacklists (from r114332)
- [rev:114079] Reverted r108515
- [rev:114078] Documentation for Aggregate caching (from r114077)
- [rev:114062] fixed visual glitch in CMS access tab for IE
- [rev:114036] Defined $backlinks as an array before adding entries to it
- [rev:114016] Fixed php tag in !SecurityTokenTest, should be "<?php" not "<?"
- [rev:113984] Installer now writes "!SetEnv HTTP_MOD_REWRITE On" in .htaccess to be consistent with the original .htaccess file that comes with the phpinstaller project
- [rev:113968] Fixed PHP strict standard where non-variables cannot be passed by reference
- [rev:113967] Fixed undefined variable $groupList
- [rev:113964] Re-use variable instead of check temp folder again
- [rev:113956] Make sure that Translatable creates a translated parent of !SiteTree only when the parent is not translated (from r113955)
- [rev:113937] don't trigger notice but Debug::show it
- [rev:113936] don't trigger notice but Debug::show it
- [rev:113933] test doesn't fail anymore due to time differences between db and php. The test now issues notices, warnings and errors depending on the severity of the offset
- [rev:113924] Fixed spaces with tabs in Core
- [rev:113923] Fixed spaces with tabs for Core::getTempFolder()
- [rev:113696] call jquery-ui from thirdparty folder instead google api (see ticket 5915) (from r113656)
- [rev:113695] Typo in !AssetAdmin (fixes #6191, thanks Juanitou)
- [rev:114464] FIX: Revert last commit
- [rev:114463] FIX: Revert last commit