Headline
CVE-2023-4274: class-wpvivid-setting.php in wpvivid-backuprestore/tags/0.9.89/includes – WordPress Plugin Repository
The Migration, Backup, Staging – WPvivid plugin for WordPress is vulnerable to Directory Traversal in versions up to, and including, 0.9.89. This allows authenticated attackers with administrative privileges to delete the contents of arbitrary directories on the server, which can be a critical issue in a shared environments.
1<?php23if (!defined(‘WPVIVID_PLUGIN_DIR’)){4 die;5}6class WPvivid_Setting7{8 public static function init_option()9 {10 $ret=self::get_option(‘wpvivid_email_setting’);11 if(empty($ret))12 {13 self::set_default_email_option();14 }1516 $ret=self::get_option(‘wpvivid_compress_setting’);17 if(empty($ret))18 {19 self::set_default_compress_option();20 }2122 $ret=self::get_option(‘wpvivid_local_setting’);23 if(empty($ret))24 {25 self::set_default_local_option();26 }2728 $ret=self::get_option(‘wpvivid_upload_setting’);29 if(empty($ret))30 {31 self::set_default_upload_option();32 }3334 $ret=self::get_option(‘wpvivid_common_setting’);35 if(empty($ret))36 {37 self::set_default_common_option();38 }39 }4041 public static function get_default_option($option_name)42 {43 $options=array();4445 switch ($option_name)46 {47 case 'wpvivid_compress_setting’:48 $options=self::set_default_compress_option();49 break;50 case 'wpvivid_local_setting’:51 $options=self::set_default_local_option();52 break;53 case 'wpvivid_upload_setting’:54 $options=self::set_default_upload_option();55 break;56 case 'wpvivid_common_setting’:57 $options=self::set_default_common_option();58 break;59 }60 return $options;61 }6263 public static function set_default_option()64 {65 self::set_default_compress_option();66 self::set_default_local_option();67 self::set_default_upload_option();68 self::set_default_common_option();69 }7071 public static function set_default_compress_option()72 {73 $compress_option[‘compress_type’]=WPVIVID_DEFAULT_COMPRESS_TYPE;74 $compress_option[‘max_file_size’]=WPVIVID_DEFAULT_MAX_FILE_SIZE;75 $compress_option[‘no_compress’]=WPVIVID_DEFAULT_NO_COMPRESS;76 $compress_option[‘use_temp_file’]=WPVIVID_DEFAULT_USE_TEMP;77 $compress_option[‘use_temp_size’]=WPVIVID_DEFAULT_USE_TEMP_SIZE;78 $compress_option[‘exclude_file_size’]=WPVIVID_DEFAULT_EXCLUDE_FILE_SIZE;79 $compress_option[‘subpackage_plugin_upload’]=WPVIVID_DEFAULT_SUBPACKAGE_PLUGIN_UPLOAD;80 self::update_option('wpvivid_compress_setting’,$compress_option);81 return $compress_option;82 }8384 public static function set_default_local_option()85 {86 $local_option[‘path’]=WPVIVID_DEFAULT_BACKUP_DIR;87 $local_option[‘save_local’]=1;88 self::update_option(‘wpvivid_local_setting’,$local_option);89 return $local_option;90 }9192 public static function set_default_upload_option()93 {94 $upload_option=array();95 self::update_option(‘wpvivid_upload_setting’,$upload_option);96 return $upload_option;97 }9899 public static function set_default_email_option()100 {101 $email_option[‘send_to’]=array();102 $email_option[‘always’]=true;103 $email_option[‘email_enable’]=false;104 self::update_option(‘wpvivid_email_setting’,$email_option);105 return $email_option;106 }107108 public static function set_default_common_option()109 {110 $sapi_type=php_sapi_name();111112 if($sapi_type==’cgi-fcgi’||$sapi_type==’ fpm-fcgi’)113 {114 $common_option[‘max_execution_time’]=WPVIVID_MAX_EXECUTION_TIME_FCGI;115 }116 else117 {118 $common_option[‘max_execution_time’]=WPVIVID_MAX_EXECUTION_TIME;119 }120121 $common_option[‘log_save_location’]=WPVIVID_DEFAULT_LOG_DIR;122 $common_option[‘max_backup_count’]=WPVIVID_DEFAULT_BACKUP_COUNT;123 $common_option[‘show_admin_bar’]=WPVIVID_DEFAULT_ADMIN_BAR;124 //$common_option[‘show_tab_menu’]=WPVIVID_DEFAULT_TAB_MENU;125 $common_option[‘domain_include’]=WPVIVID_DEFAULT_DOMAIN_INCLUDE;126 $common_option[‘estimate_backup’]=WPVIVID_DEFAULT_ESTIMATE_BACKUP;127 $common_option[‘max_resume_count’]=WPVIVID_RESUME_RETRY_TIMES;128 $common_option[‘memory_limit’]=WPVIVID_MEMORY_LIMIT;129 $common_option[‘restore_memory_limit’]=WPVIVID_RESTORE_MEMORY_LIMIT;130 $common_option[‘migrate_size’]=WPVIVID_MIGRATE_SIZE;131 self::update_option(‘wpvivid_common_setting’,$common_option);132 return $common_option;133 }134135 public static function get_option($option_name, $default = array())136 {137 $ret = get_option($option_name, $default);138 if(empty($ret))139 {140 self::get_default_option($option_name);141 }142 return $ret;143 }144145 public static function get_last_backup_message($option_name, $default = array()){146 $message = self::get_option($option_name, $default);147 $ret = array();148 if(!empty($message[‘id’])) {149 $ret[‘id’] = $message[‘id’];150 $ret[‘status’] = $message[‘status’];151 $ret[‘status’][‘start_time’] = date("M d, Y H:i", $ret[‘status’][‘start_time’]);152 $ret[‘status’][‘run_time’] = date("M d, Y H:i", $ret[‘status’][‘run_time’]);153 $ret[‘status’][‘timeout’] = date("M d, Y H:i", $ret[‘status’][‘timeout’]);154 if(isset($message[‘options’][‘log_file_name’]))155 $ret[‘log_file_name’] = $message[‘options’][‘log_file_name’];156 else157 $ret[‘log_file_name’] =’’;158 }159 return $ret;160 }161162 public static function get_backupdir()163 {164 $dir=self::get_option(‘wpvivid_local_setting’);165166 if(!isset($dir[‘path’]))167 {168 $dir=self::set_default_local_option();169 }170 if(!is_dir(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir[‘path’]))171 {172 @mkdir(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir[‘path’],0777,true);173 @fopen(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir[‘path’].DIRECTORY_SEPARATOR.’index.html’, ‘x’);174 $tempfile=@fopen(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir[‘path’].DIRECTORY_SEPARATOR.’.htaccess’, ‘x’);175 if($tempfile)176 {177 //$text="deny from all";178 $text="<IfModule mod_rewrite.c>\r\nRewriteEngine On\r\nRewriteRule .* - [F,L]\r\n</IfModule>";179 fwrite($tempfile,$text );180 fclose($tempfile);181 }182 else183 {184 return false;185 }186187 }188189 return $dir[‘path’];190 }191192 public static function set_backupdir($dir)193 {194 if(!isset($dir[‘path’]))195 {196 $dir=self::set_default_local_option();197 }198 else199 {200 self::update_option(‘wpvivid_local_setting’,$dir);201 }202203 if(!is_dir(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir[‘path’]))204 {205 @mkdir(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir[‘path’],0777,true);206 }207208 @fopen(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir[‘path’].’/index.html’, ‘x’);209 $tempfile=@fopen(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir[‘path’].’/.htaccess’, ‘x’);210 if($tempfile)211 {212 //$text="deny from all";213 $text="<IfModule mod_rewrite.c>\r\nRewriteEngine On\r\nRewriteRule .* - [F,L]\r\n</IfModule>";214 fwrite($tempfile,$text );215 fclose($tempfile);216 }217 }218219 public static function wpvivid_remove_directory($directory)220 {221 if(file_exists($directory))222 {223 if($dir_handle=@opendir($directory))224 {225 while($filename=readdir($dir_handle))226 {227 if($filename!=’.’ && $filename!=’…’)228 {229 $subFile=$directory."/".$filename;230 if(is_dir($subFile))231 {232 self::wpvivid_remove_directory($subFile);233 }234 if(is_file($subFile))235 {236 unlink($subFile);237 }238 }239 }240 closedir($dir_handle);241 rmdir($directory);242 }243 }244 }245246 public static function wpvivid_write_htaccess_rule($wpvivid_backup_dir_htaccess)247 {248 $tempfile=@fopen($wpvivid_backup_dir_htaccess, ‘x’);249 if($tempfile)250 {251 $text="<IfModule mod_rewrite.c>\r\nRewriteEngine On\r\nRewriteRule .* - [F,L]\r\n</IfModule>";252 fwrite($tempfile,$text );253 fclose($tempfile);254 }255 }256257 public static function get_save_local()258 {259 $local=self::get_option(‘wpvivid_local_setting’);260261 if(!isset($local[‘save_local’]))262 {263 $local=self::set_default_local_option();264 }265266 return $local[‘save_local’];267 }268269 public static function update_option($option_name,$options)270 {271 update_option($option_name,$options,’no’);272 }273274 public static function delete_option($option_name)275 {276 delete_option($option_name);277 }278279 public static function get_tasks()280 {281 $default = array();282 return $options = get_option('wpvivid_task_list’, $default);283 }284285 public static function update_task($id,$task)286 {287 $default = array();288 $options = get_option('wpvivid_task_list’, $default);289 $options[$id]=$task;290 self::update_option(‘wpvivid_task_list’,$options);291 }292293 public static function delete_task($id)294 {295 $default = array();296 $options = get_option(‘wpvivid_task_list’, $default);297 unset($options[$id]);298 self::update_option(‘wpvivid_task_list’,$options);299 }300301 public static function check_compress_options()302 {303 $options =self::get_option(‘wpvivid_compress_setting’);304305 if(!isset($options[‘compress_type’])||!isset($options[‘max_file_size’])||306 !isset($options[‘no_compress’])||!isset($options[‘exclude_file_size’])||307 !isset($options[‘use_temp_file’])||!isset($options[‘use_temp_size’]))308 {309 self::set_default_compress_option();310 }311 }312313 public static function check_local_options()314 {315 $options =self::get_option(‘wpvivid_local_setting’);316317 if(!isset($options[‘path’])||!isset($options[‘save_local’]))318 {319 self::set_default_local_option();320 }321322 return true;323 }324325 /*public static function get_backup_options($post)326 {327 self::check_compress_options();328 self::check_local_options();329330 if($post==’files+db’)331 {332 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_DB]=0;333 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_THEMES]=0;334 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_PLUGIN]=0;335 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_UPLOADS]=0;336 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_CONTENT]=0;337 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_CORE]=0;338 }339 else if($post==’files’)340 {341 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_THEMES]=0;342 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_PLUGIN]=0;343 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_UPLOADS]=0;344 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_CONTENT]=0;345 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_CORE]=0;346 }347 else if($post==’db’)348 {349 $backup_options[‘backup’][‘backup_type’][WPVIVID_BACKUP_TYPE_DB]=0;350 }351 else352 {353 //return false;354 }355356 $backup_options[‘compress’]=self::get_option(‘wpvivid_compress_setting’);357 $backup_options[‘dir’]=self::get_backupdir();358 return $backup_options;359 }*/360361 public static function get_remote_option($id)362 {363 $upload_options=self::get_option(‘wpvivid_upload_setting’);364 if(array_key_exists($id,$upload_options))365 {366 return $upload_options[$id];367 }368 else369 {370 return false;371 }372 }373374 public static function get_remote_options($remote_ids=array())375 {376 if(empty($remote_ids))377 {378 $remote_ids=WPvivid_Setting::get_user_history(‘remote_selected’);379 }380381 if(empty($remote_ids))382 {383 return false;384 }385386 $options=array();387 $upload_options=WPvivid_Setting::get_option(‘wpvivid_upload_setting’);388 foreach ($remote_ids as $id)389 {390 if(array_key_exists($id,$upload_options))391 {392 $options[$id]=$upload_options[$id];393 }394 }395 if(empty($options))396 return false;397 else398 return $options;399 }400401 public static function get_all_remote_options()402 {403 $upload_options=self::get_option(‘wpvivid_upload_setting’);404 $upload_options[‘remote_selected’]=WPvivid_Setting::get_user_history(‘remote_selected’);405 return $upload_options;406 }407408 public static function add_remote_options($remote)409 {410 $upload_options=self::get_option(‘wpvivid_upload_setting’);411 $id=uniqid('wpvivid-remote-');412413 $remote=apply_filters('wpvivid_pre_add_remote’,$remote,$id);414415 $upload_options[$id]=$remote;416 self::update_option('wpvivid_upload_setting’,$upload_options);417 return $id;418 }419420 public static function delete_remote_option($id)421 {422 do_action('wpvivid_delete_remote_token’,$id);423424 $upload_options=self::get_option(‘wpvivid_upload_setting’);425426 if(array_key_exists($id,$upload_options))427 {428 unset( $upload_options[$id]);429430 self::update_option('wpvivid_upload_setting’,$upload_options);431 return true;432 }433 else434 {435 return false;436 }437 }438439 public static function update_remote_option($remote_id,$remote)440 {441 $upload_options=self::get_option(‘wpvivid_upload_setting’);442443 if(array_key_exists($remote_id,$upload_options))444 {445 $remote=apply_filters('wpvivid_pre_add_remote’,$remote,$remote_id);446 $upload_options[$remote_id]=$remote;447 self::update_option('wpvivid_upload_setting’,$upload_options);448 return true;449 }450 else451 {452 return false;453 }454 }455456 public static function get_setting($all,$options_name)457 {458 $get_options=array();459 if($all==true)460 {461 $get_options[]=’wpvivid_email_setting’;462 $get_options[]=’wpvivid_compress_setting’;463 $get_options[]=’wpvivid_local_setting’;464 $get_options[]=’wpvivid_common_setting’;465 $get_options = apply_filters('wpvivid_get_setting_addon’, $get_options);466 }467 else468 {469 $get_options[]=$options_name;470 }471472 $ret[‘result’]=’success’;473 $ret[‘options’]=array();474475 foreach ($get_options as $option_name)476 {477 $ret[‘options’][$option_name]=self::get_option($option_name);478 }479480 return $ret;481 }482483 public static function update_setting($options)484 {485 foreach ($options as $option_name=>$option)486 {487 self::update_option($option_name,$option);488 }489 $ret[‘result’]=’success’;490 return $ret;491 }492493 public static function export_setting_to_json($setting=true,$history=true,$review=true,$backup_list=true)494 {495 global $wpvivid_plugin;496 $json[‘plugin’]=$wpvivid_plugin->get_plugin_name();497 $json[‘version’]=WPVIVID_PLUGIN_VERSION;498 $json[‘setting’]=$setting;499 $json[‘history’]=$history;500 $json[‘data’][‘wpvivid_init’]=self::get_option(‘wpvivid_init’);501502 if($setting)503 {504 $json[‘data’][‘wpvivid_schedule_setting’]=self::get_option(‘wpvivid_schedule_setting’);505 if(!empty( $json[‘data’][‘wpvivid_schedule_setting’]))506 {507 if(isset($json[‘data’][‘wpvivid_schedule_setting’][‘backup’][‘backup_files’]))508 $json[‘data’][‘wpvivid_schedule_setting’][‘backup_type’]=$json[‘data’][‘wpvivid_schedule_setting’][‘backup’][‘backup_files’];509 if(isset($json[‘data’][‘wpvivid_schedule_setting’][‘backup’][‘local’]))510 {511 if($json[‘data’][‘wpvivid_schedule_setting’][‘backup’][‘local’] == 1){512 $json[‘data’][‘wpvivid_schedule_setting’][‘save_local_remote’]=’local’;513 }514 else{515 $json[‘data’][‘wpvivid_schedule_setting’][‘save_local_remote’]=’remote’;516 }517 }518519 $json[‘data’][‘wpvivid_schedule_setting’][‘lock’]=0;520 if(wp_get_schedule(WPVIVID_MAIN_SCHEDULE_EVENT))521 {522 $recurrence = wp_get_schedule(WPVIVID_MAIN_SCHEDULE_EVENT);523 $timestamp = wp_next_scheduled(WPVIVID_MAIN_SCHEDULE_EVENT);524 $json[‘data’][‘wpvivid_schedule_setting’][‘recurrence’]=$recurrence;525 $json[‘data’][‘wpvivid_schedule_setting’][‘next_start’]=$timestamp;526 }527 }528 else529 {530 $json[‘data’][‘wpvivid_schedule_setting’]=array();531 }532 $json[‘data’][‘wpvivid_compress_setting’]=self::get_option(‘wpvivid_compress_setting’);533 $json[‘data’][‘wpvivid_local_setting’]=self::get_option(‘wpvivid_local_setting’);534 $json[‘data’][‘wpvivid_upload_setting’]=self::get_option(‘wpvivid_upload_setting’);535 $json[‘data’][‘wpvivid_common_setting’]=self::get_option(‘wpvivid_common_setting’);536 $json[‘data’][‘wpvivid_email_setting’]=self::get_option(‘wpvivid_email_setting’);537 $json[‘data’][‘wpvivid_saved_api_token’]=self::get_option(‘wpvivid_saved_api_token’);538 $json = apply_filters('wpvivid_export_setting_addon’, $json);539 /*if(isset($json[‘data’][‘wpvivid_local_setting’][‘path’])){540 unset($json[‘data’][‘wpvivid_local_setting’][‘path’]);541 }*/542 if(isset($json[‘data’][‘wpvivid_common_setting’][‘log_save_location’])){543 unset($json[‘data’][‘wpvivid_common_setting’][‘log_save_location’]);544 }545 if(isset($json[‘data’][‘wpvivid_common_setting’][‘backup_prefix’])){546 unset($json[‘data’][‘wpvivid_common_setting’][‘backup_prefix’]);547 }548 }549550 if($history)551 {552 $json[‘data’][‘wpvivid_task_list’]=self::get_option(‘wpvivid_task_list’);553 $json[‘data’][‘wpvivid_last_msg’]=self::get_option(‘wpvivid_last_msg’);554 $json[‘data’][‘wpvivid_user_history’]=self::get_option(‘wpvivid_user_history’);555 $json = apply_filters('wpvivid_history_addon’, $json);556 }557558 if($backup_list){559 $json[‘data’][‘wpvivid_backup_list’]=self::get_option(‘wpvivid_backup_list’);560 $json = apply_filters('wpvivid_backup_list_addon’, $json);561 }562563 if($review)564 {565 $json[‘data’][‘wpvivid_need_review’]=self::get_option(‘wpvivid_need_review’);566 $json[‘data’][‘cron_backup_count’]=self::get_option(‘cron_backup_count’);567 $json[‘data’][‘wpvivid_review_msg’]=self::get_option(‘wpvivid_review_msg’);568 $json = apply_filters('wpvivid_review_addon’, $json);569 }570 return $json;571 }572573 public static function import_json_to_setting($json)574 {575 wp_cache_delete('notoptions’, ‘options’);576 wp_cache_delete('alloptions’, ‘options’);577 foreach ($json[‘data’] as $option_name=>$option)578 {579 wp_cache_delete($option_name, ‘options’);580 delete_option($option_name);581 self::update_option($option_name,$option);582 }583 }584585 public static function set_max_backup_count($count)586 {587 $options=self::get_option(‘wpvivid_common_setting’);588 $options[‘max_backup_count’]=$count;589 self::update_option('wpvivid_common_setting’,$options);590 }591592 public static function get_max_backup_count()593 {594 $options=self::get_option(‘wpvivid_common_setting’);595 if(isset($options[‘max_backup_count’]))596 {597 return $options[‘max_backup_count’];598 }599 else600 {601 return WPVIVID_MAX_BACKUP_COUNT;602 }603 }604605 public static function get_mail_setting()606 {607 return self::get_option(‘wpvivid_email_setting’);608 }609610 public static function get_admin_bar_setting(){611 $options=self::get_option(‘wpvivid_common_setting’);612 if(isset($options[‘show_admin_bar’]))613 {614 if($options[‘show_admin_bar’]){615 return true;616 }617 else{618 return false;619 }620 }621 else622 {623 return true;624 }625 }626627 public static function update_user_history($action,$value)628 {629 $options=self::get_option(‘wpvivid_user_history’);630 $options[$action]=$value;631 self::update_option('wpvivid_user_history’,$options);632 }633634 public static function get_user_history($action)635 {636 $options=self::get_option(‘wpvivid_user_history’);637 if(array_key_exists($action,$options))638 {639 return $options[$action];640 }641 else642 {643 return array();644 }645 }646647 public static function get_retain_local_status()648 {649 $options=self::get_option(‘wpvivid_common_setting’);650 if(isset($options[‘retain_local’]))651 {652 if($options[‘retain_local’]){653 return true;654 }655 else{656 return false;657 }658 }659 else660 {661 return false;662 }663 }664665 public static function get_sync_data()666 {667 $data[‘setting’][‘wpvivid_compress_setting’]=self::get_option(‘wpvivid_compress_setting’);668 $data[‘setting’][‘wpvivid_local_setting’]=self::get_option(‘wpvivid_local_setting’);669 $data[‘setting’][‘wpvivid_common_setting’]=self::get_option(‘wpvivid_common_setting’);670 $data[‘setting’][‘wpvivid_email_setting’]=self::get_option(‘wpvivid_email_setting’);671 $data[‘setting’][‘cron_backup_count’]=self::get_option(‘cron_backup_count’);672 $data[‘schedule’]=self::get_option(‘wpvivid_schedule_setting’);673 $data[‘remote’][‘upload’]=self::get_option(‘wpvivid_upload_setting’);674 $data[‘remote’][‘history’]=self::get_option(‘wpvivid_user_history’);675 $data[‘last_backup_report’] = get_option(‘wpvivid_backup_reports’);676677 $data[‘setting_addon’] = $data[‘setting’];678 $data[‘setting_addon’][‘wpvivid_staging_options’]=array();679 $data[‘backup_custom_setting’]=array();680 $data[‘menu_capability’]=array();681 $data[‘white_label_setting’]=array();682 $data[‘incremental_backup_setting’]=array();683 $data[‘schedule_addon’]=array();684 $data[‘time_zone’]=false;685 $data[‘is_pro’]=false;686 $data[‘is_install’]=false;687 $data[‘is_login’]=false;688 $data[‘latest_version’]=’’;689 $data[‘current_version’]=’’;690 $data[‘dashboard_version’] = '’;691 $data[‘addons_info’] = array();692 $data=apply_filters('wpvivid_get_wpvivid_info_addon_mainwp_ex’, $data);693 return $data;694 }695}