Issues (25)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Mvc/Controller/AbstractController.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Nkey\Caribu\Mvc\Controller;
3
4
use \Nkey\Caribu\Mvc\View\View;
5
use Nkey\Caribu\Mvc\View\Control;
6
use Nkey\Caribu\Mvc\Application;
7
8
/**
9
 * Basic controller functionality
10
 *
11
 * This class provides the basic functionality each controller
12
 * needs to work correctly.
13
 *
14
 * The controller call will be performed by Application::serve().
15
 *
16
 * All basic functions are final and cannot be overriden.
17
 *
18
 * @author Maik Greubel <[email protected]>
19
 *
20
 *         This file is part of Caribu MVC package
21
 */
22
abstract class AbstractController
23
{
24
25
    /**
26
     * Class of controller
27
     *
28
     * @var string
29
     */
30
    private $controllerClass = '';
31
32
    /**
33
     * Name of controller
34
     *
35
     * @var string
36
     */
37
    private $controllerName = '';
38
39
    /**
40
     * List of actions provided by controller
41
     *
42
     * @var array
43
     */
44
    private $actions = null;
45
46
    /**
47
     * Request
48
     *
49
     * @var \Nkey\Caribu\Mvc\Controller\Request
50
     */
51
    private $request;
52
53
    /**
54
     * Response
55
     *
56
     * @var \Nkey\Caribu\Mvc\Controller\Response
57
     */
58
    protected $response;
59
60
    /**
61
     * View parameters
62
     *
63
     * @var array
64
     */
65
    protected $viewParams = array();
66
67
    /**
68
     * Parse the parameters of action
69
     *
70
     * @param \ReflectionMethod $action
71
     *
72
     * @return boolean true if parameters meets conditions for a valid action method, false otherwise
73
     */
74 29
    private function parseParameters(\ReflectionMethod $action)
75
    {
76 29
        $params = $action->getParameters();
77 29
        if (count($params) < 1) {
78 22
            return false;
79
        }
80
        
81 29
        $param = $params[0];
82 29
        assert($param instanceof \ReflectionParameter);
83 29
        if (! ($class = $param->getClass()) || $class->getName() != 'Nkey\Caribu\Mvc\Controller\Request') {
84 22
            return false;
85
        }
86
        
87 29
        return true;
88
    }
89
90
    /**
91
     * Parse the settings out of annotations
92
     *
93
     * @param \ReflectionMethod $action
94
     */
95 29
    private function parseAnnotations(\ReflectionMethod $action)
96
    {
97 29
        if ($action->isConstructor() || $action->isDestructor() || $action->isStatic() || $action->isFinal()) {
98 29
            return;
99
        }
100
        
101 29
        $rfMethod = new \ReflectionMethod($this, $action->name);
102 29
        $anno = $rfMethod->getDocComment();
103
        
104 29
        if ($anno && preg_match('#@webMethod#', $anno)) {
105 29
            $this->actions[] = $action->name;
106 29
            return;
107
        }
108
        
109 29
        if (! $this->parseParameters($action)) {
110 22
            return;
111
        }
112
        
113 29
        $this->actions[] = $action->name;
114 29
    }
115
116
    /**
117
     * Get the controller prepared for service
118
     *
119
     * @return \Nkey\Caribu\Mvc\Controller\AbstractController The controller instance
120
     */
121 29
    final public function getControllerSettings()
122
    {
123 29
        $rf = new \ReflectionClass($this);
124
        
125 29
        $this->response = new Response();
126 29
        $this->controllerClass = $rf->getShortName();
127 29
        $this->controllerName = ucfirst(str_replace('Controller', '', $this->controllerClass));
128 29
        $this->response->setTitle($this->controllerName);
129
        
130 29
        $actions = $rf->getMethods(\ReflectionMethod::IS_PUBLIC);
131
        
132 29
        foreach ($actions as $action) {
133 29
            $this->parseAnnotations($action);
134
        }
135
        
136 29
        return $this;
137
    }
138
139
    /**
140
     * Checks whether controller has specific action
141
     *
142
     * @param string $action
143
     *            Name of action to search for
144
     *
145
     * @return boolean true if the action exists in controller, false otherwise
146
     */
147 19
    final public function hasAction($action)
148
    {
149 19
        return array_search($action, $this->actions) !== false;
150
    }
151
152
    /**
153
     * Call the action
154
     *
155
     * @param string $action
156
     *            The name of action to call in controller
157
     *
158
     * @return \Nkey\Caribu\Mvc\Controller\Response The response
159
     */
160 20
    final public function call($action, Request $request, View $view)
161
    {
162 20
        $this->request = $request;
163
        
164 20
        ob_start();
165
        
166 20
        $rf = new \ReflectionMethod($this, $action);
167
        
168 20
        $anno = $rf->getDocComment();
169 20
        $matches = array();
170 20
        if (preg_match('#@responseType ([\w\/]+)#', $anno, $matches)) {
171 2
            $this->response->setType($matches[1]);
172
        }
173
        
174 20
        if (preg_match('#@title ([^\\n]+)#', $anno, $matches)) {
175 3
            $this->response->setTitle($matches[1]);
176
        }
177
        
178 20
        $rf->invoke($this, $this->request);
179
        
180 20
        $this->response->appendBody(ob_get_clean());
181
        
182 20
        $view->render($this->response, $request, $this->viewParams);
183 20
        $this->addControls($this->response, $request, $view);
184
        
185 20
        return $this->response;
186
    }
187
188
    /**
189
     * Retrieve the simple name of controller
190
     *
191
     * @return string Name of controller
192
     */
193 29
    final public function getControllerSimpleName()
194
    {
195 29
        return $this->controllerName;
196
    }
197
198
    /**
199
     * Add the controls injected into view parameters
200
     *
201
     * @param Response $response
202
     *            The response rendered with controls
203
     * @param Request $request
204
     *            The request
205
     * @param View $view
206
     *            The View instance to use for rendering
207
     */
208 20
    protected function addControls(Response &$response, Request $request, View $view)
209
    {
210 20
        $matches = array();
211
        
212 20
        while (preg_match("/\{(\w+)=(\w+)\}/", $response->getBody(), $matches)) {
213 3
            $controlIdentifier = $matches[1];
214 3
            $controlName = $matches[2];
215 3
            $currentBody = $response->getBody();
216
            
217 3
            if (! isset($this->viewParams[$controlIdentifier][$controlName])
218 3
				|| ! $view->hasControl($controlIdentifier)) {
219 1
                $response->setBody(str_replace($matches[0], '', $currentBody));
220 1
                continue;
221
            }
222
            
223 2
            if ($this->viewParams[$controlIdentifier][$controlName] instanceof Control) {
224 1
                $repl = $this->viewParams[$controlIdentifier][$controlName]->render($request);
225
            } else {
226 1
                $control = $view->createControl($controlIdentifier);
227 1
                $repl = $control->render($request, $this->viewParams[$controlIdentifier][$controlName]);
228
            }
229 2
            $response->setBody(str_replace($matches[0], $repl, $currentBody));
230
        }
231 20
    }
232
233
    /**
234
     * Redirects the current request to another site
235
     *
236
     * @param string $controller
237
     *            The name of Controller to
238
     * @param string $action
239
     */
240
    protected function redirect($controller = null, $action = null)
241
    {
242
        if (null === $controller) {
243
            $controller = Application::getInstance()->getDefaultController();
244
        }
245
        if (null === $action) {
246
            $action = Application::getInstance()->getDefaultAction();
247
        }
248
        $destination = sprintf("Location: %s%s/%s", $this->request->getContextPrefix(), $controller, $action);
249
        header($destination);
250
        exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method redirect() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
251
    }
252
}
253