Headline
CVE-2023-2083: Admin.php in essential-blocks/tags/4.0.6/includes/Admin – WordPress Plugin Repository
The Essential Blocks plugin for WordPress is vulnerable to unauthorized use of functionality due to a missing capability check on the save function in versions up to, and including, 4.0.6. This makes it possible for subscriber-level attackers to save plugin settings. While a nonce check is present, it is only executed when a nonce is provided. Not providing a nonce results in the nonce verification to be skipped. There is no capability check.
1<?php23namespace EssentialBlocks\Admin;45use EssentialBlocks\Utils\Helper;6use EssentialBlocks\Utils\Settings;7use EssentialBlocks\Traits\HasSingletone;8use EssentialBlocks\Dependencies\Insights;9use EssentialBlocks\Dependencies\WPNotice\Notices;1011class Admin {1213 use HasSingletone;1415 /**16 * Plugin Usage Insight17 * @var Insights|null18 */19 private $insights = null;2021 public function __construct() {22 $this->plugin_usage_insights();23 add_action( 'admin_init’, [$this, ‘notices’] );2425 add_action( 'admin_menu’, [$this, ‘admin_menu’] );2627 //Update message for showing notice for new release28 add_action( 'in_plugin_update_message-essential-blocks/essential-blocks.php’, [$this, ‘plugin_update’], 10, 2 );2930 $_blocks_category_hook = version_compare( get_bloginfo( ‘version’ ), '5.8’, ‘>=’ ) ? ‘block_categories_all’ : 'block_categories’;31 add_filter( $_blocks_category_hook, [$this, ‘register_category’], 10, 2 );3233 add_action( 'admin_enqueue_scripts’, [$this, ‘enqueue_styles’] );34 add_action( 'admin_enqueue_scripts’, [$this, ‘enqueue_scripts’] );3536 add_action( 'wp_ajax_save_eb_admin_options’, [$this, ‘save’] );37 add_action( 'wp_ajax_get_eb_admin_options’, [$this, ‘get’] );38 add_action( 'wp_ajax_get_eb_admin_templates’, [$this, ‘templates’] );39 add_action( 'wp_ajax_get_eb_admin_template_count’, [$this, ‘template_count’] );4041 //Redirect after Plugin is updated42 add_action( 'admin_init’, [$this, ‘maybe_redirect’] );43 }4445 public function maybe_redirect(){46 if ( wp_doing_ajax()) {47 return;48 }4950 if( get_transient(‘essential_block_maybe_whatsnew_redirect’) == true ) {51 delete_transient( ‘essential_block_maybe_whatsnew_redirect’ );5253 if ( ! is_multisite() ) {54 wp_safe_redirect( add_query_arg( [‘page’ => ‘welcome-essential-blocks’], admin_url( ‘admin.php’ ) ) );55 }56 }57 }5859 public function admin_menu() {60 add_menu_page(61 __( 'Essential Blocks’, ‘essential-blocks’ ),62 __( 'Essential Blocks’, ‘essential-blocks’ ),63 'delete_user’,64 'essential-blocks’,65 [$this, ‘admin_page’],66 ESSENTIAL_BLOCKS_ADMIN_URL . 'assets/images/eb-icon-21x21.svg’,67 6068 );6970 // Welcome Page71 add_submenu_page(72 '’,73 'Welcome Page’,74 'Welcome Page’,75 'delete_user’,76 'welcome-essential-blocks’,77 [$this, ‘welcome_page’]78 );79 }8081 public function admin_page() {82 Helper::views( 'admin’, [] );83 }8485 public function welcome_page() {86 Helper::views( 'welcome’, [] );87 }8889 public function register_category( $categories, $post ) {90 $eb_category = [91 ‘slug’ => 'essential-blocks’,92 ‘title’ => __( 'Essential Blocks’, ‘essential-blocks’ )93 ];94 return array_merge( [$eb_category], $categories );95 }9697 /**98 * Update message for showing notice for new release99 */100 public function plugin_update( $plugin_data, $new_data ) {101 require_once ABSPATH . 'wp-admin/includes/plugin-install.php’;102 $upgrade_notice = false;103 if ( isset( $new_data->upgrade_notice ) ) {104 $upgrade_notice = $new_data->upgrade_notice;105 }106107 Helper::version_update_warning( $plugin_data[‘Version’], $plugin_data[‘new_version’], $upgrade_notice );108 }109110 /**111 * WP Insights Integration112 */113 public function plugin_usage_insights() {114 $this->insights = Insights::get_instance( ESSENTIAL_BLOCKS_FILE, [115 ‘opt_in’ => true,116 ‘goodbye_form’ => true,117 ‘item_id’ => 'fa45e4a52a650579e98c’118 ] );119 $this->insights->set_notice_options( [120 ‘notice’ => __( 'Congratulations, you’ve successfully installed <strong>Essential Blocks for Gutenberg</strong>. We got <strong style="color: #a022ff;">1000+ FREE Gutenberg ready Templates</strong> waiting for you <span class="gift-icon">🎁</span>’, ‘essential-blocks’ ),121 ‘extra_notice’ => __( 'We collect non-sensitive diagnostic data and plugin usage information.122 Your site URL, WordPress & PHP version, plugins & themes and email address to send you exciting deals. This data lets us make sure this plugin always stays compatible with the most123 popular plugins and themes.’, ‘essential-blocks’ ),124 ‘yes’ => __( 'Send me FREE Templates’, ‘wpinsight’ ),125 ‘no’ => __( 'I don\’t want FREE Templates’, ‘wpinsight’ )126 ] );127 $this->insights->init();128 }129130 /**131 * Admin notices for Review and others.132 *133 * @return void134 */135 public function notices() {136 $notices = new Notices( [137 ‘id’ => 'essential_blocks’,138 ‘store’ => 'options’,139 ‘storage_key’ => 'notices’,140 ‘version’ => '1.0.0’,141 ‘lifetime’ => 3,142 ‘styles’ => ESSENTIAL_BLOCKS_URL . 'assets/css/notices.css’143 ] );144145 /**146 * Review Notice147 * @var mixed $message148 */149150 $message = __(151 'We hope you\’re enjoying Essential Block for Gutenberg! Could you please do us a BIG favor and give it a 5-star rating on WordPress to help us spread the word and boost our motivation?’,152 'essential-blocks’153 );154155 $_review_notice = [156 ‘thumbnail’ => ESSENTIAL_BLOCKS_URL . 'assets/images/eb-logo.svg’,157 ‘html’ => ‘<p>’ . $message . '</p>’,158 ‘links’ => [159 ‘later’ => [160 ‘link’ => 'https://wordpress.org/support/plugin/essential-blocks/reviews/#new-post’,161 ‘label’ => __( 'Sure, you deserve it!’, ‘essential-blocks’ ),162 ‘icon_class’ => 'dashicons dashicons-external’,163 ‘attributes’ => [164 ‘target’ => '_blank’,165 ‘class’ => 'btn’,166 ‘data-dismiss’ => false167 ]168 ],169 ‘allready’ => [170 ‘label’ => __( 'I already did’, ‘essential-blocks’ ),171 ‘icon_class’ => 'dashicons dashicons-smiley’,172 ‘attributes’ => [173 ‘data-dismiss’ => true174 ]175 ],176 ‘maybe_later’ => [177 ‘label’ => __( 'Maybe Later’, ‘essential-blocks’ ),178 ‘icon_class’ => 'dashicons dashicons-calendar-alt’,179 ‘attributes’ => [180 ‘data-later’ => true,181 ‘class’ => 'dismiss-btn’182 ]183 ],184 ‘support’ => [185 ‘link’ => 'https://wpdeveloper.com/support’,186 ‘attributes’ => [187 ‘target’ => '_blank’188 ],189 ‘label’ => __( 'I need help’, ‘essential-blocks’ ),190 ‘icon_class’ => 'dashicons dashicons-sos’191 ],192 ‘never_show_again’ => [193 ‘label’ => __( 'Never show again’, ‘essential-blocks’ ),194 ‘icon_class’ => 'dashicons dashicons-dismiss’,195 ‘attributes’ => [196 ‘data-dismiss’ => true197 ]198 ]199 ]200 ];201202 $notices->add(203 'review’,204 $_review_notice,205 [206 ‘start’ => $notices->strtotime( ‘+10 days’ ),207 // ‘start’ => $notices->time(),208 ‘recurrence’ => 15,209 ‘dismissible’ => true,210 ‘refresh’ => ESSENTIAL_BLOCKS_VERSION,211 ‘screens’ => [212 'dashboard’,213 'plugins’,214 'themes’,215 'edit-page’,216 'edit-post’,217 'users’,218 'tools’,219 'options-general’,220 'nav-menus’221 ]222 ]223 );224225 /**226 * Opt-In Notice227 */228 if ( $this->insights != null ) {229 $notices->add(230 'opt_in’,231 [$this->insights, ‘notice’],232 [233 ‘classes’ => 'updated put-dismiss-notice’,234 ‘start’ => $notices->time(),235 ‘dismissible’ => true,236 ‘do_action’ => 'wpdeveloper_notice_clicked_for_essential-blocks’237 ]238 );239 }240241 $notices->init();242 }243244 public function enqueue_styles( $hook ) {245 wpdev_essential_blocks()->assets->enqueue( 'menu’, ‘css/eb-menu.css’ );246247 if ( $hook !== ‘toplevel_page_essential-blocks’ ) {248 return;249 }250251 wpdev_essential_blocks()->assets->enqueue( 'admin’, ‘css/admin.css’ );252 wpdev_essential_blocks()->assets->enqueue( 'admin-custom’, ESSENTIAL_BLOCKS_URL . ‘admin/style.css’ );253 }254255 public function enqueue_scripts( $hook ) {256 if ( $hook !== ‘toplevel_page_essential-blocks’ ) {257 return;258 }259260 wpdev_essential_blocks()->assets->register( 'vendor-bundle’, ‘…/…/vendor-bundle/index.js’ ); //??261 wpdev_essential_blocks()->assets->enqueue(262 'admin-blocks’,263 '…/admin/index.js’,264 [‘essential-blocks-vendor-bundle’]265 );266267 wpdev_essential_blocks()->assets->enqueue( 'category-icon’, ‘…/lib/update-category-icon/index.js’ );268 }269270 /**271 * AJAX Save function272 */273 public function save() {274 if ( isset( $_POST[‘admin_nonce’] ) && ! wp_verify_nonce( $_POST[‘admin_nonce’], ‘admin-nonce’ ) ) {275 wp_send_json_error( __( 'Nonce Error’, ‘essential-blocks’ ) );276 }277278 if ( isset( $_POST[‘type’] ) ) {279 $type = trim( $_POST[‘type’] );280 $key = isset( $_POST[‘key’] ) ? trim( $_POST[‘key’] ) : '’;281 $value = isset( $_POST[‘value’] ) ? trim( $_POST[‘value’] ) : '’;282283 $settings = Settings::get_instance();284285 switch ( $type ) {286 case "settings":287 /**288 * Save blocks Settings options289 */290 $updated = $settings->save( $key, $value );291 wp_send_json_success( $updated );292 break;293294 case "enable_disable":295 /**296 * Save Enable/disable blocks options297 */298 $value = json_decode( wp_unslash( $value ), true );299 $updated = $settings->save_blocks_option( $value );300 wp_send_json_success( $updated );301 break;302 default:303 wp_send_json_error( __( 'Something went wrong regarding saving options data.’, ‘essential-blocks’ ) );304 }305 } else {306 wp_send_json_error( __( 'Something went wrong regarding saving options data.’, ‘essential-blocks’ ) );307 }308 }309310 /**311 * AJAX Get function312 */313 public function get() {314 if ( isset( $_POST[‘admin_nonce’] ) && ! wp_verify_nonce( $_POST[‘admin_nonce’], ‘admin-nonce’ ) ) {315 wp_send_json_error( __( 'Nonce Error’, ‘essential-blocks’ ) );316 }317318 if ( isset( $_POST[‘key’] ) ) {319 $key = trim( $_POST[‘key’] );320 $settings = Settings::get_instance();321 $data = $settings->get( $key );322323 if ( $data ) {324 wp_send_json_success( $data );325 } else {326 wp_send_json_error( __( 'Invalid Key’, ‘essential-blocks’ ) );327 }328 } else {329 wp_send_json_error( __( 'Something went wrong regarding getting options data.’, ‘essential-blocks’ ) );330 }331 }332333 /**334 * AJAX Get Templately Templates335 */336 public function templates() {337 if ( isset( $_POST[‘admin_nonce’] ) && ! wp_verify_nonce( $_POST[‘admin_nonce’], ‘admin-nonce’ ) ) {338 wp_send_json_error( __( 'Nonce Error’, ‘essential-blocks’ ) );339 }340 $headers = [341 ‘Content-Type’ => 'application/json’342 ];343 $query = "{344 packs(plan_type: 2, per_page: 6){345 data{346 id347 name348 thumbnail,349 price,350 slug351 }352 }353 }";354 $response = wp_remote_post( 'https://app.templately.com/api/plugin’, [355 ‘timeout’ => 30,356 ‘headers’ => $headers,357 ‘body’ => wp_json_encode( [358 ‘query’ => $query359 ] )360 ] );361 if ( $response ) {362 wp_send_json_success( $response );363 } else {364 wp_send_json_error( __( 'Something went wrong regarding getting data.’, ‘essential-blocks’ ) );365 }366 }367368 /**369 * AJAX Get Templately Templates370 */371 public function template_count() {372 if ( isset( $_POST[‘admin_nonce’] ) && ! wp_verify_nonce( $_POST[‘admin_nonce’], ‘admin-nonce’ ) ) {373 wp_send_json_error( __( 'Nonce Error’, ‘essential-blocks’ ) );374 }375 $headers = [376 ‘Content-Type’ => 'application/json’377 ];378 $query = "{379 getCounts {380 key381 value382 }383 }";384 $response = wp_remote_post( 'https://app.templately.com/api/plugin’, [385 ‘timeout’ => 30,386 ‘headers’ => $headers,387 ‘body’ => wp_json_encode( [388 ‘query’ => $query389 ] )390 ] );391 if ( $response ) {392 wp_send_json_success( $response );393 } else {394 wp_send_json_error( __( 'Something went wrong regarding getting data.’, ‘essential-blocks’ ) );395 }396 }397}