CVE-2026-39640

Theme Editor <= 3.2 - Cross-Site Request Forgery

mediumCross-Site Request Forgery (CSRF)
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Theme Editor plugin for WordPress is vulnerable to Cross-Site Request Forgery in versions up to, and including, 3.2. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action via a forged request granted they can trick a site administrator into performing an action such as clicking on a link.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.2
PublishedFebruary 14, 2026
Last updatedApril 15, 2026
Affected plugintheme-editor
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-39640 (Theme Editor <= 3.2) ## 1. Vulnerability Summary The **Theme Editor** plugin for WordPress (versions <= 3.2) is vulnerable to **Cross-Site Request Forgery (CSRF)**. The vulnerability exists because the plugin fails to perform nonce validation when savi…

Show full research plan

Exploitation Research Plan - CVE-2026-39640 (Theme Editor <= 3.2)

1. Vulnerability Summary

The Theme Editor plugin for WordPress (versions <= 3.2) is vulnerable to Cross-Site Request Forgery (CSRF). The vulnerability exists because the plugin fails to perform nonce validation when saving its administrative settings. An attacker can trick a logged-in administrator into visiting a malicious website that submits a forged request to the victim's WordPress site, leading to unauthorized modification of the plugin's configuration.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin.php?page=theme-editor (or any admin page, as the logic is hooked to admin_init).
  • HTTP Method: POST
  • Vulnerable Action: The settings saving logic triggered by the presence of specific POST parameters.
  • Authentication Level: Unauthenticated (Attacker) / Administrator (Victim).
  • Preconditions:
    • The victim must be a logged-in Administrator.
    • The "Theme Editor" plugin must be active.

3. Code Flow

  1. Hook Registration: The plugin registers a function to handle settings in the admin area.
    • File: theme-editor.php (or includes/te-admin-settings.php)
    • Code: add_action( 'admin_init', 'te_save_settings_logic' ); (inferred)
  2. Logic Entry: The function te_save_settings_logic() executes on every administrative page load.
  3. Vulnerable Check:
    function te_save_settings_logic() {
        if ( isset( $_POST['te_save_settings'] ) ) {
            // VULNERABILITY: No check_admin_referer() or wp_verify_nonce() here.
            $options = $_POST['te_theme_editor_options'];
            update_option( 'te_theme_editor_options', $options );
        }
    }
    
  4. Sink: update_option() is called with the unsanitized (or poorly sanitized) and unverified data from $_POST['te_theme_editor_options'].

4. Nonce Acquisition Strategy

This vulnerability is characterized by the absence of a nonce check. Therefore, no nonce is required to perform the exploit. The attacker simply needs to forge the POST request with the correct parameter names.

5. Exploitation Strategy

The goal is to demonstrate that an external request can change the plugin's settings.

Step 1: Create the Exploit Payload

We will use an auto-submitting HTML form. The most visible setting to change for demonstration is the editor_theme or enable_theme_editor flag.

Step 2: Target Parameters

Based on the plugin structure, the settings are stored in an array under the option te_theme_editor_options.

  • te_save_settings: Must be set to trigger the logic.
  • te_theme_editor_options[editor_theme]: Setting this to a specific value (e.g., cobalt).

Step 3: Trigger via http_request

Since the security agent uses Playwright, we can simulate the CSRF by navigating an authenticated admin session to a "malicious" page or directly performing the POST request using the admin's context.

Request Details:

  • URL: http://localhost:8080/wp-admin/admin.php?page=theme-editor
  • Method: POST
  • Headers:
    • Content-Type: application/x-www-form-urlencoded
  • Body:
    te_save_settings=1&te_theme_editor_options%5Beditor_theme%5D=cobalt&te_theme_editor_options%5Benable_theme_editor%5D=1
    

6. Test Data Setup

  1. Install/Activate Plugin: Ensure theme-editor version 3.2 is installed.
  2. Initialize Settings: Visit the settings page once as admin to ensure default options exist.
    • browser_navigate("http://localhost:8080/wp-admin/admin.php?page=theme-editor")
  3. Identify Target Option: Confirm the current value of the option.
    • wp option get te_theme_editor_options

7. Expected Results

  • The server will process the request and return a 302 redirect (standard WordPress admin behavior) or a 200 OK.
  • The WordPress database will be updated. Specifically, the te_theme_editor_options option will now contain editor_theme => cobalt.

8. Verification Steps

After the http_request is sent:

  1. Check via WP-CLI:
    wp option get te_theme_editor_options --format=json
    
    Verify that "editor_theme":"cobalt" exists in the output.
  2. Verify via UI:
    Navigate to the Theme Editor settings page and observe the selected theme in the dropdown.

9. Alternative Approaches

If the plugin uses AJAX for settings (unlikely in version 3.2 for this specific plugin, but possible):

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: te_save_settings (inferred)
  • Method: POST
  • Body: action=te_save_settings&te_theme_editor_options[editor_theme]=cobalt
  • Bypass: Check if check_ajax_referer is present but uses a default action like -1 or if the result is ignored.

If the primary settings page is protected, check for the Download Theme/Plugin feature:

  • Often these plugins allow downloading zip files of themes. If the action=te_download_theme (inferred) lacks a nonce, a CSRF could be used to trigger a server-side zip generation or other resource-intensive tasks.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Theme Editor plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to and including 3.2. This vulnerability allows unauthenticated attackers to modify plugin settings by tricking a logged-in administrator into submitting a forged POST request due to missing nonce validation on the settings-saving function.

Vulnerable Code

// File: theme-editor.php (inferred from te_save_settings_logic hook)
function te_save_settings_logic() {
    if ( isset( $_POST['te_save_settings'] ) ) {
        // VULNERABILITY: No check_admin_referer() or wp_verify_nonce() here.
        $options = $_POST['te_theme_editor_options'];
        update_option( 'te_theme_editor_options', $options );
    }
}
add_action( 'admin_init', 'te_save_settings_logic' );

Security Fix

--- theme-editor/theme-editor.php
+++ theme-editor/theme-editor.php
@@ -10,6 +10,7 @@
 function te_save_settings_logic() {
     if ( isset( $_POST['te_save_settings'] ) ) {
+        check_admin_referer('te_save_settings_action', 'te_nonce');
         $options = $_POST['te_theme_editor_options'];
         update_option( 'te_theme_editor_options', $options );
     }

Exploit Outline

The exploit targets the settings saving logic triggered via the 'admin_init' hook. An attacker crafts a malicious HTML page containing a hidden form that sends a POST request to any administrative endpoint (e.g., /wp-admin/admin.php?page=theme-editor). The payload must include 'te_save_settings=1' and the 'te_theme_editor_options' array with the desired malicious configuration values. When a logged-in administrator visits the attacker's page, the form is automatically submitted via JavaScript. Because the plugin does not verify a CSRF nonce, it updates the database option 'te_theme_editor_options' with the attacker-supplied data.

Check if your site is affected.

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