From 6a2f518e74daab1f66653299f247293b390f2fc0 Mon Sep 17 00:00:00 2001 From: Niels Keurentjes Date: Mon, 4 Dec 2017 12:36:56 +0100 Subject: [PATCH] Disallow viewing dot-files in Profiler The file viewer in the profiler should not open files that were meant to be hidden, like specifically .env files, but similarly files like .htaccess that might expose server configuration knowledge. --- .../Controller/ProfilerController.php | 2 +- .../Controller/ProfilerControllerTest.php | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php index 4aca4cc354e4..0920a1aa5e18 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php @@ -385,7 +385,7 @@ public function openAction(Request $request) $filename = $this->baseDir.DIRECTORY_SEPARATOR.$file; - if (preg_match("'(^|[/\\\\])\.\.?([/\\\\]|$)'", $file) || !is_readable($filename)) { + if (preg_match("'(^|[/\\\\])\.'", $file) || !is_readable($filename)) { throw new NotFoundHttpException(sprintf('The file "%s" cannot be opened.', $file)); } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php index 839c9f21d9fe..670f71dfc176 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php @@ -14,6 +14,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController; use Symfony\Bundle\WebProfilerBundle\Csp\ContentSecurityPolicyHandler; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Profiler\Profile; use Symfony\Component\HttpFoundation\Request; @@ -46,6 +47,42 @@ public function getEmptyTokenCases() ); } + /** + * @dataProvider getOpenFileCases + */ + public function testOpeningDisallowedPaths($path, $isAllowed) + { + $urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock(); + $twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock(); + $profiler = $this + ->getMockBuilder('Symfony\Component\HttpKernel\Profiler\Profiler') + ->disableOriginalConstructor() + ->getMock(); + + $controller = new ProfilerController($urlGenerator, $profiler, $twig, array(), 'bottom', null, __DIR__.'/../..'); + + try { + $response = $controller->openAction(Request::create('/_wdt/open', Request::METHOD_GET, array('file' => $path))); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertTrue($isAllowed); + } catch (NotFoundHttpException $e) { + $this->assertFalse($isAllowed); + } + } + + public function getOpenFileCases() + { + return array( + array('README.md', true), + array('composer.json', true), + array('Controller/ProfilerController.php', true), + array('.gitignore', false), + array('../TwigBundle/README.md', false), + array('Controller/../README.md', false), + array('Controller/./ProfilerController.php', false), + ); + } + /** * @dataProvider provideCspVariants */