CVE-2026-2470

Pagelayer <= 2.0.9 - Incorrect Authorization to Authenticated (Contributor+) Mail Relay Configuration via 'contacts'

mediumIncorrect Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
2.1.0
Patched in
1d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=2.0.9
PublishedJune 12, 2026
Last updatedJune 13, 2026
Affected pluginpagelayer

What Changed in the Fix

Changes introduced in v2.1.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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:

  1. The pagelayer_save_content AJAX handler allows users with edit_posts capability (Contributors+) to save arbitrary metadata to a post.
  2. The unauthenticated pagelayer_contact_submit endpoint retrieves this configuration using a user-controlled post_id and contacts identifier 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_id and contacts (identifying the configured template).
  • Preconditions: The attacker must be able to create or edit a post (standard for Contributors).

3. Code Flow

  1. Setup Phase (Authenticated):

    • User calls pagelayer_save_content via AJAX.
    • main/ajax.php: pagelayer_save_content() checks pagelayer_user_can_edit($postID).
    • The function processes $_POST data. According to the advisory, it permits saving pagelayer_contact_templates.
    • The plugin calls update_post_meta($postID, 'pagelayer_contact_templates', $template_data).
  2. Execution Phase (Unauthenticated):

    • An unauthenticated visitor calls pagelayer_contact_submit via AJAX.
    • The handler retrieves the post_id from the request.
    • It fetches get_post_meta($post_id, 'pagelayer_contact_templates', true).
    • It uses the contacts parameter to select a specific template from the retrieved array.
    • The handler extracts email_to, subject, and message from the template.
    • It calls wp_mail() using these attacker-controlled values.

4. Nonce Acquisition Strategy

The pagelayer_save_content handler requires a nonce verified with check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce').

  1. Identify Enqueueing: Pagelayer enqueues its editor assets, including the nonce, on post-edit pages.
  2. 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_config object.
    • Tool Command: browser_eval("pagelayer_config.pagelayer_nonce") or browser_eval("pagelayer_ajax.nonce") (based on main/blocks.php localization patterns).
    • The specific JS variable can be confirmed by inspecting the page source for wp_localize_script.

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"}}
    • 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_submit
    • post_id: [POST_ID]
    • contacts: evil_template
    • pagelayer_nonce: (If required for nopriv, usually it uses a different one or none. Verify if wp_ajax_nopriv_pagelayer_contact_submit checks nonces).

6. Test Data Setup

  1. User: Create a user attacker with role contributor.
  2. Post: Create a draft post with ID 123 authored by attacker.
  3. Mail Log: Ensure WP_DEBUG is on and a mail-logging plugin (or mailhog) 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.com with the subject "Spam", bypassing any administrative controls over who can send mail from the server.

8. Verification Steps

  1. Verify Meta Persistence:
    wp post meta get [POST_ID] pagelayer_contact_templates
    Confirm the malicious JSON/array is present.
  2. 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:

  1. Construct a Pagelayer row/column structure in JSON.
  2. Add a contact_form widget.
  3. Set the widget's properties to include the malicious template.
  4. 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.