Skip to content

Commit

Permalink
[SECURITY] Mitigate directly accessible file upload in form framework
Browse files Browse the repository at this point in the history
File handling implementation in `UploadedFileReferenceConverter` of
`ext:form` creates files in `/fileadmin/user_uploads/` whenever some
Extbase controller is (implicitly) dealing with `FileReference` models,
unless particular implementations assign specific type converters or
register type converters having a higher processing priority.

As a side-effect this could lead to by-passing mime-type validators,
allowing to plant cross-site scripting and other malicious binaries
to public accessible `/fileadmin/` storage. PHP files and similar are
blocked since `fileDenyPattern` rule is active in any case.

This change makes the usage of `UploadedFileReferenceConverter` more
specific in the scope of processing contact forms with `ext:form`

* use random folder names for files, `.../form_abcde12345/image.png`
* removes `UploadedFileReferenceConverter` from being used implicitly
  by other Extbase implementations dealing with `FileReference` models

`PseudoFileReference` has been introduced to limit properties being
serialized to `uid` (in case it's a real file reference) or `uidLocal`
(in case it's a transient reference, pointing to a file).

Direct URLs to uploaded files are substituted by `fileDump` eID script
now, enforcing corresponding FAL mime-type and denying the web server
from guessing/interpreting a different mime-type based on file suffix.

A unique form `__session` value has been introduce, serving as seed
to derive for instance mentioned folder names for uploaded files. In
addition to that, form `__state` is only parsed when having been
submitted via expected `FormFrontendController::performAction`.

Resolves: #92136
Releases: master, 11.1, 10.4, 9.5
Change-Id: I7c33803443a68d6b3c895ec74da802a70bd390c1
Security-Bulletin: TYPO3-CORE-SA-2021-002
Security-References: CVE-2021-21355
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/68427
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
  • Loading branch information
ohader committed Mar 16, 2021
1 parent d5c16bc commit 20f9a7d
Show file tree
Hide file tree
Showing 24 changed files with 2,139 additions and 53 deletions.
82 changes: 82 additions & 0 deletions Build/Scripts/generateMimeTypes.php
@@ -0,0 +1,82 @@
#!/usr/bin/env php
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

$dbJson = file_get_contents(dirname(__DIR__) . '/node_modules/mime-db/db.json');
$dbJson = json_decode($dbJson, true);

$mimeTypeMapping = [];
$mimeTypeString = '';
foreach ($dbJson as $mimeType => $mimeTypeInfo) {
if (isset($mimeTypeInfo['extensions'])) {
$mimeTypeMapping[$mimeType] = $mimeTypeInfo['extensions'];
}
}

// @todo: add our own file extensions here

foreach ($mimeTypeMapping as $mimeType => $extensionInfo) {
$mimeTypeString .= " '" . $mimeType . "' => ['" . implode("', '", $extensionInfo) . "'],
";
}

$classTemplate = '<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Core\Resource;
/**
* This class contains a list of all available / known mimetypes and file extensions,
* and is automatically generated by TYPO3 via Core/Build/Scripts/generateMimeTypes.php
*/
final class MimeTypeCollection
{
private $map = [
' . rtrim($mimeTypeString, ',') .
' ];
/**
* @return array<string, List<string>>
*/
public function getMap(): array
{
return $this->map;
}
/**
* @return List<string>
*/
public function getMimeTypes(): array
{
return array_keys($this->map);
}
}
';

file_put_contents(dirname(dirname(__DIR__)) . '/typo3/sysext/core/Classes/Resource/MimeTypeCollection.php', $classTemplate);
1 change: 1 addition & 0 deletions Build/package.json
Expand Up @@ -56,6 +56,7 @@
"karma-opera-launcher": "^1.0.0",
"karma-requirejs": "^1.1.0",
"karma-safari-launcher": "^1.0.0",
"mime-db": "^1.46.0",
"node-sass": "^4.14.1",
"patch-package": "^6.2.2",
"postcss-banner": "^3.0.2",
Expand Down
5 changes: 5 additions & 0 deletions Build/yarn.lock
Expand Up @@ -5528,6 +5528,11 @@ mime-db@^1.28.0:
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea"
integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==

mime-db@^1.46.0:
version "1.46.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee"
integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==

mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24:
version "2.1.27"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
Expand Down
6 changes: 4 additions & 2 deletions typo3/sysext/core/Classes/Resource/FileReference.php
Expand Up @@ -525,14 +525,16 @@ public function getParentFolder()
public function __sleep(): array
{
$keys = get_object_vars($this);
unset($keys['originalFile']);
unset($keys['originalFile'], $keys['mergedProperties']);
return array_keys($keys);
}

public function __wakeup(): void
{
$factory = GeneralUtility::makeInstance(ResourceFactory::class);
$this->originalFile = $this->getFileObject(
(int)$this->propertiesOfFileReference['uid_local']
(int)$this->propertiesOfFileReference['uid_local'],
$factory
);
}
}

0 comments on commit 20f9a7d

Please sign in to comment.