diff --git a/app/Controller/PagesController.php b/app/Controller/PagesController.php index 97b782ac7..f4bc815f9 100644 --- a/app/Controller/PagesController.php +++ b/app/Controller/PagesController.php @@ -41,8 +41,9 @@ class PagesController extends AppController { * Displays a view * * @return void + * @throws ForbiddenException When a directory traversal attempt. * @throws NotFoundException When the view file could not be found - * or MissingViewException in debug mode. + * or MissingViewException in debug mode. */ public function display() { $path = func_get_args(); @@ -51,6 +52,9 @@ class PagesController extends AppController { if (!$count) { return $this->redirect('/'); } + if (in_array('..', $path, true) || in_array('.', $path, true)) { + throw new ForbiddenException(); + } $page = $subpage = $title_for_layout = null; if (!empty($path[0])) { diff --git a/lib/Cake/Console/Templates/skel/Controller/PagesController.php b/lib/Cake/Console/Templates/skel/Controller/PagesController.php index eb023a573..c97b9a281 100644 --- a/lib/Cake/Console/Templates/skel/Controller/PagesController.php +++ b/lib/Cake/Console/Templates/skel/Controller/PagesController.php @@ -32,6 +32,7 @@ class PagesController extends AppController { * Displays a view * * @return void + * @throws ForbiddenException When a directory traversal attempt. * @throws NotFoundException When the view file could not be found * or MissingViewException in debug mode. */ @@ -42,6 +43,9 @@ class PagesController extends AppController { if (!$count) { return $this->redirect('/'); } + if (in_array('..', $path, true) || in_array('.', $path, true)) { + throw new ForbiddenException(); + } $page = $subpage = $title_for_layout = null; if (!empty($path[0])) { diff --git a/lib/Cake/Test/Case/Controller/PagesControllerTest.php b/lib/Cake/Test/Case/Controller/PagesControllerTest.php index 402a27a54..887c88960 100644 --- a/lib/Cake/Test/Case/Controller/PagesControllerTest.php +++ b/lib/Cake/Test/Case/Controller/PagesControllerTest.php @@ -75,4 +75,21 @@ class PagesControllerTest extends CakeTestCase { $Pages = new PagesController(new CakeRequest(null, false), new CakeResponse()); $Pages->display('non_existing_page'); } + +/** + * Test directory traversal protection + * + * @expectedException ForbiddenException + * @expectedExceptionCode 403 + * @return void + */ + public function testDirectoryTraversalProtection() { + App::build(array( + 'View' => array( + CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS + ) + )); + $Pages = new PagesController(new CakeRequest(null, false), new CakeResponse()); + $Pages->display('..', 'Posts', 'index'); + } }