PluginProbe
CSS & JavaScript Toolbox / trunk
CSS & JavaScript Toolbox vtrunk
trunk 0.3 0.8 10 10.1 11 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 11.9.1 12 12.0 12.0.1 12.0.3 12.0.4 12.0.5 12.0.6 12.0.7 6.0 6.0.11 All 60 releases
← All changes | framework/mvc/controller.inc.php +108 -71 11trunk View file →
@@ -11,43 +11,43 @@
11 11 /**
12 12 * CJT controller base class.
13 13 */
14 14 abstract class CJTController extends CJTHookableClass {
15 -
15 +
16 16 /** */
17 17 const NONCE_ACTION = 'cjtoolbox';
18 -
18 +
19 19 /**
20 20 * put your comment there...
21 - *
21 + *
22 22 * @var mixed
23 23 */
24 24 protected $action;
25 -
25 +
26 26 /**
27 27 * put your comment there...
28 - *
28 + *
29 29 * @var mixed
30 30 */
31 31 protected $controllerInfo = null;
32 -
32 +
33 33 /**
34 34 * put your comment there...
35 - *
35 + *
36 36 * @var mixed
37 37 */
38 38 protected $defaultAction = 'index';
39 -
39 +
40 40 /**
41 41 * put your comment there...
42 - *
42 + *
43 43 * @var mixed
44 44 */
45 45 protected $request;
46 -
46 +
47 47 /**
48 48 * put your comment there...
49 - *
49 + *
50 50 * @var mixed
51 51 */
52 52 protected $model = null;
53 53
@@ -52,51 +52,51 @@
52 52 protected $model = null;
53 53
54 54 /**
55 55 * put your comment there...
56 - *
56 + *
57 57 * @var mixed
58 58 */
59 59 protected $oncallback = array('parameters' => array('callback', 'action', 'args'));
60 -
60 +
61 61 /**
62 62 * put your comment there...
63 - *
63 + *
64 64 * @var mixed
65 65 */
66 66 protected $ongetactionname = array('parameters' => array('action'));
67 -
67 +
68 68 /**
69 69 * put your comment there...
70 - *
70 + *
71 71 * @var mixed
72 72 */
73 73 protected static $ongetclassname = array('parameters' => array('class', 'name', 'type'));
74 -
74 +
75 75 /**
76 76 * put your comment there...
77 - *
77 + *
78 78 * @var mixed
79 79 */
80 80 protected $ongetviewname = array('parameters' => array('view'));
81 -
81 +
82 82 /**
83 83 * put your comment there...
84 - *
84 + *
85 85 * @var mixed
86 86 */
87 87 protected static $onloadcontroller = array('parameters' => array('file', 'name'));
88 -
88 +
89 89 /**
90 90 * put your comment there...
91 - *
91 + *
92 92 * @var mixed
93 93 */
94 94 protected $view = null;
95 -
95 +
96 96 /**
97 97 * put your comment there...
98 - *
98 + *
99 99 * @param mixed $hasView
100 100 * @param mixed $request
101 101 * @param mixed $overrideControllerPath
102 102 * @param mixed $overrideContollerPrefix
@@ -101,16 +101,18 @@
101 101 * @param mixed $overrideControllerPath
102 102 * @param mixed $overrideContollerPrefix
103 103 * @return CJTController
104 104 */
105 - public function __construct($hasView = null,
106 - $request = null,
107 - $overrideControllerPath = null,
105 + public function __construct($hasView = null,
106 + $request = null,
107 + $overrideControllerPath = null,
108 108 $overrideContollerPrefix = null) {
109 109 // Initialize hookable!
110 110 parent::__construct();
111 111 // Read request parameters.
112 112 $this->request = array_merge(((array) $_REQUEST), ((array) $request));
113 +
114 + $overrideControllerPath = $overrideControllerPath ? null : '';
113 115 // Create default model.
114 116 if (isset($this->controllerInfo['model'])) {
115 117 // E_ALL complain!
116 118 if (!isset($this->controllerInfo['model_file'])) {
@@ -115,10 +117,10 @@
115 117 // E_ALL complain!
116 118 if (!isset($this->controllerInfo['model_file'])) {
117 119 $this->controllerInfo['model_file'] = null;
118 120 }
119 - $this->model = CJTModel::create($this->controllerInfo['model'],
120 - $this->request,
121 + $this->model = CJTModel::create($this->controllerInfo['model'],
122 + $this->request,
121 123 $this->controllerInfo['model_file'],
122 124 dirname($overrideControllerPath),
123 125 $overrideContollerPrefix);
124 126 }
@@ -124,14 +126,14 @@
124 126 }
125 127 // Create default view.
126 128 if ($hasView === null) { // Default value for $hasView = true
127 129 // Request/passed parameters has priority over controller default view!
128 - $view = $this->ongetviewname(isset($this->request['view']) ? $this->request['view'] :
130 + $view = $this->ongetviewname(isset($this->request['view']) ? esc_html($this->request['view']) :
129 131 (isset($this->controllerInfo['view']) ? $this->controllerInfo['view'] : null)
130 132 );
131 133 if ($view) {
132 - $this->view = self::getView($view,
133 - null,
134 + $this->view = self::getView($view,
135 + null,
134 136 dirname($overrideControllerPath),
135 137 $overrideContollerPrefix)
136 138 // Push data into view.
137 139 ->setModel($this->model)
@@ -138,18 +140,18 @@
138 140 ->setRequest($this->request);
139 141 }
140 142 }
141 143 }
142 -
144 +
143 145 /**
144 146 * put your comment there...
145 - *
147 + *
146 148 */
147 149 public function _doAction() {
148 150 // Force use of internal action untless its empty
149 151 // then look for submitted action or get the default!
150 - $action = $this->action ? $this->action :
151 - (isset($_GET['action']) ? $_GET['action'] : $this->defaultAction);
152 + $action = $this->action ? $this->action :
153 + (isset($_GET['action']) ? esc_html($_GET['action']) : $this->defaultAction);
152 154 // filter action name!
153 155 $action = $this->ongetactionname($action);
154 156 if ($action) {
155 157 $actionHandler = "{$action}Action";
@@ -158,12 +160,12 @@
158 160 // Callback!
159 161 call_user_func($callback);
160 162 }
161 163 }
162 -
164 +
163 165 /**
164 166 * put your comment there...
165 - *
167 + *
166 168 * @param mixed $name
167 169 * @param mixed $hasView
168 170 * @param mixed $request
169 171 * @param mixed $overrideControllersPath
@@ -168,13 +170,18 @@
168 170 * @param mixed $request
169 171 * @param mixed $overrideControllersPath
170 172 * @param mixed $overrideControllersPrefix
171 173 */
172 - public static function create($name,
173 - $hasView = null,
174 - $request = null,
174 + public static function create($name,
175 + $hasView = null,
176 + $request = null,
175 177 $overrideControllersPath = null,
176 178 $overrideControllersPrefix = null) {
179 + // Validate controller name to prevent path traversal attacks
180 + if (!self::isValidControllerName($name)) {
181 + throw new Exception('Invalid controller name: ' . esc_html($name));
182 + }
183 +
177 184 // Import controller file.
178 185 $pathToControllers = $overrideControllersPath ? $overrideControllersPath : CJTOOLBOX_CONTROLLERS_PATH;
179 186 $controllerFile = "{$pathToControllers}/{$name}.php";
180 187 require_once self::trigger('CJTController.loadcontroller', $controllerFile, $name);
@@ -182,12 +189,42 @@
182 189 $class = self::getClassName($name, 'Controller', $overrideControllersPrefix);
183 190 // Instantiate controller class.
184 191 return new $class($hasView, $request, $overrideControllersPath, $overrideControllersPrefix);
185 192 }
186 -
193 +
187 194 /**
195 + * Validate controller name to prevent path traversal attacks
196 + *
197 + * @param string $name Controller name to validate
198 + * @return bool True if valid, false otherwise
199 + */
200 + private static function isValidControllerName($name) {
201 + // Check for null or empty string
202 + if (empty($name) || !is_string($name)) {
203 + return false;
204 + }
205 +
206 + // Check for path traversal attempts
207 + if (strpos($name, '..') !== false) {
208 + return false;
209 + }
210 +
211 + // Check for directory separators
212 + if (strpos($name, '/') !== false || strpos($name, '\\') !== false) {
213 + return false;
214 + }
215 +
216 + // Only allow alphanumeric characters, hyphens, and underscores
217 + if (!preg_match('/^[a-zA-Z0-9_-]+$/', $name)) {
218 + return false;
219 + }
220 +
221 + return true;
222 + }
223 +
224 + /**
188 225 * put your comment there...
189 - *
226 + *
190 227 * @deprecated Use cssJSToolbox::createSecurityToken
191 228 */
192 229 public function createSecurityToken() {
193 230 return wp_create_nonce(self::NONCE_ACTION);
@@ -194,13 +231,13 @@
194 231 }
195 232
196 233 /**
197 234 * put your comment there...
198 - *
235 + *
199 236 */
200 237 protected function displayAction() {
201 238 // Get view layout!
202 - $layout = isset($this->request['layout']) ? $this->request['layout'] : 'default';
239 + $layout = isset($this->request['layout']) ? esc_html($this->request['layout']) : 'default';
203 240 ob_start();
204 241 $this->view->display($layout);
205 242 $content = ob_get_clean();
206 243 return $content;
@@ -207,9 +244,9 @@
207 244 }
208 245
209 246 /**
210 247 * put your comment there...
211 - *
248 + *
212 249 * @param mixed $name
213 250 * @param mixed $hasView
214 251 * @param mixed $request
215 252 * @param mixed $overrideControllersPath
@@ -214,22 +251,22 @@
214 251 * @param mixed $request
215 252 * @param mixed $overrideControllersPath
216 253 */
217 254 public static function getInstance($name,
218 - $hasView = null,
219 - $request = null,
255 + $hasView = null,
256 + $request = null,
220 257 $overrideControllersPath = null,
221 258 $overrideControllersPrefix = null) {
222 259 return self::create($name, $hasView, $request, $overrideControllersPath, $overrideControllersPrefix);
223 260 }
224 -
261 +
225 262 /**
226 263 * Use CJTModel::create instead.
227 - *
264 + *
228 265 * @deprecated No longer used.
229 266 */
230 - public static function getModel($name,
231 - $params = array(),
267 + public static function getModel($name,
268 + $params = array(),
232 269 $file = null,
233 270 $overrideModelsPath = null,
234 271 $overrideModelsPrefix = null) {
235 272 $model = null;
@@ -247,9 +284,9 @@
247 284 }
248 285 $model = new $modelClass($params);
249 286 return $model;
250 287 }
251 -
288 +
252 289 /**
253 290 * @deprecated No longer used.
254 291 */
255 292 public static function getClassName($name, $type, $prefix = null) {
@@ -266,27 +303,27 @@
266 303 // Filter.
267 304 $className = self::trigger('CJTController.getclassname', "{$prefix}{$sanitizedName}", $name, $type);
268 305 return $className;
269 306 }
270 -
307 +
271 308 /**
272 309 * put your comment there...
273 - *
310 + *
274 311 * @param mixed $name
275 312 */
276 313 public function getRequestParameter($name) {
277 - return isset($this->request[$name]) ? $this->request[$name] : null;
314 + return isset($this->request[$name]) ? esc_html($this->request[$name]) : null;
278 315 }
279 -
316 +
280 317 /**
281 - *
318 + *
282 319 * Use CJTView:create instrad.
283 - *
320 + *
284 321 * @deprecated
285 322 */
286 - public static function getView($path,
287 - $params = null,
288 - $overrideViewsPath = null,
323 + public static function getView($path,
324 + $params = null,
325 + $overrideViewsPath = null,
289 326 $overrideViewsPrefix = null) {
290 327 $view = null;
291 328 // Import view file.
292 329 $viewInfo = self::getViewInfo($path, $overrideViewsPath, $overrideViewsPrefix);
@@ -296,16 +333,16 @@
296 333 $viewClass = self::getClassName($name, 'view', $overrideViewsPrefix);
297 334 $view = new $viewClass($viewInfo, $params);
298 335 return $view;
299 336 }
300 -
337 +
301 338 /**
302 339 * put your comment there...
303 - *
340 + *
304 341 */
305 342 public static function getViewInfo($path, $overrideViewsPath = null, $overrideViewsPrefix = null) {
306 343 // Plugin views Url
307 - $viewsUrl = $overrideViewsPath ?
344 + $viewsUrl = $overrideViewsPath ?
308 345 WP_PLUGIN_URL . '/' . basename(dirname($overrideViewsPath)) :
309 346 CJTOOLBOX_VIEWS_URL;
310 347 // Path to views dir.
311 348 $pathToViews = $overrideViewsPath ? ($overrideViewsPath . DIRECTORY_SEPARATOR . 'views') : CJTOOLBOX_VIEWS_PATH;
@@ -321,12 +358,12 @@
321 358 'viewFile' => "{$pathToViews}/{$path}/view.php",
322 359 );
323 360 return $viewInfo;
324 361 }
325 -
362 +
326 363 /**
327 364 * put your comment there...
328 - *
365 + *
329 366 * @param mixed $action
330 367 */
331 368 public function setAction($action) {
332 369 $this->action = $action;
@@ -331,12 +368,12 @@
331 368 public function setAction($action) {
332 369 $this->action = $action;
333 370 return $this;
334 371 }
335 -
372 +
336 373 /**
337 374 * put your comment there...
338 - *
375 + *
339 376 * @param mixed $name
340 377 * @param mixed $value
341 378 */
342 379 public function setRequestParameter($name, $value) {
@@ -342,9 +379,9 @@
342 379 public function setRequestParameter($name, $value) {
343 380 $this->request[$name] = $value;
344 381 return $this;
345 382 }
346 -
383 +
347 384 } // End class.
348 385
349 386 // Hookable!
350 -CJTController::define('CJTController', array('hookType' => CJTWordpressEvents::HOOK_FILTER));
387 +CJTController::define('CJTController', array('hookType' => CJTWordpressEvents::HOOK_FILTER));