CVE-2014-3773: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: Multiple SQL injection vulnerabilities in TeamPass before 2.1.20 allow remote attackers to execute arbitrary SQL commands via the login parameter in a (1) send_pw_by_email or (2) generate_new_password action in sources/main.queries.php; iDisplayStart parameter to (3) datatable.logs.php or (4) a file in source/datatable/; or iDisplayLength parameter to (5) datatable.logs.php or (6) a file in source/datatable/; or allow remote authenticated users to execute arbitrary SQL commands via a sSortDir_ parameter to (7) datatable.logs.php or (8) a file in source/datatable/.
CWE description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
Published: 2014-08-07T11:13Z
Repository: https://github.com/nilsteampassnet/TeamPass
Language: PHP
Files changed: admin.php, admin.settings_api.php, api/functions.php, api/index.php, includes/include.php, items.load.php, items.php, otv.php, sources/admin.queries.php, sources/datatable/datatable.item_edition.php, sources/datatable/datatable.kb.php, sources/datatable/datatable.logs.php, sources/datatable/datatable.users_logged.php, sources/find.queries.php, sources/items.queries.php, sources/users.queries.php
Commit date: 2014-05-03 08:06:26 +0200
Commit message: Security/API (beta) improvements

Diff: diff --git a/admin.php b/admin.php
index a59623e6..dfc19689 100644
--- a/admin.php
+++ b/admin.php
@@ -40,12 +40,10 @@ echo '
      echo '
         <div style="float:right;width:300px;padding:10px;" class="ui-state-highlight ui-corner-all">
             <h3>Some instructions</h3>
             <span class="ui-icon ui-icon-wrench" style="float: left; margin-right: .3em;">&nbsp;</span>
                 Access to <a target="_blank" href="http://www.teampass.net" style="font-weight:bold;font-style:italic;">TeamPass website</a><br />
-            <span class="ui-icon ui-icon-wrench" style="float: left; margin-right: .3em;">&nbsp;</span>
-                For any kind of Help and Support, please use the <a target="_blank" href="http://www.teampass.net/forum" style="font-weight:bold;font-style:italic;">Forum</a><br />
             <span class="ui-icon ui-icon-wrench" style="float: left; margin-right: .3em;">&nbsp;</span>
                 You discovered a Bug or you have an improvement Proposal, please use the <a target="_blank" href="https://github.com/nilsteampassnet/TeamPass/issues" style="font-weight:bold;font-style:italic;">Github channel</a>. <i>If you are not sure, always use the Forum before to obtain a confirmation. This will prevent having to much open tickets at Github</i>.<br />
             <div style="text-align:center;margin-top:10px;">
                 '.$txt['thku'].'
             </div>
diff --git a/admin.settings_api.php b/admin.settings_api.php
index a723c57f..9ae409f7 100644
--- a/admin.settings_api.php
+++ b/admin.settings_api.php
@@ -228,11 +228,11 @@ function newIPDB()
     $("#api_db").dialog("open");
 }
 
 function ip_update(id, value, ip)
 {
-    $("#api_db_type").val("admin_action_api_save_key");
+    $("#api_db_type").val("admin_action_api_save_ip");
     $("#api_db_id").val(id);
     $("#api_db_action").val("update");
     $("#div_key").show();
     $("#api_db_intro").html("'.$txt['settings_api_db_intro'].'");
     $("#api_db_label_span").html("'.$txt['label'].'");
@@ -259,10 +259,11 @@ $(function() {
 				$("#api_db_message").html("");
 				if ($("#api_db_label_input").val().length > 255 || $("#api_db_key_input").val().length > 255) {
 					$("#api_db_message").html("'.$txt['error_too_long'].'");
 					exit;
 				}
+
                 $("#div_loading").show();
                 var $this = $(this);
             	// send query
                 $.post(
                     "sources/admin.queries.php",
diff --git a/api/config.php b/api/config.php
deleted file mode 100644
index e1ac69d4..00000000
--- a/api/config.php
+++ /dev/null
@@ -1,9 +0,0 @@
-<?php
-
-// Set Teampass path
-$teampass_path = "E:/xampp/htdocs/Teampass";
-// Set Teampass config file
-$teampass_config_file = $teampass_path."/includes/settings.php";
-// Set Teampass secure keys file path
-$teampass_sk_file = "/space/private/teampass/sk.php";
-?>
diff --git a/api/functions.php b/api/functions.php
index 39462dd9..d53d503b 100644
--- a/api/functions.php
+++ b/api/functions.php
@@ -1,17 +1,32 @@
 <?php
+/**
+ *
+ * @file          configapi.php
+ * @author        Nils LaumaillÃ©
+ * @version       2.1.20
+ * @copyright     (c) 2009-2014 Nils LaumaillÃ©
+ * @licensing     GNU AFFERO GPL 3.0
+ * @link		  http://www.teampass.net
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+$teampass_config_file = "../includes/settings.php";
 
 function teampass_api_enabled() {
 	$bdd = teampass_connect();
 	$response = $bdd->query("select valeur from ".$GLOBALS['pre']."misc WHERE type = 'admin' AND intitule = 'api'");
 	return $response->fetch(PDO::FETCH_ASSOC);
 }
 
 function teampass_whitelist() {
     $bdd = teampass_connect();
 	$apiip_pool = teampass_get_ips();
-	if (count($apiip_pool) > 0 && !array_search($_SERVER['REMOTE_ADDR'], $apiip_pool)) {
+	if (count($apiip_pool) > 0 && array_search($_SERVER['REMOTE_ADDR'], $apiip_pool) === false) {
 		rest_error('IPWHITELIST');
 	}
 }
 
 function teampass_connect() {
@@ -167,40 +182,23 @@ function rest_get () {
 		$bdd = teampass_connect();
 		$rand_key = teampass_get_randkey();
 
 		if ($GLOBALS['request'][0] == "read") {
 			if($GLOBALS['request'][1] == "category") {
-				$array_category = explode(';',$GLOBALS['request'][2]);
-
-				foreach($array_category as $category) {
-					if(!preg_match_all("/^([\w\:\'\-\sÃ Ã¡Ã¢Ã£Ã¤Ã¥Ã§Ã¨Ã©ÃªÃ«Ã¬Ã­Ã®Ã¯Ã°Ã²Ã³Ã´ÃµÃ¶Ã¹ÃºÃ»Ã¼Ã½Ã¿]+)$/i", $category,$result)) {
-						rest_error('CATEGORY_MALFORMED');
-					}
-				}
-
-				if(count($array_category) > 1 && count($array_category) < 5) {
-					for ($i = count($array_category); $i > 0; $i--) {
-						$slot = $i - 1;
-						if (!$slot) {
-							$category_query .= "select id from ".$GLOBALS['pre']."nested_tree where title LIKE '".$array_category[$slot]."' AND parent_id = 0";
-						} else {
-							$category_query .= "select id from ".$GLOBALS['pre']."nested_tree where title LIKE '".$array_category[$slot]."' AND parent_id = (";
-						}
-					}
-					for ($i = 1; $i < count($array_category); $i++) { $category_query .= ")"; }
-				} elseif (count($array_category) == 1) {
-					$category_query = "select id from ".$GLOBALS['pre']."nested_tree where title LIKE '".$array_category[0]."' AND parent_id = 0";
+				// get ids
+				if (strpos($GLOBALS['request'][2],",") > 0) {
+					$condition = "id_tree IN (".$GLOBALS['request'][2].")";
 				} else {
-					rest_error ('NO_CATEGORY');
+					$condition = "id_tree = '".$GLOBALS['request'][2]."'";
 				}
-				$response = $bdd->query("select id,label,login,pw from ".$GLOBALS['pre']."items where id_tree = (".$category_query.")");
+				$response = $bdd->query("select id,label,login,pw from ".$GLOBALS['pre']."items where ".$condition);
 				while ($data = $response->fetch())
 				{
 					$id = $data['id'];
 					$json[$id]['label'] = utf8_encode($data['label']);
 					$json[$id]['login'] = utf8_encode($data['login']);
-//					$json[$id]['pw'] = teampass_decrypt_pw($data['pw'],SALT,$rand_key);
+					$json[$id]['pw'] = teampass_decrypt_pw($data['pw'],SALT,$rand_key);
 				}
 			} elseif($GLOBALS['request'][1] == "item") {
 				$array_category = explode(';',$GLOBALS['request'][2]);
 				$item = $GLOBALS['request'][3];
 
@@ -323,8 +321,6 @@ function teampass_decrypt_pw($encrypted, $salt, $rand_key, $itcount = 2072)
     $encrypted = substr($encrypted, 43);
     $mac       = substr($encrypted, -64);
     $encrypted = substr($encrypted, 0, -64);
     if ($mac !== hash_hmac('sha256', $encrypted, $salt)) return null;
     return substr(rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, 'ctr', $iv), "\0\4"), strlen($rand_key));
-}
-
-?>
+}
\ No newline at end of file
diff --git a/api/index.php b/api/index.php
index e4e7738e..9611e88e 100644
--- a/api/index.php
+++ b/api/index.php
@@ -1,8 +1,21 @@
 <?php
+/**
+ *
+ * @file          indexapi.php
+ * @author        Nils Laumaillé
+ * @version       2.1.20
+ * @copyright     (c) 2009-2014 Nils Laumaillé
+ * @licensing     GNU AFFERO GPL 3.0
+ * @link		  http://www.teampass.net
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
 
-require_once('config.php');
+//require_once('config.php');
 require_once('functions.php');
 
 header('Content-Type: application/json');
 
 $teampass_api_enabled = teampass_api_enabled();
diff --git a/includes/include.php b/includes/include.php
index e2f960b6..fda592ad 100644
--- a/includes/include.php
+++ b/includes/include.php
@@ -37,6 +37,6 @@ $mngPages = array(
     'manage_folders' => 'folders.php',
     'manage_roles' => 'roles.php',
     'manage_views' => 'views.php',
     'manage_main' => 'admin.php',
     'manage_settings' => 'admin.settings.php'
-);
+);
\ No newline at end of file
diff --git a/items.load.php b/items.load.php
index cfe3b545..72783911 100644
--- a/items.load.php
+++ b/items.load.php
@@ -2615,10 +2615,11 @@ function prepareOneTimeView()
             key     : "<?php echo $_SESSION['key'];?>"
         },
         function(data) {
             //check if format error
             if (data[0].error == "") {
+				$("#div_dialog_message").dialog({minHeight:500,minWidth:750});
                 $("#div_dialog_message").dialog('open');
                 $("#div_dialog_message_text").html(data[0].url);
             } else {
                 $("#item_history_log_error").html(data[0].error).show();
             }
diff --git a/items.php b/items.php
index 89230706..a1c379ae 100644
--- a/items.php
+++ b/items.php
@@ -94,17 +94,17 @@ echo '
 <input type="hidden" id="item_editable" />
 <input type="hidden" id="timestamp_item_displayed" />
 <input type="hidden" id="pf_selected" />';
 // Hidden objects for Item search
 if (isset($_GET['group']) && isset($_GET['id'])) {
-    echo '<input type="hidden" name="open_folder" id="open_folder" value="'.$_GET['group'].'" />';
-    echo '<input type="hidden" name="open_id" id="open_id" value="'.$_GET['id'].'" />';
-    echo '<input type="hidden" name="recherche_group_pf" id="recherche_group_pf" value="', in_array($_GET['group'], $_SESSION['personal_visible_groups']) ? '1' : '', '" />';
+    echo '<input type="hidden" name="open_folder" id="open_folder" value="'.htmlspecialchars($_GET['group']).'" />';
+    echo '<input type="hidden" name="open_id" id="open_id" value="'.htmlspecialchars($_GET['id']).'" />';
+    echo '<input type="hidden" name="recherche_group_pf" id="recherche_group_pf" value="', in_array(htmlspecialchars($_GET['group']), $_SESSION['personal_visible_groups']) ? '1' : '', '" />';
 } elseif (isset($_GET['group']) && !isset($_GET['id'])) {
-    echo '<input type="hidden" name="open_folder" id="open_folder" value="'.$_GET['group'].'" />';
+    echo '<input type="hidden" name="open_folder" id="open_folder" value="'.htmlspecialchars($_GET['group']).'" />';
     echo '<input type="hidden" name="open_id" id="open_id" value="" />';
-    echo '<input type="hidden" name="recherche_group_pf" id="recherche_group_pf" value="', in_array($_GET['group'], $_SESSION['personal_visible_groups']) ? '1' : '', '" />';
+    echo '<input type="hidden" name="recherche_group_pf" id="recherche_group_pf" value="', in_array(htmlspecialchars($_GET['group']), $_SESSION['personal_visible_groups']) ? '1' : '', '" />';
 } else {
     echo '<input type="hidden" name="open_folder" id="open_folder" value="" />';
     echo '<input type="hidden" name="open_id" id="open_id" value="" />';
     echo '<input type="hidden" name="recherche_group_pf" id="recherche_group_pf" value="" />';
 }
@@ -228,11 +228,11 @@ foreach ($folders as $folder) {
         	} else {
         		$fldTitle = str_replace("&", "&amp;", $folder->title);
         	}
             // Prepare folder
             $folderTxt = '
-                    <li class="jstreeopen" id="li_'.$folder->id.'">';
+                    <li class="jstreeopen" id="li_'.$folder->id.'" title="ID ['.$folder->id.']">';
             if (in_array($folder->id, $_SESSION['groupes_visibles'])) {
                 $folderTxt .= '
                             <a id="fld_'.$folder->id.'" class="folder" onclick="ListerItems(\''.$folder->id.'\', \'\', 0);">'.$fldTitle.' (<span class="items_count" id="itcount_'.$folder->id.'">'.$itemsNb.'</span>';
                 // display tree counters
                 if (isset($_SESSION['settings']['tree_counters']) && $_SESSION['settings']['tree_counters'] == 1) {
@@ -356,20 +356,20 @@ echo'
 // Line for LABEL
 echo '
                 <tr>
                     <td valign="top" class="td_title"><span class="ui-icon ui-icon-carat-1-e" style="float: left; margin-right: .3em;">&nbsp;</span>'.$txt['label'].' :</td>
                     <td>
-                        <input type="hidden" id="hid_label" value="', isset($dataItem) ? $dataItem['label'] : '', '" />
+                        <input type="hidden" id="hid_label" value="', isset($dataItem) ? htmlspecialchars($dataItem['label']) : '', '" />
                         <div id="id_label" style="display:inline;"></div>
                     </td>
                 </tr>';
 // Line for DESCRIPTION
 echo '
                 <tr>
                     <td valign="top" class="td_title"><span class="ui-icon ui-icon-carat-1-e" style="float: left; margin-right: .3em;">&nbsp;</span>'.$txt['description'].' :</td>
                     <td>
-                        <div id="id_desc" style="font-style:italic;display:inline;"></div><input type="hidden" id="hid_desc" value="', isset($dataItem) ? $dataItem['description'] : '', '" />
+                        <div id="id_desc" style="font-style:italic;display:inline;"></div><input type="hidden" id="hid_desc" value="', isset($dataItem) ? htmlspecialchars($dataItem['description']) : '', '" />
                     </td>
                 </tr>';
 // Line for PW
 echo '
                 <tr>
@@ -453,11 +453,11 @@ if (isset($_SESSION['settings']['item_extra_fields']) && $_SESSION['settings']['
         foreach ($elem[2] as $field) {
                     echo '
                     <tr class="tr_fields itemCatName_'.$itemCatName.'">
                         <td valign="top" class="td_title">&nbsp;&nbsp;<span class="ui-icon ui-icon-carat-1-e" style="float: left; margin: 0 .3em 0 15px; font-size:9px;">&nbsp;</span><i>'.$field[1].'</i> :</td>
                         <td>
-                            <div id="id_field_'.$field[0].'" style="display:inline;" class="fields_div"></div><input type="hidden" id="hid_field_'.$field[0].'" class="fields" />
+                            <div id="id_field_'.$field[0].'" style="display:inline;" class="fields_div"></div><input type="hidden" id="hid_field_'.htmlspecialchars($field[0]).'" class="fields" />
                         </td>
                     </tr>';
         }
     }
 }
diff --git a/otv.php b/otv.php
index 3ab1ec37..811c6057 100644
--- a/otv.php
+++ b/otv.php
@@ -68,10 +68,17 @@ if (
                 AND l.action = 'at_creation'"
             );
 
             // get data
             $pw = decrypt($dataItem['pw']);
+
+        	// get key for original pw
+        	$originalKey = $db->queryFirst('SELECT rand_key FROM `'.$pre.'keys` WHERE `table` LIKE "items" AND `id` ='.intval($_GET['item_id']));
+        	// unsalt previous pw
+        	$pw = substr(decrypt($dataItem['pw']), strlen($originalKey['rand_key']));
+
+
             $label = $dataItem['label'];
             $email = $dataItem['email'];
             $url = $dataItem['url'];
             $description = preg_replace('/(?<!\\r)\\n+(?!\\r)/', '', strip_tags($dataItem['description'], $k['allowedTags']));
             $login = str_replace('"', '&quot;', $dataItem['login']);
diff --git a/sources/admin.queries.php b/sources/admin.queries.php
index c7df3285..af507c42 100644
--- a/sources/admin.queries.php
+++ b/sources/admin.queries.php
@@ -917,10 +917,11 @@ switch ($_POST['type']) {
 			if (isset($_POST['action']) && $_POST['action'] == "update") {
 				$db->queryUpdate(
 				'api',
 				array(
 				    'label'     => $_POST['label'],
+					'value'     => $_POST['key'],
 				    'timestamp' => time()
 				),
 				"id='".intval($_POST['id'])."'"
 				);
 			}
diff --git a/sources/datatable/datatable.item_edition.php b/sources/datatable/datatable.item_edition.php
index 322b3ed3..4c736576 100644
--- a/sources/datatable/datatable.item_edition.php
+++ b/sources/datatable/datatable.item_edition.php
@@ -29,31 +29,43 @@ $db->register();
 $db = new Database\Core\DbCore($server, $user, $pass, $database, $pre);
 $db->connect();
 
 //Columns name
 $aColumns = array('e.timestamp', 'u.login', 'i.label', 'u.name', 'u.lastname');
+$aSortTypes = array('ASC', 'DESC');
 
 //init SQL variables
 $sOrder = $sLimit = $sWhere = "";
 
 /* BUILD QUERY */
 //Paging
 $sLimit = "";
 if (isset($_GET['iDisplayStart']) && $_GET['iDisplayLength'] != '-1') {
-    $sLimit = "LIMIT ". $_GET['iDisplayStart'] .", ". $_GET['iDisplayLength'] ;
+    $sLimit = "LIMIT ". filter_var($_GET['iDisplayStart'], FILTER_SANITIZE_NUMBER_INT) .", ". filter_var($_GET['iDisplayLength'], FILTER_SANITIZE_NUMBER_INT)."";
 }
 
 //Ordering
 
-if (isset($_GET['iSortCol_0'])) {
+if (isset($_GET['iSortCol_0']) && in_array($_GET['iSortCol_0'], $aSortTypes)) {
     $sOrder = "ORDER BY  ";
-    for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
+/*
+for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
         if ($_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true") {
             $sOrder .= $aColumns[ intval(mysql_real_escape_string($_GET['iSortCol_'.$i])) ]."
             ".mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
         }
     }
+*/
+	for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
+		if (
+			$_GET[ 'bSortable_'.filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT)] == "true" &&
+			preg_match("#^(asc|desc)\$#i", $_GET['sSortDir_'.$i])
+		) {
+			$sOrder .= "".$aColumns[ filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT) ]." "
+			.mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
+		}
+	}
 
     $sOrder = substr_replace($sOrder, "", -2);
     if ($sOrder == "ORDER BY") {
         $sOrder = "";
     }
diff --git a/sources/datatable/datatable.kb.php b/sources/datatable/datatable.kb.php
index 99f20468..6449c14a 100644
--- a/sources/datatable/datatable.kb.php
+++ b/sources/datatable/datatable.kb.php
@@ -29,32 +29,35 @@ $db->register();
 $db = new Database\Core\DbCore($server, $user, $pass, $database, $pre);
 $db->connect();
 
 //Columns name
 $aColumns = array('id', 'category_id', 'label', 'description', 'author_id');
+$aSortTypes = array('ASC', 'DESC');
 
 //init SQL variables
 $sWhere = $sOrder = $sLimit = "";
 
 /* BUILD QUERY */
 //Paging
 $sLimit = "";
 if (isset($_GET['iDisplayStart']) && $_GET['iDisplayLength'] != '-1') {
-    $sLimit = "LIMIT ". mysql_real_escape_string($_GET['iDisplayStart']) .", "
-            . mysql_real_escape_string($_GET['iDisplayLength']) ;
+    $sLimit = "LIMIT ". filter_var($_GET['iDisplayStart'], FILTER_SANITIZE_NUMBER_INT) .", ". filter_var($_GET['iDisplayLength'], FILTER_SANITIZE_NUMBER_INT)."";
 }
 
 //Ordering
 
-if (isset($_GET['iSortCol_0'])) {
+if (isset($_GET['iSortCol_0']) && in_array($_GET['iSortCol_0'], $aSortTypes)) {
     $sOrder = "ORDER BY  ";
-    for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
-        if ($_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true") {
-            $sOrder .= $aColumns[ intval(mysql_real_escape_string($_GET['iSortCol_'.$i])) ]."
-                    ".mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
-        }
-    }
+	for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
+		if (
+			$_GET[ 'bSortable_'.filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT)] == "true" &&
+			preg_match("#^(asc|desc)\$#i", $_GET['sSortDir_'.$i])
+		) {
+			$sOrder .= "".$aColumns[ filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT) ]." "
+			.mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
+		}
+	}
 
     $sOrder = substr_replace($sOrder, "", -2);
     if ($sOrder == "ORDER BY") {
         $sOrder = "";
     }
diff --git a/sources/datatable/datatable.logs.php b/sources/datatable/datatable.logs.php
index d434466c..ea102363 100644
--- a/sources/datatable/datatable.logs.php
+++ b/sources/datatable/datatable.logs.php
@@ -31,32 +31,35 @@ $db = new Database\Core\DbCore($server, $user, $pass, $database, $pre);
 $db->connect();
 
 if (isset($_GET['action']) && $_GET['action'] == "connections") {
     //Columns name
     $aColumns = array('l.date', 'l.label', 'l.qui', 'u.login');
+	$aSortTypes = array('ASC', 'DESC');
 
     //init SQL variables
     $sWhere = $sOrder = $sLimit = "";
 
     /* BUILD QUERY */
     //Paging
     $sLimit = "";
     if (isset($_GET['iDisplayStart']) && $_GET['iDisplayLength'] != '-1') {
-        $sLimit = "LIMIT ". mysql_real_escape_string($_GET['iDisplayStart']) .", "
-                . mysql_real_escape_string($_GET['iDisplayLength']) ;
+        $sLimit = "LIMIT ". filter_var($_GET['iDisplayStart'], FILTER_SANITIZE_NUMBER_INT) .", ". filter_var($_GET['iDisplayLength'], FILTER_SANITIZE_NUMBER_INT)."";
     }
 
     //Ordering
 
-    if (isset($_GET['iSortCol_0'])) {
+    if (isset($_GET['iSortCol_0']) && in_array($_GET['iSortCol_0'], $aSortTypes)) {
         $sOrder = "ORDER BY  ";
-        for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
-            if ($_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true") {
-                $sOrder .= $aColumns[ intval(mysql_real_escape_string($_GET['iSortCol_'.$i])) ]."
-                    ".mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
-            }
-        }
+    	for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
+    		if (
+    			$_GET[ 'bSortable_'.filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT)] == "true" &&
+    			preg_match("#^(asc|desc)\$#i", $_GET['sSortDir_'.$i])
+    		) {
+    			$sOrder .= "".$aColumns[ filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT) ]." "
+    			.mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
+    		}
+    	}
 
         $sOrder = substr_replace($sOrder, "", -2);
         if ($sOrder == "ORDER BY") {
             $sOrder = "";
         }
diff --git a/sources/datatable/datatable.users_logged.php b/sources/datatable/datatable.users_logged.php
index 1e9bac40..6e318c22 100644
--- a/sources/datatable/datatable.users_logged.php
+++ b/sources/datatable/datatable.users_logged.php
@@ -31,32 +31,35 @@ $db->register();
 $db = new Database\Core\DbCore($server, $user, $pass, $database, $pre);
 $db->connect();
 
 //Columns name
 $aColumns = array('login', 'name', 'lastname', 'timestamp', 'last_connexion');
+$aSortTypes = array('ASC', 'DESC');
 
 //init SQL variables
 $sOrder = $sLimit = "";
 
 /* BUILD QUERY */
 //Paging
 $sLimit = "";
 if (isset($_GET['iDisplayStart']) && $_GET['iDisplayLength'] != '-1') {
-    $sLimit = "LIMIT ". mysql_real_escape_string($_GET['iDisplayStart']) .", "
-            . mysql_real_escape_string($_GET['iDisplayLength']);
+    $sLimit = "LIMIT ". filter_var($_GET['iDisplayStart'], FILTER_SANITIZE_NUMBER_INT) .", ". filter_var($_GET['iDisplayLength'], FILTER_SANITIZE_NUMBER_INT)."";
 }
 
 //Ordering
 
-if (isset($_GET['iSortCol_0'])) {
+if (isset($_GET['iSortCol_0']) && in_array($_GET['iSortCol_0'], $aSortTypes)) {
     $sOrder = "ORDER BY  ";
-    for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
-        if ($_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true") {
-            $sOrder .= $aColumns[ intval(mysql_real_escape_string($_GET['iSortCol_'.$i])) ]."
-            ".mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
-        }
-    }
+	for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
+		if (
+			$_GET[ 'bSortable_'.filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT)] == "true" &&
+			preg_match("#^(asc|desc)\$#i", $_GET['sSortDir_'.$i])
+		) {
+			$sOrder .= "".$aColumns[ filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT) ]." "
+			.mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
+		}
+	}
 
     $sOrder = substr_replace($sOrder, "", -2);
     if ($sOrder == "ORDER BY") {
         $sOrder = "";
     }
diff --git a/sources/find.queries.php b/sources/find.queries.php
index 51ec69f3..e0a102bb 100644
--- a/sources/find.queries.php
+++ b/sources/find.queries.php
@@ -82,11 +82,10 @@ if (isset($_GET['iDisplayStart']) && $_GET['iDisplayLength'] != '-1') {
 
 //Ordering
 if (isset($_GET['iSortCol_0']) && in_array($_GET['iSortCol_0'], $aSortTypes)) {
     $sOrder = "ORDER BY  ";
     for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
-
         if (
             $_GET[ 'bSortable_'.filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT)] == "true" &&
             preg_match("#^(asc|desc)\$#i", $_GET['sSortDir_'.$i])
         ) {
             $sOrder .= "".$aColumns[ filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT) ]." "
diff --git a/sources/items.queries.php b/sources/items.queries.php
index 1cac4620..a584c02b 100644
--- a/sources/items.queries.php
+++ b/sources/items.queries.php
@@ -1247,11 +1247,11 @@ if (isset($_POST['type'])) {
                 $arrData['url'] = $dataItem['url'];
                 if (!empty($dataItem['url'])) {
                     $arrData['link'] = "&nbsp;<a href='".$dataItem['url']."' target='_blank'><img src='includes/images/arrow_skip.png' style='border:0px;' title='".$txt['open_url_link']."'></a>";
                 }
 
-                $arrData['description'] = preg_replace('/(?<!\\r)\\n+(?!\\r)/', '', strip_tags($dataItem['description'], $allowedTags));
+                $arrData['description'] = preg_replace('/(?<!\\r)\\n+(?!\\r)/', '', strip_tags($dataItem['description'], $k['allowedTags']));
                 $arrData['login'] = str_replace('"', '&quot;', $dataItem['login']);
                 $arrData['id_restricted_to'] = $listeRestriction;
                 $arrData['id_restricted_to_roles'] = count($listRestrictionRoles) > 0 ? implode(";", $listRestrictionRoles).";" : "";
                 $arrData['tags'] = str_replace('"', '&quot;', $tags);
                 $arrData['folder'] = $dataItem['id_tree'];
diff --git a/sources/users.queries.php b/sources/users.queries.php
index 83f79ec5..d141ad1a 100644
--- a/sources/users.queries.php
+++ b/sources/users.queries.php
@@ -371,12 +371,12 @@ if (!empty($_POST['type'])) {
                 'log_system',
                 array(
                     'type' => 'user_mngt',
                     'date' => time(),
                     'label' => 'at_user_email_changed:'.$data[0],
-                    'qui' => $_SESSION['user_id'],
-                    'field_1' => $_POST['id']
+                    'qui' => intval($_SESSION['user_id']),
+                    'field_1' => intval($_POST['id'])
                    )
             );
         	echo '[{"error" : "no"}]';
             break;
         /**

Vulnerable code:             <span class="ui-icon ui-icon-wrench" style="float: left; margin-right: .3em;">&nbsp;</span>
                For any kind of Help and Support, please use the <a target="_blank" href="http://www.teampass.net/forum" style="font-weight:bold;font-style:italic;">Forum</a><br />
    $("#api_db_type").val("admin_action_api_save_key");
<?php

// Set Teampass path
$teampass_path = "E:/xampp/htdocs/Teampass";
// Set Teampass config file
$teampass_config_file = $teampass_path."/includes/settings.php";
// Set Teampass secure keys file path
$teampass_sk_file = "/space/private/teampass/sk.php";
?>
	if (count($apiip_pool) > 0 && !array_search($_SERVER['REMOTE_ADDR'], $apiip_pool)) {
				$array_category = explode(';',$GLOBALS['request'][2]);

				foreach($array_category as $category) {
					if(!preg_match_all("/^([\w\:\'\-\sÃ Ã¡Ã¢Ã£Ã¤Ã¥Ã§Ã¨Ã©ÃªÃ«Ã¬Ã­Ã®Ã¯Ã°Ã²Ã³Ã´ÃµÃ¶Ã¹ÃºÃ»Ã¼Ã½Ã¿]+)$/i", $category,$result)) {
						rest_error('CATEGORY_MALFORMED');
					}
				}

				if(count($array_category) > 1 && count($array_category) < 5) {
					for ($i = count($array_category); $i > 0; $i--) {
						$slot = $i - 1;
						if (!$slot) {
							$category_query .= "select id from ".$GLOBALS['pre']."nested_tree where title LIKE '".$array_category[$slot]."' AND parent_id = 0";
						} else {
							$category_query .= "select id from ".$GLOBALS['pre']."nested_tree where title LIKE '".$array_category[$slot]."' AND parent_id = (";
						}
					}
					for ($i = 1; $i < count($array_category); $i++) { $category_query .= ")"; }
				} elseif (count($array_category) == 1) {
					$category_query = "select id from ".$GLOBALS['pre']."nested_tree where title LIKE '".$array_category[0]."' AND parent_id = 0";
					rest_error ('NO_CATEGORY');
				$response = $bdd->query("select id,label,login,pw from ".$GLOBALS['pre']."items where id_tree = (".$category_query.")");
//					$json[$id]['pw'] = teampass_decrypt_pw($data['pw'],SALT,$rand_key);
}

?>
require_once('config.php');
);
    echo '<input type="hidden" name="open_folder" id="open_folder" value="'.$_GET['group'].'" />';
    echo '<input type="hidden" name="open_id" id="open_id" value="'.$_GET['id'].'" />';
    echo '<input type="hidden" name="recherche_group_pf" id="recherche_group_pf" value="', in_array($_GET['group'], $_SESSION['personal_visible_groups']) ? '1' : '', '" />';
    echo '<input type="hidden" name="open_folder" id="open_folder" value="'.$_GET['group'].'" />';
    echo '<input type="hidden" name="recherche_group_pf" id="recherche_group_pf" value="', in_array($_GET['group'], $_SESSION['personal_visible_groups']) ? '1' : '', '" />';
                    <li class="jstreeopen" id="li_'.$folder->id.'">';
                        <input type="hidden" id="hid_label" value="', isset($dataItem) ? $dataItem['label'] : '', '" />
                        <div id="id_desc" style="font-style:italic;display:inline;"></div><input type="hidden" id="hid_desc" value="', isset($dataItem) ? $dataItem['description'] : '', '" />
                            <div id="id_field_'.$field[0].'" style="display:inline;" class="fields_div"></div><input type="hidden" id="hid_field_'.$field[0].'" class="fields" />
    $sLimit = "LIMIT ". $_GET['iDisplayStart'] .", ". $_GET['iDisplayLength'] ;
if (isset($_GET['iSortCol_0'])) {
    for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
    $sLimit = "LIMIT ". mysql_real_escape_string($_GET['iDisplayStart']) .", "
            . mysql_real_escape_string($_GET['iDisplayLength']) ;
if (isset($_GET['iSortCol_0'])) {
    for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
        if ($_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true") {
            $sOrder .= $aColumns[ intval(mysql_real_escape_string($_GET['iSortCol_'.$i])) ]."
                    ".mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
        }
    }
        $sLimit = "LIMIT ". mysql_real_escape_string($_GET['iDisplayStart']) .", "
                . mysql_real_escape_string($_GET['iDisplayLength']) ;
    if (isset($_GET['iSortCol_0'])) {
        for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
            if ($_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true") {
                $sOrder .= $aColumns[ intval(mysql_real_escape_string($_GET['iSortCol_'.$i])) ]."
                    ".mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
            }
        }
    $sLimit = "LIMIT ". mysql_real_escape_string($_GET['iDisplayStart']) .", "
            . mysql_real_escape_string($_GET['iDisplayLength']);
if (isset($_GET['iSortCol_0'])) {
    for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
        if ($_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true") {
            $sOrder .= $aColumns[ intval(mysql_real_escape_string($_GET['iSortCol_'.$i])) ]."
            ".mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
        }
    }

                $arrData['description'] = preg_replace('/(?<!\\r)\\n+(?!\\r)/', '', strip_tags($dataItem['description'], $allowedTags));
                    'qui' => $_SESSION['user_id'],
                    'field_1' => $_POST['id']
Fixed code:     $("#api_db_type").val("admin_action_api_save_ip");

/**
 *
 * @file          configapi.php
 * @author        Nils LaumaillÃ©
 * @version       2.1.20
 * @copyright     (c) 2009-2014 Nils LaumaillÃ©
 * @licensing     GNU AFFERO GPL 3.0
 * @link		  http://www.teampass.net
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

$teampass_config_file = "../includes/settings.php";
	if (count($apiip_pool) > 0 && array_search($_SERVER['REMOTE_ADDR'], $apiip_pool) === false) {
				// get ids
				if (strpos($GLOBALS['request'][2],",") > 0) {
					$condition = "id_tree IN (".$GLOBALS['request'][2].")";
					$condition = "id_tree = '".$GLOBALS['request'][2]."'";
				$response = $bdd->query("select id,label,login,pw from ".$GLOBALS['pre']."items where ".$condition);
					$json[$id]['pw'] = teampass_decrypt_pw($data['pw'],SALT,$rand_key);
}
/**
 *
 * @file          indexapi.php
 * @author        Nils Laumaillé
 * @version       2.1.20
 * @copyright     (c) 2009-2014 Nils Laumaillé
 * @licensing     GNU AFFERO GPL 3.0
 * @link		  http://www.teampass.net
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
//require_once('config.php');
);
				$("#div_dialog_message").dialog({minHeight:500,minWidth:750});
    echo '<input type="hidden" name="open_folder" id="open_folder" value="'.htmlspecialchars($_GET['group']).'" />';
    echo '<input type="hidden" name="open_id" id="open_id" value="'.htmlspecialchars($_GET['id']).'" />';
    echo '<input type="hidden" name="recherche_group_pf" id="recherche_group_pf" value="', in_array(htmlspecialchars($_GET['group']), $_SESSION['personal_visible_groups']) ? '1' : '', '" />';
    echo '<input type="hidden" name="open_folder" id="open_folder" value="'.htmlspecialchars($_GET['group']).'" />';
    echo '<input type="hidden" name="recherche_group_pf" id="recherche_group_pf" value="', in_array(htmlspecialchars($_GET['group']), $_SESSION['personal_visible_groups']) ? '1' : '', '" />';
                    <li class="jstreeopen" id="li_'.$folder->id.'" title="ID ['.$folder->id.']">';
                        <input type="hidden" id="hid_label" value="', isset($dataItem) ? htmlspecialchars($dataItem['label']) : '', '" />
                        <div id="id_desc" style="font-style:italic;display:inline;"></div><input type="hidden" id="hid_desc" value="', isset($dataItem) ? htmlspecialchars($dataItem['description']) : '', '" />
                            <div id="id_field_'.$field[0].'" style="display:inline;" class="fields_div"></div><input type="hidden" id="hid_field_'.htmlspecialchars($field[0]).'" class="fields" />

        	// get key for original pw
        	$originalKey = $db->queryFirst('SELECT rand_key FROM `'.$pre.'keys` WHERE `table` LIKE "items" AND `id` ='.intval($_GET['item_id']));
        	// unsalt previous pw
        	$pw = substr(decrypt($dataItem['pw']), strlen($originalKey['rand_key']));


					'value'     => $_POST['key'],
$aSortTypes = array('ASC', 'DESC');
    $sLimit = "LIMIT ". filter_var($_GET['iDisplayStart'], FILTER_SANITIZE_NUMBER_INT) .", ". filter_var($_GET['iDisplayLength'], FILTER_SANITIZE_NUMBER_INT)."";
if (isset($_GET['iSortCol_0']) && in_array($_GET['iSortCol_0'], $aSortTypes)) {
/*
for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
*/
	for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
		if (
			$_GET[ 'bSortable_'.filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT)] == "true" &&
			preg_match("#^(asc|desc)\$#i", $_GET['sSortDir_'.$i])
		) {
			$sOrder .= "".$aColumns[ filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT) ]." "
			.mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
		}
	}
$aSortTypes = array('ASC', 'DESC');
    $sLimit = "LIMIT ". filter_var($_GET['iDisplayStart'], FILTER_SANITIZE_NUMBER_INT) .", ". filter_var($_GET['iDisplayLength'], FILTER_SANITIZE_NUMBER_INT)."";
if (isset($_GET['iSortCol_0']) && in_array($_GET['iSortCol_0'], $aSortTypes)) {
	for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
		if (
			$_GET[ 'bSortable_'.filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT)] == "true" &&
			preg_match("#^(asc|desc)\$#i", $_GET['sSortDir_'.$i])
		) {
			$sOrder .= "".$aColumns[ filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT) ]." "
			.mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
		}
	}
	$aSortTypes = array('ASC', 'DESC');
        $sLimit = "LIMIT ". filter_var($_GET['iDisplayStart'], FILTER_SANITIZE_NUMBER_INT) .", ". filter_var($_GET['iDisplayLength'], FILTER_SANITIZE_NUMBER_INT)."";
    if (isset($_GET['iSortCol_0']) && in_array($_GET['iSortCol_0'], $aSortTypes)) {
    	for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
    		if (
    			$_GET[ 'bSortable_'.filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT)] == "true" &&
    			preg_match("#^(asc|desc)\$#i", $_GET['sSortDir_'.$i])
    		) {
    			$sOrder .= "".$aColumns[ filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT) ]." "
    			.mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
    		}
    	}
$aSortTypes = array('ASC', 'DESC');
    $sLimit = "LIMIT ". filter_var($_GET['iDisplayStart'], FILTER_SANITIZE_NUMBER_INT) .", ". filter_var($_GET['iDisplayLength'], FILTER_SANITIZE_NUMBER_INT)."";
if (isset($_GET['iSortCol_0']) && in_array($_GET['iSortCol_0'], $aSortTypes)) {
	for ($i=0; $i<intval($_GET['iSortingCols']); $i++) {
		if (
			$_GET[ 'bSortable_'.filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT)] == "true" &&
			preg_match("#^(asc|desc)\$#i", $_GET['sSortDir_'.$i])
		) {
			$sOrder .= "".$aColumns[ filter_var($_GET['iSortCol_'.$i], FILTER_SANITIZE_NUMBER_INT) ]." "
			.mysql_real_escape_string($_GET['sSortDir_'.$i]) .", ";
		}
	}
                $arrData['description'] = preg_replace('/(?<!\\r)\\n+(?!\\r)/', '', strip_tags($dataItem['description'], $k['allowedTags']));
                    'qui' => intval($_SESSION['user_id']),
                    'field_1' => intval($_POST['id'])