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 | * ajaxfileedit.php - backend upload attachments and update file info |
||
4 | * |
||
5 | * @copyright Copyright © 2013 geekwright, LLC. All rights reserved. |
||
6 | * @license gwiki/docs/license.txt GNU General Public License (GPL) |
||
7 | * @since 1.0 |
||
8 | * @author Richard Griffith <[email protected]> |
||
9 | * @package gwiki |
||
10 | */ |
||
11 | include __DIR__ . '/../../mainfile.php'; |
||
12 | $xoopsLogger->activated = false; |
||
13 | // provide error logging for our sanity in debugging ajax use (won't see xoops logger) |
||
14 | restore_error_handler(); |
||
15 | error_reporting(-1); |
||
16 | |||
17 | $dir = basename(__DIR__); |
||
18 | require_once XOOPS_ROOT_PATH . '/modules/' . $dir . '/class/GwikiPage.php'; |
||
19 | global $wikiPage; |
||
20 | $wikiPage = new GwikiPage; |
||
21 | |||
22 | $uploadpath = XOOPS_ROOT_PATH . "/uploads/{$dir}/"; |
||
23 | $uploadurl = XOOPS_URL . "/uploads/{$dir}/"; |
||
24 | |||
25 | $newfile = (isset($_SERVER['HTTP_GW_FILENAME']) ? $_SERVER['HTTP_GW_FILENAME'] : false); |
||
26 | $jsondata = (isset($_SERVER['HTTP_GW_JSONDATA']) ? $_SERVER['HTTP_GW_JSONDATA'] : false); |
||
27 | |||
28 | // initialize whitelist |
||
29 | $whitelist = array(); |
||
30 | $wlconfig = $xoopsModuleConfig['attach_ext_whitelist']; |
||
31 | //$wlconfig='txt,pdf,doc,docx,xls,rtf,zip'; |
||
32 | |||
33 | // populate whitelist |
||
34 | if (!empty($wlconfig)) { |
||
35 | $whitelist = explode(',', $wlconfig); |
||
36 | } |
||
37 | |||
38 | /** |
||
39 | * @param $filename |
||
40 | * |
||
41 | * @return array|bool |
||
42 | */ |
||
43 | function getExtensionInfo($filename) |
||
44 | { |
||
45 | global $whitelist; |
||
46 | |||
47 | $fi = array(); |
||
48 | |||
49 | // these choices are just from our icon set - nothing magic, just ext => filename - .png |
||
50 | $icons = array( |
||
51 | 'aac' => 'aac', |
||
52 | 'aiff' => 'aiff', |
||
53 | 'ai' => 'ai', |
||
54 | 'avi' => 'avi', |
||
55 | 'bmp' => 'bmp', |
||
56 | 'c' => 'c', |
||
57 | 'cpp' => 'cpp', |
||
58 | 'css' => 'css', |
||
59 | 'dat' => 'dat', |
||
60 | 'dmg' => 'dmg', |
||
61 | 'doc' => 'doc', |
||
62 | 'docx' => 'doc', |
||
63 | 'dot' => 'dotx', |
||
64 | 'dotx' => 'dotx', |
||
65 | 'dwg' => 'dwg', |
||
66 | 'dxf' => 'dxf', |
||
67 | 'eps' => 'eps', |
||
68 | 'exe' => 'exe', |
||
69 | 'flv' => 'flv', |
||
70 | 'gif' => 'gif', |
||
71 | 'h' => 'h', |
||
72 | 'hpp' => 'hpp', |
||
73 | 'htm' => 'html', |
||
74 | 'html' => 'html', |
||
75 | 'ics' => 'ics', |
||
76 | 'iso' => 'iso', |
||
77 | 'java' => 'java', |
||
78 | 'jpe' => 'jpg', |
||
79 | 'jpeg' => 'jpg', |
||
80 | 'jpg' => 'jpg', |
||
81 | 'key' => 'key', |
||
82 | 'mid' => 'mid', |
||
83 | 'mp3' => 'mp3', |
||
84 | 'mp4' => 'mp4', |
||
85 | 'mpg' => 'mpg', |
||
86 | 'odf' => 'odf', |
||
87 | 'ods' => 'ods', |
||
88 | 'odt' => 'odt', |
||
89 | 'otp' => 'otp', |
||
90 | 'ots' => 'ots', |
||
91 | 'ott' => 'ott', |
||
92 | 'pdf' => 'pdf', |
||
93 | 'php' => 'php', |
||
94 | 'png' => 'png', |
||
95 | 'ppt' => 'ppt', |
||
96 | 'psd' => 'psd', |
||
97 | 'py' => 'py', |
||
98 | 'qt' => 'qt', |
||
99 | 'rar' => 'rar', |
||
100 | 'rb' => 'rb', |
||
101 | 'rtf' => 'rtf', |
||
102 | 'sql' => 'sql', |
||
103 | 'tga' => 'tga', |
||
104 | 'tgz' => 'tgz', |
||
105 | 'tif' => 'tiff', |
||
106 | 'tiff' => 'tiff', |
||
107 | 'txt' => 'txt', |
||
108 | 'wav' => 'wav', |
||
109 | 'xls' => 'xls', |
||
110 | 'xlsx' => 'xlsx', |
||
111 | 'xml' => 'xml', |
||
112 | 'yml' => 'yml', |
||
113 | 'zip' => 'zip', |
||
114 | ); |
||
115 | // Also have files '_blank' '_page' |
||
116 | |||
117 | $path_parts = pathinfo($filename); |
||
118 | // =$path_parts['dirname'], "\n"; |
||
119 | $fi['file_name'] = $path_parts['basename']; |
||
120 | if (!isset($path_parts['extension'])) { |
||
121 | $ext = ''; |
||
122 | } else { |
||
123 | $ext = strtolower($path_parts['extension']); |
||
124 | } |
||
125 | //=$path_parts['filename']; |
||
126 | |||
127 | // if no name, or not on whitelist reject |
||
128 | if (empty($path_parts['filename']) || array_search($ext, $whitelist) === false) { |
||
129 | return false; |
||
130 | } |
||
131 | |||
132 | if (empty($ext)) { |
||
133 | $fi['file_icon'] = '_blank'; |
||
134 | } else { |
||
135 | if (empty($icons[$ext])) { |
||
136 | $fi['file_icon'] = '_blank'; |
||
137 | } else { |
||
138 | $fi['file_icon'] = $icons[$ext]; |
||
139 | } |
||
140 | } |
||
141 | |||
142 | return $fi; |
||
143 | } |
||
144 | |||
145 | /** |
||
146 | * @param $filename |
||
147 | * |
||
148 | * @return array |
||
149 | */ |
||
150 | function getFileInfo($filename) |
||
151 | { |
||
152 | $fi = array(); |
||
153 | |||
154 | if (function_exists('finfo_open')) { |
||
155 | $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension |
||
156 | $fi['file_type'] = finfo_file($finfo, $filename); |
||
157 | finfo_close($finfo); |
||
158 | } else { |
||
159 | $fi['file_type'] = mime_content_type($filename); |
||
160 | } |
||
161 | $fi['file_size'] = filesize($filename); |
||
162 | |||
163 | return $fi; |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * @param $string |
||
168 | * |
||
169 | * @return string |
||
170 | */ |
||
171 | View Code Duplication | function cleaner($string) |
|
0 ignored issues
–
show
The function
cleaner() has been defined more than once; this definition is ignored, only the first definition in admin/prefixes.php (L601-612) is considered.
This check looks for functions that have already been defined in other files. Some Codebases, like WordPress, make a practice of defining functions multiple times. This
may lead to problems with the detection of function parameters and types. If you really
need to do this, you can mark the duplicate definition with the /**
* @ignore
*/
function getUser() {
}
function getUser($id, $realm) {
}
See also the PhpDoc documentation for @ignore. ![]() |
|||
172 | { |
||
173 | $string = stripcslashes($string); |
||
174 | $string = html_entity_decode($string); |
||
175 | $string = strip_tags($string); // DANGER -- kills wiki text |
||
176 | $string = trim($string); |
||
177 | $string = stripslashes($string); |
||
178 | |||
179 | return $string; |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * @param $uid |
||
184 | * |
||
185 | * @return string |
||
186 | */ |
||
187 | function getUserName($uid) |
||
188 | { |
||
189 | global $xoopsConfig; |
||
190 | |||
191 | $uid = (int)$uid; |
||
192 | |||
193 | if ($uid > 0) { |
||
194 | $memberHandler = xoops_getHandler('member'); |
||
195 | $user = $memberHandler->getUser($uid); |
||
196 | if (is_object($user)) { |
||
197 | return "<a href=\"" . XOOPS_URL . "/userinfo.php?uid=$uid\">" . htmlspecialchars($user->getVar('uname'), ENT_QUOTES) . '</a>'; |
||
198 | } |
||
199 | } |
||
200 | |||
201 | return $xoopsConfig['anonymous']; |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * @param $input |
||
206 | * |
||
207 | * @return mixed |
||
208 | */ |
||
209 | View Code Duplication | function deleteData(&$input) |
|
0 ignored issues
–
show
This function seems to be duplicated in 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. ![]() |
|||
210 | { |
||
211 | global $xoopsDB, $uploadpath, $wikiPage; |
||
212 | |||
213 | $q_file_id = (int)$input['file_id']; |
||
214 | // use keyword in delete so we know id and edit authority are connected |
||
215 | $q_keyword = $wikiPage->escapeForDB($input['page']); |
||
216 | |||
217 | // look up the name and delete the image file |
||
218 | $sql = 'SELECT file_path FROM ' . $xoopsDB->prefix('gwiki_page_files') . " where file_id='{$q_file_id}' AND keyword = '{$q_keyword}' "; |
||
219 | |||
220 | $result = $xoopsDB->query($sql); |
||
221 | if ($result) { |
||
222 | $rows = $xoopsDB->getRowsNum($result); |
||
223 | if ($rows) { |
||
224 | $myrow = $xoopsDB->fetchArray($result); |
||
225 | if (!empty($myrow['file_path'])) { |
||
226 | $oldfilename = $uploadpath . '/' . $myrow['file_path']; |
||
227 | unlink($oldfilename); |
||
228 | } |
||
229 | } |
||
230 | } |
||
231 | |||
232 | // delete the row |
||
233 | $sql = 'DELETE FROM ' . $xoopsDB->prefix('gwiki_page_files') . " where file_id='{$q_file_id}' AND keyword = '{$q_keyword}' "; |
||
234 | |||
235 | $result = $xoopsDB->queryF($sql); |
||
236 | $cnt = $xoopsDB->getAffectedRows(); |
||
237 | if ($cnt) { |
||
238 | $input['message'] = _MD_GWIKI_AJAX_FILEEDIT_DEL_OK; |
||
239 | } |
||
240 | |||
241 | return $result; |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * @param $input |
||
246 | * |
||
247 | * @return mixed |
||
248 | */ |
||
249 | function updateData(&$input) |
||
250 | { |
||
251 | global $xoopsDB, $xoopsUser, $wikiPage; |
||
252 | |||
253 | $q_file_id = (int)$input['file_id']; |
||
254 | $q_keyword = $wikiPage->escapeForDB($input['page']); |
||
255 | $q_file_name = $wikiPage->escapeForDB($input['file_name']); |
||
256 | $q_file_icon = $wikiPage->escapeForDB($input['file_icon']); |
||
257 | $q_file_type = $wikiPage->escapeForDB($input['file_type']); |
||
258 | $q_file_description = $wikiPage->escapeForDB($input['file_description']); |
||
259 | // file_path only changed by image upload |
||
260 | $q_file_size = (int)$input['file_size']; |
||
261 | $q_file_path = empty($input['file_path']) ? '' : $wikiPage->escapeForDB($input['file_path']); |
||
262 | $q_file_uid = $xoopsUser ? $xoopsUser->getVar('uid') : 0; |
||
263 | $input['file_uid'] = $q_file_uid; |
||
264 | if ((int)$input['file_upload_date'] === 0) { |
||
265 | $input['file_upload_date'] = time(); |
||
266 | } |
||
267 | $q_file_upload_date = $input['file_upload_date']; |
||
268 | |||
269 | $sql = 'UPDATE ' . $xoopsDB->prefix('gwiki_page_files') . ' SET '; |
||
270 | $sql .= " file_name = '{$q_file_name}', "; |
||
271 | $sql .= " file_icon = '{$q_file_icon}', "; |
||
272 | $sql .= " file_type = '{$q_file_type}', "; |
||
273 | $sql .= " file_size = '{$q_file_size}', "; |
||
274 | $sql .= " file_path = '{$q_file_path}', "; |
||
275 | $sql .= " file_uid = '{$q_file_uid}', "; |
||
276 | // $sql.= " file_uid = '{$q_file_upload_date}', "; |
||
277 | $sql .= " file_description = '{$q_file_description}' "; |
||
278 | $sql .= " where file_id = '{$q_file_id}' AND keyword = '{$q_keyword}' "; |
||
279 | |||
280 | $result = $xoopsDB->queryF($sql); |
||
281 | if (!$result) { |
||
282 | header('Status: 500 Internal Error - Database Error'); |
||
283 | $out['message'] === $xoopsDB->error(); |
||
0 ignored issues
–
show
|
|||
284 | echo json_encode($out); |
||
285 | exit; |
||
286 | } |
||
287 | $cnt = $xoopsDB->getAffectedRows(); |
||
288 | if (!$cnt) { |
||
289 | $input['message'] = _MD_GWIKI_AJAX_FILEEDIT_NOT_DEFINED; |
||
290 | } else { |
||
291 | $input['message'] = _MD_GWIKI_AJAX_FILEEDIT_UPD_OK; |
||
292 | } |
||
293 | |||
294 | //file_id, keyword, file_name, file_path, file_type, file_icon, file_size, file_upload_date, file_description, file_uid |
||
295 | |||
296 | if ($result && !$cnt && !empty($q_file_path)) { // database is OK but nothing to update - require file_path |
||
297 | $sql = 'insert into ' . $xoopsDB->prefix('gwiki_page_files'); |
||
298 | $sql .= ' (keyword, file_name, file_path, file_type, file_icon, file_size, file_upload_date, file_description, file_uid) '; |
||
299 | $sql .= " values ('{$q_keyword}', '{$q_file_name}', '{$q_file_path}', '{$q_file_type}', '{$q_file_icon}', '{$q_file_size}', $q_file_upload_date, '{$q_file_description}', '{$q_file_uid}' )"; |
||
300 | $result = $xoopsDB->queryF($sql); |
||
0 ignored issues
–
show
$result 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 ![]() |
|||
301 | $input['file_id'] = $xoopsDB->getInsertId(); |
||
302 | $input['message'] = _MD_GWIKI_AJAX_FILEEDIT_ADD_OK; |
||
303 | } |
||
304 | |||
305 | return $input['file_id']; |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * @param $newfile |
||
310 | * @param $input |
||
311 | * |
||
312 | * @return mixed |
||
313 | */ |
||
314 | function updateFile($newfile, &$input) |
||
315 | { |
||
316 | global $uploadpath, $xoopsDB; |
||
317 | // For now, images are stored in individual directories for each page. |
||
318 | // We can change the directory distribution later, as the entire path |
||
319 | // relative to /uploads/gwiki/ ($relpath) is stored in the database. |
||
320 | |||
321 | // We get rid of any colons in the page name in case the filesystem has |
||
322 | // issues with them. (undescore is illegal in page name, so it stays unique.) |
||
323 | $relpath = 'pages/' . str_replace(':', '_', $input['page']) . '/file/'; |
||
324 | $ourpath = $uploadpath . $relpath; |
||
325 | $oldUmask = umask(0); |
||
326 | @mkdir($ourpath, 0755, true); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
327 | umask($oldUmask); |
||
328 | $tempfn = tempnam($ourpath, 'WIKIFILE_'); |
||
329 | $image = file_get_contents('php://input'); |
||
330 | file_put_contents($tempfn, $image); |
||
331 | |||
332 | $filename = $ourpath . $newfile; |
||
333 | if (empty($input['file_name'])) { |
||
334 | $input['file_name'] = $justfn; |
||
0 ignored issues
–
show
|
|||
335 | } |
||
336 | |||
337 | $fi = getFileInfo($tempfn); |
||
338 | foreach ($fi as $k => $v) { |
||
339 | $input[$k] = $v; |
||
340 | } |
||
341 | |||
342 | $input['file_name'] = $newfile; |
||
343 | $input['file_path'] = $relpath . $newfile; |
||
344 | |||
345 | rename($tempfn, $filename); |
||
346 | chmod($filename, 0644); |
||
347 | $q_file_id = (int)$input['file_id']; |
||
348 | $sql = 'SELECT file_path FROM ' . $xoopsDB->prefix('gwiki_page_files') . " where file_id='{$q_file_id}' "; |
||
349 | |||
350 | $result = $xoopsDB->query($sql); |
||
351 | if ($result) { |
||
352 | $rows = $xoopsDB->getRowsNum($result); |
||
353 | if ($rows) { |
||
354 | $myrow = $xoopsDB->fetchArray($result); |
||
355 | if (!empty($myrow['file_path'])) { |
||
356 | $oldfilename = $uploadpath . '/' . $myrow['file_path']; |
||
357 | unlink($oldfilename); |
||
358 | } |
||
359 | // update |
||
360 | } else { |
||
361 | // new row |
||
362 | } |
||
363 | } |
||
364 | $input['file_upload_date'] = time(); |
||
365 | |||
366 | return updateData($input); |
||
367 | } |
||
368 | |||
369 | if (!$jsondata) { |
||
370 | header('Status: 500 Internal Error - No Data Passed'); |
||
371 | exit; |
||
372 | } |
||
373 | $input = json_decode($jsondata, true); |
||
374 | //file_put_contents ( XOOPS_ROOT_PATH.'/uploads/debug.txt', print_r($input,true)); |
||
375 | |||
376 | if (!empty($input['file_id'])) { |
||
377 | $q_file_id = (int)$input['file_id']; |
||
378 | $sql = 'SELECT * FROM ' . $xoopsDB->prefix('gwiki_page_files') . " where file_id = '{$q_file_id}' "; |
||
379 | $result = $xoopsDB->query($sql); |
||
380 | if ($row = $xoopsDB->fetcharray($result)) { |
||
381 | $input['page'] = $row['keyword']; |
||
382 | foreach ($row as $k => $v) { |
||
383 | if (!isset($input[$k])) { |
||
384 | $input[$k] = $v; |
||
385 | } |
||
386 | } |
||
387 | } |
||
388 | } |
||
389 | |||
390 | if (empty($input['page'])) { |
||
391 | header('Status: 500 Internal Error - No Page'); |
||
392 | exit; |
||
393 | } |
||
394 | $input['page'] = strtolower($wikiPage->normalizeKeyword($input['page'])); |
||
395 | $pageX = $wikiPage->getPage($input['page']); |
||
396 | $mayEdit = $wikiPage->checkEdit(); |
||
397 | |||
398 | View Code Duplication | if (!$mayEdit) { |
|
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. ![]() |
|||
399 | header('Status: 403 Forbidden - No Permission'); |
||
400 | if (!$mayEdit) { |
||
401 | $out['message'] = _MD_GWIKI_AJAX_FILEEDIT_NO_AUTH; |
||
402 | } |
||
403 | echo json_encode($out); |
||
404 | exit; |
||
405 | } |
||
406 | |||
407 | $q_newfile = $wikiPage->escapeForDB($newfile); |
||
408 | $q_keyword = $wikiPage->escapeForDB($input['page']); |
||
409 | |||
410 | $sql = 'SELECT file_id FROM ' . $xoopsDB->prefix('gwiki_page_files') . " where file_name = '{$q_newfile}' AND keyword='{$q_keyword}' "; |
||
411 | |||
412 | $result = $xoopsDB->query($sql); |
||
413 | if ($row = $xoopsDB->fetcharray($result)) { |
||
414 | if ($input['file_id'] !== $row['file_id']) { |
||
415 | header('Status: 500 Internal Error - Duplicate File Name'); |
||
416 | $out['message'] = _MD_GWIKI_AJAX_FILEEDIT_DUPLICATE; |
||
417 | echo json_encode($out); |
||
418 | exit; |
||
419 | } |
||
420 | } |
||
421 | |||
422 | /* |
||
423 | * This creates issues if page being edited has not been saved yet, so let's not be anal about it |
||
424 | if (!$pageX) { |
||
425 | header("Status: 403 Forbidden - No Page"); |
||
426 | if(!$pageX) $out['message']='Page does not exist'; |
||
427 | echo json_encode($out); |
||
428 | exit; |
||
429 | } |
||
430 | */ |
||
431 | |||
432 | if ($newfile) { |
||
433 | $fi = getExtensionInfo($newfile); |
||
434 | if ($fi === false) { |
||
435 | header('Status: 403 Forbidden - Bad File Type'); |
||
436 | $out['message'] = _MD_GWIKI_AJAX_FILEEDIT_BAD_TYPE; |
||
437 | echo json_encode($out); |
||
438 | exit; |
||
439 | } |
||
440 | foreach ($fi as $k => $v) { |
||
441 | $input[$k] = $v; |
||
442 | } |
||
443 | $input['file_id'] = updateFile($newfile, $input); |
||
444 | if ($input['file_id']) { |
||
445 | $input['message'] = 'Attachment Saved'; |
||
446 | $input['link'] = $uploadurl . $input['file_path']; |
||
447 | $input['iconlink'] = XOOPS_URL . '/modules/' . $dir . '/assets/icons/48px/' . $input['file_icon'] . '.png'; |
||
448 | $input['userlink'] = getUserName($input['file_uid']); |
||
449 | $input['size'] = number_format($input['file_size']); |
||
450 | $input['date'] = date($wikiPage->dateFormat, $input['file_upload_date']); |
||
451 | } |
||
452 | View Code Duplication | } else { |
|
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. ![]() |
|||
453 | if (!empty($input['op']) && $input['op'] === 'delete') { |
||
454 | deleteData($input); |
||
455 | } else { |
||
456 | updateData($input); |
||
457 | } |
||
458 | } |
||
459 | echo json_encode($input); |
||
460 | exit; |
||
461 |
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.