CVE-2017-15053: Improper Privilege Management (CWE-269)
value: TeamPass before 2.1.27.9 does not properly enforce manager access control when requesting roles.queries.php. It is then possible for a manager user to modify any arbitrary roles within the application, or delete any arbitrary role. To exploit the vulnerability, an authenticated attacker must have the manager rights on the application, then tamper with the requests sent directly, for example by changing the "id" parameter when invoking "delete_role" on roles.queries.php.
CWE description: The product does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.
CVSS v3 base score: 4.9
Published: 2017-11-27T19:29Z
Repository: https://github.com/nilsteampassnet/TeamPass
Language: PHP
Files changed: changelog.md, includes/css/passman.css, index.php, install/install.queries.php, install/upgrade_run_2.1.27.php, items.load.php, items.php, roles.load.php, roles.php, sources/import.queries.php, sources/roles.queries.php
Commit date: 2017-10-04 19:14:32 +0200
Commit message: 2.1.27

Added filter in Roles page
Improve truncating title in list of items

Diff: diff --git a/changelog.md b/changelog.md
index 909d39985..5c451dd7f 100755
--- a/changelog.md
+++ b/changelog.md
@@ -9,10 +9,11 @@
  Fixed some other security failures (credit to ​security at Amossys)
  Improved security regarding uploading files
  Fixed issue while restoring DB from administration page
  Improved / Fixed administration task for encrypting/decrypting files
  Improved security regarding item history display
+ Added filter in Roles
  #1947 Dependency & array update in install checks
  #1945 Cannot delete items
  #1944 File upload results in error
  #1941 Visualisation problems
 
diff --git a/includes/css/passman.css b/includes/css/passman.css
index 2c74ffe82..9516ac5b9 100644
--- a/includes/css/passman.css
+++ b/includes/css/passman.css
@@ -163,11 +163,11 @@ width:100px;
 float:left;
 }
 
 .td_title{
 font-weight:bold;
-min-width: 150px;
+min-width: 120px;
 }
 
 ul{
 list-style-type:none;
 }
@@ -179,10 +179,15 @@ list-style-type:none;
   color: #464646;
   margin: 3px 0px 10px 0px;
   padding: 10px;
 }
 
+.normal {
+  font: normal; "Lucida Grande";
+  color: #464646;
+}
+
 .readme{
   font-family: sans-serif;
   font-size: 9px;
   line-height:15px;
   margin-top: 20px;
@@ -390,6 +395,11 @@ div.dataTables_processing { z-index: 1; }
   height: 15px;
   }
 
 .hidden {
   display: none;
+}
+
+.no-border {
+  border: none;
+  border-collapse: collapse;
 }
\ No newline at end of file
diff --git a/index.php b/index.php
index 46d0c9937..4c7d41f5f 100644
--- a/index.php
+++ b/index.php
@@ -115,10 +115,11 @@ $session_nb_folders =           $superGlobal->get("nb_folders", "SESSION");
 $session_nb_roles =             $superGlobal->get("nb_roles", "SESSION");
 $session_autoriser =            $superGlobal->get("autoriser", "SESSION");
 $session_hide_maintenance =     $superGlobal->get("hide_maintenance", "SESSION");
 $session_initial_url =          $superGlobal->get("initial_url", "SESSION");
 $server_request_uri =           $superGlobal->get("REQUEST_URI", "SERVER");
+$session_nb_users_online =        $superGlobal->get("nb_users_online", "SESSION");
 
 
 /* DEFINE WHAT LANGUAGE TO USE */
 if (isset($_GET['language']) === true) {
     // case of user has change language in the login page
@@ -781,11 +782,11 @@ if (isset($_SESSION['CPM'])) {
             <a href="http://teampass.readthedocs.io/en/latest/" target="_blank" style="color:#F0F0F0;" class="tip" title="'.addslashes($LANG['documentation_canal']).' ReadTheDocs"><i class="fa fa-book"></i></a>
             &nbsp;
             <a href="https://www.reddit.com/r/TeamPass/" target="_blank" style="color:#F0F0F0;" class="tip" title="'.addslashes($LANG['admin_help']).'"><i class="fa fa-reddit-alien"></i></a>
         </div>
         <div style="float:left;width:32%;text-align:center;">
-            ', ($session_user_id !== null && empty($session_user_id) === false) ? '<i class="fa fa-users"></i>&nbsp;'.$_SESSION['nb_users_online'].'&nbsp;'.$LANG['users_online'].'&nbsp;|&nbsp;<i class="fa fa-hourglass-end"></i>&nbsp;'.$LANG['index_expiration_in'].'&nbsp;<div style="display:inline;" id="countdown"></div>' : '', '
+            ', ($session_user_id !== null && empty($session_user_id) === false) ? '<i class="fa fa-users"></i>&nbsp;'.$session_nb_users_online.'&nbsp;'.$LANG['users_online'].'&nbsp;|&nbsp;<i class="fa fa-hourglass-end"></i>&nbsp;'.$LANG['index_expiration_in'].'&nbsp;<div style="display:inline;" id="countdown"></div>' : '', '
         </div><div id="countdown2"></div>
         <div style="float:right;text-align:right;">
             <i class="fa fa-clock-o"></i>&nbsp;'. $LANG['server_time']." : ".@date($SETTINGS['date_format'], (string) $_SERVER['REQUEST_TIME'])." - ".@date($SETTINGS['time_format'], (string) $_SERVER['REQUEST_TIME']).'
         </div>
     </div>';
diff --git a/install/install.queries.php b/install/install.queries.php
index 24d0f2fc6..2c54f402f 100644
--- a/install/install.queries.php
+++ b/install/install.queries.php
@@ -362,11 +362,11 @@ if (null !== $post_type) {
                         );
                     } elseif ($task === "misc") {
                         $mysqli_result = mysqli_query(
                             $dbTmp,
                             "CREATE TABLE IF NOT EXISTS `".$var['tbl_prefix']."misc` (
-                            `id` int(12) NOT null AUTO_INCREMENT,
+                            `increment_id` int(12) NOT null AUTO_INCREMENT,
                             `type` varchar(50) NOT NULL,
                             `intitule` varchar(100) NOT NULL,
                             `valeur` varchar(500) NOT NULL,
                             PRIMARY KEY (`id`)
                             ) CHARSET=utf8;"
diff --git a/install/upgrade_run_2.1.27.php b/install/upgrade_run_2.1.27.php
index 4013937ce..ef4f8203d 100644
--- a/install/upgrade_run_2.1.27.php
+++ b/install/upgrade_run_2.1.27.php
@@ -186,15 +186,23 @@ if (isset($session_tp_defuse_installed) !== true) {
 }
 
 // alter table Items
 mysqli_query($db_link, "ALTER TABLE `".$pre."items` MODIFY pw_len INT(5) NOT NULL DEFAULT '0'");
 
-// alter table misc to add an index
-mysqli_query(
-    $db_link,
-    "ALTER TABLE `".$pre."misc` ADD `id` INT(12) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`)"
-);
+// alter table MISC - rename ID is exists
+$result = mysqli_query("SHOW COLUMNS FROM `misc` LIKE 'id'");
+if (mysqli_num_rows($result) !== 0) {
+    // Change name of field
+    mysqli_query($db_link, "ALTER TABLE `".$pre."misc` CHANGE `id` `increment_id` INT(12) NOT NULL");
+} else {
+    // alter table misc to add an index
+    $res = addColumnIfNotExist(
+        $pre."misc",
+        "increment_id",
+        "INT(12) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`)"
+    );
+}
 
 // alter table misc to add an index
 mysqli_query(
     $db_link,
     "ALTER TABLE `".$pre."log_items` ADD `increment_id` INT(12) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`increment_id`)"
@@ -701,11 +709,11 @@ if ($any_settings === true) {
     $result = fwrite(
         $file_handler,
         utf8_encode(
             "<?php
 global \$SETTINGS;
-\$SETTINGS = array (" . $config_text . "            
+\$SETTINGS = array (" . $config_text . "
     );"
         )
     );
 }
 fclose($file_handler);
diff --git a/items.load.php b/items.load.php
index f3365d308..eff6fa8de 100755
--- a/items.load.php
+++ b/items.load.php
@@ -790,11 +790,13 @@ function AjouterItem()
     }
 }
 
 function EditerItem()
 {
-    $("#div_formulaire_edition_item_info").html("<?php echo "<i class='fa fa-cog fa-spin fa-lg'></i>&nbsp;".addslashes($LANG['please_wait'])."..."; ?>").show();
+    $("#div_formulaire_edition_item_info")
+        .html("<?php echo "<i class='fa fa-cog fa-spin fa-lg'></i>&nbsp;".addslashes($LANG['please_wait'])."..."; ?>")
+        .removeClass("hidden");
     $("#item_detail_zone_loader").addClass("hidden");
     var erreur = "";
     var  reg=new RegExp("[.|,|;|:|!|=|+|-|*|/|#|\"|'|&]");
 
     //Complete url format
@@ -963,11 +965,11 @@ function EditerItem()
                             .html('<?php echo addslashes($LANG['error_not_allowed_to']); ?>')
                             .show();
                         LoadingPage();
                     } else {
                         //refresh item in list
-                        $("#fileclass"+data.id).text($('#edit_label').val());
+                        $("#fileclass"+data.id).html('<div class="truncate">' + $('#edit_label').val() + '</div>');
 
                         //Refresh form
                         $("#id_label").text($('#edit_label').val());
                         //$("#id_pw").text($('#edit_pw1').val());
                         $("#id_email").html($('#edit_email').val());
@@ -1086,20 +1088,28 @@ function EditerItem()
 
                 }
             );*/
 
         } else {
-            $('#edit_show_error').html("<?php echo addslashes($LANG['error_complex_not_enought']); ?>").show();
+            $('#edit_show_error')
+                .html("<?php echo addslashes($LANG['error_complex_not_enought']); ?>")
+                .show();
             $("#div_formulaire_edition_item ~ .ui-dialog-buttonpane").find("button:contains('<?php echo addslashes($LANG['save_button']); ?>')").prop("disabled", false);
-            $("#div_formulaire_edition_item_info").addClass("hidden").html("");
+            $("#div_formulaire_edition_item_info")
+                .addClass("hidden")
+                .html("");
         }
     }
 
     if (erreur != "") {
         $('#edit_show_error').html(erreur).show();
-        $("#div_formulaire_edition_item_info").addClass("hidden").html("");
-        $("#div_formulaire_edition_item ~ .ui-dialog-buttonpane").find("button:contains('<?php echo addslashes($LANG['save_button']); ?>')").prop("disabled", false);
+        $("#div_formulaire_edition_item_info")
+            .addClass("hidden")
+            .html("");
+        $("#div_formulaire_edition_item ~ .ui-dialog-buttonpane")
+            .find("button:contains('<?php echo addslashes($LANG['save_button']); ?>')")
+            .prop("disabled", false);
     }
 }
 
 function AddNewFolder()
 {
@@ -3291,10 +3301,15 @@ $(function() {
                         key     : "<?php echo $_SESSION['key']; ?>"
                     },
                     function(data) {
                         if (data[0].error === "") {
                             $("#div_suggest_change_wait").html("<?php echo addslashes($LANG['suggestion_done']); ?>").show(1).delay(1500).fadeOut(1000);
+
+                            // set indicator if item has change proposal
+                            $("#item_extra_info").prepend('<i class="fa fa-lightbulb-o fa-sm mi-yellow tip" title="<?php echo addslashes($LANG['item_has_change_proposal']); ?>" onclick=""></i>&nbsp;');
+                            $(".tip").tooltipster({multiple: true});
+
                             setTimeout(
                                 function() {
                                     $("#div_suggest_change").dialog("close");
                                 },
                                 500
diff --git a/items.php b/items.php
index d1480e8a6..95af3c7e6 100644
--- a/items.php
+++ b/items.php
@@ -224,15 +224,15 @@ echo'
                 <div id="item_details_expired" style="display:none;background-color:white; margin:5px;">
                     <div class="ui-state-error ui-corner-all" style="padding:2px;">
                         <i class="fa fa-warning"></i>&nbsp;<b>'.$LANG['pw_is_expired_-_update_it'].'</b>
                     </div>
                 </div>
-                <table width="100%" id="item_details_table">';
+                <table width="100%" class="no-border" id="item_details_table">';
 // Line for LABEL
 echo '
                 <tr>
-                    <td valign="top" class="td_title" colspan="2">
+                    <td valign="top" class="td_title" width="120px" style="background-color:rgba(178, 178, 178, 0.13);">
                         <div class="quick_menu2" style="float:left; margin-right: 5px;">
                             <ul class="quick_menu ui-menu">
                                 <li><i class="fa fa-bars"></i>
                                     <ul class="menu_250">
                                         <li id="menu_button_copy_pw" class="copy_clipboard"><i class="fa fa-lock fa-fw"></i>&nbsp; '.$LANG['pw_copy_clipboard'].'</li>
@@ -250,11 +250,15 @@ echo '
                                         <li onclick="OpenDialog(\'div_suggest_change\', \'false\')"><i class="fa fa-random fa-fw"></i>&nbsp; '.$LANG['suggest_password_change'].'</li>' : '', '
                                     </ul>
                                 </li>
                             </ul>
                         </div>
-                        <div id="id_label" style="display:inline; margin:4px 0px 0px 120px; "></div>
+                    </td>
+                    <td valign="middle" style="background-color:rgba(178, 178, 178, 0.13);">
+                        <span id="id_label" style="font-weight:bold;"></span>
+                    </td>
+                    <td style="background-color:rgba(178, 178, 178, 0.13);">
                         <input type="hidden" id="hid_label" value="', isset($dataItem) ? htmlspecialchars($dataItem['label']) : '', '" />
                         <div style="float:right; font-family:arial; margin-right:5px;" id="item_viewed_x_times"></div>
 
                         <!-- INFO -->
                         <div class="" style="float:right;margin-right:5px;" id="item_extra_info" title=""></div>
@@ -264,101 +268,101 @@ echo '
                 </tr>';
 // Line for DESCRIPTION
 echo '
                 <tr>
                     <td valign="top" class="td_title" width="180px">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['description'].' :</td>
-                    <td>
+                    <td colspan="2">
                         <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>
                     <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['pw'].' :<span id="button_quick_pw_copy" class="fa fa-paste fa-border fa-sm tip" style="cursor:pointer;display:none;float:right;margin-right:2px;" title="'.$LANG['item_menu_copy_pw'].'"></i></td>
-                    <td>
+                    <td colspan="2">
                         &nbsp;
                         <div id="id_pw" class="unhide_masked_data" style="float:left; cursor:pointer; width:300px;"></div>
                         <input type="hidden" id="hid_pw" value="" />
                         <input type="hidden" id="pw_shown" value="0" />
                     </td>
                 </tr>';
 // Line for LOGIN
 echo '
                 <tr>
                     <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['index_login'].' :<span id="button_quick_login_copy" class="fa fa-paste fa-border fa-sm tip" style="cursor:pointer;display:none;float:right;margin-right:2px;" title="'.$LANG['item_menu_copy_login'].'"></span></td>
-                    <td>
+                    <td colspan="2">
                         <div id="id_login" style="float:left;"></div>
                         <input type="hidden" id="hid_login" value="" />
                     </td>
                 </tr>';
 // Line for EMAIL
 echo '
                 <tr>
                     <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['email'].' :</td>
-                    <td>
+                    <td colspan="2">
                         <div id="id_email" style="display:inline;"></div><input type="hidden" id="hid_email" value="" />
                     </td>
                 </tr>';
 // Line for URL
 echo '
                 <tr>
                     <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['url'].' :</td>
-                    <td>
+                    <td colspan="2">
                         <div id="id_url" style="display:inline;"></div><input type="hidden" id="hid_url" value="" />
                     </td>
                 </tr>';
 // Line for FILES
 echo '
                 <tr>
                     <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['files_&_images'].' :</td>
-                    <td>
+                    <td colspan="2">
                         <div id="id_files" style="display:inline;font-size:11px;"></div><input type="hidden" id="hid_files" />
                         <div id="dialog_files" style="display: none;">
 
                         </div>
                     </td>
                 </tr>';
 // Line for RESTRICTED TO
 echo '
                 <tr>
                     <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['restricted_to'].' :</td>
-                    <td>
+                    <td colspan="2">
                         <div id="id_restricted_to" style="display:inline;"></div><input type="hidden" id="hid_restricted_to" /><input type="hidden" id="hid_restricted_to_roles" />
                     </td>
                 </tr>';
 // Line for TAGS
 echo '
                 <tr>
                     <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['tags'].' :</td>
-                    <td>
+                    <td colspan="2">
                         <div id="id_tags" style="display:inline;"></div><input type="hidden" id="hid_tags" />
                     </td>
                 </tr>';
 // Line for KBs
 if (isset($SETTINGS['enable_kb']) && $SETTINGS['enable_kb'] == 1) {
     echo '
-                    <tr>
-                        <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['kbs'].' :</td>
-                        <td>
-                            <div id="id_kbs" style="display:inline;"></div><input type="hidden" id="hid_kbs" />
-                        </td>
-                    </tr>';
+                <tr>
+                    <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['kbs'].' :</td>
+                    <td colspan="2">
+                        <div id="id_kbs" style="display:inline;"></div><input type="hidden" id="hid_kbs" />
+                    </td>
+                </tr>';
 }
 // lines for FIELDS
 if (isset($SETTINGS['item_extra_fields']) && $SETTINGS['item_extra_fields'] == 1) {
     foreach ($_SESSION['item_fields'] as $elem) {
         $itemCatName = $elem[0];
         echo '
-                    <tr class="tr_fields hidden" id="tr_catfield_'.$elem[0].'">
-                        <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$elem[1].' :</td>
-                        <td></td>
-                    </tr>';
+                <tr class="tr_fields hidden" id="tr_catfield_'.$elem[0].'">
+                    <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$elem[1].' :</td>
+                    <td colspan="2"></td>
+                </tr>';
         foreach ($elem[2] as $field) {
             echo '
                     <tr class="tr_cf tr_fields hidden" id="cf_tr_'.$field[0].'">
                         <td valign="top" class="td_title">&nbsp;&nbsp;<i class="fa fa-caret-right"></i>&nbsp;<i>'.$field[1].'</i> :</td>
-                        <td>';
+                        <td colspan="2">';
             if ($field[3] === "masked") {
                 echo '
                             <div id="id_field_'.htmlspecialchars($field[0]).'_'.$elem[0].'" style="float:left; cursor:pointer; width:300px;" class="fields_div unhide_masked_data pointer"></div><input type="hidden" id="hid_field_'.htmlspecialchars($field[0]).'_'.$elem[0].'" class="fields" />';
             } else {
                 echo '
@@ -776,11 +780,11 @@ if (isset($SETTINGS['item_extra_fields']) && $SETTINGS['item_extra_fields'] == 1
             </div>
         </div>
     </div>';
 }
 echo '
-    <div style="display:none; padding:5px;" id="div_formulaire_edition_item_info" class="ui-state-default ui-corner-all"></div>
+    <div style="padding:5px;" id="div_formulaire_edition_item_info" class="ui-state-default ui-corner-all hidden"></div>
     </div>
     </form>
 </div>';
 
 /*
diff --git a/roles.load.php b/roles.load.php
index a4cbada21..939e92388 100644
--- a/roles.load.php
+++ b/roles.load.php
@@ -203,12 +203,10 @@ $(function() {
         open: function() {
             $("#accordion").accordion({ autoHeight: false, navigation: true, collapsible: true, active: false });
         }
     });
 
-
-
     refresh_roles_matrix();
 });
 
 //###########
 //## FUNCTION : Change the actual right of the role other the select folder
@@ -278,11 +276,11 @@ function allow_pw_change_for_role(id, value)
 function refresh_roles_matrix(order)
 {
     $("#div_loading").show();
 
     //clean up
-    $("#roles_next, #roles_previous").hide();
+    $(".roles_next, .roles_previous").hide();
 
     //manage start query
     if (order == "next") {
         var start = $('#next_role').val();
     } else if (order == "previous") {
@@ -297,30 +295,46 @@ function refresh_roles_matrix(order)
     //send query
     $.post(
         "sources/roles.queries.php",
         {
             type    : "refresh_roles_matrix",
-            start    : start
+            start   : start,
+            filter  : $("#filter_roles").val()
         },
         function(data) {
             //decrypt data
             data = $.parseJSON(data);
             $("#matrice_droits").html("");
-            if (data.new_table != "") {
+            if (data.new_table !== "") {
                 $("#matrice_droits").html(data.new_table);
-                if (data.next < data.all) {
-                    $("#roles_next").show();
+                if (data.next < data.all && data.next >= 9) {
+                    $(".roles_next").show();
                 }
                 if (data.next >= 9 && data.previous >= 0) {
-                    $("#roles_previous").show();
+                    $(".roles_previous").show();
                 }
                 //manage next & previous arrows
                 $('#next_role').val(data.next);
                 $('#previous_role').val(data.previous);
+
+                $("#filter_roles").val("");
             } else {
                 $("#matrice_droits").html(data.error);
             }
+
+            // Prepare autocomplete for filterbox
+            //Prepare autocomplete for filter
+            $("#filter_roles")
+                .autocomplete({
+                    source: data.list_of_roles,
+                    focus: function() {
+                        // prevent value inserted on focus
+                        return false;
+                    }
+                }
+            );
+
             $("#div_loading").hide();
         }
    );
 }
 
diff --git a/roles.php b/roles.php
index 16e0c91a9..44076b1ce 100644
--- a/roles.php
+++ b/roles.php
@@ -48,21 +48,34 @@ foreach ($rows as $reccord) {
 //display
 echo '
 <div class="title ui-widget-content ui-corner-all">
     '.$LANG['admin_functions'].'&nbsp;&nbsp;
     <button title="'.htmlentities(strip_tags($LANG['add_role_tip']), ENT_QUOTES).'" onclick="OpenDialog(\'add_new_role\')" class="button" style="font-size:16px;">
-        <i class="fa fa-plus"></i>
+        <span class="fa fa-plus"></span>
     </button>
+    &nbsp;
+    <span class="normal"><input id="filter_roles" class="ui-widget ui-corner-all" type="text" value="" placeholder="No filter" /></span>
     <button title="'.htmlentities(strip_tags($LANG['refresh_matrix']), ENT_QUOTES).'" onclick="refresh_roles_matrix()" class="button" style="font-size:16px;">
-        <i class="fa fa-refresh"></i>
+        <span class="fa fa-refresh"></span>
+    </button>
+    &nbsp;
+    <button onclick="refresh_roles_matrix(\'previous\')" class="button roles_previous" style="font-size:16px;">
+        <span class="fa fa-arrow-left"></span>
+    </button>
+    <button onclick="refresh_roles_matrix(\'next\')" class="button roles_next" style="font-size:16px;">
+        <span class="fa fa-arrow-right"></span>
     </button>
 </div>
 <div style="line-height:20px;" align="center">
     <div id="matrice_droits"></div>
     <div style="">
-        <span class="fa fa-arrow-left" style="display:none;cursor:pointer" id="roles_previous" onclick="refresh_roles_matrix(\'previous\')"></span>&nbsp;
-        <span class="fa fa-arrow-right" style="display:none;cursor:pointer" id="roles_next" onclick="refresh_roles_matrix(\'next\')"></span>
+        <button onclick="refresh_roles_matrix(\'previous\')" class="button roles_previous" style="font-size:16px;">
+            <span class="fa fa-arrow-left"></span>
+        </button>
+        <button onclick="refresh_roles_matrix(\'next\')" class="button roles_next" style="font-size:16px;">
+            <span class="fa fa-arrow-right"></span>
+        </button>
     </div>
 </div>
 <input type="hidden" id="selected_function" />
 <input type="hidden" id="next_role" value="0" />
 <input type="hidden" id="previous_role" value="0" />
diff --git a/sources/import.queries.php b/sources/import.queries.php
index 349d89b0f..e51cc4506 100644
--- a/sources/import.queries.php
+++ b/sources/import.queries.php
@@ -249,11 +249,11 @@ switch (filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING)) {
             $display .= '</select></div>';
 
             // Show results to user.
             echo '[{"error":"no" , "output" : "'.$display.'"}]';
         }
-        
+
         //delete file
         unlink($file);
 
         break;
 
diff --git a/sources/roles.queries.php b/sources/roles.queries.php
index 193bf6bef..3f480068e 100644
--- a/sources/roles.queries.php
+++ b/sources/roles.queries.php
@@ -286,28 +286,37 @@ if (null !== filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING)) {
                 );
             }
 
             // Prepare POST variables
             $post_start = filter_input(INPUT_POST, 'start', FILTER_SANITIZE_NUMBER_INT);
+            $post_filter = filter_input(INPUT_POST, 'filter', FILTER_SANITIZE_STRING);
 
             $tree = $tree->getDescendants();
             $texte = '<table><thead><tr><th>'.$LANG['groups'].'</th>';
             $gpes_ok = array();
             $gpes_nok = array();
-            $tab_fonctions = array();
+            $arrRolesTitle = array();
             $arrRoles = array();
             $display_nb = 8;
             $sql_limit = "";
             $next = 1;
             $previous = 1;
+            $where = "";
+
+            // Should we filter on role names
+            if (empty($post_filter) === false) {
+                $where = " WHERE title LIKE '".$post_filter."%'";
+            }
 
             //count nb of roles
             $arrUserRoles = array_filter($_SESSION['user_roles']);
-            if (count($arrUserRoles) == 0 || $_SESSION['is_admin'] == 1) {
-                $where = "";
-            } else {
-                $where = " WHERE id IN (".implode(',', $arrUserRoles).")";
+            if (count($arrUserRoles) >= 0 && $_SESSION['is_admin'] !== "1") {
+                if (empty($where) === false) {
+                    $where = " WHERE id IN (".implode(',', $arrUserRoles).")";
+                } else {
+                    $where .= " AND id IN (".implode(',', $arrUserRoles).")";
+                }
             }
             DB::query("SELECT * FROM ".prefix_table("roles_title").$where);
             $roles_count = DB::count();
             if ($roles_count > $display_nb) {
                 if (null === $post_start || $post_start === 0) {
@@ -316,11 +325,11 @@ if (null !== filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING)) {
                 } else {
                     $start = $post_start;
                     $previous = $start - $display_nb;
                 }
                 $sql_limit = " LIMIT ".mysqli_real_escape_string($link, filter_var($start, FILTER_SANITIZE_NUMBER_INT)).", ".mysqli_real_escape_string($link, filter_var($display_nb, FILTER_SANITIZE_NUMBER_INT));
-                $next = $start + $display_nb;
+                $next = $start + $display_nb + 1;
             }
 
             // array of roles for actual user
             $my_functions = $arrUserRoles;
 
@@ -346,10 +355,11 @@ if (null !== filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING)) {
                         '<span class=\'fa fa-trash fa-2x mi-grey-1\' style=\'cursor:pointer;\' onclick=\'delete_this_role('.$record['id'].',"'.htmlentities($record['title'], ENT_QUOTES, "UTF-8").'")\'></span>'.
                         $allow_pw_change.
                         '<div style=\'margin-top:-8px;\'>[&nbsp;'.$SETTINGS_EXT['pwComplexity'][$record['complexity']][1].'&nbsp;]</div></th>';
 
                     array_push($arrRoles, $record['id']);
+                    array_push($arrRolesTitle, $record['title']);
                 }
             }
             $texte .= '</tr></thead><tbody>';
 
             //Display each folder with associated rights by role
@@ -417,11 +427,12 @@ if (null !== filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING)) {
 
             $return_values = array(
                 "new_table" => $texte,
                 "all" => $roles_count,
                 "next" => $next,
-                "previous" => $previous
+                "previous" => $previous,
+                "list_of_roles" => $arrRolesTitle
             );
 
             $return_values = json_encode($return_values, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
 
             //return data

Vulnerable code: min-width: 150px;
            ', ($session_user_id !== null && empty($session_user_id) === false) ? '<i class="fa fa-users"></i>&nbsp;'.$_SESSION['nb_users_online'].'&nbsp;'.$LANG['users_online'].'&nbsp;|&nbsp;<i class="fa fa-hourglass-end"></i>&nbsp;'.$LANG['index_expiration_in'].'&nbsp;<div style="display:inline;" id="countdown"></div>' : '', '
                            `id` int(12) NOT null AUTO_INCREMENT,
// alter table misc to add an index
mysqli_query(
    $db_link,
    "ALTER TABLE `".$pre."misc` ADD `id` INT(12) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`)"
);
\$SETTINGS = array (" . $config_text . "            
    $("#div_formulaire_edition_item_info").html("<?php echo "<i class='fa fa-cog fa-spin fa-lg'></i>&nbsp;".addslashes($LANG['please_wait'])."..."; ?>").show();
                        $("#fileclass"+data.id).text($('#edit_label').val());
            $('#edit_show_error').html("<?php echo addslashes($LANG['error_complex_not_enought']); ?>").show();
            $("#div_formulaire_edition_item_info").addClass("hidden").html("");
        $("#div_formulaire_edition_item_info").addClass("hidden").html("");
        $("#div_formulaire_edition_item ~ .ui-dialog-buttonpane").find("button:contains('<?php echo addslashes($LANG['save_button']); ?>')").prop("disabled", false);
                <table width="100%" id="item_details_table">';
                    <td valign="top" class="td_title" colspan="2">
                        <div id="id_label" style="display:inline; margin:4px 0px 0px 120px; "></div>
                    <td>
                    <td>
                    <td>
                    <td>
                    <td>
                    <td>
                    <td>
                    <td>
                    <tr>
                        <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['kbs'].' :</td>
                        <td>
                            <div id="id_kbs" style="display:inline;"></div><input type="hidden" id="hid_kbs" />
                        </td>
                    </tr>';
                    <tr class="tr_fields hidden" id="tr_catfield_'.$elem[0].'">
                        <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$elem[1].' :</td>
                        <td></td>
                    </tr>';
                        <td>';
    <div style="display:none; padding:5px;" id="div_formulaire_edition_item_info" class="ui-state-default ui-corner-all"></div>


    $("#roles_next, #roles_previous").hide();
            start    : start
            if (data.new_table != "") {
                if (data.next < data.all) {
                    $("#roles_next").show();
                    $("#roles_previous").show();
        <i class="fa fa-plus"></i>
        <i class="fa fa-refresh"></i>
        <span class="fa fa-arrow-left" style="display:none;cursor:pointer" id="roles_previous" onclick="refresh_roles_matrix(\'previous\')"></span>&nbsp;
        <span class="fa fa-arrow-right" style="display:none;cursor:pointer" id="roles_next" onclick="refresh_roles_matrix(\'next\')"></span>
        
            $tab_fonctions = array();
            if (count($arrUserRoles) == 0 || $_SESSION['is_admin'] == 1) {
                $where = "";
            } else {
                $where = " WHERE id IN (".implode(',', $arrUserRoles).")";
                $next = $start + $display_nb;
                "previous" => $previous
Fixed code:  Added filter in Roles
min-width: 120px;
.normal {
  font: normal; "Lucida Grande";
  color: #464646;
}

}

.no-border {
  border: none;
  border-collapse: collapse;
$session_nb_users_online =        $superGlobal->get("nb_users_online", "SESSION");
            ', ($session_user_id !== null && empty($session_user_id) === false) ? '<i class="fa fa-users"></i>&nbsp;'.$session_nb_users_online.'&nbsp;'.$LANG['users_online'].'&nbsp;|&nbsp;<i class="fa fa-hourglass-end"></i>&nbsp;'.$LANG['index_expiration_in'].'&nbsp;<div style="display:inline;" id="countdown"></div>' : '', '
                            `increment_id` int(12) NOT null AUTO_INCREMENT,
// alter table MISC - rename ID is exists
$result = mysqli_query("SHOW COLUMNS FROM `misc` LIKE 'id'");
if (mysqli_num_rows($result) !== 0) {
    // Change name of field
    mysqli_query($db_link, "ALTER TABLE `".$pre."misc` CHANGE `id` `increment_id` INT(12) NOT NULL");
} else {
    // alter table misc to add an index
    $res = addColumnIfNotExist(
        $pre."misc",
        "increment_id",
        "INT(12) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`)"
    );
}
\$SETTINGS = array (" . $config_text . "
    $("#div_formulaire_edition_item_info")
        .html("<?php echo "<i class='fa fa-cog fa-spin fa-lg'></i>&nbsp;".addslashes($LANG['please_wait'])."..."; ?>")
        .removeClass("hidden");
                        $("#fileclass"+data.id).html('<div class="truncate">' + $('#edit_label').val() + '</div>');
            $('#edit_show_error')
                .html("<?php echo addslashes($LANG['error_complex_not_enought']); ?>")
                .show();
            $("#div_formulaire_edition_item_info")
                .addClass("hidden")
                .html("");
        $("#div_formulaire_edition_item_info")
            .addClass("hidden")
            .html("");
        $("#div_formulaire_edition_item ~ .ui-dialog-buttonpane")
            .find("button:contains('<?php echo addslashes($LANG['save_button']); ?>')")
            .prop("disabled", false);

                            // set indicator if item has change proposal
                            $("#item_extra_info").prepend('<i class="fa fa-lightbulb-o fa-sm mi-yellow tip" title="<?php echo addslashes($LANG['item_has_change_proposal']); ?>" onclick=""></i>&nbsp;');
                            $(".tip").tooltipster({multiple: true});

                <table width="100%" class="no-border" id="item_details_table">';
                    <td valign="top" class="td_title" width="120px" style="background-color:rgba(178, 178, 178, 0.13);">
                    </td>
                    <td valign="middle" style="background-color:rgba(178, 178, 178, 0.13);">
                        <span id="id_label" style="font-weight:bold;"></span>
                    </td>
                    <td style="background-color:rgba(178, 178, 178, 0.13);">
                    <td colspan="2">
                    <td colspan="2">
                    <td colspan="2">
                    <td colspan="2">
                    <td colspan="2">
                    <td colspan="2">
                    <td colspan="2">
                    <td colspan="2">
                <tr>
                    <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$LANG['kbs'].' :</td>
                    <td colspan="2">
                        <div id="id_kbs" style="display:inline;"></div><input type="hidden" id="hid_kbs" />
                    </td>
                </tr>';
                <tr class="tr_fields hidden" id="tr_catfield_'.$elem[0].'">
                    <td valign="top" class="td_title">&nbsp;<i class="fa fa-angle-right"></i>&nbsp;'.$elem[1].' :</td>
                    <td colspan="2"></td>
                </tr>';
                        <td colspan="2">';
    <div style="padding:5px;" id="div_formulaire_edition_item_info" class="ui-state-default ui-corner-all hidden"></div>
    $(".roles_next, .roles_previous").hide();
            start   : start,
            filter  : $("#filter_roles").val()
            if (data.new_table !== "") {
                if (data.next < data.all && data.next >= 9) {
                    $(".roles_next").show();
                    $(".roles_previous").show();

                $("#filter_roles").val("");

            // Prepare autocomplete for filterbox
            //Prepare autocomplete for filter
            $("#filter_roles")
                .autocomplete({
                    source: data.list_of_roles,
                    focus: function() {
                        // prevent value inserted on focus
                        return false;
                    }
                }
            );

        <span class="fa fa-plus"></span>
    &nbsp;
    <span class="normal"><input id="filter_roles" class="ui-widget ui-corner-all" type="text" value="" placeholder="No filter" /></span>
        <span class="fa fa-refresh"></span>
    </button>
    &nbsp;
    <button onclick="refresh_roles_matrix(\'previous\')" class="button roles_previous" style="font-size:16px;">
        <span class="fa fa-arrow-left"></span>
    </button>
    <button onclick="refresh_roles_matrix(\'next\')" class="button roles_next" style="font-size:16px;">
        <span class="fa fa-arrow-right"></span>
        <button onclick="refresh_roles_matrix(\'previous\')" class="button roles_previous" style="font-size:16px;">
            <span class="fa fa-arrow-left"></span>
        </button>
        <button onclick="refresh_roles_matrix(\'next\')" class="button roles_next" style="font-size:16px;">
            <span class="fa fa-arrow-right"></span>
        </button>

            $post_filter = filter_input(INPUT_POST, 'filter', FILTER_SANITIZE_STRING);
            $arrRolesTitle = array();
            $where = "";

            // Should we filter on role names
            if (empty($post_filter) === false) {
                $where = " WHERE title LIKE '".$post_filter."%'";
            }
            if (count($arrUserRoles) >= 0 && $_SESSION['is_admin'] !== "1") {
                if (empty($where) === false) {
                    $where = " WHERE id IN (".implode(',', $arrUserRoles).")";
                } else {
                    $where .= " AND id IN (".implode(',', $arrUserRoles).")";
                }
                $next = $start + $display_nb + 1;
                    array_push($arrRolesTitle, $record['title']);
                "previous" => $previous,
                "list_of_roles" => $arrRolesTitle