Headline
CVE-2023-5231: functions.php in magic-action-box/tags/2.17.2/lib – WordPress Plugin Repository
The Magic Action Box plugin for WordPress is vulnerable to Stored Cross-Site Scripting via shortcodes in versions up to, and including, 2.17.2 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers with contributor-level and above permissions to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
1<?php23/**4 * Return a MAB API variable, or NULL if it doesn’t exist5 *6 * Like the fuel() function, except that ommitting $name returns the current MabStats instance rather than the fuel.7 * The distinction may not matter in most cases.8 *9 * @param string $name If ommitted, returns a MabStats_Fuel object with references to all the fuel.10 * @return mixed MAB_Fuel value if available, NULL if not. 11 *12 */13function MAB($name = ‘MAB’) {14 return MAB_Base::getFuel($name); 15}1617/**18 * Get an action box19 * @param int $actionBoxId - Post ID of action box20 * @param bool $loadAssets - whether to load action box assets or not21 * @param bool $forceShow - default FALSE. USed only if $actionBoxId is not set. 22 If TRUE will show the action box even if the post23 * it is being shown in has not set the action box to be shown “Manually"24 * @param bool $fallbackToDefaults set to TRUE to let action box show default action box if any25 * @return string - HTML of action box. Or empty string26 */27function mab_get_actionbox( $actionBoxId = null, $loadAssets = true, $forceShow = false, $fallbackToDefaults = false ){28 global $post, $Mab;29 $MabBase = MAB();30 $actionBox = '’;31 32 if( is_null( $actionBoxId ) || $actionBoxId === ‘’ ){33 /** Get action box used for a post - if it is specified **/34 35 //get postmeta. NOTE: This is not postmeta from Action Box but36 //from a regular post/CPT where Action Box is to be shown37 $postmeta = $MabBase->get_mab_meta( $post->ID, ‘post’ );3839 $post_action_box = isset($postmeta[‘post-action-box’]) ? $postmeta[‘post-action-box’] : '’;40 $post_action_box_placement = isset($postmeta[‘post-action-box-placement’]) ? $postmeta[‘post-action-box-placement’] : '’;41 42 //return nothing if action box is disabled or if placement is not set to 'manual’43 if( ‘none’ == $post_action_box ){44 /** Action box is “Disabled” **/45 return '’;4647 //if action box is not set or is set to “default"48 } elseif( !isset( $post_action_box ) || $post_action_box === ‘’ || $post_action_box == ‘default’ ){49 if( $fallbackToDefaults && ($forceShow || $post_action_box_placement == ‘manual’ ) ){50 //get post type51 $post_type = get_post_type( $post );52 $post_type = ( $post_type == ‘page’ ) ? ‘page’ : 'single’;53 $post_action_box = mab_get_action_box_id_from_context($post_type);54 } else {55 return '’;56 }57 } elseif( !$forceShow && $post_action_box_placement != ‘manual’ ){58 /** Action box must be set to show “manually” **/59 return '’;60 }61 62 $actionBoxId = $post_action_box;63 }64 65 $actionBoxObj = new MAB_ActionBox( $actionBoxId );66 67 $actionBox = $actionBoxObj->getActionBox(null, $loadAssets); //also loads assets68 69 return $actionBox;70}7172/**73 * Loads an action box css and js assets. Uses wp_enqueue_* api74 * @param int $mabid ID of the action box75 * @return void76 */77function mab_load_actionbox_assets($mabid){78 if(empty($mabid)) return;7980 $actionBox = new MAB_ActionBox($mabid);81 $actionBox->loadAssets();82}838485/**86 * Register action box87 * 88 * Form the array $box like this:89 * $box = array(90 * ‘type’ => 'action-box-type’, //use letters, numbers, underscore, dash only91 * ‘name’ => 'Human readable name’,92 * ‘description’ => 'Short description about the action box type’93 * );94 * 95 * @param array $box required96 * @return none97 */98function mab_register_action_box( $box ){99 $MabBase = MAB();100 $MabBase->register_action_box_type( $box );101}102103/**104 * @param string $context - single | page | default105 * @return int|bool Post ID of Action Box or FALSE if actionbox is not specified for a context106 */107function mab_get_action_box_id_from_context( $context = ‘default’ ){108 $MabBase = MAB();109 110 $settings = MAB_Utils::getSettings();111 $globalMab = $settings[‘global-mab’];112 113 $actionBoxId = '’;114 115 $default = ( isset( $globalMab[‘default’][‘actionbox’] ) && $globalMab[‘default’][‘actionbox’] != ‘none’ ) ? $globalMab[‘default’][‘actionbox’] : '’;116 117 $defaultPlacement = $placement = isset( $globalMab[‘default’][‘placement’] ) ? $globalMab[‘default’][‘placement’] : 'bottom’;118119 switch( $context ){120 case 'single’:121 global $post;122 if( !is_object( $post ) ){123 //something’s wrong124 $actionBoxId = '’;125 break;126 }127 128 /** Single Post Setting **/129 $postmeta = $MabBase->get_mab_meta( $post->ID, ‘post’ );130 $singleActionBoxId = isset($postmeta[‘post-action-box’]) ? $postmeta[‘post-action-box’] : '’;131 132 //if $pageActionBoxId is empty string, then action box is not yet set133 if( ‘’ !== $singleActionBoxId && ‘default’ != $singleActionBoxId ){134 //specific action box set for Post135 $actionBoxId = $singleActionBoxId;136 $placement = isset( $postmeta[‘post-action-box-placement’] ) ? $postmeta[‘post-action-box-placement’] : $defaultPlacement;137 138 } else {139 //use global settings140 141 /** Global Single Post Setting **/142 $actionBoxId = isset( $globalMab[‘post’][‘actionbox’] ) ? $globalMab[‘post’][‘actionbox’] : 'default’;143 $placement = isset( $globalMab[‘post’][‘placement’] ) ? $globalMab[‘post’][‘placement’] : $defaultPlacement;144 145 /** Global Category Setting - will override Global Single Post Setting **/146 $terms = get_the_terms( $post->ID, ‘category’ );147 if( $terms && !is_wp_error( $terms ) ){148 foreach( $terms as $term ){149 //catch the first category set150 if( isset( $globalMab[‘category’][$term->term_id][‘actionbox’] ) AND $globalMab[‘category’][$term->term_id][‘actionbox’] != ‘default’ ){151 $actionBoxId = $globalMab[‘category’][$term->term_id][‘actionbox’];152 $placement = $globalMab[‘category’][$term->term_id][‘placement’];153 break; //break out of foreach loop154 }//endif155 }//endforeach156 }//endif157 158 }//endif159 160 break;161 162 case 'page’:163 global $post;164 if( !is_object( $post ) ){165 //something’s wrong166 $actionBoxId = '’;167 }168 169 $postmeta = $MabBase->get_mab_meta( $post->ID, ‘post’ );170 $pageActionBoxId = isset($postmeta[‘post-action-box’]) ? $postmeta[‘post-action-box’] : '’;171 172 //if $pageActionBoxId is empty string, then action box is not yet set173 if( ‘’ !== $pageActionBoxId && ‘default’ != $pageActionBoxId ){174 //specific action box set for Page175 $actionBoxId = $pageActionBoxId;176 $placement = isset( $postmeta[‘post-action-box-placement’] ) ? $postmeta[‘post-action-box-placement’] : $defaultPlacement;177 178 } else {179 //use global setting180 $actionBoxId = isset( $globalMab[‘page’][‘actionbox’] ) ? $globalMab[‘page’][‘actionbox’] : 'default’;181 $placement = isset( $globalMab[‘page’][‘placement’] ) ? $globalMab[‘page’][‘placement’] : $defaultPlacement;182 183 }184 185 break;186 case 'front_page’:187 global $wp_query;188 189 //make sure that the front page is set to display a static page190 if( !is_page() ){191 break;192 }193 194 $post = $wp_query->get_queried_object();195 if( !is_object( $post ) ){196 //something’s wrong197 $actionBoxId = '’;198 }199 200 $postmeta = $MabBase->get_mab_meta( $post->ID, ‘post’ );201 $pageActionBoxId = isset($postmeta[‘post-action-box’]) ? $postmeta[‘post-action-box’] : '’;202 203 //if $pageActionBoxId is empty string, then action box is not yet set204 if( ‘’ !== $pageActionBoxId && ‘default’ != $pageActionBoxId ){205 //specific action box set for Page206 $actionBoxId = $pageActionBoxId;207 $placement = isset( $postmeta[‘post-action-box-placement’] ) ? $postmeta[‘post-action-box-placement’] : $defaultPlacement;208 209 } else {210 //use global setting211 $actionBoxId = isset( $globalMab[‘page’][‘actionbox’] ) ? $globalMab[‘page’][‘actionbox’] : 'default’;212 $placement = isset( $globalMab[‘page’][‘placement’] ) ? $globalMab[‘page’][‘placement’] : $defaultPlacement;213 214 }215 216 break;217 case 'tag’:218 case 'archive’:219 case 'blog’:220 case 'category’:221 default: 222 $actionBoxId = '’;223 break;224 }//endswitch225 226 if( $actionBoxId == ‘default’ ){227 $actionBoxId = $default;228 } elseif( $actionBoxId == ‘none’ ){229 $actionBoxId = '’;230 }231 232 //return array( ‘id’ => $actionBoxId, ‘placement’ => $placement );233 return $actionBoxId;234}235236237/**238 * Returns the value of an array index from a key-value array. Will check if an array index is set. 239 * By default, will return an empty string if not set.240 *241 * @param array $array array to get value from242 * @param string $index key index243 * @param string $empty_value value to return if array key is not set244 * @return mixed value of array index245 */246function mab_array_index_value($array, $index, $empty_value = ‘’){247 return isset($array[$index]) ? $array[$index] : $empty_value;248}249250251252/**253 * Return a button254 */255function mab_button($args){256 $defaults = array(257 ‘id’ => '’,258 ‘text’ => 'Button Text’,259 ‘url’ => '’,260 ‘class’ => '’,261 ‘target’ => '’,262 ‘title’ => '’,263 ‘name’ => '’,264 ‘new_window’ => false265 );266267 $args = wp_parse_args($args, $defaults);268269 //stop if we have no id270 if( $args[‘id’] === ‘’ || is_null($args[‘id’]) )271 return '’;272273 //add our button key to class274 $args[‘class’] .= ' mab-button-' . intval($args[‘id’]);275276 if(empty($args[‘target’]) && $args[‘new_window’]){277 $args[‘target’] = '_blank’;278 }279280 if(empty($args[‘url’])){281 //we will output a submit button282 $template = '<input type="submit” value="%s” name="%s" class="%s" />’;283 $button = sprintf($template, $args[‘text’], $args[‘name’], $args[‘class’]);284 } else {285 //we will output an <a> button286 $template = '<a href="%s" class="%s" title="%s" target="%s">%s</a>’;287 $button = sprintf($template, $args[‘url’], $args[‘class’], $args[‘title’], $args[‘target’], $args[‘text’]);288 }289290 return $button;291}292293/**294 * Wrapper for MAB_MetaBoxes::optionBox()295 */296function mab_option_box($name = '’, $data = array()){297 return MAB_MetaBoxes::optionBox($name, $data);298}