Bug #98382
Updated by Oliver Hader about 2 years ago
h4. Disclaimer This was originally reported as a vulnerability, after analyzing the scenario, the TYPO3 Security Team came to the conclusion to handle it in public. It cannot be exploited directly without knowing the backend form protection token of a particular user session. --- h4. Original Report This has been reported as "self XSS". We simplified the mentioned PoC to a @HTTP GET@ request, however it does not seem to be vulnerable via cross-site requests. <pre> v11: https://example.com/typo3/ajax/file/process?token=<token>&data[newfile][0][target]=1:/&data[newfile][0][data]=<script>alert(1)</script>N0T3X15T1N6.php v10: https://example.com/typo3/index.php?route=%2Fajax%2Ffile%2Fprocess&token=<token>&data[newfile][0][target]=1:/&data[newfile][0][data]=%3Cscript%3Ealert(1)%3C/script%3EN0T3X15T1N6.php </pre> With the following response: <pre> HTTP/1.1 500 (AJAX) Date: Tue, 20 Sep 2022 10:49:35 GMT Server: Apache/2.4.54 (Unix) OpenSSL/3.0.5 mod_fcgid/2.3.9 X-Powered-By: PHP/8.1.9 X-Frame-Options: SAMEORIGIN Expires: 0 Cache-Control: no-cache, must-revalidate Pragma: no-cache Last-Modified: Tue, 20 Sep 2022 10:49:35 GMT Connection: close Transfer-Encoding: chunked Content-Type: text/html; charset=utf-8 <t3err>Extension of file "<script>alert(1)</script>N0T3X15T1N6.php" was not allowed!</t3err>% </pre> In TYPO3 v12 the response has been streamline to be @application/json@. For earlier versions it would be considered as "hardening" by encoding the HTML output. This probably can be handled in public. <pre> diff --git a/typo3/sysext/backend/Classes/Controller/File/FileController.php b/typo3/sysext/backend/Classes/Controller/File/FileController.php index be3db3ee5e..5242e8feeb 100644 --- a/typo3/sysext/backend/Classes/Controller/File/FileController.php +++ b/typo3/sysext/backend/Classes/Controller/File/FileController.php @@ -142,6 +142,7 @@ class FileController $includeMessages = (bool)($request->getQueryParams()['includeMessages'] ?? false); $errors = $this->fileProcessor->getErrorMessages(); if (!$includeMessages && !empty($errors)) { + $errors = array_map('htmlspecialchars', $errors); return (new HtmlResponse('<t3err>' . implode(',', $errors) . '</t3err>'))->withStatus(500, '(AJAX)'); } $flatResult = []; </pre>