Issues (10)

Security Analysis    no request data  

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.

modules/main_menu.php (2 issues)

Severity

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
/**
3
*
4
* @package Board3 Portal v2.1
5
* @copyright (c) 2013 Board3 Group ( www.board3.de )
6
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
7
*
8
*/
9
10
namespace board3\portal\modules;
11
12
/**
13
* @package Main Menu
14
*/
15
class main_menu extends module_base
16
{
17
	/**
18
	* Allowed columns: Just sum up your options (Exp: left + right = 10)
19
	* top		1
20
	* left		2
21
	* center	4
22
	* right		8
23
	* bottom	16
24
	*/
25
	public $columns = 10;
26
27
	/**
28
	* Default modulename
29
	*/
30
	public $name = 'M_MENU';
31
32
	/**
33
	* Default module-image:
34
	* file must be in "{T_THEME_PATH}/images/portal/"
35
	*/
36
	public $image_src = 'portal_menu.png';
37
38
	/**
39
	* module-language file
40
	* file must be in "language/{$user->lang}/mods/portal/"
41
	*/
42
	public $language = 'portal_main_menu_module';
43
44
	/**
45
	* custom acp template
46
	* file must be in "adm/style/portal/"
47
	*/
48
	public $custom_acp_tpl = 'acp_portal_menu';
49
50
	/** @var bool Can include this module multiple times */
51
	protected $multiple_includes = true;
52
53
	/**
54
	* constants
55
	*/
56
	const LINK_CAT = 0;
57
	const LINK_INT = 1;
58
	const LINK_EXT = 2;
59
60
	/** @var \phpbb\config\config */
61
	protected $config;
62
63
	/** @var \phpbb\db\driver\driver_interface */
64
	protected $db;
65
66
	/** @var \phpbb\request\request */
67
	protected $request;
68
69
	/** @var \phpbb\template\template */
70
	protected $template;
71
72
	/** @var string PHP file extension */
73
	protected $php_ext;
74
75
	/** @var string phpBB root path */
76
	protected $phpbb_root_path;
77
78
	/** @var \phpbb\user */
79
	protected $user;
80
81
	/** @var \phpbb\log\log phpBB log */
82
	protected $log;
83
84
	/**
85
	* Construct a main menu object
86
	*
87
	* @param \phpbb\config\config $config phpBB config
88
	* @param \phpbb\db\driver\driver_interface $db phpBB db driver
89
	* @param \phpbb\request\request $request phpBB request
90
	* @param \phpbb\template\template $template phpBB template
91
	* @param string $phpbb_root_path phpBB root path
92
	* @param string $phpEx php file extension
93
	* @param \phpbb\user $user phpBB user object
94
	* @param \phpbb\log\log $log phpBB log
95
	*/
96 View Code Duplication
	public function __construct($config, $db, $request, $template, $phpbb_root_path, $phpEx, $user, $log)
97
	{
98
		$this->config = $config;
99
		$this->db = $db;
100
		$this->request = $request;
101
		$this->template = $template;
102
		$this->phpbb_root_path = $phpbb_root_path;
103
		$this->php_ext = $phpEx;
104
		$this->user = $user;
105
		$this->log = $log;
106
	}
107
108
	/**
109
	* {@inheritdoc}
110
	*/
111
	public function get_template_side($module_id)
112
	{
113
		$portal_config = obtain_portal_config();
114
115
		$links = json_decode($portal_config['board3_menu_array_' . $module_id], true);
116
117
		$this->template->assign_block_vars('portal_menu', array('MODULE_ID' => $module_id));
118
119
		// get user's groups
120
		$groups_ary = get_user_groups();
121
122
		for ($i = 0; $i < sizeof($links); $i++)
123
		{
124
			if ($links[$i]['type'] == self::LINK_CAT)
125
			{
126
				$this->template->assign_block_vars('portal_menu.category', array(
127
					'CAT_TITLE'		=> (isset($this->user->lang[$links[$i]['title']])) ? $this->user->lang[$links[$i]['title']] : $links[$i]['title'],
128
				));
129
			}
130
			else
131
			{
132 View Code Duplication
				if ($links[$i]['type'] == self::LINK_INT)
133
				{
134
					$links[$i]['url'] = str_replace('&', '&amp;', $links[$i]['url']); // we need to do this in order to prevent XHTML validation errors
135
					$cur_url = append_sid($this->phpbb_root_path . $links[$i]['url']); // the user should know what kind of file it is
136
				}
137
				else
138
				{
139
					$cur_url = $links[$i]['url'];
140
				}
141
142
				$cur_permissions = explode(',', $links[$i]['permission']);
143
				$permission_check = array_intersect($groups_ary, $cur_permissions);
144
145 View Code Duplication
				if (!empty($permission_check) || $links[$i]['permission'] == '')
146
				{
147
					$this->template->assign_block_vars('portal_menu.category.links', array(
148
						'LINK_TITLE'		=> (isset($this->user->lang[$links[$i]['title']])) ? $this->user->lang[$links[$i]['title']] : $links[$i]['title'],
149
						'LINK_URL'			=> $cur_url,
150
						'NEW_WINDOW'		=> ($links[$i]['type'] != self::LINK_INT && $this->config['board3_menu_url_new_window_' . $module_id]) ? true : false,
151
					));
152
				}
153
			}
154
		}
155
156
		return 'main_menu_side.html';
157
	}
158
159
	/**
160
	* {@inheritdoc}
161
	*/
162 View Code Duplication
	public function get_template_acp($module_id)
163
	{
164
		return array(
165
			'title'	=> 'ACP_PORTAL_MENU',
166
			'vars'	=> array(
167
				'legend1'				=> 'ACP_PORTAL_MENU',
168
				'board3_menu_' . $module_id	=> array('lang' => 'ACP_PORTAL_MENU_MANAGE', 'validate' => 'string',	'type' => 'custom',	'explain' => true, 'method' => 'manage_links', 'submit' => 'update_links'),
169
				'board3_menu_url_new_window_' . $module_id => array('lang' => 'ACP_PORTAL_MENU_EXT_NEW_WINDOW', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
170
			),
171
		);
172
	}
173
174
	/**
175
	* {@inheritdoc}
176
	*/
177
	public function install($module_id)
178
	{
179
		// get the correct group IDs from the database
180
		$in_ary = array('GUESTS', 'REGISTERED', 'REGISTERED_COPPA');
181
		$groups_ary = array();
182
183
		$sql = 'SELECT group_id, group_name FROM ' . GROUPS_TABLE . ' WHERE ' . $this->db->sql_in_set('group_name', $in_ary);
184
		$result = $this->db->sql_query($sql);
185 View Code Duplication
		while ($row = $this->db->sql_fetchrow($result))
186
		{
187
			$groups_ary[$row['group_name']] = $row['group_id'];
188
		}
189
190
		$links = array();
191
192
		$links_titles = array(
193
			'M_CONTENT',
194
			'INDEX',
195
			'SEARCH',
196
			'REGISTER',
197
			'MEMBERLIST',
198
			'THE_TEAM',
199
			'M_HELP',
200
			'FAQ',
201
			'M_BBCODE',
202
			'M_TERMS',
203
			'M_PRV',
204
		);
205
206
		$links_types = array(
207
			self::LINK_CAT,
208
			self::LINK_INT,
209
			self::LINK_INT,
210
			self::LINK_INT,
211
			self::LINK_INT,
212
			self::LINK_INT,
213
			self::LINK_CAT,
214
			self::LINK_INT,
215
			self::LINK_INT,
216
			self::LINK_INT,
217
			self::LINK_INT,
218
		);
219
220
		$links_urls = array(
221
			'',
222
			'index.' . $this->php_ext,
223
			'search.' . $this->php_ext,
224
			'ucp.' . $this->php_ext . '?mode=register',
225
			'memberlist.' . $this->php_ext,
226
			'memberlist.' . $this->php_ext . '?mode=leaders',
227
			'',
228
			'faq.' . $this->php_ext,
229
			'faq.' . $this->php_ext . '?mode=bbcode',
230
			'ucp.' . $this->php_ext . '?mode=terms',
231
			'ucp.' . $this->php_ext . '?mode=privacy',
232
		);
233
234
		$links_permissions = array(
235
			'',
236
			'',
237
			'',
238
			$groups_ary['GUESTS'],
239
			$groups_ary['REGISTERED'] . ',' . $groups_ary['REGISTERED_COPPA'],
240
			$groups_ary['REGISTERED'] . ',' . $groups_ary['REGISTERED_COPPA'],
241
			'',
242
			'',
243
			'',
244
			'',
245
			'',
246
		);
247
248 View Code Duplication
		foreach ($links_urls as $i => $url)
249
		{
250
			$links[] = array(
251
				'title' 		=> $links_titles[$i],
252
				'url'			=> $links_urls[$i],
253
				'type'			=> $links_types[$i],
254
				'permission'	=> $links_permissions[$i],
255
			);
256
		}
257
258
		$board3_menu_array = json_encode($links);
259
		set_portal_config('board3_menu_array_' . $module_id, $board3_menu_array);
260
		$this->config->set('board3_menu_' . $module_id, '');
261
		$this->config->set('board3_menu_url_new_window_' . $module_id, 0);
262
263
		return true;
264
	}
265
266
	/**
267
	* {@inheritdoc}
268
	*/
269 View Code Duplication
	public function uninstall($module_id, $db)
270
	{
271
		$del_config = array(
272
			'board3_menu_array_' . $module_id,
273
		);
274
		$sql = 'DELETE FROM ' . PORTAL_CONFIG_TABLE . '
275
			WHERE ' . $db->sql_in_set('config_name', $del_config);
276
277
		$db->sql_query($sql);
278
279
		$del_config = array(
280
			'board3_menu_' . $module_id,
281
			'board3_menu_url_new_window_' . $module_id,
282
		);
283
		$sql = 'DELETE FROM ' . CONFIG_TABLE . '
284
			WHERE ' . $db->sql_in_set('config_name', $del_config);
285
		return $db->sql_query($sql);
286
	}
287
288
	/**
289
	* Manage the menu links
290
	*
291
	* @param mixed $value Value of input
292
	* @param string $key Key name
293
	* @param int $module_id Module ID
294
	*
295
	* @return null
296
	*/
297
	public function manage_links($value, $key, $module_id)
0 ignored issues
show
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
298
	{
299
		$action = $this->request->variable('action', '');
300
		$action = ($this->request->is_set_post('add')) ? 'add' : $action;
301
		$action = ($this->request->is_set_post('save')) ? 'save' : $action;
302
		$link_id = $this->request->variable('id', 99999999); // 0 will trigger unwanted behavior, therefore we set a number we should never reach
303
		$portal_config = obtain_portal_config();
304
305
		$links = json_decode($portal_config['board3_menu_array_' . $module_id], true);
306
307
		$u_action = append_sid('index.' . $this->php_ext, 'i=-board3-portal-acp-portal_module&amp;mode=config&amp;module_id=' . $module_id);
308
309
		switch ($action)
310
		{
311
			// Save changes
312
			case 'save':
313 View Code Duplication
				if (!check_form_key('acp_portal'))
314
				{
315
					trigger_error($this->user->lang['FORM_INVALID']. adm_back_link($u_action), E_USER_WARNING);
316
				}
317
318
				$link_title = $this->request->variable('link_title', ' ', true);
319
				$link_is_cat = $this->request->variable('link_is_cat', false);
320
				$link_type = (!$link_is_cat) ? $this->request->variable('link_type', self::LINK_INT) : self::LINK_CAT;
321
				$link_url = ($link_is_cat) ? ' ' : $this->request->variable('link_url', ' ', true);
322
				$link_url = str_replace('&amp;', '&', $link_url);
323
				$link_permission = $this->request->variable('permission-setting-menu', array(0 => ''));
324
				$groups_ary = array();
325
326
				// get groups and check if the selected groups actually exist
327
				$sql = 'SELECT group_id
328
						FROM ' . GROUPS_TABLE . '
329
						ORDER BY group_id ASC';
330
				$result = $this->db->sql_query($sql);
331
				while ($row = $this->db->sql_fetchrow($result))
332
				{
333
					$groups_ary[] = $row['group_id'];
334
				}
335
				$this->db->sql_freeresult($result);
336
337
				$link_permissions = array_intersect($link_permission, $groups_ary);
338
				$link_permissions = implode(',', $link_permissions);
339
340
				// Check for errors
341 View Code Duplication
				if (!$link_title)
342
				{
343
					trigger_error($this->user->lang['NO_LINK_TITLE'] . adm_back_link($u_action), E_USER_WARNING);
344
				}
345
346 View Code Duplication
				if (!$link_is_cat && !$link_url)
347
				{
348
					trigger_error($this->user->lang['NO_LINK_URL'] . adm_back_link($u_action), E_USER_WARNING);
349
				}
350
351
				// overwrite already existing links and make sure we don't try to save a link outside of the normal array size of $links
352
				if (isset($link_id) && $link_id < sizeof($links))
353
				{
354
					$message = $this->user->lang['LINK_UPDATED'];
355
356
					$links[$link_id] = array(
357
						'title' 		=> $link_title,
358
						'url'			=> htmlspecialchars_decode($link_url),
359
						'type'			=> $link_type,
360
						'permission'	=> $link_permissions,
361
					);
362
363
					$this->log->add('admin', $this->user->data['user_id'], $this->user->data['user_ip'], 'LOG_PORTAL_LINK_UPDATED', false, array($link_title));
364
				}
365
				else
366
				{
367
					$message = $this->user->lang['LINK_ADDED'];
368
369
					if ($link_type != self::LINK_CAT && sizeof($links) < 1)
370
					{
371
						trigger_error($this->user->lang['ACP_PORTAL_MENU_CREATE_CAT'] . adm_back_link($u_action), E_USER_WARNING);
372
					}
373
					$links[] = array(
374
						'title' 		=> $link_title,
375
						'url'			=> htmlspecialchars_decode($link_url),
376
						'type'			=> $link_type,
377
						'permission'	=> $link_permissions,
378
					);
379
					$this->log->add('admin', $this->user->data['user_id'], $this->user->data['user_ip'], 'LOG_PORTAL_LINK_ADDED', false, array($link_title));
380
				}
381
382
				$board3_menu_array = json_encode($links);
383
				set_portal_config('board3_menu_array_' . $module_id, $board3_menu_array);
384
385
				trigger_error($message . adm_back_link($u_action));
386
387
			break;
388
389
			// Delete link
390 View Code Duplication
			case 'delete':
391
392
				if (!isset($link_id) && $link_id >= sizeof($links))
393
				{
394
					trigger_error($this->user->lang['MUST_SELECT_LINK'] . adm_back_link($u_action), E_USER_WARNING);
395
				}
396
397
				if (confirm_box(true))
398
				{
399
					$cur_link_title = $links[$link_id]['title'];
400
					// delete the selected link and reset the array numbering afterwards
401
					array_splice($links, $link_id, 1);
402
					$links = array_merge($links);
403
404
					$board3_menu_array = json_encode($links);
405
					set_portal_config('board3_menu_array_' . $module_id, $board3_menu_array);
406
407
					$this->log->add('admin', $this->user->data['user_id'], $this->user->data['user_ip'], 'LOG_PORTAL_LINK_REMOVED', false, array($cur_link_title));
408
				}
409
				else
410
				{
411
					confirm_box(false, $this->user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
412
						'link_id'	=> $link_id,
413
						'action'	=> 'delete',
414
					)));
415
				}
416
417
			break;
418
419
			// Move items up or down
420
			case 'move_up':
421 View Code Duplication
			case 'move_down':
422
423
				if (!isset($link_id) && $link_id >= sizeof($links))
424
				{
425
					trigger_error($this->user->lang['MUST_SELECT_LINK'] . adm_back_link($u_action), E_USER_WARNING);
426
				}
427
428
				// make sure we don't try to move a link where it can't be moved
429
				if (($link_id == 0 && $action == 'move_up') || ($link_id == (sizeof($links) - 1) && $action == 'move_down'))
430
				{
431
					break;
432
				}
433
434
				/*
435
				* on move_down, switch position with next order_id...
436
				* on move_up, switch position with previous order_id...
437
				* move up means a lower ID, move down means a higher ID
438
				*/
439
				$switch_order_id = ($action == 'move_down') ? $link_id + 1 : $link_id - 1;
440
441
				// back up the info of the link we want to move
442
				$cur_link = array(
443
					'title' 		=> $links[$link_id]['title'],
444
					'url'			=> $links[$link_id]['url'],
445
					'type'			=> $links[$link_id]['type'],
446
					'permission'	=> $links[$link_id]['permission'],
447
				);
448
449
				// move the info of the links we replace in the order
450
				$links[$link_id] = array(
451
					'title'			=> $links[$switch_order_id]['title'],
452
					'url'			=> $links[$switch_order_id]['url'],
453
					'type'			=> $links[$switch_order_id]['type'],
454
					'permission'	=> $links[$switch_order_id]['permission'],
455
				);
456
457
				// insert the info of the moved link
458
				$links[$switch_order_id] = $cur_link;
459
460
				$board3_menu_array = json_encode($links);
461
				set_portal_config('board3_menu_array_' . $module_id, $board3_menu_array);
462
463
			break;
464
465
			// Edit or add menu item
466
			case 'edit':
467
			case 'add':
468
				$this->template->assign_vars(array(
469
					'LINK_TITLE'	=> (isset($links[$link_id]['title']) && $action != 'add') ? $links[$link_id]['title'] : '',
470
					'LINK_URL'		=> (isset($links[$link_id]['url']) && $links[$link_id]['type'] != self::LINK_CAT && $action != 'add') ? str_replace('&', '&amp;', $links[$link_id]['url']) : '',
471
472
					'LINK_ID'		=> $link_id,
473
474
					'S_EDIT'				=> true,
475
					'S_LINK_IS_CAT'			=> (!isset($links[$link_id]['type']) || $links[$link_id]['type'] == self::LINK_CAT) ? true : false,
476
					'S_LINK_IS_INT'			=> (isset($links[$link_id]['type']) && $links[$link_id]['type'] == self::LINK_INT) ? true : false,
477
				));
478
479
				$groups_ary = (isset($links[$link_id]['permission'])) ? explode(',', $links[$link_id]['permission']) : array();
480
481
				// get group info from database and assign the block vars
482
				$sql = 'SELECT group_id, group_name 
483
						FROM ' . GROUPS_TABLE . '
484
						ORDER BY group_id ASC';
485
				$result = $this->db->sql_query($sql);
486 View Code Duplication
				while ($row = $this->db->sql_fetchrow($result))
487
				{
488
					$this->template->assign_block_vars('permission_setting_menu', array(
489
						'SELECTED'		=> (in_array($row['group_id'], $groups_ary)) ? true : false,
490
						'GROUP_NAME'	=> (isset($this->user->lang['G_' . $row['group_name']])) ? $this->user->lang['G_' . $row['group_name']] : $row['group_name'],
491
						'GROUP_ID'		=> $row['group_id'],
492
					));
493
				}
494
				$this->db->sql_freeresult($result);
495
496
				return;
497
		}
498
499
		for ($i = 0; $i < sizeof($links); $i++)
500
		{
501
			$this->template->assign_block_vars('links', array(
502
				'LINK_TITLE'	=> ($action != 'add') ? ((isset($this->user->lang[$links[$i]['title']])) ? $this->user->lang[$links[$i]['title']] : $links[$i]['title']) : '',
503
				'LINK_URL'		=> ($action != 'add') ? str_replace('&', '&amp;', $links[$i]['url']) : '',
504
505
				'U_EDIT'		=> $u_action . '&amp;action=edit&amp;id=' . $i,
506
				'U_DELETE'		=> $u_action . '&amp;action=delete&amp;id=' . $i,
507
				'U_MOVE_UP'		=> $u_action . '&amp;action=move_up&amp;id=' . $i,
508
				'U_MOVE_DOWN'	=> $u_action . '&amp;action=move_down&amp;id=' . $i,
509
510
				'S_LINK_IS_CAT'	=> ($links[$i]['type'] == self::LINK_CAT) ? true : false,
511
			));
512
		}
513
	}
514
515
	/**
516
	* Update links
517
	*
518
	* @param string $key Key name
519
	* @param int $module_id Module ID
520
	*
521
	* @return null
522
	*/
523
	public function update_links($key, $module_id)
524
	{
525
		$this->manage_links('', $key, $module_id);
526
	}
527
}
528