Skip to content

Commit a7625e8

Browse files
authored
Update
1 parent 80b5774 commit a7625e8

1 file changed

Lines changed: 45 additions & 34 deletions

File tree

simple-wp-site-exporter.php

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<?php
22
/*
3-
Plugin Name: Simple WP Site Exporter
4-
Description: Exports the site files and database as a zip archive.
5-
Version: 1.7.0
6-
Author: EngineScript
7-
License: GPL v3 or later
8-
Text Domain: Simple-WP-Site-Exporter
3+
Plugin Name: Simple WP Site Exporter
4+
Description: Exports the site files and database as a zip archive.
5+
Version: 1.7.0
6+
Author: EngineScript
7+
License: GPL v3 or later
8+
Text Domain: Simple-WP-Site-Exporter
99
*/
1010

1111
// Prevent direct access. Note: Using return here instead of exit.
1212
if ( ! defined( 'ABSPATH' ) ) {
13-
return; // Prevent direct access
13+
return; // Prevent direct access.
1414
}
1515

1616
// Define plugin version.
@@ -42,17 +42,19 @@
4242
*
4343
* @return string Client IP address or 'unknown' if not available.
4444
*/
45-
function sse_get_client_ip() {
45+
function sse_get_client_ip()
46+
{
4647
// WordPress-style IP detection with validation.
47-
$ip = 'unknown';
48+
$client_ip = 'unknown';
4849

50+
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- $_SERVER['REMOTE_ADDR'] is safe for IP logging when properly sanitized
4951
if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
50-
$ip = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
52+
$client_ip = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
5153
}
5254

5355
// Basic IP validation.
54-
if ( filter_var( $ip, FILTER_VALIDATE_IP ) ) {
55-
return $ip;
56+
if ( filter_var( $client_ip, FILTER_VALIDATE_IP ) ) {
57+
return $client_ip;
5658
}
5759

5860
return 'unknown';
@@ -67,7 +69,8 @@ function sse_get_client_ip() {
6769
* @param string $level The log level.
6870
* @return void
6971
*/
70-
function sse_store_log_in_database( $message, $level ) {
72+
function sse_store_log_in_database( $message, $level )
73+
{
7174
// Store last 20 important messages in an option.
7275
$logs = get_option( 'sse_error_logs', [] );
7376
$logs[] = [
@@ -85,7 +88,7 @@ function sse_store_log_in_database( $message, $level ) {
8588

8689
update_option( 'sse_error_logs', $logs );
8790

88-
} //end sse_store_log_in_database()
91+
} //end sse_store_log_in_database() //end sse_store_log_in_database()
8992

9093

9194
/**
@@ -94,7 +97,8 @@ function sse_store_log_in_database( $message, $level ) {
9497
* @param string $formatted_message The formatted log message.
9598
* @return void
9699
*/
97-
function sse_output_log_message( $formatted_message ) {
100+
function sse_output_log_message( $formatted_message )
101+
{
98102
// Use WordPress logging (wp_debug_log is available in WP 5.1+).
99103
if ( function_exists( 'wp_debug_log' ) ) {
100104
wp_debug_log( $formatted_message );
@@ -110,7 +114,8 @@ function sse_output_log_message( $formatted_message ) {
110114
* @param string $level The log level (error, warning, info).
111115
* @return void
112116
*/
113-
function sse_log( $message, $level = 'info' ) {
117+
function sse_log( $message, $level = 'info' )
118+
{
114119
// Check if WP_DEBUG is enabled.
115120
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
116121
return;
@@ -141,10 +146,11 @@ function sse_log( $message, $level = 'info' ) {
141146

142147
/**
143148
* Safely get the PHP execution time limit
144-
*
149+
*
145150
* @return int Current PHP execution time limit in seconds
146151
*/
147-
function sse_get_execution_time_limit() {
152+
function sse_get_execution_time_limit()
153+
{
148154
// Get the current execution time limit
149155
$max_exec_time = ini_get('max_execution_time');
150156

@@ -165,10 +171,12 @@ function sse_get_execution_time_limit() {
165171
}
166172

167173
return (int)$max_exec_time;
168-
}
174+
175+
} //end sse_get_execution_time_limit()
169176

170177
// --- Admin Menu ---
171-
function sse_admin_menu() {
178+
function sse_admin_menu()
179+
{
172180
add_management_page(
173181
esc_html__( 'Simple WP Site Exporter', 'Simple-WP-Site-Exporter' ), // Escaped title
174182
esc_html__( 'Site Exporter', 'Simple-WP-Site-Exporter' ), // Escaped menu title
@@ -180,7 +188,8 @@ function sse_admin_menu() {
180188
add_action( 'admin_menu', 'sse_admin_menu' );
181189

182190
// --- Exporter Page HTML ---
183-
function sse_exporter_page_html() {
191+
function sse_exporter_page_html()
192+
{
184193
if ( ! current_user_can( 'manage_options' ) ) {
185194
wp_die( esc_html__( 'You do not have permission to view this page.', 'Simple-WP-Site-Exporter' ), 403 );
186195
}
@@ -270,7 +279,8 @@ function sse_handle_export() {
270279
*
271280
* @return bool True if request is valid, false otherwise.
272281
*/
273-
function sse_validate_export_request() { // phpcs:ignore WordPress.Security.NonceVerification.Missing
282+
function sse_validate_export_request()
283+
{ // phpcs:ignore WordPress.Security.NonceVerification.Missing
274284
$post_action = isset( $_POST['action'] ) ? sanitize_key( $_POST['action'] ) : '';
275285
if ( 'sse_export_site' !== $post_action ) {
276286
return false;
@@ -295,7 +305,8 @@ function sse_validate_export_request() { // phpcs:ignore WordPress.Security.Nonc
295305
*
296306
* @return void
297307
*/
298-
function sse_prepare_execution_environment() {
308+
function sse_prepare_execution_environment()
309+
{
299310
$max_exec_time = sse_get_execution_time_limit();
300311
$target_exec_time = 1800; // 30 minutes in seconds.
301312

@@ -555,13 +566,13 @@ function sse_add_file_to_zip( $zip, $file_info, $file, $pathname, $relative_path
555566

556567
if ( $file_info->isFile() ) {
557568
// Use real path (getRealPath() must succeed for security)
558-
if ( false !== $file ) {
559-
$file_to_add = $file;
560-
} else {
569+
if ( false === $file ) {
561570
sse_log( "Skipping file with unresolvable real path: " . $pathname, 'warning' );
562571
return true; // Skip this file but continue processing
563572
}
564573

574+
$file_to_add = $file;
575+
565576
if ( ! $zip->addFile( $file_to_add, $relative_path ) ) {
566577
sse_log( "Failed to add file to zip: " . $relative_path . " (Source: " . $file_to_add . ")", 'error' );
567578
}
@@ -893,10 +904,10 @@ function sse_validate_parent_directory_safety($parent_dir, $upload_dir) {
893904
}
894905

895906
// Ensure parent directory is within WordPress upload directory
896-
$normalized_parent_dir = wp_normalize_path($parent_dir);
897-
$normalized_upload_dir = wp_normalize_path($upload_dir);
907+
$norm_parent_dir = wp_normalize_path($parent_dir);
908+
$norm_upload_dir = wp_normalize_path($upload_dir);
898909

899-
if (strpos($normalized_parent_dir, $normalized_upload_dir) !== 0) {
910+
if (strpos($norm_parent_dir, $norm_upload_dir) !== 0) {
900911
sse_log('Parent directory not within WordPress upload directory: ' . $parent_dir, 'security');
901912
return false;
902913
}
@@ -913,24 +924,24 @@ function sse_validate_parent_directory_safety($parent_dir, $upload_dir) {
913924
*/
914925
function sse_resolve_parent_directory($parent_dir, $upload_dir) {
915926
// Normalize and validate upload directory first
916-
$normalized_upload_dir = wp_normalize_path($upload_dir);
917-
$real_upload_dir = realpath($normalized_upload_dir);
927+
$norm_upload_dir = wp_normalize_path($upload_dir);
928+
$real_upload_dir = realpath($norm_upload_dir);
918929
if ($real_upload_dir === false) {
919930
sse_log('Upload directory cannot be resolved: ' . $upload_dir, 'security');
920931
return false;
921932
}
922933

923934
// Normalize parent directory and perform basic validation
924-
$normalized_parent_dir = wp_normalize_path($parent_dir);
935+
$norm_parent_dir = wp_normalize_path($parent_dir);
925936

926937
// Validate that normalized parent dir starts with normalized upload dir (before realpath)
927-
if (strpos($normalized_parent_dir, $normalized_upload_dir) !== 0) {
938+
if (strpos($norm_parent_dir, $norm_upload_dir) !== 0) {
928939
sse_log('Parent directory not within normalized upload directory: ' . $parent_dir, 'security');
929940
return false;
930941
}
931942

932943
// Now safe to resolve real path after validation - filesystem checks removed to prevent SSRF
933-
$real_parent_dir = realpath($normalized_parent_dir);
944+
$real_parent_dir = realpath($norm_parent_dir);
934945
if ($real_parent_dir === false) {
935946
sse_log('Parent directory resolution failed: ' . $parent_dir, 'security');
936947
return false;

0 commit comments

Comments
 (0)