Headline
CVE-2023-5250: grid.plus.base.class.php in grid-plus/tags/1.3.2/core – WordPress Plugin Repository
The Grid Plus plugin for WordPress is vulnerable to Local File Inclusion in versions up to, and including, 1.3.2 via a shortcode attribute. This allows subscriber-level, and above, attackers to include and execute arbitrary files on the server, allowing the execution of any PHP code in those files. This can be used to bypass access controls, obtain sensitive data, or achieve code execution in cases where PHP files with arbitrary content can be uploaded and included. This is limited to .php files.
1<?php2if (!defined(‘ABSPATH’)) {3 exit;4}56class Grid_Plus_Base7{89 /**10 * GET Plugin template11 * *******************************************************12 */1314 public static function gf_get_template($slug, $args = array())15 {16 if ($args && is_array($args)) {17 extract($args);18 }19 $located = G5PLUS_GRID_DIR . $slug . '.php’;20 if (!file_exists($located)) {21 _doing_it_wrong(__FUNCTION__, sprintf('<code>%s</code> does not exist.’, $slug), ‘1.0’);22 return;23 }24 include($located);25 }2627 /**28 * GET list post type29 * *******************************************************30 */3132 public static function gf_get_posttypes()33 {34 $post_types = get_post_types(array(35 ‘public’ => true,36 ‘publicly_queryable’ => true,37 ));38 foreach ($post_types as $key => $type) {39 $post_type_object = get_post_type_object($type);40 if (empty($post_type_object)) {41 $post_types[$key] = $type;42 continue;43 }44 $post_types[$key] = $post_type_object->labels->name;45 }46 return apply_filters('grid_plus_post_types’, $post_types);47 }4849 /**50 * GET list categories51 * *******************************************************52 */5354 public static function gf_get_categories()55 {56 $post_categories = $terms = $obj_taxonomies = array();57 $post_types = Grid_Plus_Base::gf_get_posttypes();5859 foreach ($post_types as $post_type => $value) {60 $terms = $obj_taxonomies = array();61 $obj_taxonomies = get_object_taxonomies(62 array(‘post_type’ => $post_type),63 'objects’64 );6566 foreach ($obj_taxonomies as $taxonomy_key => $taxonomy_values) {67 $terms = get_terms(array(68 ‘taxonomy’ => $taxonomy_values->name,69 ‘hide_empty’ => false,70 ));71 if (isset($terms) && is_array($terms)) {72 foreach ($terms as $term) {73 $post_categories[$post_type][$taxonomy_values->labels->name][] = array(74 ‘taxonomy’ => $taxonomy_values->name,75 ‘term_id’ => $term->term_id,76 ‘term_name’ => $term->name,77 ‘term_count’ => $term->count78 );79 }80 }81 }82 }83 return $post_categories;84 }8586 /**87 * GET categories taxonomy by post type88 * *******************************************************89 */9091 public static function gf_get_category_taxonomy($post_type)92 {93 $obj_taxonomies = get_object_taxonomies(94 array(‘post_type’ => $post_type),95 'objects’96 );97 $category_taxonomy = array();98 if (is_array($obj_taxonomies) && count($obj_taxonomies) > 0) {99 foreach ($obj_taxonomies as $taxonomy_key => $taxonomy_values) {100 $category_taxonomy[] = $taxonomy_values->name;101 }102 return $category_taxonomy;103 }104 return $category_taxonomy[] = ‘category’;105 }106107 /**108 * GET categories by post type109 * *******************************************************110 */111 public static function gf_get_categories_info($post_type, $category_ids)112 {113 $post_categories = $terms = array();114 $obj_taxonomies = get_object_taxonomies( array(‘post_type’ => $post_type), ‘objects’ );115 foreach ($obj_taxonomies as $taxonomy_key => $taxonomy_values) {116 $terms = get_categories(array( ‘taxonomy’ => $taxonomy_values->name, ‘hide_empty’ => ‘0’ ));117 if (isset($terms) && is_array($terms)) {118 foreach ($terms as $term) {119 if (in_array($term->term_id, $category_ids)) {120 $post_categories[array_search($term->term_id, $category_ids)] = array(121 ‘term_id’ => $term->term_id,122 ‘slug’ => $term->slug,123 ‘name’ => $term->name,124 ‘count’ => $term->count125 );126 }127 }128 }129 }130 return $post_categories;131 }132133 public static function gf_get_categories_info_by_posttype($post_type)134 {135 $post_categories = $terms = $obj_taxonomies = array();136137 $terms = $obj_taxonomies = array();138 $obj_taxonomies = get_object_taxonomies(139 array(‘post_type’ => $post_type),140 ‘objects’141 );142 foreach ($obj_taxonomies as $taxonomy_key => $taxonomy_values) {143 $terms = get_terms(array(144 ‘taxonomy’ => $taxonomy_values->name,145 ‘hide_empty’ => true,146 ));147 if (isset($terms) && is_array($terms)) {148 foreach ($terms as $term) {149 $post_categories[$term->slug] = array(150 ‘term_id’ => $term->term_id,151 ‘slug’ => $term->slug,152 ‘name’ => $term->name,153 ‘count’ => $term->count154 );155 }156 }157 }158 return $post_categories;159 }160161162 /**163 * GET list user164 * *******************************************************165 */166 public static function gf_get_users()167 {168 $users = get_users(array(169 ‘orderby’ => ‘display_name’,170 ‘order’ => ‘DESC’,171 ‘fields’ => array(‘ID’, ‘user_nicename’),172 ));173 if ($users) {174 $array = array();175 foreach ($users as $user) {176 $array[$user->ID] = $user->user_nicename;177 }178 }179 return $users;180 }181182 /**183 * GET grid by grid name184 * *******************************************************185 */186 public static function gf_get_grid_by_name($name)187 {188 $grids = get_option(G5PLUS_GRID_OPTION_KEY, array());189 if (is_array($grids)) {190 foreach ($grids as $grid) {191 if (strtolower($grid[‘name’]) == strtolower($name)) {192 return get_option(G5PLUS_GRID_OPTION_KEY . ‘_’ . $grid[‘id’], array());193 }194 }195 }196 return null;197 }198199 /**200 * GET post format201 * *******************************************************202 */203 public static function gf_get_post_format($post = null)204 {205 if (!$post = get_post($post))206 return false;207208 $_format = get_the_terms($post->ID, ‘post_format’);209210 if (empty($_format))211 return false;212213 $format = reset($_format);214215 return str_replace(‘post-format-‘, ‘’, $format->slug);216 }217218 /**219 * Enqueue custom css220 * *******************************************************221 */222 public static function gf_enqueue_custom_css()223 {224 global $grid_plus_custom_css;225 if (isset($grid_plus_custom_css) && is_array($grid_plus_custom_css)) {226 $css = ‘<div id="grid-plus-custom-css"><style type="text/css">’;227 foreach ($grid_plus_custom_css as $section => $grid_config) {228 if(isset($grid_config[‘category_color’]) && $grid_config[‘category_color’]!=’’){229 $css .= "230 .grid-{$section} .grid-category a,231 .grid-{$section} .grid-cate-expanded > span {232 color: {$grid_config[‘category_color’]} !important;233 }234 ";235 }236 if(isset($grid_config[‘category_hover_color’]) && $grid_config[‘category_hover_color’]!=’’){237 $css .= "238 .grid-{$section} .grid-category a.active,239 .grid-{$section} .grid-category a:hover,240 .grid-{$section} .grid-category a:focus,241 .grid-{$section} .grid-category a:active,242 .grid-{$section} .grid-cate-expanded > span:hover,243 .grid-{$section} .grid-cate-expanded > span:active,244 .grid-{$section} .grid-cate-expanded > span:focus {245 color: {$grid_config[‘category_hover_color’]} !important;246 }247 ";248 }249250 if(isset($grid_config[‘no_image_background_color’]) && $grid_config[‘no_image_background_color’]!=’’){251 $css .= "252 .grid-{$section} div.grid-post-item .thumbnail-image {253 background-color: {$grid_config[‘no_image_background_color’]} !important;254 }255 ";256 }257 if(isset($grid_config[‘background_color’]) && $grid_config[‘background_color’]!=’’){258 $css .= "259 .grid-{$section} div.grid-post-item .hover-outer {260 background-color: {$grid_config[‘background_color’]} !important;261 }262 ";263 }264 if(isset($grid_config[‘icon_color’]) && $grid_config[‘icon_color’]!=’’){265 $css .= "266 .grid-{$section} .icon-groups a {267 color: {$grid_config[‘icon_color’]} !important;268 border-color: {$grid_config[‘icon_color’]} !important;269 }270 ";271 }272 if(isset($grid_config[‘icon_hover_color’]) && $grid_config[‘icon_hover_color’]!=’’){273 $css .= "274 .grid-{$section} .icon-groups a:hover {275 color: {$grid_config[‘icon_hover_color’]} !important;276 border-color: {$grid_config[‘icon_hover_color’]} !important;277 }278 ";279 }280 if(isset($grid_config[‘title_color’]) && $grid_config[‘title_color’]!=’’){281 $css .= "282 .grid-{$section} .grid-plus-inner .grid-post-item .title,283 .grid-{$section} .grid-plus-inner .grid-post-item .title a {284 color: {$grid_config[‘title_color’]} !important;285 }286 ";287 }288 if(isset($grid_config[‘title_hover_color’]) && $grid_config[‘title_hover_color’]!=’’){289 $css .= "290 .grid-{$section} .grid-plus-inner .grid-post-item .title:hover,291 .grid-{$section} .grid-plus-inner .grid-post-item .title a:hover {292 color: {$grid_config[‘title_hover_color’]} !important;293 }294 ";295 }296 if(isset($grid_config[‘excerpt_color’]) && $grid_config[‘excerpt_color’]!=’’){297 $css .= "298 .grid-{$section} .grid-plus-inner .grid-post-item .excerpt,299 .grid-{$section} .grid-plus-inner .grid-post-item .categories {300 color: {$grid_config[‘excerpt_color’]} !important;301 }302 ";303 }304 }305 $css .= $grid_config[‘custom_css’];306 $css .="</style></div>";307 echo sprintf('%s’,$css);308 }309 }310311 public static function gf_get_attachment_image($attachment_id, $crop, $crop_size, &$with_after_crop,312 &$height_after_crop, &$with_origin, &$height_origin, &$attachment_url, &$crop_url){313314 $orig_image = wp_get_attachment_image_src($attachment_id, ‘full’);315 if ($orig_image === false) {316 return;317 }318 $attachment_url = $crop_url = isset($orig_image[0]) ? $orig_image[0] : ‘’ ;319 $with_origin = $with_after_crop = isset($orig_image[1]) ? $orig_image[1] : $with_origin;320 $height_origin = $height_after_crop = isset($orig_image[2]) ? $orig_image[2] : $height_origin;321322 if($crop){323 $percent = 1;324 if($with_after_crop>=$crop_size){325 $percent = floor($with_after_crop/$crop_size);326 $with_after_crop = $crop_size;327 $height_after_crop = floor($height_after_crop/$percent);328 }elseif($height_after_crop>=$crop_size){329 $percent = floor($height_after_crop/$crop_size);330 $height_after_crop = $crop_size;331 $with_after_crop = floor($with_after_crop/$percent);332 }333 $crop_url = G5Plus_Image_Resize::init()->resize(array(334 ‘image_id’ => $attachment_id,335 ‘width’ => $with_after_crop,336 ‘height’ => $height_after_crop,337 ));338 $crop_url = isset($crop_url[‘url’]) ? $crop_url[‘url’] : '’;339 }340 }341 public static function gf_get_attachment_image_size($attachment_id, $crop, $crop_size, &$with_after_crop,342 &$height_after_crop, &$with_origin, &$height_origin, &$attachment_url, &$crop_url, $use_image){343344 if ($crop) {345 $use_image = 'full’;346 }347 $orig_image = wp_get_attachment_image_src($attachment_id, $use_image);348349 //haven’t got image350 if ($orig_image === false) {351 return;352 }353 $attachment_url = $crop_url = isset($orig_image[0]) ? $orig_image[0] : ‘’ ;354 $with_origin = $with_after_crop = isset($orig_image[1]) ? $orig_image[1] : $with_origin;355 $height_origin = $height_after_crop = isset($orig_image[2]) ? $orig_image[2] : $height_origin;356357 if($crop){358 $percent = 1;359 if($with_after_crop>=$crop_size){360 $percent = floor($with_after_crop/$crop_size);361 $with_after_crop = $crop_size;362 $height_after_crop = floor($height_after_crop/$percent);363 }elseif($height_after_crop>=$crop_size){364 $percent = floor($height_after_crop/$crop_size);365 $height_after_crop = $crop_size;366 $with_after_crop = floor($with_after_crop/$percent);367 }368 $crop_url = G5Plus_Image_Resize::init()->resize(array(369 ‘image_id’ => $attachment_id,370 ‘width’ => $with_after_crop,371 ‘height’ => $height_after_crop,372 ));373 $crop_url = isset($crop_url[‘url’]) ? $crop_url[‘url’] : '’;374 }375 }376}