CVE-2020-13796 (PHP, published 2020-06-03T22:15Z)
Description: value: An issue was discovered in Navigate CMS through 2.8.7. It allows XSS because of a lack of purify calls in lib/packages/structure/structure.class.php.
Severity: MEDIUM (CVSS v3 base score: 6.1)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/NavigateCMS/Navigate-CMS
Files changed:
lib/packages/feeds/feed.class.php
lib/packages/menus/menu.class.php
lib/packages/menus/menus.php
lib/packages/structure/structure.class.php
lib/packages/websites/website.class.php
Commit message: + HTML Purify some fields to prevent XSS attacks


Vulnerable code:
			if(empty($value)) continue;
					$this->dictionary[substr($key, strlen($field.'-'))][$field] = $value;
				$this->paths[substr($key, strlen('path-'))] = $value;
			$this->categories	= explode(',', $_REQUEST['categories']);				
		global $DB;

			return $this->update();
			return $this->insert();			
		    throw new Exception($DB->get_last_error());
			$cols[] = 'i.id IN ('.implode(',', $dict_ids).')';
			$id = $current['id'];
			if($limit <= 0)	$limit = 10;
							$fitem->description = '<img src="'.$image.'&width=640"><br />'.$fitem->description;
		if(empty($this->functions))	$this->functions = array();		
				$this->functions[] = $function;
	}	
	
		global $DB;

		  return $this->update();
		  return $this->insert();
			throw new Exception($DB->get_last_error());
			throw new Exception($DB->get_last_error());
					$DB->queryLimit('id,lid,codename,icon,enabled', 
									'nv_menus', 
									$where, 
									$orderby, 
									$offset, 
									$max);
	$navibars->add_actions(	array(	'<a href="?fid='.$_REQUEST['fid'].'&act=2"><img height="16" align="absmiddle" width="16" src="img/icons/silk/add.png"> '.t(38, 'Create').'</a>',
									'<a href="?fid='.$_REQUEST['fid'].'&act=0"><img height="16" align="absmiddle" width="16" src="img/icons/silk/application_view_list.png"> '.t(39, 'List').'</a>',
									'search_form' ));
		$navibars->title(t(244, 'Menus').' / '.t(38, 'Create'));	
		$navibars->title(t(244, 'Menus').' / '.t(170, 'Edit').' ['.$item->id.']');		
	$navibars->add_actions(	array(	(!empty($item->id)? '<a href="?fid=menus&act=2"><img height="16" align="absmiddle" width="16" src="img/icons/silk/add.png"> '.t(38, 'Create').'</a>' : ''),
									'<a href="?fid=menus&act=0"><img height="16" align="absmiddle" width="16" src="img/icons/silk/application_view_list.png"> '.t(39, 'List').'</a>',
									'search_form' ));
	if(empty($item->functions)) $item->functions = array();
					$sortable_assigned[] = '<li class="ui-state-highlight" value="'.$function->id.'" category="'.$function->category.'"><img src="'.NAVIGATE_URL.'/'.$function->icon.'" align="absmiddle" /> '.t($function->lid, $function->lid).'</li>';
					$sortable_assigned[] = '<li class="ui-state-highlight ui-state-disabled" value="'.$function->id.'" category="'.$function->category.'"><img src="'.NAVIGATE_URL.'/'.$function->icon.'" align="absmiddle" /> '.t($function->lid, $function->lid).'</li>';
				$sortable_unassigned[] = '<li class="ui-state-default" value="'.$function->id.'" category="'.$function->category.'"><img src="'.NAVIGATE_URL.'/'.$function->icon.'" align="absmiddle" /> '.t($function->lid, $function->lid).'</li>';
				$sortable_unassigned[] = '<li class="ui-state-default ui-state-disabled" value="'.$function->id.'" category="'.$function->category.'"><img src="'.NAVIGATE_URL.'/'.$function->icon.'" align="absmiddle" /> '.t($function->lid, $function->lid).'</li>';
	$navibars->add_tab_content_row(array(	'<label>'.t(78, 'Category').'</label>',
											$naviforms->selectfield('menus_functions_category_select', $func_cats, $func_cats, 'web', "navigate_menus_change_functions_category();", false)
										)
									);
	$navibars->add_tab_content($naviforms->hidden("menu-functions", implode('#', $item->functions)));	
	$navibars->add_tab_content_row(array(	'<label>'.t(240, 'Functions').'</label>',
											implode("\n", $sortable_assigned),
											implode("\n", $sortable_unassigned)
										)
									);
                    $this->dictionary[substr($key, strlen($field.'-'))][$field] = $value;
                $this->paths[substr($key, strlen('path-'))] = $value;
		$this->name				= $_REQUEST['title'];

Fixed code:
	    global $purifier;

			if(empty($value))
            {
                continue;
            }
                {
                    $this->dictionary[substr($key, strlen($field.'-'))][$field] = $purifier->purify($value);
                }
            {
                $this->paths[substr($key, strlen('path-'))] = $purifier->purify($value);
            }
        {
            $this->categories	= explode(',', $_REQUEST['categories']);
        }
        {
            return $this->update();
        }
        {
            return $this->insert();
        }
        {
        }
        {
            throw new Exception($DB->get_last_error());
        }
        {
            $cols[] = 'i.id IN ('.implode(',', $dict_ids).')';
        }
        {
            $id = $current['id'];
        }
        {
        }
			if($limit <= 0)
            {
                $limit = 10;
            }
                        {
                        }
                                {
                                }
                                {
                                }
                                {
                                }
                            {
                            }
                        {
                            $fitem->description = '<img src="'.$image.'&width=640"><br />'.$fitem->description;
                        }
        {
        }
		if(empty($this->functions))
        {
            $this->functions = array();
        }
            {
                $this->functions[] = $function;
            }
	}
        {
            return $this->update();
        }
        {
            return $this->insert();
        }
        {
            throw new Exception($DB->get_last_error());
        }
        {
            throw new Exception($DB->get_last_error());
        }
        {
        }
					$DB->queryLimit(
					    'id,lid,codename,icon,enabled',
                        'nv_menus',
                        $where,
                        $orderby,
                        $offset,
                        $max
                    );
	$navibars->add_actions(
	    array(
	        '<a href="?fid='.$_REQUEST['fid'].'&act=2"><img height="16" align="absmiddle" width="16" src="img/icons/silk/add.png"> '.t(38, 'Create').'</a>',
			'<a href="?fid='.$_REQUEST['fid'].'&act=0"><img height="16" align="absmiddle" width="16" src="img/icons/silk/application_view_list.png"> '.t(39, 'List').'</a>',
			'search_form'
        )
    );
    {
        $navibars->title(t(244, 'Menus').' / '.t(38, 'Create'));
    }
    {
        $navibars->title(t(244, 'Menus').' / '.t(170, 'Edit').' ['.$item->id.']');
    }
	$navibars->add_actions(
	    array(
	        (!empty($item->id)? '<a href="?fid=menus&act=2"><img height="16" align="absmiddle" width="16" src="img/icons/silk/add.png"> '.t(38, 'Create').'</a>' : ''),
			'<a href="?fid=menus&act=0"><img height="16" align="absmiddle" width="16" src="img/icons/silk/application_view_list.png"> '.t(39, 'List').'</a>',
			'search_form'
        )
    );
	if(empty($item->functions))
    {
        $item->functions = array();
    }
                {
                    $sortable_assigned[] = '<li class="ui-state-highlight" value="'.$function->id.'" category="'.$function->category.'"><img src="'.NAVIGATE_URL.'/'.$function->icon.'" align="absmiddle" /> '.t($function->lid, $function->lid).'</li>';
                }
                {
                    $sortable_assigned[] = '<li class="ui-state-highlight ui-state-disabled" value="'.$function->id.'" category="'.$function->category.'"><img src="'.NAVIGATE_URL.'/'.$function->icon.'" align="absmiddle" /> '.t($function->lid, $function->lid).'</li>';
                }
            {
                $sortable_unassigned[] = '<li class="ui-state-default" value="'.$function->id.'" category="'.$function->category.'"><img src="'.NAVIGATE_URL.'/'.$function->icon.'" align="absmiddle" /> '.t($function->lid, $function->lid).'</li>';
            }
            {
                $sortable_unassigned[] = '<li class="ui-state-default ui-state-disabled" value="'.$function->id.'" category="'.$function->category.'"><img src="'.NAVIGATE_URL.'/'.$function->icon.'" align="absmiddle" /> '.t($function->lid, $function->lid).'</li>';
            }
	$navibars->add_tab_content_row(
	    array(
	        '<label>'.t(78, 'Category').'</label>',
			$naviforms->selectfield('menus_functions_category_select', $func_cats, $func_cats, 'web', "navigate_menus_change_functions_category();", false)
        )
    );
	$navibars->add_tab_content(
	    $naviforms->hidden("menu-functions", implode('#', $item->functions))
    );

	$navibars->add_tab_content_row(
	    array(
	        '<label>'.t(240, 'Functions').'</label>',
			implode("\n", $sortable_assigned),
			implode("\n", $sortable_unassigned)
        )
    );
	    global $purifier;

                    $this->dictionary[substr($key, strlen($field.'-'))][$field] = $purifier->purify($value);
                $this->paths[substr($key, strlen('path-'))] = $purifier->purify($value);
        global $purifier;
		$this->name				= $purifier->purify($_REQUEST['title']);