Headline
CVE-2023-1910: rest-api.php in getwid/tags/1.8.3/includes – WordPress Plugin Repository
The Getwid – Gutenberg Blocks plugin for WordPress is vulnerable to unauthorized modification of data due to an insufficient capability check on the get_remote_templates function in versions up to, and including, 1.8.3. This makes it possible for authenticated attackers with subscriber-level permissions or above to flush the remote template cache. Cached template information can also be accessed via this endpoint but these are not considered sensitive as they are publicly accessible from the developer’s site.
1<?php23namespace Getwid;45/**6 * Class REST API7 * @package Getwid8 */9class RestAPI {1011 protected $_namespace = 'getwid/v1’;1213 protected $remote_template_library_url;1415 /**16 * RestAPI constructor.17 */18 public function __construct( ) {1920 $this->remote_template_library_url = defined( ‘GETWID_REMOTE_TEMPLATE_LIBRARY_URL’ ) ?21 GETWID_REMOTE_TEMPLATE_LIBRARY_URL : 'https://cgw.motopress.com’;2223 add_action( 'rest_api_init’, [ $this, ‘register_rest_route’ ] );2425 }2627 public function register_rest_route(){2829 register_rest_route( $this->_namespace, '/get_remote_templates’, array(30 array(31 ‘methods’ => 'GET’,32 ‘callback’ => [ $this, ‘get_remote_templates’ ],33 ‘permission_callback’ => [ $this, ‘permissions_check’ ],34 )35 ) );3637 register_rest_route( $this->_namespace, '/get_remote_content’, array(38 array(39 ‘methods’ => 'GET’,40 ‘callback’ => [ $this, ‘get_remote_content’ ],41 ‘permission_callback’ => [ $this, ‘permissions_check’ ],42 )43 ) );4445 register_rest_route( $this->_namespace, '/taxonomies’, array(46 array(47 ‘methods’ => 'GET’,48 ‘callback’ => [ $this, ‘get_taxonomies’ ],49 ‘permission_callback’ => [ $this, ‘permissions_check’ ],50 ),51 ‘schema’ => array( $this, ‘taxonomy_schema’ )52 ) );5354 register_rest_route( $this->_namespace, '/terms’, array(55 array(56 ‘methods’ => 'GET’,57 ‘callback’ => [ $this, ‘get_terms’ ],58 ‘permission_callback’ => [ $this, ‘permissions_check’ ],59 ),60 ‘schema’ => array( $this, ‘terms_schema’ )61 ) );6263 register_rest_route( $this->_namespace, '/templates’, array(64 array(65 ‘methods’ => 'GET’,66 ‘callback’ => [ $this, ‘get_templates’ ],67 ‘permission_callback’ => [ $this, ‘permissions_check’ ],68 ),69 ‘schema’ => array( $this, ‘templates_schema’ )70 ) );71 }7273 public function permissions_check( $request ) {74 if ( ! current_user_can( ‘read’ ) ) {75 return new \WP_Error(76 'rest_forbidden’,77 esc_html__( ‘Forbidden.’ ),78 array( ‘status’ => $this->authorization_status_code() )79 );80 }8182 return true;83 }8485 // Sets up the proper HTTP status code for authorization.86 public function authorization_status_code() {8788 $status = 401;8990 if ( is_user_logged_in() ) {91 $status = 403;92 }9394 return $status;95 }9697 /**98 * Schema for a taxonomy.99 *100 * @param WP_REST_Request $request Current request.101 */102 public function taxonomy_schema() {103 $schema = array(104 ‘$schema’ => 'http://json-schema.org/draft-04/schema#’,105 ‘title’ => 'taxonomy’,106 ‘type’ => 'object’,107 ‘properties’ => array(108 ‘post_type_name’ => array(109 ‘description’ => esc_html__( ‘Post Type’ ),110 ‘type’ => 'string’,111 ‘context’ => array( 'view’, 'edit’, ‘embed’ ),112 ‘readonly’ => true,113 )114 )115 );116117 return $schema;118 }119120 /**121 * Schema for a terms.122 *123 * @param WP_REST_Request $request Current request.124 */125 public function terms_schema() {126 $schema = array(127 ‘$schema’ => 'http://json-schema.org/draft-04/schema#’,128 ‘title’ => 'terms’,129 ‘type’ => 'object’,130 ‘properties’ => array(131 ‘taxonomy_name’ => array(132 ‘description’ => esc_html__( ‘Taxonomy’ ),133 ‘type’ => 'string’,134 ‘context’ => array( 'view’, 'edit’, ‘embed’ ),135 ‘readonly’ => true,136 )137 )138 );139140 return $schema;141 }142143 /**144 * Schema for a templates.145 *146 * @param WP_REST_Request $request Current request.147 */148 public function templates_schema() {149 $schema = array(150 ‘$schema’ => 'http://json-schema.org/draft-04/schema#’,151 ‘title’ => 'templates’,152 ‘type’ => 'object’,153 ‘properties’ => array(154 ‘post_type_name’ => array(155 ‘description’ => esc_html__( ‘Templates’ ),156 ‘type’ => 'string’,157 ‘context’ => array( 'view’, 'edit’, ‘embed’ ),158 ‘readonly’ => true,159 )160 )161 );162163 return $schema;164 }165166 public function get_remote_templates() {167168 $cache = sanitize_text_field( wp_unslash( $_GET[‘cache’] ) );169 $templates_data = [];170171 if ($cache == ‘cache’){172 $templates_data = get_transient( ‘getwid_templates_response_data’ ); //Get Cache response173 } elseif ($cache == ‘refresh’) {174 delete_transient( ‘getwid_templates_response_data’ ); //Delete cache data175 }176177 if ( $templates_data == false || empty( $templates_data ) ) {178179 //Get Templates from remote server180 $response = wp_remote_get(181 $this->remote_template_library_url . "/wp-json/getwid-templates-server/v1/get_templates",182 array(183 ‘timeout’ => 15,184 )185 );186 // var_dump( $response ); exit();187188 if ( is_wp_error( $response ) ) {189 return ‘<p>’ . $response->get_error_message() . '</p>’;190 } else {191192 $templates_data = json_decode( wp_remote_retrieve_body( $response ), false );193194 //JSON valid195 if ( json_last_error() === JSON_ERROR_NONE && $templates_data ) {196197 set_transient( 'getwid_templates_response_data’, $templates_data, 24 * HOUR_IN_SECONDS ); //Cache response198 return $templates_data;199200 } else {201 return __( 'Error in json_decode.’, ‘getwid’ );202 }203 }204 } else {205 return $templates_data;206 }207 }208209 public function get_remote_content() {210 $get_content_url = esc_url_raw( $_GET[‘get_content_url’] );211212 //Get Templates from remote server213 $response = wp_remote_get(214 $get_content_url,215 array(216 ‘timeout’ => 15,217 )218 );219220 // var_dump( wp_remote_retrieve_body( $response ) ); exit();221222 $templates_data = json_decode( wp_remote_retrieve_body( $response ) );223224 //JSON valid225 if ( json_last_error() === JSON_ERROR_NONE ) {226 return $templates_data;227 } else {228 return __( ‘Error in json_decode.’, ‘getwid’ );229 }230 }231232 public function get_taxonomies($object) {233 $post_type_name = sanitize_text_field( wp_unslash( $_GET[‘post_type_name’] ) );234 $taxonomies = get_object_taxonomies( $post_type_name, ‘objects’ );235236 $return = [];237 if (!empty($taxonomies)){238 foreach ($taxonomies as $key => $taxonomy_name) {239 $return[] = array(240 ‘value’ => $key,241 ‘label’ => $taxonomy_name->labels->name.’ (‘.$key.’)‘242 );243 }244 }245 return $return;246 }247248 public function get_terms($object) {249 $taxonomy_name = getwid_recursive_sanitize_array( wp_unslash( $_GET[‘taxonomy_name’] ) );250251 $return = [];252 $terms = get_terms(array(253 ‘taxonomy’ => $taxonomy_name,254 ‘hide_empty’ => false,255 ));256257 if (!empty($terms)){258 foreach ($terms as $key => $term_name) {259 $taxonomy_obj = get_taxonomy( $term_name->taxonomy );260261 $return[$term_name->taxonomy][‘group_name’] = $taxonomy_obj->label;262 $return[$term_name->taxonomy][‘group_value’][] = array(263 ‘value’ => $term_name->taxonomy.’[‘.$term_name->term_id.’]',264 ‘label’ => $term_name->name,265 );266 }267 }268 return $return;269 }270271 public function get_templates($object) {272 $template_name = sanitize_text_field( wp_unslash( $_GET[‘template_name’] ) );273274 $posts = get_posts( array(275 ‘numberposts’ => -1,276 ‘orderby’ => 'date’,277 ‘order’ => 'DESC’,278 ‘post_type’ => $template_name,279 ) );280281 $return = [];282 if (!empty($posts)){283 foreach ($posts as $key => $post) {284 $return[] = array(285 ‘value’ => $post->ID,286 ‘label’ => $post->post_title287 );288 }289 }290 return $return;291 }292}
Related news
WordPress Getwid Gutenberg Blocks plugin versions 1.8.3 and below suffer from improper authorization and server-side request forgery vulnerabilities.