Skip to content

Commit

Permalink
* security fix: replace string filtering by parameterization in almos…
Browse files Browse the repository at this point in the history
…t all queries
  • Loading branch information
NavigateCMS committed Sep 24, 2018
1 parent a56ff90 commit 6df73cc
Show file tree
Hide file tree
Showing 72 changed files with 1,969 additions and 905 deletions.
23 changes: 15 additions & 8 deletions lib/core/core.php
Expand Up @@ -184,15 +184,22 @@ function core_load_function($fid)
break;

default:
$query_params = NULL;
if(is_numeric($fid))
{
$where = 'id = '.intval($fid);
}
else
$where = 'codename = '.protect($fid);
{
$where = 'codename = :codename';
$query_params = array(':codename' => $fid);
}

$DB->query('SELECT *
FROM nv_functions
WHERE '.$where.'
AND enabled = 1');
$DB->query(
'SELECT * FROM nv_functions WHERE '.$where.' AND enabled = 1',
'object',
$query_params
);

$func = $DB->first();

Expand Down Expand Up @@ -1179,9 +1186,9 @@ function navigate_compose_email($data, $style=array())
$title_color = '#595959';
$text_color = '#595959';

$background_color_db = $DB->query_single('value', 'nv_permissions', 'name = ' . protect("nvweb.comments.background_color") . ' AND website = ' . protect($website->id), 'id DESC');
$text_color_db = $DB->query_single('value', 'nv_permissions', 'name = ' . protect("nvweb.comments.text_color") . ' AND website = ' . protect($website->id), 'id DESC');
$title_color_db = $DB->query_single('value', 'nv_permissions', 'name = ' . protect("nvweb.comments.titles_color") . ' AND website = ' . protect($website->id), 'id DESC');
$background_color_db = $DB->query_single('value', 'nv_permissions', 'name = "nvweb.comments.background_color" AND website = ' . intval($website->id), 'id DESC');
$text_color_db = $DB->query_single('value', 'nv_permissions', 'name = "nvweb.comments.text_color" AND website = ' . intval($website->id), 'id DESC');
$title_color_db = $DB->query_single('value', 'nv_permissions', 'name = "nvweb.comments.titles_color" AND website = ' . intval($website->id), 'id DESC');

if (!empty($background_color_db))
$background_color = str_replace('"', '', $background_color_db);
Expand Down
53 changes: 44 additions & 9 deletions lib/core/database.class.php
Expand Up @@ -92,10 +92,11 @@ public function reconnect()
* in the current active language.
*
* @param string $sql The complete SQL query
* @param string $fetch_mode How to retrieve the data: "object" or "array"
* @param string $fetch_mode How to retrieve the data: "object" or "array"
* @param array $parameters SQL query parameters associative array
* @return boolean True if the query was executed without errors
*/
public function query($sql, $fetch_mode='object')
public function query($sql, $fetch_mode='object', $parameters=array())
{
$this->lastError = '';
$this->lastResult = '';
Expand All @@ -114,7 +115,15 @@ public function query($sql, $fetch_mode='object')

try
{
$statement = $this->db->query($sql);
if(empty($parameters))
{
$statement = $this->db->query($sql);
}
else
{
$statement = $this->db->prepare($sql);
$statement->execute($parameters);
}
$this->queries_count++;

// avoid firing a fatal error exception when the result is NULL
Expand Down Expand Up @@ -146,17 +155,28 @@ public function query($sql, $fetch_mode='object')
* @param string $table Table name to get the data from
* @param string $where SQL conditions in the WHERE clause
* @param string $order SQL order conditions in the ORDER BY clause
* @param array $parameters SQL query parameters associative array
* @return string|integer Value of the first column of the first row of the resultset
*/
public function query_single($column, $table, $where = '1=1', $order = '')
public function query_single($column, $table, $where = '1=1', $order = '', $parameters=array())
{
$rs = null;
if(!empty($order))
$order = ' ORDER BY '.$order;

$sql = 'SELECT ' . $column . ' FROM ' . $table . ' WHERE ' . $where . $order . ' LIMIT 1';

try
{
$stm = $this->db->query('SELECT ' . $column . ' FROM ' . $table . ' WHERE ' . $where . $order . ' LIMIT 1');
if(empty($parameters))
{
$stm = $this->db->query($sql);
}
else
{
$stm = $this->db->prepare($sql);
$stm->execute($parameters);
}
$this->queries_count++;
$stm->setFetchMode(PDO::FETCH_NUM);
$rs = $stm->fetchAll();
Expand All @@ -168,8 +188,14 @@ public function query_single($column, $table, $where = '1=1', $order = '')
return NULL;
}

if(empty($rs)) return NULL;
else return $rs[0][0];
if(empty($rs))
{
return NULL;
}
else
{
return $rs[0][0];
}
}


Expand All @@ -184,7 +210,7 @@ public function query_single($column, $table, $where = '1=1', $order = '')
* @param integer $max How many rows will be returned of the resultset (after applying offset)
* @return boolean True if the query could be executed without errors
*/
public function queryLimit($cols, $table, $where="1=1", $order="", $offset=0, $max=100)
public function queryLimit($cols, $table, $where="1=1", $order="", $offset=0, $max=100, $parameters=array())
{
$this->lastError = '';
$this->lastResult = '';
Expand All @@ -199,7 +225,16 @@ public function queryLimit($cols, $table, $where="1=1", $order="", $offset=0, $m
LIMIT '.$max.'
OFFSET '.$offset;

$statement = $this->db->query($sql);
if(empty($parameters))
{
$statement = $this->db->query($sql);
}
else
{
$statement = $this->db->prepare($sql);
$statement->execute($parameters);
}

$this->queries_count++;
$statement->setFetchMode($fetch);
$this->lastResult = $statement->fetchAll();
Expand Down
6 changes: 5 additions & 1 deletion lib/core/language.class.php
Expand Up @@ -18,7 +18,11 @@ public function load($code='en')
{
global $DB;

$DB->query('SELECT * FROM nv_languages WHERE code = '.protect($code));
$DB->query(
'SELECT * FROM nv_languages WHERE code = :code',
'object',
array(':code' => $code)
);
$data = $DB->first();

if(empty($data->id))
Expand Down
23 changes: 16 additions & 7 deletions lib/core/user.class.php
Expand Up @@ -51,10 +51,13 @@ public function authenticate($user, $pass)
$user = mb_strtolower($user);

$A1 = md5($user.':'.APP_REALM.':'.$pass);

if($DB->query('SELECT *
FROM nv_users
WHERE LOWER(username) = '.protect($user)))
$found = $DB->query(
'SELECT * FROM nv_users WHERE LOWER(username) = :username',
'object',
array(':username' => $user)
);

if(!empty($found))
{
$data = $DB->result();

Expand Down Expand Up @@ -336,9 +339,15 @@ public function setting($name, $value=NULL)
'SELECT *
FROM nv_settings
WHERE type = "user" AND
user = '.protect($this->id).' AND
website = '.protect($website->id).' AND
name = '.protect($name)
user = :user AND
website = :website AND
name = :name',
'object',
array(
':user' => $this->id,
':website' => $website->id,
':name' => $name
)
);

$setting = $DB->first();
Expand Down
9 changes: 8 additions & 1 deletion lib/layout/layout.class.php
Expand Up @@ -563,7 +563,13 @@ public function navigate_session()
if(empty($fid))
$fid = 'dashboard';

$user_profile_name = $DB->query_single('name', 'nv_profiles', 'id='.protect($user->profile));
$user_profile_name = $DB->query_single(
'name',
'nv_profiles',
'id = :user_profile',
'NULL',
array(':user_profile' => $user->profile)
);

$this->add_content(
'<div class="navigate-help">'.
Expand Down Expand Up @@ -753,6 +759,7 @@ public function navigate_additional_scripts()
92: "'.t(92, 'Close').'",
141: "'.t(141, 'Folder').'",
152: "'.t(152, 'Continue').'",
159: "'.t(159, 'Name').'",
170: "'.t(170, 'Edit').'",
171: "'.t(171, 'Order').'",
185: "'.t(185, 'Searching elements').'",
Expand Down
2 changes: 1 addition & 1 deletion lib/layout/navibars.class.php
Expand Up @@ -33,7 +33,7 @@ function add_actions($actions)
{
// we are displaying a list
$actions[$search_form_pos][] = '<img onclick="$(this).next().triggerHandler(\'submit\');" height="16" align="absmiddle" width="16" src="img/icons/silk/zoom.png"></a>';
$actions[$search_form_pos][] = '<form method="GET" action="#" onsubmit=" navitable_quicksearch($(\'#navigate-quicksearch\').val()); return false;">';
$actions[$search_form_pos][] = '<form method="GET" action="#" onsubmit=" if(typeof(navitable_quicksearch)==\'function\') { navitable_quicksearch($(\'#navigate-quicksearch\').val()); return false; } else return true;">';
}
else // other screen than a list
{
Expand Down
1 change: 1 addition & 0 deletions lib/layout/naviforms.class.php
Expand Up @@ -263,6 +263,7 @@ public function autocomplete($name, $value="", $source, $callback='""', $width="
$("a[data-action=create_custom_value][data-uid='.$uid.']").on("click", function()
{
var text = prompt(navigate_t(159, "Name"));
if(!text) return;
text = text.trim();
if(text != "")
{
Expand Down
2 changes: 1 addition & 1 deletion lib/packages/about/about.php
Expand Up @@ -54,7 +54,7 @@ function about_layout()
$navibars->add_tab_content_row(
array(
'<label>'.t(218, 'Third party libraries').'</label>',
'<a href="http://www.tinymce.com" target="_blank">TinyMCE 4.8.0c</a><br />'
'<a href="http://www.tinymce.com" target="_blank">TinyMCE 4.8.3</a><br />'
)
);

Expand Down
20 changes: 14 additions & 6 deletions lib/packages/blocks/block.class.php
Expand Up @@ -610,8 +610,12 @@ public static function types($orderby='id', $asc='asc')
$theme_blocks[$b]['count'] = $DB->query_single(
'COUNT(*) AS total',
'nv_blocks',
' website = '.$website->id.' AND
type = '.protect($theme_blocks[$b]['id'])
' website = :wid AND type = :type',
NULL,
array(
':wid' => $website->id,
':type' => $theme_blocks[$b]['id']
)
);
}
}
Expand Down Expand Up @@ -671,11 +675,15 @@ public static function types_update($array)
sort($array);

$array = serialize($array);

$ok = $DB->execute('
UPDATE nv_websites
SET block_types = '.protect($array).'
WHERE id = '.$website->id
SET block_types = :block_types
WHERE id = :wid',
array(
':wid' => $website->id,
':block_types' => $array
)
);

if(!$ok)
Expand Down Expand Up @@ -939,7 +947,7 @@ public function backup($type='json')
$DB->query('
SELECT *
FROM nv_blocks
WHERE website = '.protect($website->id),
WHERE website = '.intval($website->id),
'object'
);

Expand Down
18 changes: 13 additions & 5 deletions lib/packages/blocks/block_group.class.php
Expand Up @@ -27,9 +27,17 @@ public function load_by_code($code)
global $DB;
global $website;

if($DB->query('SELECT * FROM nv_block_groups
WHERE code = '.protect($code).'
AND website = '.$website->id))
$found = $DB->query(
'SELECT * FROM nv_block_groups
WHERE code = :code
AND website = '.$website->id,
'object',
array(
':code' => $code
)
);

if($found)
{
$data = $DB->result();
$this->load_from_resultset($data);
Expand Down Expand Up @@ -198,7 +206,7 @@ public static function paginated_list($offset, $limit, $order_by_field, $order_b
$DB->queryLimit(
'*',
'nv_block_groups',
'website = '.protect($website->id),
'website = '.intval($website->id),
$order_by_field.' '.$order_by_ascdesc,
$offset,
$limit
Expand Down Expand Up @@ -235,7 +243,7 @@ public function backup($type='json')
$DB->query('
SELECT *
FROM nv_block_groups
WHERE website = '.protect($website->id),
WHERE website = '.intval($website->id),
'object'
);
$out = $DB->result();
Expand Down
10 changes: 7 additions & 3 deletions lib/packages/blocks/blocks.php
Expand Up @@ -274,13 +274,17 @@ function run()

case 'path':
case 5: // search an existing path
$DB->query('SELECT path as id, path as label, path as value
$DB->query(
'SELECT path as id, path as label, path as value
FROM nv_paths
WHERE path LIKE '.protect('%'.$_REQUEST['term'].'%').'
WHERE path LIKE :path
AND website = '.$website->id.'
ORDER BY path ASC
LIMIT 10',
'array');
'array',
array(
':path' => '%' . $_REQUEST['term'] . '%'
));

echo json_encode($DB->result());

Expand Down
2 changes: 1 addition & 1 deletion lib/packages/brands/brand.class.php
Expand Up @@ -134,7 +134,7 @@ public function backup($type='json')
global $DB;
global $website;

$DB->query('SELECT * FROM nv_brands WHERE website = '.protect($website->id), 'object');
$DB->query('SELECT * FROM nv_brands WHERE website = '.intval($website->id), 'object');
$out = $DB->result();

if($type='json')
Expand Down

0 comments on commit 6df73cc

Please sign in to comment.