Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-0553: settings.php in quick-restaurant-menu/tags/2.0.2/includes/admin/settings – WordPress Plugin Repository

The Quick Restaurant Menu plugin for WordPress is vulnerable to Stored Cross-Site Scripting via its settings parameters in versions up to, and including, 2.0.2 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with administrator-level permissions and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.

CVE
#xss#web#git#wordpress#php#auth

1<?php2/**3 * Settings4 *5 * From Easy Digital Downloads, changed and added sections to tabs6 * @package ERM7 * @subpackage Admin8 * @copyright Copyright © 2022, Alejandro Pascual9 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License10 * @since 1.011 */1213/**14 * Class ERM_Settings15 *16 * @since 1.017 */18class ERM_Settings {1920 private $options;21 private $set_name;2223 public function __construct( $name = ‘erm_settings’ )24 {25 $this->set_name = $name;26 $this->options = get_option( $this->set_name, array() );27 add_action( 'admin_init’, array( $this, ‘register_settings’) );28 }2930 public function register_settings() {3132 if ( false == get_option( $this->set_name ) ) {33 add_option( $this->set_name );34 }3536 foreach( $this->list_of_settings() as $tab => $settings ) {3738 // Manage tab with several sections inside (name_) underscore at the end means sub settings39 if (preg_match('/.+_$/’, $tab)) {4041 foreach($settings as $sec=>$sub_settings) {42 $this->add_settings_section( $tab.$sec );43 $this->add_settings_fields( $tab.$sec, $sub_settings );44 }45 }46 else {47 $this->add_settings_section( $tab);48 $this->add_settings_fields( $tab, $settings );49 }50 }5152 register_setting( $this->set_name, $this->set_name, array( $this, ‘sanitize’) );53 }5455 public function add_settings_section( $tab ) {5657 add_settings_section(58 $this->set_name . ‘_’ . $tab,59 __return_null(),60 '__return_false’,61 $this->set_name . ‘_’ . $tab62 );63 }6465 public function add_settings_fields( $tab, $settings ) {6667 foreach( $settings as $key => $option ) {6869 $name = isset( $option[‘name’] ) ? $option[‘name’] : '’;7071 $callback = is_callable( array($this, 'show_’.$option[‘type’]) ) ? array($this, 'show_’.$option[‘type’]) : array($this, ‘show_missing’);7273 add_settings_field(74 $this->set_name . '[' . $key . ']',75 $name,76 $callback,77 $this->set_name . ‘_’ . $tab, // Page78 $this->set_name . ‘_’ . $tab, // Section79 array(80 ‘id’ => $key,81 ‘desc’ => ! empty( $option[‘desc’] ) ? $option[‘desc’] : '’,82 ‘name’ => isset( $option[‘name’] ) ? $option[‘name’] : null,83 ‘section’ => $tab,84 ‘size’ => isset( $option[‘size’] ) ? $option[‘size’] : null,85 ‘options’ => isset( $option[‘options’] ) ? $option[‘options’] : '’,86 ‘std’ => isset( $option[‘std’] ) ? $option[‘std’] : '’,87 'callback’=> isset( $option[‘callback’] ) ? $option[‘callback’] : '’,88 ‘options’ => isset( $option[‘options’] ) ? $option[‘options’] : '’89 )90 );91 }92 }9394 public function list_of_settings() {9596 $list = array(97 ‘general’ => apply_filters( ‘erm_settings_general’, // Tab general98 array(99 /*’erm_menu_slug’ => array(100 ‘name’ => __( 'Menu slug’, ‘erm’ ),101 ‘desc’ => __( ‘Use this for changing the slug for the menu Custom Post Type. By default is qr_menu.’ , ‘erm’ ),102 ‘type’ => 'text’,103 ‘size’ => 'medium’,104 ‘std’ => 'qr_menu’105 ),*/106 ‘erm_currency’ => array(107 ‘name’ => __( 'Currency’, ‘erm’ ),108 ‘desc’ => __( ‘Add this character to the price. Leave it blank if you don\’t want to display.’ , ‘erm’ ),109 ‘type’ => 'text’,110 ‘size’ => 'small’,111 ‘std’ => '’112 ),113 ‘erm_currency_position’ => array(114 ‘name’ => __( 'Currency position’, ‘erm’ ),115 ‘desc’ => __( ‘’ , ‘erm’ ),116 ‘type’ => 'radio’,117 ‘size’ => 'regular’,118 ‘std’ => 'before’,119 ‘options’ => array(120 ‘before’ => __('Before price’, ‘erm’),121 ‘after’ => __(‘After price’, ‘erm’)122 )123 ),124 /*’erm_show_dashboard_menu_items’ => array(125 ‘name’ => __( 'Show Menu Items’, ‘erm’ ),126 ‘desc’ => __( ‘Display the Dashboard MENU for post type "Menu Items"’ , ‘erm’ ),127 ‘type’ => 'checkbox’,128 ‘size’ => '’,129 ‘std’ => '’130 ),*/131 ‘erm_menu_thumb_size’ => array(132 ‘name’ => __( 'Menu items thumbnail size’, ‘erm’ ),133 ‘desc’ => __( ‘’ , ‘erm’ ),134 ‘type’ => 'select_size’,135 ‘size’ => 'regular’,136 ‘std’ => '’137 ),138 ‘erm_custom_css’ => array(139 ‘name’ => __( 'Custom CSS’, ‘erm’ ),140 ‘desc’ => __( ‘’ , ‘erm’ ),141 ‘type’ => 'textarea’,142 ‘size’ => 'large’,143 ‘std’ => '’144 ),145 ‘erm_custom_css_display’ => array(146 ‘name’ => __( 'Insert Custom CSS’, ‘erm’ ),147 ‘desc’ => __( ‘Inject the CSS in the Front End’ , ‘erm’ ),148 ‘type’ => 'checkbox’,149 ‘size’ => '’,150 ‘std’ => '’151 )152 )153 )154 );155156 return apply_filters( 'erm_registered_settings’, $list );157 }158159 public function get( $key , $default = false ) {160 return empty( $this->options[$key] ) ? $default : $this->options[$key];161 }162163 public function delete( $key )164 {165 if (isset($this->options[$key]) ) { unset($this->options[$key]);166 }167 $options = get_option(ERM_SETTINGS);168 unset($options[$key]);169 update_option(ERM_SETTINGS, $options);170 }171172 public function get_all( $key ) {173 return $this->options;174 }175176 public function sanitize( $input ) {177178 if ( empty( $_POST[‘_wp_http_referer’] ) ) {179 return $input;180 }181182 // Get tab & section183 parse_str( sanitize_text_field($_POST[‘_wp_http_referer’]), $referrer );184185 $saved = get_option( $this->set_name, array() );186 if( ! is_array( $saved ) ) {187 $saved = array();188 }189190 // Get list of settings191 $settings = $this->list_of_settings();192 $tab = isset( $referrer[‘tab’] ) ? $referrer[‘tab’] : 'general’; // TAB, First key by default193 $section = isset( $referrer[‘section’] ) ? $referrer[‘tab’] : '’; // SECTION194195 $input = $input ? $input : array();196197 // Sanitize tab section198 $input = apply_filters( ‘erm_settings_’ . $tab . $section . '_sanitize’, $input );199200201 // Ensure checkbox is passed202 if( !empty($settings[$tab]) ) {203204 // Has sections inside tab205 if ( preg_match('/.+_$/’, $tab ) ) {206 $comprobar = $settings[$tab][$section];207 }208 // No sections inside tab209 else {210 $comprobar = $settings[ $tab ];211 }212213 foreach ( $comprobar as $key => $setting ) {214 // Single checkbox215 if ( isset( $settings[ $tab ][ $key ][ ‘type’ ] ) && ‘checkbox’ == $settings[ $tab ][ $key ][ ‘type’ ] ) {216 $input[ $key ] = ! empty( $input[ $key ] );217 }218 // Multicheck list219 if ( isset( $settings[ $tab ][ $key ][ ‘type’ ] ) && ‘multicheck’ == $settings[ $tab ][ $key ][ ‘type’ ] ) {220 if( empty( $input[ $key ] ) ) {221 $input[ $key ] = array();222 }223 }224 }225226 }227228 // Loop each input to be saved and sanitize229 foreach( $input as $key => $value ) {230231 // With sections inside tab232 if ( preg_match(‘/.+_$/’, $tab ) ) {233 $type = isset( $settings[$tab][$section][$key][‘type’] ) ? $settings[$tab][$section][$key][‘type’] : false;234 }235 // No sections inside tab236 else {237 $type = isset( $settings[$tab][$key][‘type’] ) ? $settings[$tab][$key][‘type’] : false;238 }239240 // Specific sanitize. Ex. erm_settings_sanitize_textarea241 $input[$key] = apply_filters( ERM_SETTINGS.’_sanitize_’.$type , $value, $key );242243 // General sanitize244 $input[$key] = apply_filters( ERM_SETTINGS.’_sanitize’ , $value, $key );245 }246247 add_settings_error( 'erm-notices’, '’, __( 'Settings updated.’, ‘erm’ ), ‘updated’ );248249 return array_merge( $saved, $input );250 }251252 // Show fields, depends on type253 //-------------------------------------254255 /**256 * Not found callback function257 *258 * @since 1.0259 * @param $args260 */261 public function show_missing( $args ) {262263 printf( __( 'The callback function for setting <strong>%s</strong> is missing.’, ‘erm’ ), $args[‘id’] );264 }265266 public function show_esc_label($name, $desc)267 {268 echo '<label for="’.esc_attr($name).’"> ' . esc_html($desc). '</label>’;269 }270271 /**272 * Checkbox field273 *274 * @since 1.0275 * @param $args276 */277 public function show_checkbox( $args )278 {279 $checked = isset($this->options[$args[‘id’]]) ? checked(1, $this->options[$args[‘id’]], false) : '’;280 $name = “{$this->set_name}[{$args[‘id’]}]“;281 $desc = $args[‘desc’];282283 echo '<input type="checkbox” id="’.esc_attr($name).’” name="’.esc_attr($name).’" value="1" ' . esc_attr($checked) . '/>’;284 $this->show_esc_label($name, $desc);285 }286287 /**288 * Show text field289 *290 * @since 1.0291 * @param $args292 */293 public function show_text( $args ) {294295 if (isset($this->options[ $args[‘id’] ]) ) {296 $value = $this->options[$args[‘id’]];297 } else {298 $value = isset($args[‘std’]) ? $args[‘std’] : ‘’;299 }300301 $size = ( isset($args[‘size’]) && ! is_null($args[‘size’]) ) ? $args[‘size’] : ‘regular’;302 $name = "{$this->set_name}[{$args[‘id’]}]“;303 $desc = $args[‘desc’];304305306 echo '<input type="text” class="’ . esc_attr($size) . '-text" id="’.esc_attr($name).’" name="’.esc_attr($name).’" value="’ . esc_attr(stripslashes($value)) . '"/>’;307 $this->show_esc_label($name, $desc);308 }309310 /**311 * Show textarea312 *313 * @since 1.0314 * @param $args315 */316 public function show_textarea( $args ) {317318 if (isset($this->options[ $args[‘id’] ]) ) {319 $value = $this->options[$args[‘id’]];320 } else {321 $value = isset($args[‘std’]) ? $args[‘std’] : '’;322 }323324 $size = ( isset($args[‘size’]) && ! is_null($args[‘size’]) ) ? $args[‘size’] : ‘regular’;325 $name = “{$this->set_name}[{$args[‘id’]}]“;326 $desc = $args[‘desc’];327328 echo ‘<textarea class="’.esc_attr($size).’-text” cols="50” rows="10" id="’.esc_attr($name).’" name="’.esc_attr($name).’">’ .329 esc_textarea(stripslashes($value)) .330 '</textarea>’;331 echo ‘<div class="qrr-settings-desc">’.esc_html($desc).’</div>’;332 }333334 /**335 * Radio field336 *337 * @since 1.0338 * @param $args339 */340 public function show_radio( $args ) {341342 foreach( $args[‘options’] as $key => $value ) {343 $checked = false;344 if (isset($this->options[ $args[‘id’] ]) && $this->options[ $args[‘id’] ] == $key ) {345 $checked = true;346 } else if (!isset($this->options[ $args[‘id’] ]) && isset($args[‘std’]) && $args[‘std’] == $key ) {347 $checked = true;348 }349350 $name = "{$this->set_name}[{$args[‘id’]}]“;351 $id = “{$this->set_name}[{$args[‘id’]}][{$key}]“;352 $desc = $args[‘desc’];353354 echo '<input name="’.esc_attr($name).’” id="’.esc_attr($id).’” type="radio” value="’ . esc_attr($key) . '" ' . checked(true, $checked, false) . '/> ';355 echo ‘<label for="’.esc_attr($id).’">’ . esc_html($value) . '</label><br/>’;356 }357 echo ‘<p class="description">’ . esc_html($desc) . '</p>’;358 }359360 /**361 * Select image size field362 *363 * @since 1.0364 * @param $args365 */366 public function show_select_size( $args )367 {368369 if (isset($this->options[ $args[‘id’] ]) ) {370 $value = $this->options[$args[‘id’]];371 } else {372 $value = isset($args[‘std’]) ? $args[‘std’] : '’;373 }374375 $sizes = erm_get_image_sizes();376 $size = ( isset($args[‘size’]) && ! is_null($args[‘size’]) ) ? $args[‘size’] : 'regular’;377 $name = “{$this->set_name}[{$args[‘id’]}]“;378 $desc = $args[‘desc’];379380 echo '<select name="’.esc_attr($name).’” id="’.esc_attr($name).’” >’;381 foreach($sizes as $key => $dim) {382 $selected = ($key == $value ? ‘selected’: ‘’);383 $size = $key.’(‘.$dim[‘width’].’x’.$dim[‘height’].’)';384 echo '<option value="’.esc_attr($key).’" '.esc_attr($selected).’>’.esc_html($size).’</option>’;385 }386 echo '</option>’;387 echo ‘<p class="description">’ . esc_html($desc) . '</p>’;388 }389390 /**391 * Show description392 *393 * @since 1.0394 * @param $args395 */396 public function show_desc( $args )397 {398399 echo’<p>’.esc_html($args[‘desc’]).’</p>’;400 }401402 /**403 * Call a callback function, name has to be in $args[‘callback’]404 *405 * @since 1.0406 * @param $args407 */408 public function show_callback( $args )409 {410 $func = $args[‘callback’];411 if (is_callable($func)) {412 call_user_func( $func, $args );413 }414 }415}416417/**418 * Sanitize text field419 *420 * @since 1.0421 * @param $value422 * @return mixed423 */424function erm_settings_sanitize_text( $value )425{426 return trim( $value );427}428add_filter(‘erm_settings_sanitize_text’,’erm_settings_sanitize_text’);429430/**431 * Sanitize textarea field432 *433 * @since 1.0434 * @param $value435 * @return mixed436 */437function erm_settings_sanitize_textarea( $value )438{439 return $value;440}441add_filter(‘erm_settings_sanitize_textarea’,’erm_settings_sanitize_textarea’);442

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907