Edit File by line

Deprecated: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in /home/sportsfever/public_html/filemanger/function.php on line 93
/home/sportsfe.../httpdocs/clone/wp-conte.../plugins/wordfenc.../lib
File: wfScanEngine.php
<?php
[0] Fix | Delete
require_once(__DIR__ . '/wordfenceClass.php');
[1] Fix | Delete
require_once(__DIR__ . '/wordfenceHash.php');
[2] Fix | Delete
require_once(__DIR__ . '/wfAPI.php');
[3] Fix | Delete
require_once(__DIR__ . '/wordfenceScanner.php');
[4] Fix | Delete
require_once(__DIR__ . '/wfIssues.php');
[5] Fix | Delete
require_once(__DIR__ . '/wfDB.php');
[6] Fix | Delete
require_once(__DIR__ . '/wfUtils.php');
[7] Fix | Delete
require_once(__DIR__ . '/wfFileUtils.php');
[8] Fix | Delete
require_once(__DIR__ . '/wfScanPath.php');
[9] Fix | Delete
require_once(__DIR__ . '/wfScanFile.php');
[10] Fix | Delete
require_once(__DIR__ . '/wfScanFileListItem.php');
[11] Fix | Delete
require_once(__DIR__ . '/wfScanEntrypoint.php');
[12] Fix | Delete
require_once(__DIR__ . '/wfCurlInterceptor.php');
[13] Fix | Delete
[14] Fix | Delete
class wfScanEngine {
[15] Fix | Delete
const SCAN_MANUALLY_KILLED = -999;
[16] Fix | Delete
const SCAN_CHECK_INTERVAL = 10; //Seconds
[17] Fix | Delete
[18] Fix | Delete
private static $scanIsRunning = false; //Indicates that the scan is running in this specific process
[19] Fix | Delete
[20] Fix | Delete
public $api = false;
[21] Fix | Delete
private $dictWords = array();
[22] Fix | Delete
private $forkRequested = false;
[23] Fix | Delete
private $lastCheck = 0;
[24] Fix | Delete
[25] Fix | Delete
//Beginning of serialized properties on sleep
[26] Fix | Delete
/** @var wordfenceHash */
[27] Fix | Delete
private $hasher = false;
[28] Fix | Delete
private $jobList = array();
[29] Fix | Delete
private $i = false;
[30] Fix | Delete
private $wp_version = false;
[31] Fix | Delete
private $apiKey = false;
[32] Fix | Delete
private $startTime = 0;
[33] Fix | Delete
public $maxExecTime = false; //If more than $maxExecTime has elapsed since last check, fork a new scan process and continue
[34] Fix | Delete
private $publicScanEnabled = false;
[35] Fix | Delete
private $fileContentsResults = false;
[36] Fix | Delete
/**
[37] Fix | Delete
* @var bool|wordfenceScanner
[38] Fix | Delete
*/
[39] Fix | Delete
private $scanner = false;
[40] Fix | Delete
private $scanQueue = array();
[41] Fix | Delete
/**
[42] Fix | Delete
* @var bool|wordfenceURLHoover
[43] Fix | Delete
*/
[44] Fix | Delete
private $hoover = false;
[45] Fix | Delete
private $scanData = array();
[46] Fix | Delete
private $statusIDX = array(
[47] Fix | Delete
'core' => false,
[48] Fix | Delete
'plugin' => false,
[49] Fix | Delete
'theme' => false,
[50] Fix | Delete
'unknown' => false
[51] Fix | Delete
);
[52] Fix | Delete
private $userPasswdQueue = "";
[53] Fix | Delete
private $passwdHasIssues = wfIssues::STATUS_SECURE;
[54] Fix | Delete
private $suspectedFiles = false; //Files found with the ".suspected" extension
[55] Fix | Delete
private $gsbMultisiteBlogOffset = 0;
[56] Fix | Delete
private $updateCheck = false;
[57] Fix | Delete
private $pluginRepoStatus = array();
[58] Fix | Delete
private $malwarePrefixesHash;
[59] Fix | Delete
private $coreHashesHash;
[60] Fix | Delete
private $scanMode = wfScanner::SCAN_TYPE_STANDARD;
[61] Fix | Delete
private $pluginsCounted = false;
[62] Fix | Delete
private $themesCounted = false;
[63] Fix | Delete
private $cycleStartTime;
[64] Fix | Delete
[65] Fix | Delete
/**
[66] Fix | Delete
* @var wfScanner
[67] Fix | Delete
*/
[68] Fix | Delete
private $scanController; //Not serialized
[69] Fix | Delete
[70] Fix | Delete
/**
[71] Fix | Delete
* @var wordfenceDBScanner
[72] Fix | Delete
*/
[73] Fix | Delete
private $dbScanner;
[74] Fix | Delete
[75] Fix | Delete
/**
[76] Fix | Delete
* @var wfScanKnownFilesLoader
[77] Fix | Delete
*/
[78] Fix | Delete
private $knownFilesLoader;
[79] Fix | Delete
[80] Fix | Delete
private $metrics = array();
[81] Fix | Delete
[82] Fix | Delete
private $checkHowGetIPsRequestTime = 0;
[83] Fix | Delete
[84] Fix | Delete
/**
[85] Fix | Delete
* Returns whether or not the Wordfence scan is running. When $inThisProcessOnly is true, it returns true only
[86] Fix | Delete
* if the scan is running in this process. Otherwise it returns true if the scan is running at all.
[87] Fix | Delete
*
[88] Fix | Delete
* @param bool $inThisProcessOnly
[89] Fix | Delete
* @return bool
[90] Fix | Delete
*/
[91] Fix | Delete
public static function isScanRunning($inThisProcessOnly = true) {
[92] Fix | Delete
if ($inThisProcessOnly) {
[93] Fix | Delete
return self::$scanIsRunning;
[94] Fix | Delete
}
[95] Fix | Delete
[96] Fix | Delete
return wfScanner::shared()->isRunning();
[97] Fix | Delete
}
[98] Fix | Delete
[99] Fix | Delete
public static function testForFullPathDisclosure($url = null, $filePath = null) {
[100] Fix | Delete
if ($url === null && $filePath === null) {
[101] Fix | Delete
$url = includes_url('rss-functions.php');
[102] Fix | Delete
$filePath = ABSPATH . WPINC . '/rss-functions.php';
[103] Fix | Delete
}
[104] Fix | Delete
[105] Fix | Delete
$response = wp_remote_get($url);
[106] Fix | Delete
$html = wp_remote_retrieve_body($response);
[107] Fix | Delete
return preg_match("/" . preg_quote(realpath($filePath), "/") . "/i", $html);
[108] Fix | Delete
}
[109] Fix | Delete
[110] Fix | Delete
public static function isDirectoryListingEnabled($url = null) {
[111] Fix | Delete
if ($url === null) {
[112] Fix | Delete
$uploadPaths = wp_upload_dir();
[113] Fix | Delete
$url = $uploadPaths['baseurl'];
[114] Fix | Delete
}
[115] Fix | Delete
[116] Fix | Delete
$response = wp_remote_get($url);
[117] Fix | Delete
return !is_wp_error($response) && ($responseBody = wp_remote_retrieve_body($response)) &&
[118] Fix | Delete
stripos($responseBody, '<title>Index of') !== false;
[119] Fix | Delete
}
[120] Fix | Delete
[121] Fix | Delete
public static function refreshScanNotification($issuesInstance = null) {
[122] Fix | Delete
if ($issuesInstance === null) {
[123] Fix | Delete
$issuesInstance = new wfIssues();
[124] Fix | Delete
}
[125] Fix | Delete
[126] Fix | Delete
$message = wfConfig::get('lastScanCompleted', false);
[127] Fix | Delete
if ($message === false || empty($message)) {
[128] Fix | Delete
$n = wfNotification::getNotificationForCategory('wfplugin_scan');
[129] Fix | Delete
if ($n !== null) {
[130] Fix | Delete
$n->markAsRead();
[131] Fix | Delete
}
[132] Fix | Delete
} else if ($message == 'ok') {
[133] Fix | Delete
$issueCount = $issuesInstance->getIssueCount();
[134] Fix | Delete
if ($issueCount) {
[135] Fix | Delete
new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, "<a href=\"" . wfUtils::wpAdminURL('admin.php?page=WordfenceScan') . "\">" .
[136] Fix | Delete
/* translators: Number of scan results. */
[137] Fix | Delete
sprintf(_n('%d issue found in most recent scan', '%d issues found in most recent scan', $issueCount, 'wordfence'), $issueCount)
[138] Fix | Delete
. '</a>', 'wfplugin_scan');
[139] Fix | Delete
} else {
[140] Fix | Delete
$n = wfNotification::getNotificationForCategory('wfplugin_scan');
[141] Fix | Delete
if ($n !== null) {
[142] Fix | Delete
$n->markAsRead();
[143] Fix | Delete
}
[144] Fix | Delete
}
[145] Fix | Delete
} else {
[146] Fix | Delete
$failureType = wfConfig::get('lastScanFailureType');
[147] Fix | Delete
if ($failureType == 'duration') {
[148] Fix | Delete
new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, '<a href="' . wfUtils::wpAdminURL('admin.php?page=WordfenceScan') . '">Scan aborted due to duration limit</a>', 'wfplugin_scan');
[149] Fix | Delete
} else if ($failureType == 'versionchange') {
[150] Fix | Delete
//No need to create a notification
[151] Fix | Delete
} else {
[152] Fix | Delete
$trimmedError = substr($message, 0, 100) . (strlen($message) > 100 ? '...' : '');
[153] Fix | Delete
new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, '<a href="' . wfUtils::wpAdminURL('admin.php?page=WordfenceScan') . '">Scan failed: ' . esc_html($trimmedError) . '</a>', 'wfplugin_scan');
[154] Fix | Delete
}
[155] Fix | Delete
}
[156] Fix | Delete
}
[157] Fix | Delete
[158] Fix | Delete
public function __sleep() { //Same order here as above for properties that are included in serialization
[159] Fix | Delete
return array('hasher', 'jobList', 'i', 'wp_version', 'apiKey', 'startTime', 'maxExecTime', 'publicScanEnabled', 'fileContentsResults', 'scanner', 'scanQueue', 'hoover', 'scanData', 'statusIDX', 'userPasswdQueue', 'passwdHasIssues', 'suspectedFiles', 'dbScanner', 'knownFilesLoader', 'metrics', 'checkHowGetIPsRequestTime', 'gsbMultisiteBlogOffset', 'updateCheck', 'pluginRepoStatus', 'malwarePrefixesHash', 'coreHashesHash', 'scanMode', 'pluginsCounted', 'themesCounted');
[160] Fix | Delete
}
[161] Fix | Delete
[162] Fix | Delete
public function __construct($malwarePrefixesHash = '', $coreHashesHash = '', $scanMode = wfScanner::SCAN_TYPE_STANDARD) {
[163] Fix | Delete
$this->startTime = time();
[164] Fix | Delete
$this->recordMetric('scan', 'start', $this->startTime);
[165] Fix | Delete
$this->maxExecTime = self::getMaxExecutionTime();
[166] Fix | Delete
$this->i = new wfIssues();
[167] Fix | Delete
$this->cycleStartTime = time();
[168] Fix | Delete
$this->wp_version = wfUtils::getWPVersion();
[169] Fix | Delete
$this->apiKey = wfConfig::get('apiKey');
[170] Fix | Delete
$this->api = new wfAPI($this->apiKey, $this->wp_version);
[171] Fix | Delete
$this->malwarePrefixesHash = $malwarePrefixesHash;
[172] Fix | Delete
$this->coreHashesHash = $coreHashesHash;
[173] Fix | Delete
include(dirname(__FILE__) . '/wfDict.php'); //$dictWords
[174] Fix | Delete
$this->dictWords = $dictWords;
[175] Fix | Delete
$this->scanMode = $scanMode;
[176] Fix | Delete
[177] Fix | Delete
$this->scanController = new wfScanner($scanMode);
[178] Fix | Delete
$jobs = $this->scanController->jobs();
[179] Fix | Delete
foreach ($jobs as $job) {
[180] Fix | Delete
if (method_exists($this, 'scan_' . $job . '_init')) {
[181] Fix | Delete
foreach (array('init', 'main', 'finish') as $op) {
[182] Fix | Delete
$this->jobList[] = $job . '_' . $op;
[183] Fix | Delete
}
[184] Fix | Delete
} else if (method_exists($this, 'scan_' . $job)) {
[185] Fix | Delete
$this->jobList[] = $job;
[186] Fix | Delete
}
[187] Fix | Delete
}
[188] Fix | Delete
}
[189] Fix | Delete
[190] Fix | Delete
public function scanController() {
[191] Fix | Delete
return $this->scanController;
[192] Fix | Delete
}
[193] Fix | Delete
[194] Fix | Delete
/**
[195] Fix | Delete
* Deletes all new issues. To only delete specific types, provide an array of issue types.
[196] Fix | Delete
*
[197] Fix | Delete
* @param null|array $types
[198] Fix | Delete
*/
[199] Fix | Delete
public function deleteNewIssues($types = null) {
[200] Fix | Delete
$this->i->deleteNew($types);
[201] Fix | Delete
}
[202] Fix | Delete
[203] Fix | Delete
public function __wakeup() {
[204] Fix | Delete
$this->cycleStartTime = time();
[205] Fix | Delete
$this->api = new wfAPI($this->apiKey, $this->wp_version);
[206] Fix | Delete
include(dirname(__FILE__) . '/wfDict.php'); //$dictWords
[207] Fix | Delete
$this->dictWords = $dictWords;
[208] Fix | Delete
$this->scanController = new wfScanner($this->scanMode);
[209] Fix | Delete
}
[210] Fix | Delete
[211] Fix | Delete
public function isFullScan() {
[212] Fix | Delete
return $this->scanMode != wfScanner::SCAN_TYPE_QUICK;
[213] Fix | Delete
}
[214] Fix | Delete
[215] Fix | Delete
public function go() {
[216] Fix | Delete
self::$scanIsRunning = true;
[217] Fix | Delete
try {
[218] Fix | Delete
self::checkForKill();
[219] Fix | Delete
$this->doScan();
[220] Fix | Delete
wfConfig::set('lastScanCompleted', 'ok');
[221] Fix | Delete
wfConfig::set('lastScanFailureType', false);
[222] Fix | Delete
self::checkForKill();
[223] Fix | Delete
//updating this scan ID will trigger the scan page to load/reload the results.
[224] Fix | Delete
$this->scanController->recordLastScanTime();
[225] Fix | Delete
//scan ID only incremented at end of scan to make UI load new results
[226] Fix | Delete
$this->emailNewIssues();
[227] Fix | Delete
if ($this->isFullScan()) {
[228] Fix | Delete
$this->recordMetric('scan', 'duration', (time() - $this->startTime));
[229] Fix | Delete
$this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
[230] Fix | Delete
$this->submitMetrics();
[231] Fix | Delete
}
[232] Fix | Delete
[233] Fix | Delete
wfScanEngine::refreshScanNotification($this->i);
[234] Fix | Delete
[235] Fix | Delete
if (wfCentral::isConnected()) {
[236] Fix | Delete
wfCentral::updateScanStatus();
[237] Fix | Delete
}
[238] Fix | Delete
self::$scanIsRunning = false;
[239] Fix | Delete
} catch (wfScanEngineDurationLimitException $e) {
[240] Fix | Delete
wfConfig::set('lastScanCompleted', $e->getMessage());
[241] Fix | Delete
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_DURATION_REACHED);
[242] Fix | Delete
$this->scanController->recordLastScanTime();
[243] Fix | Delete
[244] Fix | Delete
$this->emailNewIssues(true);
[245] Fix | Delete
$this->recordMetric('scan', 'duration', (time() - $this->startTime));
[246] Fix | Delete
$this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
[247] Fix | Delete
$this->submitMetrics();
[248] Fix | Delete
[249] Fix | Delete
wfScanEngine::refreshScanNotification($this->i);
[250] Fix | Delete
self::$scanIsRunning = false;
[251] Fix | Delete
throw $e;
[252] Fix | Delete
} catch (wfScanEngineCoreVersionChangeException $e) {
[253] Fix | Delete
wfConfig::set('lastScanCompleted', $e->getMessage());
[254] Fix | Delete
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_VERSION_CHANGE);
[255] Fix | Delete
$this->scanController->recordLastScanTime();
[256] Fix | Delete
[257] Fix | Delete
$this->recordMetric('scan', 'duration', (time() - $this->startTime));
[258] Fix | Delete
$this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
[259] Fix | Delete
$this->submitMetrics();
[260] Fix | Delete
[261] Fix | Delete
$this->deleteNewIssues();
[262] Fix | Delete
[263] Fix | Delete
wfScanEngine::refreshScanNotification($this->i);
[264] Fix | Delete
self::$scanIsRunning = false;
[265] Fix | Delete
throw $e;
[266] Fix | Delete
} catch (wfScanEngineTestCallbackFailedException $e) {
[267] Fix | Delete
wfConfig::set('lastScanCompleted', $e->getMessage());
[268] Fix | Delete
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
[269] Fix | Delete
$this->scanController->recordLastScanTime();
[270] Fix | Delete
[271] Fix | Delete
$this->recordMetric('scan', 'duration', (time() - $this->startTime));
[272] Fix | Delete
$this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
[273] Fix | Delete
$this->recordMetric('scan', 'failure', $e->getMessage());
[274] Fix | Delete
$this->submitMetrics();
[275] Fix | Delete
[276] Fix | Delete
wfScanEngine::refreshScanNotification($this->i);
[277] Fix | Delete
self::$scanIsRunning = false;
[278] Fix | Delete
throw $e;
[279] Fix | Delete
} catch (Exception $e) {
[280] Fix | Delete
if ($e->getCode() != wfScanEngine::SCAN_MANUALLY_KILLED) {
[281] Fix | Delete
wfConfig::set('lastScanCompleted', $e->getMessage());
[282] Fix | Delete
wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_GENERAL);
[283] Fix | Delete
}
[284] Fix | Delete
[285] Fix | Delete
$this->recordMetric('scan', 'duration', (time() - $this->startTime));
[286] Fix | Delete
$this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
[287] Fix | Delete
$this->recordMetric('scan', 'failure', $e->getMessage());
[288] Fix | Delete
$this->submitMetrics();
[289] Fix | Delete
[290] Fix | Delete
wfScanEngine::refreshScanNotification($this->i);
[291] Fix | Delete
self::$scanIsRunning = false;
[292] Fix | Delete
throw $e;
[293] Fix | Delete
}
[294] Fix | Delete
}
[295] Fix | Delete
[296] Fix | Delete
public function checkForDurationLimit() {
[297] Fix | Delete
static $timeLimit = false;
[298] Fix | Delete
if ($timeLimit === false) {
[299] Fix | Delete
$timeLimit = intval(wfConfig::get('scan_maxDuration'));
[300] Fix | Delete
if ($timeLimit < 1) {
[301] Fix | Delete
$timeLimit = WORDFENCE_DEFAULT_MAX_SCAN_TIME;
[302] Fix | Delete
}
[303] Fix | Delete
}
[304] Fix | Delete
[305] Fix | Delete
if ((time() - $this->startTime) > $timeLimit) {
[306] Fix | Delete
$error = sprintf(
[307] Fix | Delete
/* translators: 1. Time duration. 2. Support URL. */
[308] Fix | Delete
__('The scan time limit of %1$s has been exceeded and the scan will be terminated. This limit can be customized on the options page. <a href="%2$s" target="_blank" rel="noopener noreferrer">Get More Information<span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>', 'wordfence'),
[309] Fix | Delete
wfUtils::makeDuration($timeLimit),
[310] Fix | Delete
wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_TIME_LIMIT)
[311] Fix | Delete
);
[312] Fix | Delete
$this->addIssue('timelimit', wfIssues::SEVERITY_HIGH, md5($this->startTime), md5($this->startTime), __('Scan Time Limit Exceeded', 'wordfence'), $error, array());
[313] Fix | Delete
[314] Fix | Delete
$this->status(1, 'info', '-------------------');
[315] Fix | Delete
$this->status(1, 'info', sprintf(
[316] Fix | Delete
/* translators: 1. Number of files. 2. Number of plugins. 3. Number of themes. 4. Number of posts. 5. Number of comments. 6. Number of URLs. 7. Time duration. */
[317] Fix | Delete
__('Scan interrupted. Scanned %1$d files, %2$d plugins, %3$d themes, %4$d posts, %5$d comments and %6$d URLs in %7$s.', 'wordfence'),
[318] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_FILES, 0),
[319] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_PLUGINS, 0),
[320] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_THEMES, 0),
[321] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_POSTS, 0),
[322] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_COMMENTS, 0),
[323] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, 0),
[324] Fix | Delete
wfUtils::makeDuration(time() - $this->startTime, true)
[325] Fix | Delete
));
[326] Fix | Delete
if ($this->i->totalIssues > 0) {
[327] Fix | Delete
$this->status(10, 'info', "SUM_FINAL:" . sprintf(
[328] Fix | Delete
/* translators: Number of scan results. */
[329] Fix | Delete
_n(
[330] Fix | Delete
"Scan interrupted. You have %d new issue to fix. See below.",
[331] Fix | Delete
"Scan interrupted. You have %d new issues to fix. See below.",
[332] Fix | Delete
$this->i->totalIssues,
[333] Fix | Delete
'wordfence'),
[334] Fix | Delete
$this->i->totalIssues
[335] Fix | Delete
)
[336] Fix | Delete
);
[337] Fix | Delete
} else {
[338] Fix | Delete
$this->status(10, 'info', "SUM_FINAL:" . __('Scan interrupted. No problems found prior to stopping.', 'wordfence'));
[339] Fix | Delete
}
[340] Fix | Delete
throw new wfScanEngineDurationLimitException($error);
[341] Fix | Delete
}
[342] Fix | Delete
}
[343] Fix | Delete
[344] Fix | Delete
public function checkForCoreVersionChange() {
[345] Fix | Delete
$startVersion = wfConfig::get('wfScanStartVersion');
[346] Fix | Delete
$currentVersion = wfUtils::getWPVersion(true);
[347] Fix | Delete
if (version_compare($startVersion, $currentVersion) != 0) {
[348] Fix | Delete
throw new wfScanEngineCoreVersionChangeException(sprintf(
[349] Fix | Delete
/* translators: 1. Software version. 2. Software version. */
[350] Fix | Delete
__('Aborting scan because WordPress updated from version %1$s to %2$s. The scan will be reattempted later.', 'wordfence'), $startVersion, $currentVersion));
[351] Fix | Delete
}
[352] Fix | Delete
}
[353] Fix | Delete
[354] Fix | Delete
private function checkScanStatus() {
[355] Fix | Delete
wfIssues::updateScanStillRunning();
[356] Fix | Delete
$this->checkForCoreVersionChange();
[357] Fix | Delete
self::checkForKill();
[358] Fix | Delete
$this->checkForDurationLimit();
[359] Fix | Delete
}
[360] Fix | Delete
[361] Fix | Delete
public function shouldFork() {
[362] Fix | Delete
$timestamp = time();
[363] Fix | Delete
[364] Fix | Delete
if ($timestamp - $this->cycleStartTime > $this->maxExecTime) {
[365] Fix | Delete
$this->checkScanStatus();
[366] Fix | Delete
return true;
[367] Fix | Delete
}
[368] Fix | Delete
[369] Fix | Delete
if ($this->lastCheck > $timestamp - $this->maxExecTime) {
[370] Fix | Delete
return false;
[371] Fix | Delete
}
[372] Fix | Delete
[373] Fix | Delete
if ($timestamp - $this->lastCheck > self::SCAN_CHECK_INTERVAL)
[374] Fix | Delete
$this->checkScanStatus();
[375] Fix | Delete
[376] Fix | Delete
$this->lastCheck = $timestamp;
[377] Fix | Delete
[378] Fix | Delete
return false;
[379] Fix | Delete
}
[380] Fix | Delete
[381] Fix | Delete
public function forkIfNeeded() {
[382] Fix | Delete
if ($this->shouldFork()) {
[383] Fix | Delete
wordfence::status(4, 'info', __("Forking during malware scan to ensure continuity.", 'wordfence'));
[384] Fix | Delete
$this->fork();
[385] Fix | Delete
}
[386] Fix | Delete
}
[387] Fix | Delete
[388] Fix | Delete
public function fork() {
[389] Fix | Delete
wordfence::status(4, 'info', __("Entered fork()", 'wordfence'));
[390] Fix | Delete
if (wfConfig::set_ser('wfsd_engine', $this, true, wfConfig::DONT_AUTOLOAD)) {
[391] Fix | Delete
$this->scanController->flushSummaryItems();
[392] Fix | Delete
wordfence::status(4, 'info', __("Calling startScan(true)", 'wordfence'));
[393] Fix | Delete
self::startScan(true, $this->scanMode);
[394] Fix | Delete
} //Otherwise there was an error so don't start another scan.
[395] Fix | Delete
exit(0);
[396] Fix | Delete
}
[397] Fix | Delete
[398] Fix | Delete
public function emailNewIssues($timeLimitReached = false) {
[399] Fix | Delete
if (!wfCentral::pluginAlertingDisabled()) {
[400] Fix | Delete
$this->i->emailNewIssues($timeLimitReached, $this->scanController);
[401] Fix | Delete
}
[402] Fix | Delete
}
[403] Fix | Delete
[404] Fix | Delete
public function submitMetrics() {
[405] Fix | Delete
if (wfConfig::get('other_WFNet', true)) {
[406] Fix | Delete
//Trim down the malware matches if needed to allow the report call to succeed
[407] Fix | Delete
if (isset($this->metrics['malwareSignature'])) {
[408] Fix | Delete
//Get count
[409] Fix | Delete
$count = 0;
[410] Fix | Delete
$extra_count = 0;
[411] Fix | Delete
$rules_with_extras = 0;
[412] Fix | Delete
foreach ($this->metrics['malwareSignature'] as $rule => $payloads) {
[413] Fix | Delete
$count += count($payloads);
[414] Fix | Delete
$extra_count += (count($payloads) - 1);
[415] Fix | Delete
if (count($payloads) > 1) {
[416] Fix | Delete
$rules_with_extras++;
[417] Fix | Delete
}
[418] Fix | Delete
}
[419] Fix | Delete
[420] Fix | Delete
//Trim additional matches
[421] Fix | Delete
$overage = $extra_count - WORDFENCE_SCAN_ISSUES_MAX_REPORT;
[422] Fix | Delete
if ($overage > 0) {
[423] Fix | Delete
foreach ($this->metrics['malwareSignature'] as $rule => $payloads) {
[424] Fix | Delete
$percent = min(1, (count($payloads) - 1) / $extra_count); //Percentage of the overage this rule is responsible for
[425] Fix | Delete
$to_remove = min(count($payloads) - 1, ceil($percent * $overage)); //Remove the lesser of (all but one, the percentage of the overage)
[426] Fix | Delete
$sliced = array_slice($this->metrics['malwareSignature'][$rule], 0, max(1, count($payloads) - $to_remove));
[427] Fix | Delete
$count -= (count($this->metrics['malwareSignature'][$rule]) - count($sliced));
[428] Fix | Delete
$this->metrics['malwareSignature'][$rule] = $sliced;
[429] Fix | Delete
}
[430] Fix | Delete
}
[431] Fix | Delete
[432] Fix | Delete
//Trim single matches
[433] Fix | Delete
if ($count > WORDFENCE_SCAN_ISSUES_MAX_REPORT) {
[434] Fix | Delete
$sliced = array_slice($this->metrics['malwareSignature'], 0, WORDFENCE_SCAN_ISSUES_MAX_REPORT, true);
[435] Fix | Delete
$this->metrics['malwareSignature'] = $sliced;
[436] Fix | Delete
}
[437] Fix | Delete
}
[438] Fix | Delete
[439] Fix | Delete
$this->api->call('record_scan_metrics', array(), array('metrics' => $this->metrics));
[440] Fix | Delete
}
[441] Fix | Delete
}
[442] Fix | Delete
[443] Fix | Delete
private function doScan() {
[444] Fix | Delete
if ($this->scanController->useLowResourceScanning()) {
[445] Fix | Delete
$isFork = ($_GET['isFork'] == '1' ? true : false);
[446] Fix | Delete
wfConfig::set('lowResourceScanWaitStep', !wfConfig::get('lowResourceScanWaitStep'));
[447] Fix | Delete
if ($isFork && wfConfig::get('lowResourceScanWaitStep')) {
[448] Fix | Delete
sleep((int) round($this->maxExecTime / 2));
[449] Fix | Delete
$this->fork(); //exits
[450] Fix | Delete
}
[451] Fix | Delete
}
[452] Fix | Delete
[453] Fix | Delete
while (sizeof($this->jobList) > 0) {
[454] Fix | Delete
self::checkForKill();
[455] Fix | Delete
$jobName = $this->jobList[0];
[456] Fix | Delete
$callback = array($this, 'scan_' . $jobName);
[457] Fix | Delete
if (is_callable($callback)) {
[458] Fix | Delete
call_user_func($callback);
[459] Fix | Delete
}
[460] Fix | Delete
array_shift($this->jobList); //only shift once we're done because we may pause halfway through a job and need to pick up where we left off
[461] Fix | Delete
self::checkForKill();
[462] Fix | Delete
if ($this->forkRequested) {
[463] Fix | Delete
$this->fork();
[464] Fix | Delete
} else {
[465] Fix | Delete
$this->forkIfNeeded();
[466] Fix | Delete
}
[467] Fix | Delete
}
[468] Fix | Delete
[469] Fix | Delete
$this->status(1, 'info', '-------------------');
[470] Fix | Delete
[471] Fix | Delete
$peakMemory = wfScan::logPeakMemory();
[472] Fix | Delete
$this->status(2, 'info', sprintf(
[473] Fix | Delete
/* translators: 1. Memory in bytes. 2. Memory in bytes. */
[474] Fix | Delete
__('Wordfence used %1$s of memory for scan. Server peak memory usage was: %2$s', 'wordfence'),
[475] Fix | Delete
wfUtils::formatBytes($peakMemory - wfScan::$peakMemAtStart),
[476] Fix | Delete
wfUtils::formatBytes($peakMemory)
[477] Fix | Delete
));
[478] Fix | Delete
[479] Fix | Delete
wfScanMonitor::endMonitoring();
[480] Fix | Delete
[481] Fix | Delete
if ($this->isFullScan()) {
[482] Fix | Delete
$this->status(1, 'info', sprintf(
[483] Fix | Delete
/* translators: 1. Number of files. 2. Number of plugins. 3. Number of themes. 4. Number of posts. 5. Number of comments. 6. Number of URLs. 7. Time duration. */
[484] Fix | Delete
__('Scan Complete. Scanned %1$d files, %2$d plugins, %3$d themes, %4$d posts, %5$d comments and %6$d URLs in %7$s.', 'wordfence'),
[485] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_FILES, 0),
[486] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_PLUGINS, 0),
[487] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_THEMES, 0),
[488] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_POSTS, 0),
[489] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_COMMENTS, 0),
[490] Fix | Delete
$this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, 0),
[491] Fix | Delete
wfUtils::makeDuration(time() - $this->startTime, true)
[492] Fix | Delete
));
[493] Fix | Delete
} else {
[494] Fix | Delete
$this->status(1, 'info', sprintf(
[495] Fix | Delete
/* translators: 1. Time duration. */
[496] Fix | Delete
__("Quick Scan Complete. Scanned in %s.", 'wordfence'),
[497] Fix | Delete
wfUtils::makeDuration(time() - $this->startTime, true)
[498] Fix | Delete
));
[499] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function