Browse Source

Disallow direct controller names

Controller names with the default routing should not allow direct
plugin, or fully qualified namespace names.
mark_story 10 years ago
parent
commit
67d1c9890e

+ 3 - 0
src/Routing/Filter/ControllerFactoryFilter.php

@@ -73,6 +73,9 @@ class ControllerFactoryFilter extends DispatcherFilter
             );
             $namespace .= '/' . implode('/', $prefixes);
         }
+        if (strpos($controller, '\\') !== false || strpos($controller, '.') !== false) {
+            return false;
+        }
         $className = false;
         if ($pluginPath . $controller) {
             $className = App::classname($pluginPath . $controller, $namespace, 'Controller');

+ 48 - 1
tests/TestCase/Routing/DispatcherTest.php

@@ -23,7 +23,6 @@ use Cake\Network\Response;
 use Cake\Network\Session;
 use Cake\Routing\Dispatcher;
 use Cake\Routing\Filter\ControllerFactoryFilter;
-use Cake\Routing\Router;
 use Cake\TestSuite\TestCase;
 use Cake\Utility\Inflector;
 
@@ -410,6 +409,54 @@ class DispatcherTest extends TestCase
     }
 
     /**
+     * test forbidden controller names.
+     *
+     * @expectedException \Cake\Routing\Exception\MissingControllerException
+     * @expectedExceptionMessage Controller class TestPlugin.Tests could not be found.
+     * @return void
+     */
+    public function testDispatchBadPluginName()
+    {
+        Plugin::load('TestPlugin');
+
+        $request = new Request([
+            'url' => 'TestPlugin.Tests/index',
+            'params' => [
+                'plugin' => '',
+                'controller' => 'TestPlugin.Tests',
+                'action' => 'index',
+                'pass' => [],
+                'return' => 1
+            ]
+        ]);
+        $response = $this->getMock('Cake\Network\Response');
+        $this->dispatcher->dispatch($request, $response);
+    }
+
+    /**
+     * test forbidden controller names.
+     *
+     * @expectedException \Cake\Routing\Exception\MissingControllerException
+     * @expectedExceptionMessage Controller class TestApp\Controller\PostsController could not be found.
+     * @return void
+     */
+    public function testDispatchBadName()
+    {
+        $request = new Request([
+            'url' => 'TestApp%5CController%5CPostsController/index',
+            'params' => [
+                'plugin' => '',
+                'controller' => 'TestApp\Controller\PostsController',
+                'action' => 'index',
+                'pass' => [],
+                'return' => 1
+            ]
+        ]);
+        $response = $this->getMock('Cake\Network\Response');
+        $this->dispatcher->dispatch($request, $response);
+    }
+
+    /**
      * Test dispatcher filters being called.
      *
      * @return void