In this technical blog post we examine a critical vulnerability in the core of the TYPO3 CMS (CVE-2019-12747). A reliable exploit allows the execution of arbitrary PHP code on the underlying system as authenticated user. Affected are TYPO3 8.x through 8.7.26, and TYPO3 9.x through 9.5.7. A deserialization of untrusted data leads to a Remote Code Execution vulnerability, which can be combined with a Cross-Site Scripting vulnerability that was also detected in the backend (CVE-2019-12748).
Overriding the Database with a Payload
The vulnerability occurs when saving any form in the backend section of TYPO3. If a user modifies the pages section, for example, the data to be edited is fetched from the SQL database of TYPO3 and written back to the database. After fetching the data from the database, the application logic allows overriding single columns of the fetched data with user input. This feature allows a malicious authenticated backend user to override database values containing serialized data which are later deserialized. This leads to a PHP Object Injection that allows an attacker to remotely execute code (CVE-2019-12747).
Technical Details
When saving a backend form in TYPO3, the compile()
method of the $formDataCompiler
object is called. The argument is an array which is populated with user input, as seen in line 1263 of the following listing.
typo3/sysext/backend/Classes/Controller/EditDocumentController.php
The method makes use of a for
loop iterating over an ordered list of FormDataProvider
objects and invokes the addData()
method on each $provider
object in sequence.
typo3/sysext/backend/Classes/Form/FormDataGroup/OrderedProviderList.php
As you can see in the source code listing on line 64, the $result
of the previous $provider->addData()
invocation is used as an argument in the next addData()
call. On each iteration, the $result
variable which represents an array is modified after the $provider
has processed its contents. One of those providers is an instance of the DatabaseRecordOverrideValues
class which allows to override the data fetched from the database stored under the databaseRow
key of the $result
array.
typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseRecordOverrideValues.php
Finally, one of the following FormDataProvider
objects implements an unserialize()
call on the overridden data, leading to the vulnerability:
typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseLanguageRows.php
You can find more information on how to exploit PHP Object Injections with gadget chains in our blogpost.
Stored Cross-Site Scripting in Backend
A Cross-Site Scripting vulnerability exists in the TYPO3 backend (CVE-2019-12748). An unprivileged user who has access to the Site Redirects section can inject a malicious URL which makes use of the t3://
pseudo protocol.
By adding this specific site redirect another benign higher-privileged TYPO3 user can be tricked into clicking the link which triggers the malicious JavaScript. He could use this vulnerability as a pivot point to launch the remote code execution exploit from above.
TYPO3 prevents a user to make use of the dangerous javascript:
pseudo protocol in links and URLs provided by the user which would mean the direct execution of JavaScript. However, it does not prevent a user to make use of TYPO3’s builtin t3://
pseudo protocol which implements multiple functionalities like referencing TYPO3 internal pages, files, email addresses or URLs. In fact, specifying a URL which is automatically translated into a clickable link bypasses the whitelist of TYPO3 which initially prevented the javascript:
pseudo protocol.
Timetable
Date | What |
09 May 2019 | Sent vendor vulnerability details |
09 May 2019 | Vendor acknowledged |
10 May 2019 | Coordination with security lead of vendor on fixing the issue |
06 June 2019 | Vendor informs us about detailed release plans 25 June 2019 |
25 June 2019 | TYPO3 9.5.8 patch released |
Summary
The presented vulnerabilities can have critical impact on any TYPO3 system with one or more TYPO3 backend users. An authenticated backend user with access to the Pages section can execute code on the underlying remote system. He could use the Cross-Site Scripting vulnerability in the Site Redirects module as a pivoting point to exploit this vulnerability.