Changeset 2717317
- Timestamp:
- 05/02/2022 10:08:25 PM (4 years ago)
- Location:
- stafflist/trunk
- Files:
-
- 2 edited
-
readme.txt (modified) (2 diffs)
-
stafflist.php (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
stafflist/trunk/readme.txt
r2717270 r2717317 4 4 Tags: staff, directory, faculty, personnel, phonebook, rubrik 5 5 Requires at least: 3.2.1 6 Tested up to: 5. 7.26 Tested up to: 5.9.3 7 7 Requires PHP: 5.6 8 8 Stable tag: trunk … … 103 103 104 104 == Changelog == 105 = 3.1.6 = 106 * Added wp_nonce_url and check_admin_referer to admin delete record feature to defend against CSRF, as suggested by Hassan Khan Yusufzai (thank you); 107 105 108 = 3.1.5 = 106 * Fixed a vulnerability in admin search discoverd by H Yusufzai (thank you);109 * Fixed a vulnerability in admin search discoverd by Hassan Khan Yusufzai (thank you); 107 110 108 111 = 3.1.2 = -
stafflist/trunk/stafflist.php
r2717270 r2717317 4 4 Plugin URI: http://wordpress.org/plugins/stafflist/ 5 5 Description: A super simplified staff directory tool 6 Version: 3.1. 56 Version: 3.1.6 7 7 Author: era404 8 8 Author URI: http://www.era404.com … … 138 138 * Build Admin Page 139 139 ***********************************************************************************/ 140 function stafflist_plugin_options() {140 function stafflist_plugin_options(){ 141 141 if ( !current_user_can( 'edit_stafflist' ) ) { 142 142 wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); … … 191 191 //handle deleting records 192 192 $cr = 0; 193 if(isset($_GET['remove'])) { 194 $q = "SELECT count(id) FROM $staffdb WHERE id=%s"; 195 $cr = $wpdb->get_var($wpdb->prepare($q, (int) $_GET['remove']) ); 196 $q = "DELETE FROM $staffdb WHERE id=%s"; 197 $wpdb->query($wpdb->prepare( $q, (int) $_GET['remove']) ); 193 if(isset($_GET['remove']) && is_numeric($_GET['remove'])){ 194 if(check_admin_referer()){ 195 $q = "SELECT count(id) FROM $staffdb WHERE id=%s"; 196 $r = (int) trim($_GET['remove']); 197 $cr = $wpdb->get_var($wpdb->prepare($q,$r)); 198 if($wpdb->get_var($wpdb->prepare($q,$r)==1)){ 199 $q = "DELETE FROM $staffdb WHERE id=%s"; 200 $wpdb->query($wpdb->prepare($q,$r)); 201 } 202 } 198 203 } 199 204 200 205 //handle sorting 201 $s = $_GET['s'] = (!isset($_GET['s']) ? $cols[0]['id'] : $_GET['s']); 202 $dir = strstr($s,"-")?"ASC":"DESC"; $default = false; $sort = false; 203 //front-end sorting 204 foreach($cols as $col){ 205 if(!$default) $default = $col['col']; 206 if($col['id'] == str_replace("-","",$s)){ $sort = $col['col']; break; } 207 } 208 //back-end sorting 209 if(!$sort && !is_numeric($s)){ 210 $sorts = array("last"=>"lastname","first"=>"firstname","dept"=>"department","email"=>"email"); 211 if(isset($sorts[ str_replace("-","",$s) ])) $sort = $sorts[ str_replace("-","",$s) ]; 212 } 213 if(!$sort) $sort = $default; 214 206 $sorts = array("last"=>"lastname","first"=>"firstname","dept"=>"department","email"=>"email"); 207 $s = $_GET['s'] = (isset($_GET['s']) && in_array(trim($_GET['s']),array("last","first","dept","email","last-","first-","dept-","email-")) ? (string) trim($_GET['s']) : "last"); 208 $sort = $sorts[str_replace("-","",$s)]; 209 $dir = (strstr($s,"-")?"DESC":"ASC"); 210 215 211 //handle search (use mb_strtolower, where available) 216 212 if(isset($_GET['search']) && (string) trim($_GET['search'])!=""){ 217 213 218 214 $w = (function_exists('mb_strtolower') ? 219 mb_strtolower( $_GET['search'],'utf8') :220 strtolower( $_GET['search']));215 mb_strtolower( sanitize_text_field($_GET['search']),'utf8') : 216 strtolower( sanitize_text_field($_GET['search']))); 221 217 $ws = '%'.$wpdb->esc_like($w).'%'; 222 218 $where = "WHERE LOWER(lastname) LIKE %s OR … … 244 240 $q = "SELECT count(id) FROM $staffdb {$where}"; 245 241 $sql = $wpdb->prepare($q,$params); 246 $count = $wpdb->get_var( ); //echo "COUNT: $count<br /><br />";242 $count = $wpdb->get_var($sql); 247 243 248 244 //handle paging 249 245 $pg = array((int) $count, (int) $rows, (int) ceil($count/$rows)); 250 $p = $_GET['p'] = $pg[3] = (!isset($_GET['p']) || $_GET['p']<1 || $_GET['p']>$pg[2] ? 1 : $_GET['p']);246 $p = $_GET['p'] = $pg[3] = (!isset($_GET['p']) || !is_numeric($_GET['p']) || intval($_GET['p'])<2 || intval($_GET['p'])>$pg[2] ? 1 : intval($_GET['p'])); 251 247 $pg[4] = (int) ($pg[1]*$pg[3])-$pg[1]; 252 248 $pg[5] = (int) ($pg[4]+$pg[1])-1; if($pg[5]+1>$pg[0]) $pg[5]=($pg[0]-1); … … 291 287 echo "<div id='warning' class='orange' style='display:".($cr>0?"block":"none").";'>".(($cr>0)?"<strong>NOTE:</strong> [ $cr ] Staff Record removed.":"")."</div>"; 292 288 echo "<input type='text' id='searchdirectory' name='searchdirectory' value='".esc_attr(stripslashes($w))."' placeholder='Search Directory' />"; 293 294 global $stafflisturl; $stafflisturl = STAFFLIST_URL . ($w ? "&search={$w}" : ""); 289 290 global $stafflisturl; 291 $stafflisturl = STAFFLIST_URL . ($w ? "&search={$w}" : "") . ($s ? "&s={$s}" : ""); 295 292 echo renderAdminPager($pg); 296 293 … … 298 295 <table id='stafflists' style='border:1px solid #E8E8E8;'>"; 299 296 echo "<thead id='stafflisthead'><tr> 300 <th><a href='{$stafflisturl}&s=last' title='Sort by Last Name A-Z' class='sort_a ".($ _GET['s']=='last'?'selected':'')."'><span>Ascending</span></a> Last Name301 <a href='{$stafflisturl}&s=last-' title='Sort by Last Name Z-A' class='sort_d ".($ _GET['s']=='last-'?'selected':'')."'><span>Descending</span></a>297 <th><a href='{$stafflisturl}&s=last' title='Sort by Last Name A-Z' class='sort_a ".($s=='last'?'selected':'')."'><span>Ascending</span></a> Last Name 298 <a href='{$stafflisturl}&s=last-' title='Sort by Last Name Z-A' class='sort_d ".($s=='last-'?'selected':'')."'><span>Descending</span></a> 302 299 </th><th> </th> 303 <th><a href='{$stafflisturl}&s=first' title='Sort by First Name Ascending' class='sort_a ".($ _GET['s']=='first'?'selected':'')."'><span>Ascending</span></a> First Name304 <a href='{$stafflisturl}&s=first-' title='Sort by First Name Descending' class='sort_d ".($ _GET['s']=='first-'?'selected':'')."'><span>Descending</span></a>300 <th><a href='{$stafflisturl}&s=first' title='Sort by First Name Ascending' class='sort_a ".($s=='first'?'selected':'')."'><span>Ascending</span></a> First Name 301 <a href='{$stafflisturl}&s=first-' title='Sort by First Name Descending' class='sort_d ".($s=='first-'?'selected':'')."'><span>Descending</span></a> 305 302 </th><th> </th> 306 <th><a href='{$stafflisturl}&s=dept' title='Sort by Department Ascending' class='sort_a ".($ _GET['s']=='dept'?'selected':'')."'><span>Ascending</span></a> Department307 <a href='{$stafflisturl}&s=dept-' title='Sort by Department Descending' class='sort_d ".($ _GET['s']=='dept-'?'selected':'')."'><span>Descending</span></a>303 <th><a href='{$stafflisturl}&s=dept' title='Sort by Department Ascending' class='sort_a ".($s=='dept'?'selected':'')."'><span>Ascending</span></a> Department 304 <a href='{$stafflisturl}&s=dept-' title='Sort by Department Descending' class='sort_d ".($s=='dept-'?'selected':'')."'><span>Descending</span></a> 308 305 </th><th> </th> 309 <th><a href='{$stafflisturl}&s=email' title='Sort by Email Address Ascending' class='sort_a ".($ _GET['s']=='email'?'selected':'')."'><span>Ascending</span></a> Email Address310 <a href='{$stafflisturl}&s=email-' title='Sort by Email Address Descending' class='sort_d ".($ _GET['s']=='email-'?'selected':'')."'><span>Descending</span></a>306 <th><a href='{$stafflisturl}&s=email' title='Sort by Email Address Ascending' class='sort_a ".($s=='email'?'selected':'')."'><span>Ascending</span></a> Email Address 307 <a href='{$stafflisturl}&s=email-' title='Sort by Email Address Descending' class='sort_d ".($s=='email-'?'selected':'')."'><span>Descending</span></a> 311 308 </th><th> </th> 312 309 <th>Phone / Ext</th><th> </th>"; … … 315 312 316 313 $i=0; 317 foreach($staff as $k=>$ s){318 $del = "<a href=' {$stafflisturl}&remove={$s['id']}&p={$p}&s={$_GET['s']}' class='remove'314 foreach($staff as $k=>$v){ 315 $del = "<a href='".wp_nonce_url("{$stafflisturl}&remove={$v['id']}&p={$p}&s={$s}")."' class='remove' 319 316 onclick='javascript:if(!confirm(\"Are you sure you want to delete this staff record?\")) return false;' 320 317 title='Permanently Delete This Staff Record' target='_self' … … 322 319 $i++; 323 320 324 echo "<tr class='row' id='staff_{$ s['id']}'>325 <td><input type='text' id='lastname:{$ s['id']}' value='".esc_attr($s['lastname'])."' autocomplete='Off' /></td><td></td>326 <td><input type='text' id='firstname:{$ s['id']}' value='".esc_attr($s['firstname'])."' autocomplete='Off' /></td><td></td>327 <td><input type='text' id='department:{$ s['id']}' value='".esc_attr($s['department'])."' autocomplete='Off' /></td><td></td>328 <td><input type='text' id='email:{$ s['id']}' value='".esc_attr($s['email'])."' autocomplete='Off' /></td><td></td>329 <td><input type='text' id='phone:{$ s['id']}' value='".esc_attr($s['phone'])."' autocomplete='Off' /></td><td></td>";321 echo "<tr class='row' id='staff_{$v['id']}'> 322 <td><input type='text' id='lastname:{$v['id']}' value='".esc_attr($v['lastname'])."' autocomplete='Off' /></td><td></td> 323 <td><input type='text' id='firstname:{$v['id']}' value='".esc_attr($v['firstname'])."' autocomplete='Off' /></td><td></td> 324 <td><input type='text' id='department:{$v['id']}' value='".esc_attr($v['department'])."' autocomplete='Off' /></td><td></td> 325 <td><input type='text' id='email:{$v['id']}' value='".esc_attr($v['email'])."' autocomplete='Off' /></td><td></td> 326 <td><input type='text' id='phone:{$v['id']}' value='".esc_attr($v['phone'])."' autocomplete='Off' /></td><td></td>"; 330 327 for($i = 1; $i <= $activeCols; $i++){ 331 328 $col = $i+5; 332 329 $key = "col{$col}"; 333 echo "<td><input type='text' id='col{$col}:{$ s['id']}' value='".esc_attr($s[$key])."' autocomplete='Off' /></td>";330 echo "<td><input type='text' id='col{$col}:{$v['id']}' value='".esc_attr($v[$key])."' autocomplete='Off' /></td>"; 334 331 if($i < $activeCols) echo "<td></td>"; 335 332 } … … 526 523 $cur = $pg[3]; 527 524 $last = $pg[2]; 528 global $stafflisturl; //includes search 525 global $stafflisturl; //includes search & sort 529 526 530 527 //one page or less? 531 528 if($pg[0]<1 || $last<2) return(""); 532 529 //previous 533 $html = ($cur > 1 ? "<p class='pager'><a href='{$stafflisturl}&p=".($cur-1)." &s={$_GET['s']}'>Previous </a></p>" : ""); //<530 $html = ($cur > 1 ? "<p class='pager'><a href='{$stafflisturl}&p=".($cur-1)."'>Previous </a></p>" : ""); 534 531 //pages 535 532 if($cur<=3){ … … 550 547 } 551 548 //next 552 $html .= (($cur < $pg[2] && $pg[2] > 1) ? "<p class='pager'><a href='{$stafflisturl}&p=".($cur+1)." &s={$_GET['s']}'> Next</a></p>" : ""); //>549 $html .= (($cur < $pg[2] && $pg[2] > 1) ? "<p class='pager'><a href='{$stafflisturl}&p=".($cur+1)."'> Next</a></p>" : ""); //> 553 550 //page numbering 554 551 $html .= "<div class='pageNum'>Page: ".($pg[3])." ( ".($pg[4]+1)."-".($pg[5]+1)." of ".($pg[0])." )</div>"; … … 557 554 function renderAdminPage($style, $page){ 558 555 global $stafflisturl; //includes search 559 return("<p class='pager{$style}'>".(is_numeric($page)?"<a href='{$stafflisturl}&p={$page} &s={$_GET['s']}'>{$page}</a>":$page)."</p>");556 return("<p class='pager{$style}'>".(is_numeric($page)?"<a href='{$stafflisturl}&p={$page}'>{$page}</a>":$page)."</p>"); 560 557 } 561 558 /*********************************************************************************** … … 580 577 $limit = (empty($_POST) ? array("sort"=>$cols[0]['id'],"page"=>1,"search"=>"") : $_POST); 581 578 $wait = (isset($_POST['wait']) && (string) trim($_POST['wait']) == "true" ? true : false); 582 if(!isset($limit['sort']) || $limit['sort'] == "") $limit['sort'] = $cols[0]['id']; 579 if(!isset($limit['sort']) || $limit['sort'] == "" || !preg_match('/^[\d]+-?$/', trim($limit['sort']))) $limit['sort'] = $cols[0]['id']; 580 if(!isset($limit['page']) || !is_numeric($limit['page'])) $limit['page'] = 1; 583 581 if(!isset($limit['search'])) $limit['search'] = ""; 584 582 … … 636 634 637 635 //if $_POST['rows'] use that instead of default RECORDS_PER_PAGE; 638 if(isset($_POST['rows']) && is_numeric($_POST['rows']) && $_POST['rows'] > 0 && $_POST['rows'] <= 100) $rows = $_POST['rows'];636 if(isset($_POST['rows']) && is_numeric($_POST['rows']) && $_POST['rows'] > 0 && $_POST['rows'] <= 100) $rows = intval($_POST['rows']); 639 637 640 638 //handle paging 641 639 $pg = array((int) $count, (int) $rows, (int) ceil($count/$rows)); 642 $pg[3] = (int) (!isset($limit['page']) || $limit['page']< 1|| $limit['page']>$pg[2] ? 1 : $limit['page']);640 $pg[3] = (int) (!isset($limit['page']) || $limit['page']<2 || $limit['page']>$pg[2] ? 1 : $limit['page']); 643 641 $pg[4] = (int) ($pg[1]*$pg[3])-$pg[1]; 644 642 $pg[5] = (int) ($pg[4]+$pg[1])-1; if($pg[5]+1>$pg[0]) $pg[5]=($pg[0]-1); … … 1276 1274 global $wpdb,$cols, //wpdb object 1277 1275 $staffdb,$staffmetadb; //csvs and the like 1278 1279 error_reporting(E_ALL); ini_set('display_errors',1);1280 1276 1281 1277 //column names … … 1288 1284 //sorting 1289 1285 $sorts = array("last"=>"lastname","first"=>"firstname","dept"=>"department","email"=>"email"); 1290 $s = (isset($_GET['s']) && array_key_exists(rtrim($_GET['s'],"-"), $sorts) ? $_GET['s'] : "last-"); 1291 $dir = strstr($s,"-")?"ASC":"DESC"; 1292 $sort = $sorts[ str_replace("-","",$s) ]; 1293 1294 //filter by searched keyword 1295 $w = (isset($_GET['search']) && (string) trim($_GET['search'])!="" ? strtolower($wpdb->_real_escape( stripslashes( trim($_GET['search']) ))) : false); 1296 $where = ($w ? "WHERE LOWER(lastname) LIKE '%{$w}%' ". 1297 "OR LOWER(firstname) LIKE '%{$w}%' ". 1298 "OR LOWER(department) LIKE '%{$w}%' ". 1299 "OR LOWER(email) LIKE '%{$w}%'" : ""); 1300 $nonstd = getNonstandardRows(1); //add nonstandard rows to search 1301 if($w && !empty($nonstd)) foreach($nonstd as $k=>$v) $where.= " OR LOWER({$k}) LIKE '%{$w}%' "; 1302 1303 //query 1304 $q = "SELECT * FROM {$staffdb} {$where} ORDER BY {$sort} {$dir}"; 1305 $staff = $wpdb->get_results($q, ARRAY_A); 1286 $s = $_GET['s'] = (isset($_GET['s']) && in_array(trim($_GET['s']),array("last","first","dept","email","last-","first-","dept-","email-")) ? (string) trim($_GET['s']) : "last"); 1287 $sort = $sorts[str_replace("-","",$s)]; 1288 $dir = (strstr($s,"-")?"DESC":"ASC"); 1289 1290 1291 //handle search (use mb_strtolower, where available) 1292 if(isset($_GET['search']) && (string) trim($_GET['search'])!=""){ 1293 1294 $w = (function_exists('mb_strtolower') ? 1295 mb_strtolower( sanitize_text_field($_GET['search']),'utf8') : 1296 strtolower( sanitize_text_field($_GET['search']))); 1297 $ws = '%'.$wpdb->esc_like($w).'%'; 1298 $where = "WHERE LOWER(lastname) LIKE %s OR 1299 LOWER(firstname) LIKE %s OR 1300 LOWER(department) LIKE %s OR 1301 LOWER(email) LIKE %s"; 1302 $params = array($ws,$ws,$ws,$ws); 1303 1304 //add nonstandard rows to search 1305 $nonstd = getNonstandardRows(1); 1306 if(!empty($nonstd)){ 1307 foreach($nonstd as $k=>$v){ 1308 $where.= " OR LOWER({$k}) LIKE %s "; 1309 $params[] = $ws; 1310 } 1311 } 1312 1313 } else { 1314 $w = false; 1315 $where = ""; 1316 $params = array(); 1317 } 1318 1319 //build query 1320 $q = "SELECT * FROM {$staffdb} {$where} ORDER BY {$sort} {$dir}"; //echo $q; 1321 $sql = $wpdb->prepare($q,$params); 1322 $staff = $wpdb->get_results($sql, ARRAY_A); //myprint_r($staff); 1306 1323 1307 1324 //build the output
Note: See TracChangeset
for help on using the changeset viewer.