From aa4e270d04313fe7d8ea508a9c694db83875e981 Mon Sep 17 00:00:00 2001 From: Christian Kuhn Date: Thu, 12 Jul 2018 11:32:06 +0200 Subject: [PATCH] [SECURITY] Mitigate phar stream wrapper SoftReferenceIndex throws exceptions on phar streams LegacyLinkNotationConverter throws exceptions on phar streams Resolves: #85385 Releases: master, 8.7, 7.6 Security-Commit: f11da6bc371729fd8ab556af8e2b84c9f8501704 Security-Bulletin: TYPO3-CORE-SA-2018-002 Change-Id: Iad230e9a0fe876b879eac810b6fa14b6d9f4fcdb Reviewed-on: https://review.typo3.org/57545 Reviewed-by: Oliver Hader Tested-by: Oliver Hader --- Classes/Database/SoftReferenceIndex.php | 7 +++ .../LegacyLinkNotationConverter.php | 7 +++ .../Unit/Database/SoftReferenceIndexTest.php | 57 +++++++++++++++++++ .../LegacyLinkNotationConverterTest.php | 32 +++++++++++ 4 files changed, 103 insertions(+) create mode 100644 Tests/Unit/Database/SoftReferenceIndexTest.php diff --git a/Classes/Database/SoftReferenceIndex.php b/Classes/Database/SoftReferenceIndex.php index e7fdb7af39..2af5d4e634 100644 --- a/Classes/Database/SoftReferenceIndex.php +++ b/Classes/Database/SoftReferenceIndex.php @@ -443,6 +443,13 @@ public function getTypoLinkParts($typolinkValue) // we define various keys below, "url" might be misleading unset($finalTagParts['url']); + if (stripos(rawurldecode(trim($link_param)), 'phar://') === 0) { + throw new \RuntimeException( + 'phar scheme not allowed as soft reference target', + 1530030672 + ); + } + // Parse URL: $pU = @parse_url($link_param); diff --git a/Classes/LinkHandling/LegacyLinkNotationConverter.php b/Classes/LinkHandling/LegacyLinkNotationConverter.php index bb1120462e..a811b649db 100644 --- a/Classes/LinkHandling/LegacyLinkNotationConverter.php +++ b/Classes/LinkHandling/LegacyLinkNotationConverter.php @@ -55,6 +55,13 @@ class LegacyLinkNotationConverter */ public function resolve(string $linkParameter): array { + if (stripos(rawurldecode(trim($linkParameter)), 'phar://') === 0) { + throw new \RuntimeException( + 'phar scheme not allowed as soft reference target', + 1530030673 + ); + } + $result = []; // Parse URL scheme $scheme = parse_url($linkParameter, PHP_URL_SCHEME); diff --git a/Tests/Unit/Database/SoftReferenceIndexTest.php b/Tests/Unit/Database/SoftReferenceIndexTest.php new file mode 100644 index 0000000000..69a20aa0cc --- /dev/null +++ b/Tests/Unit/Database/SoftReferenceIndexTest.php @@ -0,0 +1,57 @@ + [ + 'phar%3a//some-file.jpg', + ], + 'URL encoded absolute' => [ + 'phar%3a///path/some-file.jpg', + ], + 'not URL encoded local' => [ + 'phar://some-file.jpg', + ], + 'not URL encoded absolute' => [ + 'phar:///path/some-file.jpg', + ], + ]; + } + + /** + * @test + * @dataProvider getTypoLinkPartsThrowExceptionWithPharReferencesDataProvider + */ + public function getTypoLinkPartsThrowExceptionWithPharReferences(string $pharUrl) + { + $this->expectException(\RuntimeException::class); + $this->expectExceptionCode(1530030672); + (new SoftReferenceIndex())->getTypoLinkParts($pharUrl); + } +} diff --git a/Tests/Unit/LinkHandling/LegacyLinkNotationConverterTest.php b/Tests/Unit/LinkHandling/LegacyLinkNotationConverterTest.php index 838f64f028..131105d022 100644 --- a/Tests/Unit/LinkHandling/LegacyLinkNotationConverterTest.php +++ b/Tests/Unit/LinkHandling/LegacyLinkNotationConverterTest.php @@ -278,4 +278,36 @@ public function splitParametersToUnifiedIdentifierForFiles($input, $parameters, $subject = new LinkService(); $this->assertEquals($expected, $subject->asString($parameters)); } + + /** + * @return array + */ + public function resolveThrowExceptionWithPharReferencesDataProvider(): array + { + return [ + 'URL encoded local' => [ + 'phar%3a//some-file.jpg', + ], + 'URL encoded absolute' => [ + 'phar%3a///path/some-file.jpg', + ], + 'not URL encoded local' => [ + 'phar://some-file.jpg', + ], + 'not URL encoded absolute' => [ + 'phar:///path/some-file.jpg', + ], + ]; + } + + /** + * @test + * @dataProvider resolveThrowExceptionWithPharReferencesDataProvider + */ + public function resolveThrowExceptionWithPharReferences(string $pharUrl) + { + $this->expectException(\RuntimeException::class); + $this->expectExceptionCode(1530030673); + (new LegacyLinkNotationConverter())->resolve($pharUrl); + } }