Headline
CVE-2023-5251: ajax_be.php in grid-plus/tags/1.3.2/core – WordPress Plugin Repository
The Grid Plus plugin for WordPress is vulnerable to unauthorized modification of data and loss of data due to a missing capability check on the ‘grid_plus_save_layout_callback’ and ‘grid_plus_delete_callback’ functions in versions up to, and including, 1.3.2. This makes it possible for authenticated attackers with subscriber privileges or above, to add, update or delete grid layout.
1<?php2/**3 * Created by PhpStorm.4 * User: g5theme5 * Date: 12/14/20166 * Time: 11:23 AM7 */89add_action("wp_ajax_grid_plus_save_layout", ‘grid_plus_save_layout_callback’);10function grid_plus_save_layout_callback()11{12 $grid_layout = $_POST[‘grid_layout’];13 $grid_data_source = $_POST[‘grid_data_source’];14 $grid_config = $_POST[‘grid_config’];1516 if($grid_config[‘type’]==’metro’){17 echo json_encode(array(18 ‘id’ => -1,19 ‘message’ => 'Please use premium version to create metro layout’20 ));21 }22 $grids = get_option(G5PLUS_GRID_OPTION_KEY, array());2324 $grids = is_array($grids) ? $grids : array();2526 if (!isset($grid_config[‘name’]) || $grid_config[‘name’] == ‘’) {27 echo json_encode(array(28 ‘code’ => -1,29 ‘message’ => esc_html__('Please input grid name !’, ‘grid-plus’)30 ));31 wp_die();32 }33 if (!isset($grid_config[‘id’]) || $grid_config[‘id’] == ‘’) {34 $grid = Grid_Plus_Base::gf_get_grid_by_name(strtolower($grid_config[‘name’]));35 if ($grid != null) {36 echo json_encode(array(37 ‘code’ => -1,38 ‘message’ => esc_html__('The grid name already exist. Please change grid name !’, ‘grid-plus’)39 ));40 wp_die();41 }42 $grid_config[‘id’] = uniqid();43 }4445 $grids[$grid_config[‘id’]] = array(46 ‘id’ => $grid_config[‘id’],47 ‘name’ => $grid_config[‘name’],48 ‘type’ => $grid_config[‘type’],49 );5051 update_option(G5PLUS_GRID_OPTION_KEY, $grids);5253 update_option(G5PLUS_GRID_OPTION_KEY . ‘_’ . $grid_config[‘id’], array(54 ‘id’ => $grid_config[‘id’],55 ‘name’ => $grid_config[‘name’],56 ‘grid_config’ => $grid_config,57 ‘grid_data_source’ => $grid_data_source,58 ‘grid_layout’ => $grid_layout59 ), false);6061 echo json_encode(array(62 ‘id’ => $grid_config[‘id’],63 ));6465 wp_die();66}6768add_action("wp_ajax_grid_plus_delete", ‘grid_plus_delete_callback’);69function grid_plus_delete_callback()70{71 $grid_id = $_POST[‘grid_id’];72 $grids = get_option(G5PLUS_GRID_OPTION_KEY, array());73 unset($grids[$grid_id]);74 update_option(G5PLUS_GRID_OPTION_KEY, $grids);75 delete_option(G5PLUS_GRID_OPTION_KEY . ‘_’ . $grid_id);76 $list_grid = array();77 foreach($grids as $key => $value){78 $list_grid[] = $value;79 }80 echo json_encode($list_grid);81 wp_die();82}8384add_action("wp_ajax_grid_plus_get_info", ‘grid_plus_get_info_callback’);85add_action("wp_ajax_nopriv_grid_plus_get_info", ‘grid_plus_get_info_callback’);86function grid_plus_get_info_callback()87{88 $grid_id = $_POST[‘grid_id’];89 $grid = get_option(G5PLUS_GRID_OPTION_KEY. ‘_’ . $grid_id, array());90 if (isset($grid[‘id’])) {91 echo json_encode($grid);92 } else {93 echo json_encode(array(94 ‘code’ => -1,95 ‘message’ => esc_html__('Cannot find grid information !’, ‘grid-plus’)96 ));97 }98 wp_die();99}100101add_action("wp_ajax_grid_plus_get_list", ‘grid_plus_get_list_callback’);102function grid_plus_get_list_callback()103{104 $grid_name = isset($_POST[‘grid_name’]) ? $_POST[‘grid_name’] : '’;105 $grids = get_option(G5PLUS_GRID_OPTION_KEY, array());106 $list_grids = array();107108 foreach ($grids as $grid) {109 if ($grid_name != ‘’) {110 if (strripos($grid[‘name’], $grid_name) !== false) {111 $list_grids[] = array(112 ‘id’ => $grid[‘id’],113 ‘name’ => $grid[‘name’]114 );115 }116 } else {117 $list_grids[] = array(118 ‘id’ => $grid[‘id’],119 ‘type’ => $grid[‘type’],120 ‘name’ => $grid[‘name’]121 );122 }123124 }125 echo json_encode($list_grids);126 wp_die();127}128129if (!function_exists(‘grid_plus_title_like_posts_where’)) {130 function grid_plus_title_like_posts_where($where, &$wp_query)131 {132 global $wpdb;133 if ($search_term = $wp_query->get(‘post_title_like’)) {134 $where .= ' AND ' . $wpdb->posts . ‘.post_title LIKE \’%’ . esc_sql($wpdb->esc_like($search_term)) . '%\’’;135 }136 return $where;137 }138}139140if (!function_exists(‘grid_plus_get_posts’)) {141 function grid_plus_get_posts()142 {143 add_filter('posts_where’, 'grid_plus_title_like_posts_where’, 10, 2);144 $title = isset($_GET[‘title’]) ? $_GET[‘title’] : '’;145 $post_type = isset($_GET[‘post_type’]) ? $_GET[‘post_type’] : 'post’;146 $search_query = array(147 ‘post_title_like’ => $title,148 ‘order’ => 'ASC’,149 ‘orderby’ => 'post_title’,150 ‘post_type’ => $post_type,151 ‘post_status’ => 'publish’,152 ‘posts_per_page’ => 10,153 );154155 $search = new WP_Query($search_query);156 $ret = array();157 foreach ($search->posts as $post) {158 $ret[] = array(159 ‘value’ => $post->ID,160 ‘label’ => $post->post_title161 );162 }163 echo json_encode($ret);164 die();165 }166167 add_action('wp_ajax_grid_plus_get_posts’, ‘grid_plus_get_posts’);168}169170