As we continue to work with the VIP team, they identified a security issues with Scripts Organizer and I thought you would like to know, especially with the work on version 3. As you will see in the message below they will be contacting you directly.

Here is the text they sent us:

As of version 2.4.2 of the plugin (the most current version in GitHub), a request to the “admin AJAX” url at /wp-admin/admin-ajax.php?action=saveScript can be ran without authentication and without requiring a security toke (nonce). The code is triggered by the unauthenticated wp_ajax_nopriv_saveScript action, located in plugins/scripts-organizer/admin/feature__scripts-manager-functions.php:add_action( ‘wp_ajax_nopriv_saveScript’, array($this, ‘saveScript_func’) );

This will call the SCORG_scripts_manager::saveScript_func() function that takes in unsanitized/unvalidated user input and saves it directly to the database:public function

saveScript_func(){
parse_str($_REQUEST[‘form_data’], $params);
//echo “<pre>”; print_r($params); “</pre>”; exit;
$php_script = json_decode(stripcslashes($_POST[‘php_script’]));
$php_script_unslashed = str_replace(”, ‘REPLACE_BACKSLASH’, $php_script);
$header_script = json_decode(stripslashes($_POST[‘header_script’]));
$footer_script = json_decode(stripslashes($_POST[‘footer_script’]));
$SCORG_enable_script = $_POST[‘SCORG_enable_script’];
//print_r($php_script); exit;
$post_id = $params[‘post_ID’];
$post_name = !empty($params[‘post_name’]) ? $params[‘post_name’] : strtolower(str_replace(” “, “-“, $params[‘post_name’]));
$post_data = array(
‘post_status’ => $params[‘post_status’],
‘post_title’ => $params[‘post_title’],
‘post_name’ => $post_name,
‘post_author’ => $params[‘post_author’],
);
if(get_post($post_id)){
$post_data[‘ID’] = $post_id;
$post_id = wp_update_post($post_data);
} else {
$post_id = wp_insert_post($post_data);
}
if(!empty($php_script)){
$SCORG_Post = new SCORG_Post();
$SCORG_Post->save_php_script($post_id, $php_script);
update_post_meta($post_id, ‘SCORG_php_script’, $php_script_unslashed);
} else {
update_post_meta($post_id, ‘SCORG_php_script’, “”);
}
update_post_meta($post_id, ‘SCORG_header_script’, $header_script);
update_post_meta($post_id, ‘SCORG_footer_script’, $footer_script);
update_post_meta($post_id, ‘SCORG_enable_script’, $SCORG_enable_script);

$meta_keys = array(
‘SCORG_enable_script’,
‘SCORG_trigger_location’,
‘SCORG_script_type’,
‘SCORG_page_post’,
‘SCORG_selected_page_post’,
‘SCORG_specific_post_type’,
‘SCORG_specific_taxonomy’,
‘SCORG_script_schedule’,
‘SCORG_specific_date’,
‘SCORG_days’,
‘SCORG_specific_date_from’,
‘SCORG_specific_date_to’,
‘SCORG_script_time’,
‘SCORG_specific_time_start’,
‘SCORG_specific_time_end’,
‘SCORG_scripts_manager’,
‘SCORG_script_description’,
‘SCORG_dequeue_scripts’,
‘SCORG_enqueue_scripts’,
‘SCORG_scss_partial_manager’,
‘SCORG_partials’,
‘SCORG_view’,
‘SCORG_header_mode’,
‘SCORG_footer_mode’,
‘SCORG_toggle_sidebar’,
‘SCORG_active_tab’,
); foreach($meta_keys as $key){
if(!empty($params[$key])){
delete_post_meta($post_id, $key);
if(is_array($params[$key])){
foreach($params[$key] as $value){
add_post_meta($post_id, $key, $value);
}
} else {
update_post_meta($post_id, $key, $params[$key]);
}
} else {
delete_post_meta($post_id, $key);
}
} $checkboxes = array( ‘SCORG_header_file’, ‘SCORG_footer_file’ );
foreach($checkboxes as $checkbox){
if(isset($params[$checkbox])){
update_post_meta($post_id, $checkbox, 1);
} else {
delete_post_meta($post_id, $checkbox);
}
} if(!empty($params[‘tax_input’][‘scorg_tags’])){
$term_slugs = explode(“,”, $params[‘tax_input’][‘scorg_tags’]);
if(!empty($term_slugs)){
wp_set_object_terms($post_id, $term_slugs, ‘scorg_tags’);
}
} else {
$term_ids = wp_get_object_terms($post_id, ‘scorg_tags’, array(‘fields’ => ‘ids’));
if(!empty($term_ids)){
wp_remove_object_terms($post_id, $term_ids, ‘scorg_tags’);
}
} $message = SCORG_create_header_footer_file($post_id, $header_script, $footer_script, $params, true);
echo $message; wp_die();
}
The parse_str($_REQUEST[‘form_data’], $params); line will take the raw form_data query parameter and parse it as a URL encoded string and save it to the database in a number of places.The critical issue is raised when the SCORG_php_script post meta is updated directly from user input (update_post_meta($post_id, ‘SCORG_php_script’, $php_script_unslashed);) along with a number of other meta keys that determine when and where to run this PHP code.This function can also cause a number of other less severe issues such as adding arbitrary Javascript to a site (can be used to steal cookies or deliver malicious content to visitors), modify CSS, or even update the title of any post.

As a simple proof of concept, you can visit the URL “/wp-admin/admin-ajax.php?action=saveScript&form_data=post_ID%3D1%26post_status%3Dpublish%26post_title%3DGoodbye%20World%26post_name%3Dgoodbye-world%26post_author%3D1” to modify the “Hello World!” post on the unlaunched VIP Go site to “Goodbye World”. If you would like to test this on a different site, you can modify the form_data query parameter to change any post. The 1 in the %3D1%26 refers to the post ID and can be changed to any valid post ID. Any invalid post ID will instead create a new post with that title.As mentioned, with a more complicated URL, it may be possible for someone to add or modify saved scripts and their run conditions.

I’ve reached out to our Jetpack Security team, who is going to do a deeper dive into the plugin to see if there may be other issues, and will be reaching out to the author to properly notify them of the security concerns.

In the meantime, I would strongly recommend not launching the VIP Go site with the plugin in its current state. If we need to, we can add some simple security checks to the affected areas to help secure it. I would also recommend checking to see if the current live site is also in a state of vulnerability. It’s likely that if this version of the plugin is running then it is affected also.

If needed, we can work with you to bring this plugin into a more secure state, but we cannot offer any guarantee of its security. It may also be good to do a full audit of the other third party code running on the site to see if there may be other issues.

3 responses to “Security Vulnerability”

  1. cmsexpertss says:

    Hi Stephen,

    It seems like you are using old version of plugin because in latest release we have already handled this vulnerability using nonce verification. So, please try to use latest version even if its in beta.

    Regards,
    Muhammad Osama

  2. stphnwlkr says:

    I am using the latest, non-beta, version (2.4.2). I tested 2.4.2 on a couple of sites and had the same issue – just to make sure it wasn’t just their environment. I will give the beta (RC) a try on a test site to see if I experience the same issue.

  3. aglyons says:

    this seems pretty significant. I think a 2.4.3 version should be put out quickly to cover this security concern.

    I myself can’t disable the plugin as the scripts being added are required. I don’t mean to be confrontational but this is the deal with software dev, esp with WP. If there is a security concern it needs to be addressed immediately even if there is a new version in dev.

Leave a Reply

Your email address will not be published.