CVE-2017-15053 (published 2017-11-27T19:29Z)

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.

Severity: MEDIUM
CVSS v2 base score: 4.0 (AV:N/AC:L/Au:S/C:N/I:P/A:N)
CVSS v3 base score: 4.9, MEDIUM (CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:N)

Weakness information:
cwe_id: CWE-269
cwe_name: Improper Privilege Management
description: The product does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.
extended_description: 
            
         
         

Fix information:
repo_url: https://github.com/nilsteampassnet/TeamPass
commit_details: repo_url: https://github.com/nilsteampassnet/TeamPass
author: nilsteampassnet
author_date: 2017-10-04 19:14:32+02:00
msg: 2.1.27

Added filter in Roles page
Improve truncating title in list of items
repository: repo_url: https://github.com/nilsteampassnet/TeamPass
repo_name: nilsteampassnet/TeamPass
description: Collaborative Passwords Manager
repo_language: PHP
owner: nilsteampassnet
file_changes: filename: changelog.md
change_type: ModificationType.MODIFY
diff: @@ -11,6 +11,7 @@
  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

programming_language: Markdown
filename: passman.css
change_type: ModificationType.MODIFY
diff: @@ -165,7 +165,7 @@ float:left;
 
 .td_title{
 font-weight:bold;
-min-width: 150px;
+min-width: 120px;
 }
 
 ul{
@@ -181,6 +181,11 @@ list-style-type:none;
   padding: 10px;
 }
 
+.normal {
+  font: normal; "Lucida Grande";
+  color: #464646;
+}
+
 .readme{
   font-family: sans-serif;
   font-size: 9px;
@@ -392,4 +397,9 @@ div.dataTables_processing { z-index: 1; }
 
 .hidden {
   display: none;
+}
+
+.no-border {
+  border: none;
+  border-collapse: collapse;
 }
\ No newline at end of file

programming_language: CSS
filename: index.php
change_type: ModificationType.MODIFY
diff: @@ -117,6 +117,7 @@ $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 */
@@ -783,7 +784,7 @@ if (isset($_SESSION['CPM'])) {
             <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']).'

programming_language: PHP
filename: install.queries.php
change_type: ModificationType.MODIFY
diff: @@ -364,7 +364,7 @@ if (null !== $post_type) {
                         $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,

programming_language: PHP
filename: upgrade_run_2.1.27.php
change_type: ModificationType.MODIFY
diff: @@ -188,11 +188,19 @@ 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(
@@ -703,7 +711,7 @@ if ($any_settings === true) {
         utf8_encode(
             "<?php
 global \$SETTINGS;
-\$SETTINGS = array (" . $config_text . "            
+\$SETTINGS = array (" . $config_text . "
     );"
         )
     );

programming_language: PHP
filename: items.load.php
change_type: ModificationType.MODIFY
diff: @@ -792,7 +792,9 @@ 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("[.|,|;|:|!|=|+|-|*|/|#|\"|'|&]");
@@ -965,7 +967,7 @@ function EditerItem()
                         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());
@@ -1088,16 +1090,24 @@ 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);
     }
 }
 
@@ -3293,6 +3303,11 @@ $(function() {
                     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");

programming_language: PHP
filename: items.php
change_type: ModificationType.MODIFY
diff: @@ -226,11 +226,11 @@ echo'
                         <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>
@@ -252,7 +252,11 @@ echo '
                                 </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>
 
@@ -266,7 +270,7 @@ echo '
 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>';
@@ -274,7 +278,7 @@ echo '
 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="" />
@@ -285,7 +289,7 @@ echo '
 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>
@@ -294,7 +298,7 @@ echo '
 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>';
@@ -302,7 +306,7 @@ echo '
 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>';
@@ -310,7 +314,7 @@ echo '
 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;">
 
@@ -321,7 +325,7 @@ echo '
 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>';
@@ -329,34 +333,34 @@ echo '
 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" />';
@@ -778,7 +782,7 @@ if (isset($SETTINGS['item_extra_fields']) && $SETTINGS['item_extra_fields'] == 1
     </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>';

programming_language: PHP
filename: roles.load.php
change_type: ModificationType.MODIFY
diff: @@ -205,8 +205,6 @@ $(function() {
         }
     });
 
-
-
     refresh_roles_matrix();
 });
 
@@ -280,7 +278,7 @@ 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") {
@@ -299,26 +297,42 @@ function refresh_roles_matrix(order)
         "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();
         }
    );

programming_language: PHP
filename: roles.php
change_type: ModificationType.MODIFY
diff: @@ -50,17 +50,30 @@ 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" />

programming_language: PHP
filename: import.queries.php
change_type: ModificationType.MODIFY
diff: @@ -251,7 +251,7 @@ switch (filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING)) {
             // Show results to user.
             echo '[{"error":"no" , "output" : "'.$display.'"}]';
         }
-        
+
         //delete file
         unlink($file);
 

programming_language: PHP
filename: roles.queries.php
change_type: ModificationType.MODIFY
diff: @@ -288,24 +288,33 @@ 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();
@@ -318,7 +327,7 @@ if (null !== filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING)) {
                     $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
@@ -348,6 +357,7 @@ if (null !== filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING)) {
                         '<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>';
@@ -419,7 +429,8 @@ if (null !== filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING)) {
                 "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);

programming_language: PHP