Browse Source

Check for directory traversal in layout paths.

Refs #3945
mark_story 11 years ago
parent
commit
fcec8ef537
2 changed files with 24 additions and 4 deletions
  1. 4 4
      src/View/View.php
  2. 20 0
      tests/TestCase/View/ViewTest.php

+ 4 - 4
src/View/View.php

@@ -923,7 +923,6 @@ class View {
 			$subDir = $this->layoutPath . DS;
 		}
 		list($plugin, $name) = $this->pluginSplit($name);
-		$paths = $this->_paths($plugin);
 
 		$layoutPaths = ['Layout' . DS . $subDir];
 		if (!empty($this->request->params['prefix'])) {
@@ -933,10 +932,11 @@ class View {
 			);
 		}
 
-		foreach ($paths as $path) {
+		foreach ($this->_paths($plugin) as $path) {
 			foreach ($layoutPaths as $layoutPath) {
-				if (file_exists($path . $layoutPath . $name . $this->_ext)) {
-					return $path . $layoutPath . $name . $this->_ext;
+				$currentPath = $path . $layoutPath;
+				if (file_exists($currentPath . $name . $this->_ext)) {
+					return $this->_checkFilePath($currentPath . $name . $this->_ext, $currentPath);
 				}
 			}
 		}

+ 20 - 0
tests/TestCase/View/ViewTest.php

@@ -614,6 +614,26 @@ class ViewTest extends TestCase {
 	}
 
 /**
+ * Test that getLayoutFileName() protects against malicious directory traversal.
+ *
+ * @expectedException Cake\View\Error\MissingViewException
+ * @return void
+ */
+	public function testGetLayoutFileNameDirectoryTraversal() {
+		$viewOptions = [
+			'plugin' => null,
+			'name' => 'Pages',
+			'viewPath' => 'Pages',
+		];
+		$request = $this->getMock('Cake\Network\Request');
+		$response = $this->getMock('Cake\Network\Response');
+
+		$view = new TestView(null, null, null, $viewOptions);
+		$view->ext('.php');
+		$view->getLayoutFileName('../../../../bootstrap');
+	}
+
+/**
  * Test for missing views
  *
  * @expectedException \Cake\View\Error\MissingViewException