This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Default elFinder connector. |
||
5 | * |
||
6 | * @author Dmitry (dio) Levashov |
||
7 | **/ |
||
8 | class elFinderConnector |
||
0 ignored issues
–
show
|
|||
9 | { |
||
10 | /** |
||
11 | * elFinder instance. |
||
12 | * |
||
13 | * @var elFinder |
||
14 | **/ |
||
15 | protected $elFinder; |
||
16 | |||
17 | /** |
||
18 | * Options. |
||
19 | * |
||
20 | * @var aray |
||
21 | **/ |
||
22 | protected $options = []; |
||
23 | |||
24 | /** |
||
25 | * Must be use output($data) $data['header']. |
||
26 | * |
||
27 | * @var string |
||
28 | * @deprecated |
||
29 | **/ |
||
30 | protected $header = ''; |
||
31 | |||
32 | /** |
||
33 | * HTTP request method. |
||
34 | * |
||
35 | * @var string |
||
36 | */ |
||
37 | protected $reqMethod = ''; |
||
38 | |||
39 | /** |
||
40 | * Content type of output JSON. |
||
41 | * |
||
42 | * @var string |
||
43 | */ |
||
44 | protected static $contentType = 'Content-Type: application/json'; |
||
45 | |||
46 | /** |
||
47 | * Constructor. |
||
48 | * |
||
49 | * @param $elFinder |
||
50 | * @param bool $debug |
||
51 | * @author Dmitry (dio) Levashov |
||
52 | */ |
||
53 | public function __construct($elFinder, $debug = false) |
||
0 ignored issues
–
show
__construct uses the super-global variable $_SERVER which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
|||
54 | { |
||
55 | $this->elFinder = $elFinder; |
||
56 | $this->reqMethod = strtoupper($_SERVER['REQUEST_METHOD']); |
||
57 | if ($debug) { |
||
58 | self::$contentType = 'Content-Type: text/plain; charset=utf-8'; |
||
59 | } |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * Execute elFinder command and output result. |
||
64 | * |
||
65 | * @return void |
||
66 | * @author Dmitry (dio) Levashov |
||
67 | **/ |
||
68 | public function run() |
||
0 ignored issues
–
show
run uses the super-global variable $_POST which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() run uses the super-global variable $_GET which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() run uses the super-global variable $_REQUEST which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() run uses the super-global variable $_FILES which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
|||
69 | { |
||
70 | $isPost = $this->reqMethod === 'POST'; |
||
71 | $src = $isPost ? $_POST : $_GET; |
||
72 | $maxInputVars = (! $src || isset($src['targets'])) ? ini_get('max_input_vars') : null; |
||
73 | if ((! $src || $maxInputVars) && $rawPostData = file_get_contents('php://input')) { |
||
0 ignored issues
–
show
The expression
$maxInputVars of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
74 | // for max_input_vars and supports IE XDomainRequest() |
||
75 | $parts = explode('&', $rawPostData); |
||
76 | if (! $src || $maxInputVars < count($parts)) { |
||
77 | $src = []; |
||
78 | foreach ($parts as $part) { |
||
79 | list($key, $value) = array_pad(explode('=', $part), 2, ''); |
||
80 | $key = rawurldecode($key); |
||
81 | if (preg_match('/^(.+?)\[([^\[\]]*)\]$/', $key, $m)) { |
||
82 | $key = $m[1]; |
||
83 | $idx = $m[2]; |
||
84 | if (! isset($src[$key])) { |
||
85 | $src[$key] = []; |
||
86 | } |
||
87 | if ($idx) { |
||
88 | $src[$key][$idx] = rawurldecode($value); |
||
89 | } else { |
||
90 | $src[$key][] = rawurldecode($value); |
||
91 | } |
||
92 | } else { |
||
93 | $src[$key] = rawurldecode($value); |
||
94 | } |
||
95 | } |
||
96 | $_POST = $this->input_filter($src); |
||
97 | $_REQUEST = $this->input_filter(array_merge_recursive($src, $_REQUEST)); |
||
98 | } |
||
99 | } |
||
100 | |||
101 | if (isset($src['targets']) && $this->elFinder->maxTargets && count($src['targets']) > $this->elFinder->maxTargets) { |
||
102 | $error = $this->elFinder->error(elFinder::ERROR_MAX_TARGTES); |
||
0 ignored issues
–
show
$error is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
103 | $this->output(['error' => $this->elFinder->error(elFinder::ERROR_MAX_TARGTES)]); |
||
104 | } |
||
105 | |||
106 | $cmd = isset($src['cmd']) ? $src['cmd'] : ''; |
||
107 | $args = []; |
||
108 | |||
109 | if (! function_exists('json_encode')) { |
||
110 | $error = $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_JSON); |
||
111 | $this->output(['error' => '{"error":["'.implode('","', $error).'"]}', 'raw' => true]); |
||
112 | } |
||
113 | |||
114 | if (! $this->elFinder->loaded()) { |
||
115 | $this->output(['error' => $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_VOL), 'debug' => $this->elFinder->mountErrors]); |
||
116 | } |
||
117 | |||
118 | // telepat_mode: on |
||
119 | if (! $cmd && $isPost) { |
||
120 | $this->output(['error' => $this->elFinder->error(elFinder::ERROR_UPLOAD, elFinder::ERROR_UPLOAD_TOTAL_SIZE), 'header' => 'Content-Type: text/html']); |
||
121 | } |
||
122 | // telepat_mode: off |
||
123 | |||
124 | if (! $this->elFinder->commandExists($cmd)) { |
||
125 | $this->output(['error' => $this->elFinder->error(elFinder::ERROR_UNKNOWN_CMD)]); |
||
126 | } |
||
127 | |||
128 | // collect required arguments to exec command |
||
129 | $hasFiles = false; |
||
130 | foreach ($this->elFinder->commandArgsList($cmd) as $name => $req) { |
||
131 | if ($name === 'FILES') { |
||
132 | if (isset($_FILES)) { |
||
133 | $hasFiles = true; |
||
134 | } elseif ($req) { |
||
135 | $this->output(['error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)]); |
||
136 | } |
||
137 | } else { |
||
138 | $arg = isset($src[$name]) ? $src[$name] : ''; |
||
139 | |||
140 | if (! is_array($arg) && $req !== '') { |
||
141 | $arg = trim($arg); |
||
142 | } |
||
143 | if ($req && $arg === '') { |
||
144 | $this->output(['error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)]); |
||
145 | } |
||
146 | $args[$name] = $arg; |
||
147 | } |
||
148 | } |
||
149 | |||
150 | $args['debug'] = isset($src['debug']) ? (bool) $src['debug'] : false; |
||
151 | |||
152 | $args = $this->input_filter($args); |
||
153 | if ($hasFiles) { |
||
154 | $args['FILES'] = $_FILES; |
||
155 | } |
||
156 | |||
157 | $this->output($this->elFinder->exec($cmd, $args)); |
||
158 | } |
||
159 | |||
160 | /** |
||
161 | * Output JSON. |
||
162 | * |
||
163 | * @param array $data |
||
164 | */ |
||
165 | public static function outputJson($data) |
||
166 | { |
||
167 | // send header |
||
168 | $header = isset($data['header']) ? $data['header'] : self::$contentType; |
||
169 | self::sendHeader($header); |
||
170 | |||
171 | unset($data['header']); |
||
172 | |||
173 | if (! empty($data['raw']) && ! empty($data['error'])) { |
||
174 | $out = $data['error']; |
||
175 | } else { |
||
176 | if (isset($data['debug']) && isset($data['debug']['phpErrors'])) { |
||
177 | $data['debug']['phpErrors'] = array_merge($data['debug']['phpErrors'], elFinder::$phpErrors); |
||
178 | } |
||
179 | $out = json_encode($data); |
||
180 | } |
||
181 | |||
182 | // clear output buffer |
||
183 | while (ob_get_level() && ob_end_clean()) { |
||
0 ignored issues
–
show
|
|||
184 | } |
||
185 | |||
186 | header('Content-Length: '.strlen($out)); |
||
187 | |||
188 | echo $out; |
||
189 | |||
190 | flush(); |
||
191 | } |
||
192 | |||
193 | /** |
||
194 | * Output json. |
||
195 | * |
||
196 | * @param array data to output |
||
197 | * @return void |
||
198 | * @author Dmitry (dio) Levashov |
||
199 | **/ |
||
200 | protected function output(array $data) |
||
0 ignored issues
–
show
output uses the super-global variable $_SERVER which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
|||
201 | { |
||
202 | // unlock session data for multiple access |
||
203 | $this->elFinder->getSession()->close(); |
||
204 | // client disconnect should abort |
||
205 | ignore_user_abort(false); |
||
206 | |||
207 | if ($this->header) { |
||
0 ignored issues
–
show
The property
elFinderConnector::$header has been deprecated.
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
|||
208 | self::sendHeader($this->header); |
||
0 ignored issues
–
show
The property
elFinderConnector::$header has been deprecated.
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
|||
209 | } |
||
210 | |||
211 | if (isset($data['pointer'])) { |
||
212 | // set time limit to 0 |
||
213 | elFinder::extendTimeLimit(0); |
||
214 | |||
215 | // send optional header |
||
216 | if (! empty($data['header'])) { |
||
217 | self::sendHeader($data['header']); |
||
218 | } |
||
219 | |||
220 | // clear output buffer |
||
221 | while (ob_get_level() && ob_end_clean()) { |
||
0 ignored issues
–
show
|
|||
222 | } |
||
223 | |||
224 | $toEnd = true; |
||
225 | $fp = $data['pointer']; |
||
226 | if (($this->reqMethod === 'GET' || $this->reqMethod === 'HEAD') |
||
227 | && elFinder::isSeekableStream($fp) |
||
228 | && (array_search('Accept-Ranges: none', headers_list()) === false)) { |
||
229 | header('Accept-Ranges: bytes'); |
||
230 | $psize = null; |
||
231 | if (! empty($_SERVER['HTTP_RANGE'])) { |
||
232 | $size = $data['info']['size']; |
||
233 | $start = 0; |
||
0 ignored issues
–
show
$start is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
234 | $end = $size - 1; |
||
235 | if (preg_match('/bytes=(\d*)-(\d*)(,?)/i', $_SERVER['HTTP_RANGE'], $matches)) { |
||
236 | if (empty($matches[3])) { |
||
237 | if (empty($matches[1]) && $matches[1] !== '0') { |
||
238 | $start = $size - $matches[2]; |
||
239 | } else { |
||
240 | $start = intval($matches[1]); |
||
241 | if (! empty($matches[2])) { |
||
242 | $end = intval($matches[2]); |
||
243 | if ($end >= $size) { |
||
244 | $end = $size - 1; |
||
245 | } |
||
246 | $toEnd = ($end == ($size - 1)); |
||
247 | } |
||
248 | } |
||
249 | $psize = $end - $start + 1; |
||
250 | |||
251 | header('HTTP/1.1 206 Partial Content'); |
||
252 | header('Content-Length: '.$psize); |
||
253 | header('Content-Range: bytes '.$start.'-'.$end.'/'.$size); |
||
254 | |||
255 | fseek($fp, $start); |
||
256 | } |
||
257 | } |
||
258 | } |
||
259 | if (is_null($psize)) { |
||
260 | elFinder::rewind($fp); |
||
261 | } |
||
262 | } else { |
||
263 | header('Accept-Ranges: none'); |
||
264 | if (isset($data['info']) && ! $data['info']['size']) { |
||
265 | if (function_exists('header_remove')) { |
||
266 | header_remove('Content-Length'); |
||
267 | } else { |
||
268 | header('Content-Length:'); |
||
269 | } |
||
270 | } |
||
271 | } |
||
272 | |||
273 | if ($reqMethod !== 'HEAD') { |
||
0 ignored issues
–
show
|
|||
274 | View Code Duplication | if ($toEnd) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
275 | fpassthru($fp); |
||
276 | } else { |
||
277 | $out = fopen('php://output', 'wb'); |
||
278 | stream_copy_to_stream($fp, $out, $psize); |
||
0 ignored issues
–
show
The variable
$psize does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
279 | fclose($out); |
||
280 | } |
||
281 | } |
||
282 | |||
283 | if (! empty($data['volume'])) { |
||
284 | $data['volume']->close($data['pointer'], $data['info']['hash']); |
||
285 | } |
||
286 | exit(); |
||
0 ignored issues
–
show
The method
output() 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 ![]() |
|||
287 | } else { |
||
288 | self::outputJson($data); |
||
289 | exit(0); |
||
0 ignored issues
–
show
The method
output() 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 ![]() |
|||
290 | } |
||
291 | } |
||
292 | |||
293 | /** |
||
294 | * Remove null & stripslashes applies on "magic_quotes_gpc". |
||
295 | * |
||
296 | * @param mixed $args |
||
297 | * @return mixed |
||
298 | * @author Naoki Sawada |
||
299 | */ |
||
300 | protected function input_filter($args) |
||
301 | { |
||
302 | static $magic_quotes_gpc = null; |
||
303 | |||
304 | if ($magic_quotes_gpc === null) { |
||
305 | $magic_quotes_gpc = (version_compare(PHP_VERSION, '5.4', '<') && get_magic_quotes_gpc()); |
||
306 | } |
||
307 | |||
308 | if (is_array($args)) { |
||
309 | return array_map([&$this, 'input_filter'], $args); |
||
310 | } |
||
311 | $res = str_replace("\0", '', $args); |
||
312 | $magic_quotes_gpc && ($res = stripslashes($res)); |
||
313 | |||
314 | return $res; |
||
315 | } |
||
316 | |||
317 | /** |
||
318 | * Send HTTP header. |
||
319 | * |
||
320 | * @param string|array $header optional header |
||
321 | */ |
||
322 | protected static function sendHeader($header = null) |
||
323 | { |
||
324 | if ($header) { |
||
325 | if (is_array($header)) { |
||
326 | foreach ($header as $h) { |
||
327 | header($h); |
||
328 | } |
||
329 | } else { |
||
330 | header($header); |
||
331 | } |
||
332 | } |
||
333 | } |
||
334 | }// END class |
||
335 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.