Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore files refactoring #459

Merged
merged 6 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 41 additions & 19 deletions inc/spbc-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use CleantalkSP\SpbctWP\LinkConstructor;
use CleantalkSP\SpbctWP\Scanner\Cure;
use CleantalkSP\SpbctWP\Escape;
use CleantalkSP\SpbctWP\SpbcEnqueue;
use CleantalkSP\Variables\Post;
use CleantalkSP\Variables\Server;
use CleantalkSP\SpbctWP\Firewall\WAF;
Expand Down Expand Up @@ -413,11 +414,11 @@ function spbc_enqueue_scripts($hook)
global $spbc;

// For ALL admin pages
wp_enqueue_style('spbc_admin_css', SPBC_PATH . '/css/spbc-admin.min.css', array(), SPBC_VERSION, 'all');
wp_enqueue_style('spbc-icons', SPBC_PATH . '/css/spbc-icons.min.css', array(), SPBC_VERSION, 'all');
wp_enqueue_script('spbc-common-js', SPBC_PATH . '/js/spbc-common.min.js', array('jquery'), SPBC_VERSION, false);
wp_enqueue_script('spbc-admin-js', SPBC_PATH . '/js/spbc-admin.min.js', array('jquery'), SPBC_VERSION, false);
wp_enqueue_script('spbc-react-bundle-js', SPBC_PATH . '/js/spbc-react-bundle.js', array('wp-i18n'), SPBC_VERSION, ['in_footer']);
SpbcEnqueue::getInstance()->css('spbc-admin.css');
SpbcEnqueue::getInstance()->css('spbc-icons.css');
SpbcEnqueue::getInstance()->js('spbc-common.js', array('jquery'));
SpbcEnqueue::getInstance()->js('spbc-admin.js', array('jquery'));
SpbcEnqueue::getInstance()->js('spbc-react-bundle.js', array('wp-i18n'), ['in_footer']);
wp_set_script_translations('spbc-react-bundle-js', 'security-malware-firewall');

$vulnerability_show_install = (
Expand Down Expand Up @@ -453,9 +454,10 @@ function spbc_enqueue_scripts($hook)
),
));

wp_enqueue_script('spbc_cookie', SPBC_PATH . '/js/spbc-cookie.min.js', array('jquery'), SPBC_VERSION, false /*in header*/);
SpbcEnqueue::getInstance()->js('spbc-cookie.js', array('jquery'));

wp_localize_script(
'spbc_cookie',
'spbc-cookie-js',
'spbcPublic',
array (
'_ajax_nonce' => wp_create_nonce('ct_secret_stuff'),
Expand All @@ -470,12 +472,19 @@ function spbc_enqueue_scripts($hook)
);

if ($spbc->settings['upload_checker__file_check'] && in_array($hook, array('upload.php', 'media-new.php'))) {
wp_enqueue_script('spbc-upload-js', SPBC_PATH . '/js/spbc-upload.min.js', array('jquery'), SPBC_VERSION, false);
SpbcEnqueue::getInstance()->js('spbc-upload.js', array('jquery'));
}

// Load UI (modal window) for profile pages
if ($hook === 'profile.php' || $hook === 'user-edit.php') {
wp_enqueue_style('jquery-ui', SPBC_PATH . '/css/jquery-ui.min.css', array(), '1.12.1', 'all'); // JS
SpbcEnqueue::getInstance()->custom(
'jquery-ui',
SPBC_PATH . '/css/jquery-ui.min.css',
array(),
'1.12.1',
null,
'all'
);
wp_enqueue_script('jquery-ui-dialog');
}

Expand All @@ -494,23 +503,36 @@ function spbc_enqueue_scripts($hook)
$actions_modified = $button_template_approve . $button_template_replace . $button_template_compare . $button_template_view_bad;

// CSS
wp_enqueue_style('spbc-settings', SPBC_PATH . '/css/spbc-settings.min.css', array(), SPBC_VERSION, 'all');
wp_enqueue_style('spbc-settings-media', SPBC_PATH . '/css/spbc-settings-media.min.css', array(), SPBC_VERSION, 'all');
wp_enqueue_style('spbc-table', SPBC_PATH . '/css/spbc-table.min.css', array(), SPBC_VERSION, 'all');
SpbcEnqueue::getInstance()->css('spbc-settings.css');
SpbcEnqueue::getInstance()->css('spbc-settings-media.css');
SpbcEnqueue::getInstance()->css('spbc-table.css');
wp_deregister_style('jquery-ui-style');
wp_enqueue_style('jquery-ui', SPBC_PATH . '/css/jquery-ui.min.css', array(), '1.12.1', 'all');

SpbcEnqueue::getInstance()->custom(
'jquery-ui',
SPBC_PATH . '/css/jquery-ui.min.css',
array(),
'1.12.1',
null,
'all'
);
// JS
wp_enqueue_script('jquery-ui', SPBC_PATH . '/js/jquery-ui.min.js', array('jquery'), '1.13.1', true);
wp_enqueue_script('spbc-settings-js', SPBC_PATH . '/js/spbc-settings.min.js', array('jquery'), SPBC_VERSION, true);
wp_enqueue_script('spbc-table-js', SPBC_PATH . '/js/spbc-table.min.js', array('jquery'), SPBC_VERSION, true);
wp_enqueue_script('spbc-scanner-plugin-js', SPBC_PATH . '/js/spbc-scanner-plugin.min.js', array('jquery'), SPBC_VERSION, true);
SpbcEnqueue::getInstance()->custom(
'jquery-ui',
SPBC_PATH . '/js/jquery-ui.min.js',
array('jquery'),
'1.13.1',
true,
null
);
SpbcEnqueue::getInstance()->js('spbc-settings.js', array('jquery'), true);
SpbcEnqueue::getInstance()->js('spbc-table.js', array('jquery'), true);
SpbcEnqueue::getInstance()->js('spbc-scanner-plugin.js', array('jquery'), true);

wp_localize_script('spbc-table-js', 'spbcTableLocalize', array(
'scannerIsActive' => esc_html__('Scanner is active for now. Try later.', 'security-malware-firewall'),
));

wp_enqueue_script('spbc-modal', SPBC_PATH . '/js/spbc-modal.min.js', array('jquery'), SPBC_VERSION, true);
SpbcEnqueue::getInstance()->js('spbc-modal.js', array('jquery'), true);

wp_localize_script('spbc-settings-js', 'spbcSettingsSecLogs', array(
'amount' => SPBC_LAST_ACTIONS_TO_VIEW,
Expand Down
30 changes: 16 additions & 14 deletions inc/spbc-backups.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ function spbc_backup__delete($direct_call = false, $backup_id = null)

if (empty($output['error'])) {
if (rmdir(SPBC_PLUGIN_DIR . 'backups/backup_' . $backup_id)) {
if ($wpdb->delete(SPBC_TBL_BACKUPED_FILES, array('backup_id' => $backup_id), array('%d'))) {
if ($wpdb->delete(SPBC_TBL_BACKUPS, array('backup_id' => $backup_id), array('%d'))) {
if (false !== $wpdb->delete(SPBC_TBL_BACKUPED_FILES, array('backup_id' => $backup_id), array('%d'))) {
if (false !== $wpdb->delete(SPBC_TBL_BACKUPS, array('backup_id' => $backup_id), array('%d'))) {
$output = array(
'html' => '<td ' . (isset($_POST['cols']) ? "colspan='{$_POST['cols']}'" : '') . '>Backup deleted</td>',
'success' => true,
Expand Down Expand Up @@ -91,7 +91,7 @@ function spbc_backup__files_with_signatures_handler()

$output = array('success' => true);

$files_to_backup = $wpdb->get_results('SELECT path, weak_spots FROM ' . SPBC_TBL_SCAN_FILES . ' WHERE weak_spots LIKE "%\"SIGNATURES\":%";', ARRAY_A);
$files_to_backup = $wpdb->get_results('SELECT path, weak_spots, checked_heuristic, checked_signatures, status, severity FROM ' . SPBC_TBL_SCAN_FILES . ' WHERE weak_spots LIKE "%\"SIGNATURES\":%";', ARRAY_A);

if (!is_array($files_to_backup) || !count($files_to_backup)) {
$output = array('success' => true);
Expand All @@ -100,6 +100,9 @@ function spbc_backup__files_with_signatures_handler()

$sql_data = array();
foreach ($files_to_backup as $file) {
if (spbc_file_has_backup($file['path'])) {
continue;
}
$weak_spots = json_decode($file['weak_spots'], true);

$signtures_in_file = array();
Expand All @@ -113,15 +116,6 @@ function spbc_backup__files_with_signatures_handler()
continue;
}

$sql_signatures_placeholder = rtrim(str_repeat('%s,', count($signtures_in_file)), ',');
$sql_signatures = 'SELECT * FROM ' . SPBC_TBL_SCAN_SIGNATURES . " WHERE id IN ($sql_signatures_placeholder) AND cci IS NOT NULL;";
$signatures_with_cci = $wpdb->get_results($wpdb->prepare($sql_signatures, $signtures_in_file), ARRAY_A);

// Backup only files which will be cured
if (!$signatures_with_cci) {
continue;
}

// Adding new backup batch
if ( ! isset($backup_id)) {
$wpdb->insert(SPBC_TBL_BACKUPS, array('type' => 'SIGNATURES', 'datetime' => date('Y-m-d H:i:s')));
Expand All @@ -143,8 +137,16 @@ function spbc_backup__files_with_signatures_handler()

$result = spbc_backup__file($file['path'], $backup_id);

$backup_prev_results_state = json_encode($file);
$backup_prev_results_state = $backup_prev_results_state === false ? 'ERROR' : $backup_prev_results_state;

if (empty($result['error'])) {
$sql_data[] = '(' . $backup_id . ',' . Helper::prepareParamForSQLQuery($file['path']) . ',' . Helper::prepareParamForSQLQuery($result) . ')';
$sql_data[] = '('
. $backup_id . ','
. Helper::prepareParamForSQLQuery($file['path']) . ','
. Helper::prepareParamForSQLQuery($result) . ','
. Helper::prepareParamForSQLQuery($backup_prev_results_state)
. ')';
} else {
// Mark the backup STOPPED while errors occurred
$wpdb->update(SPBC_TBL_BACKUPS, array('status' => 'STOPPED'), array('backup_id' => $backup_id));
Expand All @@ -161,7 +163,7 @@ function spbc_backup__files_with_signatures_handler()
$backup_id = isset($backup_id) ? $backup_id : $spbc->data['scanner']['last_backup'];

// Writing backuped files to DB
$sql_query = 'INSERT INTO ' . SPBC_TBL_BACKUPED_FILES . ' (backup_id, real_path, back_path) VALUES';
$sql_query = 'INSERT INTO ' . SPBC_TBL_BACKUPED_FILES . ' (backup_id, real_path, back_path, backup_prev_results_state) VALUES';
// suppress because data is already prepared in Helper::prepareParamForSQLQuery method
// @psalm-suppress WpdbUnsafeMethodsIssue
$result = $wpdb->query($sql_query . implode(',', $sql_data) . ';');
Expand Down
90 changes: 78 additions & 12 deletions inc/spbc-scanner.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use CleantalkSP\Common\Scanner\SignaturesAnalyser\Structures\Verdict;
use CleantalkSP\SpbctWP\DB;
use CleantalkSP\SpbctWP\API as SpbcAPI;
use CleantalkSP\SpbctWP\Helpers\CSV;
Expand Down Expand Up @@ -2068,7 +2069,33 @@ function spbc_cure_file($file_fast_hash)
);
}

// rescan file on a single run!
$rescan_results = spbc_scanner_rescan_single_file($file_data['path'], md5_file(spbc_get_root_path() . $file_data['path']), spbc_get_root_path());
$merged_result = $rescan_results['merged_result'];
$verdict = isset($rescan_results['signature_result']) && $rescan_results['signature_result'] instanceof Verdict
? $rescan_results['signature_result']
: new Verdict();

$cure_log = new CureLog();
if ( $verdict->status === 'OK') {
$cure_log->deleteCureLogRecord($file_data['fast_hash']);
// update file in the table
$wpdb->update(
SPBC_TBL_SCAN_FILES,
array(
'checked_signatures' => 1,
'checked_heuristic' => 1,
'status' => $file_data['status'] === 'MODIFIED' ? 'MODIFIED' : $merged_result['status'],
'severity' => $merged_result['severity'],
'weak_spots' => json_encode($merged_result['weak_spots']),
'full_hash' => md5_file(spbc_get_root_path() . $file_data['path']),
),
array('fast_hash' => $file_data['fast_hash']),
array('%s', '%s', '%s', '%s', '%s', '%s'),
array('%s')
);
return esc_html__('No threats detected for current file statement.', 'security-malware-firewall');
}

$cure_stage = new CureStage(DB::getInstance());
$cure_log_record = $cure_stage->processCure($file_data);
Expand Down Expand Up @@ -2111,19 +2138,37 @@ function spbc_restore_file_from_backup_ajax_action_handler($id)

// Getting backup path
$sql_prepared = $wpdb->prepare(
'SELECT back_path '
'SELECT back_path, backup_prev_results_state '
. ' FROM ' . SPBC_TBL_BACKUPED_FILES
. ' WHERE real_path="%s"'
. ' ORDER BY backup_id DESC LIMIT 1;',
$file_path
);
$backup_path = $wpdb->get_row($sql_prepared, ARRAY_A);
// prepare backup data
$backup_data = $wpdb->get_results($sql_prepared, ARRAY_A);
$backup_path = isset($backup_data[0]['back_path']) ? $backup_data[0]['back_path'] : null;
// prepare previous state of the file
$backup_prev_results_state = isset($backup_data[0]['backup_prev_results_state']) ? $backup_data[0]['backup_prev_results_state'] : null;
$backup_prev_results_state = empty($backup_prev_results_state) || json_decode($backup_prev_results_state, true) === false
? null
: json_decode($backup_prev_results_state, true);
if (
!isset(
$backup_prev_results_state['weak_spots'],
$backup_prev_results_state['checked_heuristic'],
$backup_prev_results_state['checked_signatures'],
$backup_prev_results_state['status'],
$backup_prev_results_state['severity'],
$backup_prev_results_state['path']
)
) {
$backup_prev_results_state = null;
}

if (is_null($backup_path)) {
return array('error' => esc_html__('Error: Backup not found.', 'security-malware-firewall'));
}

$backup_path = $backup_path['back_path'];
$full_backup_path = ABSPATH . ltrim($backup_path, '/');

// Trying to replace backup and original file
Expand Down Expand Up @@ -2161,20 +2206,41 @@ function spbc_restore_file_from_backup_ajax_action_handler($id)
$delete = $wpdb->query($sql_prepared);

if (is_null($delete)) {
return array('error' => esc_html__('Error: Something is wrong.', 'security-malware-firewall'));
return array('error' => esc_html__('Error: Something is wrong during deleting backup.', 'security-malware-firewall'));
}

// Remove from cure log
// update cure log
$sql_prepared = $wpdb->prepare(
'DELETE '
. ' FROM ' . SPBC_TBL_CURE_LOG
. ' WHERE real_path="%s";',
$file_path
'UPDATE ' . SPBC_TBL_CURE_LOG
. ' SET is_restored = 1, '
. ' cure_status = 0 '
. ' WHERE real_path = %s;',
array($file_path)
);
$delete = $wpdb->query($sql_prepared);
$update_cure_log = $wpdb->query($sql_prepared);

if (is_null($delete)) {
return array('error' => esc_html__('Error: Something is wrong.', 'security-malware-firewall'));
if (is_null($update_cure_log)) {
return array('error' => esc_html__('Error: Something is wrong during updating cure log.', 'security-malware-firewall'));
}

if ($backup_prev_results_state !== null) {
// update scan results table
$sql_prepared = $wpdb->prepare(
'UPDATE ' . SPBC_TBL_SCAN_FILES
. ' SET weak_spots = %s, checked_heuristic = %s, checked_signatures = %s, status = %s, severity = %s'
. ' WHERE path = %s;',
array(
$backup_prev_results_state['weak_spots'],
$backup_prev_results_state['checked_heuristic'],
$backup_prev_results_state['checked_signatures'],
$backup_prev_results_state['status'],
$backup_prev_results_state['severity'],
$file_path)
);
$updated = $wpdb->query($sql_prepared);
if (is_null($updated)) {
return array('error' => esc_html__('Error: Something is wrong during saving previous state of file.', 'security-malware-firewall'));
}
}
} catch (\Exception $e) {
return array('error' => esc_html__('Error: Something is wrong.', 'security-malware-firewall'));
Expand Down
21 changes: 15 additions & 6 deletions inc/spbc-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -4409,7 +4409,7 @@ function spbc_list_table__get_args_by_type($table_type)
'cb' => array('heading' => '<input type=checkbox>', 'class' => 'check-column', 'width_percent' => 2),
'real_path' => array('heading' => 'Path','primary' => true, 'width_percent' => 27),
'last_cure_date' => array('heading' => 'Cure date', 'width_percent' => 10),
'cured' => array('heading' => 'Status', 'width_percent' => 13),
'cure_status' => array('heading' => 'Status', 'width_percent' => 13),
'weak_spots_cured' => array('heading' => 'Threats cured', 'width_percent' => 24),
'weak_spots_uncured' => array('heading' => 'Threats uncured', 'width_percent' => 24),
),
Expand Down Expand Up @@ -5785,21 +5785,30 @@ function spbc_scanner__cure_log_data_prepare(&$table)
if ($table->items_count) {
foreach ($table->rows as $_key => $row) {
// Add Cure action if file was not cure
if ($row->cured === 'CURED') {
if ($row->cure_status === 'CURED') {
unset($row->actions['cure']);
}

$cure_status_string = $row->cured === 'CURED'
? '<span class="spbcGreen">' . $row->cured . '</span>'
: '<span class="spbcRed">' . $row->cured . '</span>';
// rewrite on restored
if ($row->cure_status === 'RESTORED' || $row->cure_status === 'FAILED') {
unset($row->actions['restore']);
}

$cure_status_string = $row->cure_status === 'CURED'
? '<span class="spbc---green">' . $row->cure_status . '</span>'
: '<span class="spbc---red">' . $row->cure_status . '</span>';
// rewrite on restored
if ($row->is_restored === '1') {
$cure_status_string = '<span class="spbc---gray">' . $row->cure_status . '</span>';
}

$table->items[] = array(
'cb' => $row->fast_hash,
'uid' => $row->fast_hash,
'actions' => $row->actions,
'real_path' => $row->real_path,
'last_cure_date' => $row->last_cure_date,
'cured' => $cure_status_string,
'cure_status' => $cure_status_string,
'weak_spots_cured' => $row->weak_spots_cured,
'weak_spots_uncured' => $row->weak_spots_uncured,
);
Expand Down
Loading
Loading