Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-4994: allowphp.php in allow-php-in-posts-and-pages/trunk – WordPress Plugin Repository

The Allow PHP in Posts and Pages plugin for WordPress is vulnerable to Remote Code Execution in versions up to, and including, 3.0.4 via the ‘php’ shortcode. This allows authenticated attackers with subscriber-level permissions or above, to execute code on the server.

CVE
#sql#wordpress#php#rce#auth

1<?php2/*3Plugin Name: Allow PHP in Posts and Pages4version: 3.0.45Plugin URI: http://www.hitreach.co.uk/wordpress-plugins/allow-php-in-posts-and-pages/6Description: Allow PHP in posts and pages allows you to add php functionality to Wordpress Posts and Pages whilst still retaining HTML tags7Author: Hit Reach8Author URI: http://www.hitreach.co.uk/9*/1011global $allow_php;12if(! class_exists( “allow_php_in_posts” ) ){131415 class allow_php_in_posts{16 /* Static Variables */17 static $capabilities = “manage_options";18 static $plugin_title = “Allow PHP in Post and Pages";19 static $menu_slug = “allow-php-menu";20 static $menu_title = “Allow PHP in posts"; 21 static $menu_page_title = “Allow PHP in posts and pages";22 static $submenu_slug = “allow-php-information";23 static $submenu_title = “Plugin Information";24 static $submenu_page_title = “Plugin Information";25 static $option_name = “allowPHP_options";26 static $database_version = “3";27 static $database_prefix = “allowphp_functions";28 static $stylesheet_slug = “allow-php-stylesheet";29 static $post_prefix = “h29fno22lk32";30 public $_shared = “";31 32 function __construct(){33 $this->_shared = array();34 add_shortcode( 'php’, array( __CLASS__, “shortcode” ) );35 add_shortcode( 'PHP’, array( __CLASS__, “shortcode” ) );36 add_shortcode( 'allowphp’, array( __CLASS__, “shortcode” ) );37 add_shortcode( 'ALLOWPHP’, array( __CLASS__, “shortcode” ) );38 add_action( “admin_menu", array( __CLASS__, “menu_register” ) );39 add_action( 'admin_init’, array( __CLASS__, “menu_register_extras”),0); 40 add_filter('widget_text’, ‘do_shortcode’);41 add_filter('the_content’, array( __CLASS__, “shortcode_advanced” ),0);42 }43 44 function menu_register_extras(){45 wp_register_style( self::$stylesheet_slug, plugins_url('additional-styles.css’, __FILE__) );46 }47 48 function menu_register(){49 $page = add_menu_page( self::$menu_page_title, self::$menu_title, self::$capabilities, self::$menu_slug, array(__CLASS__, “menu_primary”), plugins_url(“ap.png", __FILE__) );50 $page2 = add_submenu_page( self::$menu_slug, self::$submenu_title, self::$submenu_page_title, self::$capabilities, self::$submenu_slug, array(__CLASS__, “menu_sub”));51 add_action( 'admin_print_styles-' . $page, array( __CLASS__, “menu_styles” ) );52 add_action( 'admin_print_styles-' . $page2, array( __CLASS__, “menu_styles” ) );53 }54 function menu_styles(){55 wp_enqueue_style( self::$stylesheet_slug );56 }57 function menu_primary(){58 echo '<div class="wrap">’; 59 echo '<h2>’.self::$plugin_title.’</h2>’;60 self::check_post();61 $option = self::option_get();62 echo '<h3>General Options</h3>’;63 self::form_general_options($option);64 echo “<p> </p>";65 echo ‘<h3>Code Snippets</h3>’;66 $snippets = self::snippet_get_all();67 foreach($snippets as $id=>$snippet){68 echo "<fieldset class=’snippet’>";69 echo "<legend><h4>Edit Snippet ID: ".$snippet->id."</h4></legend>";70 echo “<p><strong>Shortcode: <code>[php function=".$snippet->id.”]</code></strong></p>";71 self::form_edit_snippet($snippet); 72 echo "</fieldset>";73 }74 echo "<fieldset class=’snippet’>";75 echo "<legend><h4>ADD A NEW SNIPPET</h4></legend>";76 echo “<p><strong>Shortcode: <code>[php][/php]</code></strong></p>";77 self::form_add_snippet();78 echo “</fieldset>";79 echo '</div>’;80 }81 function menu_sub(){82 echo '<div class="wrap">’;83 echo ‘<h2>’ . self::$plugin_title . '</h2>’;84 echo ‘<h3>’ . self::$submenu_title . '</h3>’;85 include( “information.php” ); 86 echo ‘</div>’;87 }88 89 function check_post(){90 if( isset( $_REQUEST[self::$post_prefix] ) ){91 $expected = array(92 "opt"=>array(),93 "action"=>"",94 “action_code” => "",95 “verification"=>"”);96 $outcome = array_merge($expected, $_REQUEST[self::$post_prefix]);97 extract($outcome);98 if( wp_verify_nonce( $action_code, $action) ){99 if($action === “update_plugin_options”){100 $options = self::option_get();101 foreach($opt as $key=>$value){102 if((int)$value === 1 || (int)$value === 0){103 $options[$key] = (int)$value;104 }105 }106 $res = self::option_set($options);107 if($res === true || $res === NULL){108 self::display_message(“Plugin Options Updated”);109 }110 else{111 self::display_message(“Could Not Update Options, they may not have changed!", false);112 }113 }114 elseif( $action ==="snippet_add” ){115 $opt[“snippet_title”] = esc_html($opt[“snippet_title”]);116 $id = self::snippet_add( array( “name"=>$opt[“snippet_title”], “function"=>$opt[“snippet_code”] ) );117 if( $id > 0){118 self::display_message (“Code Snippet Added, you can use this snippet using the shortcode <code>[php function={$id}]</code>”); 119 }120 else{121 self::display_message (“Oh dear, could not add the code snippet", false); 122 }123 }124 elseif ($action ==="snippet_edit”){125 if( wp_verify_nonce( $verification, $action.$opt[“snippet_id”] ) ){126 $opt[“snippet_title”] = esc_html($opt[“snippet_title”]);127 $id = self::snippet_edit( $opt[“snippet_id”], array( “name"=>$opt[“snippet_title”], “function"=>$opt[“snippet_code”] ) );128 if( $id > 0){129 self::display_message (“Code snippet has been updated”); 130 }131 else{132 self::display_message (“Oh dear, could not update that code snippet", false); 133 }134 }135 }136 elseif ($action === “snippet_delete”){137 if( wp_verify_nonce( $verification, $action.$opt[“snippet_id”] ) ){138 self::snippet_delete( $opt[“snippet_id”] );139 self::display_message (“Code snippet has been deleted”); 140 }141 }142 }143 else{144 self::display_message( “An error occured, please try again", false );145 }146 } 147 }148 149 function display_message( $message="", $good = true){150 $clas = “updated";151 if( $good === false){$clas=’error’;}152 echo ‘<div class="’.$clas.’ settings-error” id="setting-error-settings_updated"><p><strong>’.$message.’</strong></p></div>’;153 }154 155 function snippet_add( $snippet = array( “name” => “", “function"=>"” ) ){156 global $wpdb;157 if( $wpdb->insert( $wpdb->prefix.self::$database_prefix, $snippet, array(“%s", “%s”) ) ){158 return $wpdb->insert_id;159 }160 else{161 return 0; 162 }163 }164 function snippet_edit( $id = 0, $snippet = array( “name” => “", “function"=>"” ) ){165 global $wpdb;166 return $wpdb->update( $wpdb->prefix.self::$database_prefix, $snippet, array( “id” => $id ), array(“%s", “%s”), array(“%d”) );167 }168 function snippet_delete( $snippet_id = 0){169 global $wpdb;170 return $wpdb->get_results( $wpdb->prepare( “DELETE FROM `".$wpdb->prefix.self::$database_prefix."` WHERE `id` = %d LIMIT 1", $snippet_id ) ); 171 }172 function snippet_get( $snippet_id = 0 ){173 global $wpdb;174 $row = $wpdb->get_row( $wpdb->prepare( “SELECT * FROM `".$wpdb->prefix.self::$database_prefix."` WHERE `id` = %d", $snippet_id ) ); 175 if(sizeof($row) > 0){176 $row->function = htmlspecialchars_decode($row->function);177 }178 return $row;179 }180 function snippet_get_all( ){181 global $wpdb;182 $rows = $wpdb->get_results( “SELECT * FROM `".$wpdb->prefix.self::$database_prefix."`” ); 183 return $rows;184 }185 function snippet_swap( $snippet_id = 0){186 $snippet = self::snippet_get($snippet_id);187 if(sizeof($snippet) == 0){188 echo self::snippet_404();189 }190 else{191 eval( stripslashes($snippet->function));192 }193 }194 function snippet_404(){195 $option = self::option_get();196 if( $option[“show404”] == 1 ){197 if( is_int( $option[“fourohfourmsg”] ) && $option[“fourohfourmsg”] !== 0 ){198 $snippet = self::snippet_get( $option[“fourohfourmsg”] );199 return $snippet->function;200 }201 else{202 return “<span style=’font-weight:bold; color:red’>Function does not exist</span>";;203 }204 }205 return “";206 }207 208 function form_add_snippet(){209 ?> 210 <form action="?page=<?php echo self::$menu_slug?>” method="post">211 <input type="hidden” name="<?php echo self::$post_prefix?>[action]" value="snippet_add” />212 <?php wp_nonce_field( “snippet_add", self::$post_prefix.”[action_code]");?>213 <p>214 <label for="<?php echo self::$post_prefix?>[opt][snippet_title]“>Snippet Title</label><input type="text” class="form-field” name="<?php echo self::$post_prefix?>[opt][snippet_title]" required placeholder="Snippet Title, e.g. My First Snippet” />215 </p>216 <p>217 <label for="<?php echo self::$post_prefix?>[opt][snippet_code]“>Snippet Code<br /><br /><em>all snippets automatically start with <?php</em></label>218 <textarea name="<?php echo self::$post_prefix?>[opt][snippet_code]" required class="code-field” placeholder="Your Code Snippet"></textarea>219 </p>220 <input type="submit” value="Save Snippet” />221 </form>222 <?php223 }224 function form_edit_snippet( $snippet ){225 ?> 226 <form action="?page=<?php echo self::$menu_slug?>” method="post">227 <input type="hidden” name="<?php echo self::$post_prefix?>[action]" value="snippet_edit” />228 <?php wp_nonce_field( “snippet_edit", self::$post_prefix.”[action_code]");?>229 <?php wp_nonce_field( “snippet_edit".$snippet->id, self::$post_prefix.”[verification]");?>230 <input type="hidden” name="<?php echo self::$post_prefix?>[opt][snippet_id]" value="<?php echo esc_attr($snippet->id)?>” />231 <p>232 <label for="<?php echo self::$post_prefix?>[opt][snippet_title]“>Snippet Title</label><input type="text” class="form-field” name="<?php echo self::$post_prefix?>[opt][snippet_title]" required placeholder="Snippet Title, e.g. My First Snippet” value=’<?php echo esc_attr(stripslashes($snippet->name))?>’ />233 </p>234 <p>235 <label for="<?php echo self::$post_prefix?>[opt][snippet_code]“>Snippet Code<br /><br /><em>all snippets automatically start with <?php</em></label>236 <textarea name="<?php echo self::$post_prefix?>[opt][snippet_code]" required class="code-field” placeholder="Your Code Snippet"><?php echo esc_html(stripslashes($snippet->function))?></textarea>237 </p>238 <input type="submit” value="Update Snippet” /> <a href="?page=<?php echo self::$menu_slug?>&<?php echo self::$post_prefix?>[action]=snippet_delete&<?php echo self::$post_prefix?>[action_code]=<?php echo wp_create_nonce( “snippet_delete”)?>&<?php echo self::$post_prefix?>[opt][snippet_id]=<?php echo $snippet->id?>&<?php echo self::$post_prefix?>[verification]=<?php echo wp_create_nonce( “snippet_delete".$snippet->id)?>” class=’delete-button’ onclick="return confirm(‘Are you sure you want to delete this snippet?’)“>Delete This Snippet</a>239 </form>240 <?php 241 }242 function form_general_options($option){243 extract($option);244 ?>245 <form action="?page=<?php echo self::$menu_slug;?>” method="post">246 <input type="hidden” name="<?php echo self::$post_prefix?>[action]" value="update_plugin_options” />247 <?php wp_nonce_field( “update_plugin_options", self::$post_prefix.”[action_code]");?>248 <input type="hidden” value="0” name="<?php echo self::$post_prefix?>[opt][fourohfourmsg]" />249 <table class="form-table">250 <tbody>251 <tr valign="top">252 <th scope="row">253 <label for="<?php echo self::$post_prefix?>[opt][show404]“><strong>Show the snippet not found message?</strong></label>254 </th>255 <td>256 Yes: <input type="radio” name="<?php echo self::$post_prefix?>[opt][show404]" <?php checked($show404, 1, true);?> value="1” /><br />No: <input type="radio” name="<?php echo self::$post_prefix?>[opt][show404]" <?php checked($show404, 0, true);?> value="0” />257 </td>258 </tr>259 <tr valign="top">260 <th scope="row">261 <label for="<?php echo self::$post_prefix?>[opt][preparse]“><strong>Use the old (pre 2.2) code replacement method</strong><br /><em>Not Recommended</em></label>262 </th>263 <td>264 Yes: <input type="radio” name="<?php echo self::$post_prefix?>[opt][preparse]" <?php checked($preparse, 1, true);?> value="1” /><br />No: <input type="radio” name="<?php echo self::$post_prefix?>[opt][preparse]" <?php checked($preparse, 0, true);?> value="0” />265 </td>266 </tr>267 <tr valign="top">268 <th scope="row">269 <label for="<?php echo self::$post_prefix?>[opt][use_advanced_filter]“><strong>Use the advanced filter method</strong><br /><em>Removes the code replacement method</em></label>270 </th>271 <td>272 Yes: <input type="radio” name="<?php echo self::$post_prefix?>[opt][use_advanced_filter]" <?php checked($use_advanced_filter, 1, true);?> value="1” /><br />No: <input type="radio” name="<?php echo self::$post_prefix?>[opt][use_advanced_filter]" <?php checked($use_advanced_filter, 0, true);?> value="0” />273 </td>274 </tr>275 <tr valign="top">276 <th scope="row">277 <label for="<?php echo self::$post_prefix?>[opt][total_uninstall]“><strong>Remove all plugin data on uninstall</strong><br /><em>only applies when the plugin is deleted via the plugins menu</em></label>278 </th>279 <td>280 Yes: <input type="radio” name="<?php echo self::$post_prefix?>[opt][total_uninstall]" <?php checked($total_uninstall, 1, true);?> value="1” /><br />No: <input type="radio” name="<?php echo self::$post_prefix?>[opt][total_uninstall]" <?php checked($total_uninstall, 0, true);?> value="0” />281 </td>282 </tr>283 </tbody>284 </table>285 <p><input type="submit” class="button-primary" value="Update Options" /></p>286 </form> 287 <?php288 }289 290 function option_get(){291 $defaults = array(292 “show404” => 0,293 “fourohfourmsg” => 0, 294 “dbVersion” => 0,295 “use_advanced_filter” => 0,296 “preparse” => 0,297 “total_uninstall” => 0,298 );299 $options = get_option(self::$option_name,$defaults);300 return array_merge($defaults, $options);301 }302 function option_set( $new_options = array() ){303 return update_option( self::$option_name, $new_options);304 }305306 function shortcode($args, $content=""){307 $option = self::option_get();308 $default_args = array(‘debug’ => 0,’silentdebug’ => 0, ‘function’ => 0, ‘mode’=>’new’);309 extract( shortcode_atts( $default_args, $args));310 $four0four_used = false;311 //Debug settings312 if($debug == 1){313 error_reporting(E_ALL);314 ini_set(“display_errors","1”);315 }316 317 if($function == 0):318 if( $mode == “new” || ($option[“preparse”] == 0 && $mode == “new”) ){319 $content = strip_tags($content);320 $content = preg_replace(“/\[{1}([\/]*)([a-zA-z\/]{1}[a-zA-Z0-9]*[^\’\”])([a-zA-Z0-9 \!\"\£\$\%\^\&\*\*\(\)\_\-\+\=\|\\\,\.\/\?\:\;\@\’\#\~\{\}\¬\¦\`\<\>]*)([\/]*)([\]]{1})/ix","<$1$2$3>",$content,"-1");321 $content = htmlspecialchars($content, ENT_NOQUOTES);322 $content = str_replace("&#8217;","’",$content);323 $content = str_replace("&#8216;","’",$content);324 $content = str_replace("&#8242;","’",$content);325 $content = str_replace("&#8220;","\"",$content);326 $content = str_replace("&#8221;","\"",$content);327 $content = str_replace("&#8243;","\"",$content);328 $content = str_replace("&#039;","’",$content);329 $content = str_replace("’","’",$content);330 $content = str_replace("&#038;","&",$content);331 $content = str_replace("&gt;",’>’,$content);332 $content = str_replace("&lt;",’<’,$content);333 $content = htmlspecialchars_decode($content);334 }335 else{336 $content =(htmlspecialchars($content,ENT_QUOTES));337 $content = str_replace("&#8217;","’",$content);338 $content = str_replace("&#8216;","’",$content);339 $content = str_replace("&#8242;","’",$content);340 $content = str_replace("&#8220;","\"",$content);341 $content = str_replace("&#8221;","\"",$content);342 $content = str_replace("&#8243;","\"",$content);343 $content = str_replace("&#039;","’",$content);344 $content = str_replace("’","’",$content);345 $content = str_replace("&#038;","&",$content);346 $content = str_replace(“&lt;br /&gt;",” ", $content);347 $content = htmlspecialchars_decode($content);348 $content = str_replace(“<br />",” ",$content);349 $content = str_replace(“<p>",” ",$content);350 $content = str_replace(“</p>",” ",$content);351 $content = str_replace("[br/]","<br/>",$content);352 $content = str_replace("\\[“,”[",$content);353 $content = str_replace("\\]“,”]",$content);354 $content = str_replace("[","<",$content);355 $content = str_replace("]",">",$content);356 $content = str_replace("[",’[‘,$content);357 $content = str_replace("]",’]',$content);358 $content = str_replace(">",’>’,$content);359 $content = str_replace("<",’<’,$content);360 }361 else:362 //function selected363 $snippet = self::snippet_get($function);364 if( sizeof( $snippet ) == 0){365 $four0four_used = true;366 $content = self::snippet_404();367 }368 else{369 $content = stripslashes($snippet->function);370 }371 endif;372 ob_start();373 eval($content);374 if($debug == 1||$silentdebug == 1){375 if($silentdebug == 1){376 echo "\n\n<!-- ALLOW PHP SILENT DEBUG MODE - - > \n\n\n";377 }else{378 echo "<p align=’center’>Allow PHP Debug</p>";379 }380 if($four0four_used){381 $content = "Function id : $function : cannot be found<br/>";382 }else{383 $content =(htmlspecialchars($content,ENT_QUOTES));384 }385 echo "<pre>".$content."</pre>";386 if($silentdebug == 1){387 echo "\n\n\n<- - END ALLOW PHP SILENT DEBUG MODE -->\n\n";388 }else{389 echo "<p align=’center’>End Allow PHP Debug</p>";390 }391 }392 return ob_get_clean(); 393 }394 395 function shortcode_advanced($args){396 $options = self::option_get();397 if( isset( $options[‘use_advanced_filter’] ) ){398 399 if( $options[‘use_advanced_filter’] == “1” ){400 remove_shortcode(“php”);401 remove_shortcode(“PHP”);402 remove_shortcode(“allowphp”);403 remove_shortcode(“ALLOWPHP”);404 405 $args = str_ireplace("[php]","<?php ",$args);406 $args = str_ireplace("[/php]“,” ?>",$args);407 408 $args = str_ireplace("[php useadvancedfilter]","<?php ",$args);409 $args = str_ireplace("[/php useadvancedfilter]“,” ?>",$args);410 411 $args = str_ireplace("[allowphp]","<?php ",$args);412 $args = str_ireplace("[/allowphp]“,” ?>",$args);413 414 $args = str_ireplace("[allowphp useadvancedfilter]","<?php ",$args);415 $args = str_ireplace("[/allowphp useadvancedfilter]“,” ?>",$args);416 417 $args = preg_replace( "#\[php(.*?)function=([0-9]*)(.*?)\]#", "<?php allow_php_in_posts::snippet_swap( $2 ) ?>",$args);418 $args = preg_replace( "#\[allowphp(.*?)function=([0-9]*)(.*?)\]#", "<?php allow_php_in_posts::snippet_swap( $2 ) ?>",$args);419 ob_start();420 eval("?>".$args);421 $return = ob_get_clean();422 return $return;423 }424 else{425 return $args; 426 }427 428 }429 $args = str_ireplace("[php useadvancedfilter]","<?php ",$args);430 $args = str_ireplace("[/php useadvancedfilter]“,” ?>",$args);431 432 $args = str_ireplace("[allowphp useadvancedfilter]","<?php ",$args);433 $args = str_ireplace("[/allowphp useadvancedfilter]“,” ?>",$args);434 435 ob_start();436 eval("?>".$args);437 $returned = ob_get_clean();438 return $returned; 439 }440 441 function hook_activation(){442 self::db_check(); 443 }444 function hook_uninstall(){445 $option = self::option_get();446 if($option[“total_uninstall”] === 1){447 global $wpdb;448 $wpdb->query(“DROP TABLE `".$wpdb->prefix.self::$database_prefix."`”);449 delete_option( self::$option_name );450 }451 }452 453 function db_check(){454 $opt = self::option_get();455 if($opt[“dbVersion”] != self::$database_version){456 self::db_upgrade();457 }458 }459 function db_upgrade(){460 global $wpdb;461 $sql = "RENAME TABLE `".$wpdb->prefix."allowPHP_functions` TO `".$wpdb->prefix.self::$database_prefix."`";462 $wpdb->get_results($sql);463 $sql = "CREATE TABLE IF NOT EXISTS “.$wpdb->prefix.self::$database_prefix.”(464 id int NOT NULL AUTO_INCREMENT,465 name varchar(100) NOT NULL,466 function longtext NOT NULL,467 PRIMARY KEY(id)468 );";469 require_once(ABSPATH . ‘wp-admin/includes/upgrade.php’);470 dbDelta($sql);471 //need to manually change existing function columns472 $wpdb->get_results("ALTER TABLE `".$wpdb->prefix.self::$database_prefix."` CHANGE `function` `function` LONGTEXT NOT NULL ");473 $opt = self::option_get();474 $opt[“dbVersion”] = self::$database_version;475 self::option_set($opt);476 }477 }478 479 function allow_php_init(){480 global $allow_php;481 $allow_php = new allow_php_in_posts(); 482 }483 add_action(“init","allow_php_init”);484 register_activation_hook( __FILE__ , array( “allow_php_in_posts” , “hook_activation” ) );485 register_uninstall_hook( __FILE__, array( "allow_php_in_posts", “hook_uninstall” ) );486}

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