Version Description
- Improvement: Increased frequency of filesystem permission check and update of the WAF config files.
- Improvement: More complete data removal when deactivating with remove tables and files checked.
- Improvement: Better diagnostics logging for GeoIP conflicts.
- Fix: Text fix in invalid username lockout message.
- Fix: PHP 7.3 syntax compatibility fixes.
Download this release
Release Info
Developer | wfryan |
Plugin | Wordfence Security – Firewall & Malware Scan |
Version | 7.1.17 |
Comparing to | |
See all releases |
Code changes from version 7.1.16 to 7.1.17
- css/{activity-report-widget.1539704326.css → activity-report-widget.1541524007.css} +0 -0
- css/{diff.1539704326.css → diff.1541524007.css} +0 -0
- css/{dt_table.1539704326.css → dt_table.1541524007.css} +0 -0
- css/{fullLog.1539704326.css → fullLog.1541524007.css} +0 -0
- css/{iptraf.1539704326.css → iptraf.1541524007.css} +0 -0
- css/{jquery-ui-timepicker-addon.1539704326.css → jquery-ui-timepicker-addon.1541524007.css} +0 -0
- css/{jquery-ui.min.1539704326.css → jquery-ui.min.1541524007.css} +0 -0
- css/{jquery-ui.structure.min.1539704326.css → jquery-ui.structure.min.1541524007.css} +0 -0
- css/{jquery-ui.theme.min.1539704326.css → jquery-ui.theme.min.1541524007.css} +0 -0
- css/{main.1539704326.css → main.1541524007.css} +0 -0
- css/{phpinfo.1539704326.css → phpinfo.1541524007.css} +0 -0
- css/{wf-adminbar.1539704326.css → wf-adminbar.1541524007.css} +0 -0
- css/{wf-colorbox.1539704326.css → wf-colorbox.1541524007.css} +0 -0
- css/{wf-font-awesome.1539704326.css → wf-font-awesome.1541524007.css} +0 -0
- css/{wf-ionicons.1539704326.css → wf-ionicons.1541524007.css} +0 -0
- css/{wf-onboarding.1539704326.css → wf-onboarding.1541524007.css} +0 -0
- css/{wf-roboto-font.1539704326.css → wf-roboto-font.1541524007.css} +0 -0
- css/{wfselect2.min.1539704326.css → wfselect2.min.1541524007.css} +0 -0
- css/{wordfenceBox.1539704326.css → wordfenceBox.1541524007.css} +0 -0
- js/{Chart.bundle.min.1539704326.js → Chart.bundle.min.1541524007.js} +0 -0
- js/{admin.1539704326.js → admin.1541524007.js} +0 -0
- js/{admin.ajaxWatcher.1539704326.js → admin.ajaxWatcher.1541524007.js} +0 -0
- js/{admin.liveTraffic.1539704326.js → admin.liveTraffic.1541524007.js} +0 -0
- js/{date.1539704326.js → date.1541524007.js} +0 -0
- js/{jquery-ui-timepicker-addon.1539704326.js → jquery-ui-timepicker-addon.1541524007.js} +0 -0
- js/{jquery.colorbox-min.1539704326.js → jquery.colorbox-min.1541524007.js} +0 -0
- js/{jquery.colorbox.1539704326.js → jquery.colorbox.1541524007.js} +0 -0
- js/{jquery.dataTables.min.1539704326.js → jquery.dataTables.min.1541524007.js} +0 -0
- js/{jquery.qrcode.min.1539704326.js → jquery.qrcode.min.1541524007.js} +0 -0
- js/{jquery.tmpl.min.1539704326.js → jquery.tmpl.min.1541524007.js} +0 -0
- js/{jquery.tools.min.1539704326.js → jquery.tools.min.1541524007.js} +0 -0
- js/{knockout-3.3.0.1539704326.js → knockout-3.3.0.1541524007.js} +0 -0
- js/{perf.1539704326.js → perf.1541524007.js} +0 -0
- js/{wfdashboard.1539704326.js → wfdashboard.1541524007.js} +0 -0
- js/{wfdropdown.1539704326.js → wfdropdown.1541524007.js} +0 -0
- js/{wfglobal.1539704326.js → wfglobal.1541524007.js} +0 -0
- js/{wfpopover.1539704326.js → wfpopover.1541524007.js} +0 -0
- js/{wfselect2.min.1539704326.js → wfselect2.min.1541524007.js} +0 -0
- lib/wfConfig.php +3 -0
- lib/wfDiagnostic.php +35 -2
- lib/wfUtils.php +73 -3
- lib/wordfenceClass.php +113 -5
- lib/wordfenceScanner.php +3 -2
- models/block/wfBlock.php +5 -5
- readme.txt +9 -2
- vendor/wordfence/wf-waf/src/lib/storage.php +2 -0
- vendor/wordfence/wf-waf/src/lib/storage/file.php +30 -0
- vendor/wordfence/wf-waf/src/lib/waf.php +9 -1
- waf/bootstrap.php +88 -13
- wordfence.php +3 -3
css/{activity-report-widget.1539704326.css → activity-report-widget.1541524007.css}
RENAMED
File without changes
|
css/{diff.1539704326.css → diff.1541524007.css}
RENAMED
File without changes
|
css/{dt_table.1539704326.css → dt_table.1541524007.css}
RENAMED
File without changes
|
css/{fullLog.1539704326.css → fullLog.1541524007.css}
RENAMED
File without changes
|
css/{iptraf.1539704326.css → iptraf.1541524007.css}
RENAMED
File without changes
|
css/{jquery-ui-timepicker-addon.1539704326.css → jquery-ui-timepicker-addon.1541524007.css}
RENAMED
File without changes
|
css/{jquery-ui.min.1539704326.css → jquery-ui.min.1541524007.css}
RENAMED
File without changes
|
css/{jquery-ui.structure.min.1539704326.css → jquery-ui.structure.min.1541524007.css}
RENAMED
File without changes
|
css/{jquery-ui.theme.min.1539704326.css → jquery-ui.theme.min.1541524007.css}
RENAMED
File without changes
|
css/{main.1539704326.css → main.1541524007.css}
RENAMED
File without changes
|
css/{phpinfo.1539704326.css → phpinfo.1541524007.css}
RENAMED
File without changes
|
css/{wf-adminbar.1539704326.css → wf-adminbar.1541524007.css}
RENAMED
File without changes
|
css/{wf-colorbox.1539704326.css → wf-colorbox.1541524007.css}
RENAMED
File without changes
|
css/{wf-font-awesome.1539704326.css → wf-font-awesome.1541524007.css}
RENAMED
File without changes
|
css/{wf-ionicons.1539704326.css → wf-ionicons.1541524007.css}
RENAMED
File without changes
|
css/{wf-onboarding.1539704326.css → wf-onboarding.1541524007.css}
RENAMED
File without changes
|
css/{wf-roboto-font.1539704326.css → wf-roboto-font.1541524007.css}
RENAMED
File without changes
|
css/{wfselect2.min.1539704326.css → wfselect2.min.1541524007.css}
RENAMED
File without changes
|
css/{wordfenceBox.1539704326.css → wordfenceBox.1541524007.css}
RENAMED
File without changes
|
js/{Chart.bundle.min.1539704326.js → Chart.bundle.min.1541524007.js}
RENAMED
File without changes
|
js/{admin.1539704326.js → admin.1541524007.js}
RENAMED
File without changes
|
js/{admin.ajaxWatcher.1539704326.js → admin.ajaxWatcher.1541524007.js}
RENAMED
File without changes
|
js/{admin.liveTraffic.1539704326.js → admin.liveTraffic.1541524007.js}
RENAMED
File without changes
|
js/{date.1539704326.js → date.1541524007.js}
RENAMED
File without changes
|
js/{jquery-ui-timepicker-addon.1539704326.js → jquery-ui-timepicker-addon.1541524007.js}
RENAMED
File without changes
|
js/{jquery.colorbox-min.1539704326.js → jquery.colorbox-min.1541524007.js}
RENAMED
File without changes
|
js/{jquery.colorbox.1539704326.js → jquery.colorbox.1541524007.js}
RENAMED
File without changes
|
js/{jquery.dataTables.min.1539704326.js → jquery.dataTables.min.1541524007.js}
RENAMED
File without changes
|
js/{jquery.qrcode.min.1539704326.js → jquery.qrcode.min.1541524007.js}
RENAMED
File without changes
|
js/{jquery.tmpl.min.1539704326.js → jquery.tmpl.min.1541524007.js}
RENAMED
File without changes
|
js/{jquery.tools.min.1539704326.js → jquery.tools.min.1541524007.js}
RENAMED
File without changes
|
js/{knockout-3.3.0.1539704326.js → knockout-3.3.0.1541524007.js}
RENAMED
File without changes
|
js/{perf.1539704326.js → perf.1541524007.js}
RENAMED
File without changes
|
js/{wfdashboard.1539704326.js → wfdashboard.1541524007.js}
RENAMED
File without changes
|
js/{wfdropdown.1539704326.js → wfdropdown.1541524007.js}
RENAMED
File without changes
|
js/{wfglobal.1539704326.js → wfglobal.1541524007.js}
RENAMED
File without changes
|
js/{wfpopover.1539704326.js → wfpopover.1541524007.js}
RENAMED
File without changes
|
js/{wfselect2.min.1539704326.js → wfselect2.min.1541524007.js}
RENAMED
File without changes
|
lib/wfConfig.php
CHANGED
@@ -217,6 +217,9 @@ class wfConfig {
|
|
217 |
'touppPromptNeeded' => array('value' => false, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_BOOL)),
|
218 |
'touppBypassNextCheck' => array('value' => false, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_BOOL)),
|
219 |
'autoUpdateAttempts' => array('value' => 0, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_INT)),
|
|
|
|
|
|
|
220 |
),
|
221 |
);
|
222 |
public static $serializedOptions = array('lastAdminLogin', 'scanSched', 'emailedIssuesList', 'wf_summaryItems', 'adminUserList', 'twoFactorUsers', 'alertFreqTrack', 'wfStatusStartMsgs', 'vulnerabilities_plugin', 'vulnerabilities_theme', 'dashboardData', 'malwarePrefixes', 'coreHashes', 'noc1ScanSchedule', 'allScansScheduled', 'disclosureStates', 'scanStageStatuses', 'adminNoticeQueue');
|
217 |
'touppPromptNeeded' => array('value' => false, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_BOOL)),
|
218 |
'touppBypassNextCheck' => array('value' => false, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_BOOL)),
|
219 |
'autoUpdateAttempts' => array('value' => 0, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_INT)),
|
220 |
+
'lastPermissionsTemplateCheck' => array('value' => 0, 'autoload' => self::AUTOLOAD, 'validation' => array('type' => self::TYPE_INT)),
|
221 |
+
'previousWflogsFileList' => array('value' => '[]', 'autoload' => self::DONT_AUTOLOAD, 'validation' => array('type' => self::TYPE_STRING)),
|
222 |
+
'diagnosticsWflogsRemovalHistory' => array('value' => '[]', 'autoload' => self::DONT_AUTOLOAD, 'validation' => array('type' => self::TYPE_STRING)),
|
223 |
),
|
224 |
);
|
225 |
public static $serializedOptions = array('lastAdminLogin', 'scanSched', 'emailedIssuesList', 'wf_summaryItems', 'adminUserList', 'twoFactorUsers', 'alertFreqTrack', 'wfStatusStartMsgs', 'vulnerabilities_plugin', 'vulnerabilities_theme', 'dashboardData', 'malwarePrefixes', 'coreHashes', 'noc1ScanSchedule', 'allScansScheduled', 'disclosureStates', 'scanStageStatuses', 'adminNoticeQueue');
|
lib/wfDiagnostic.php
CHANGED
@@ -58,6 +58,7 @@ class wfDiagnostic
|
|
58 |
'description' => __('General information about the Wordfence installation.', 'wordfence'),
|
59 |
'tests' => array(
|
60 |
'wfVersion' => __('Wordfence Version', 'wordfence'),
|
|
|
61 |
),
|
62 |
),
|
63 |
'Filesystem' => array(
|
@@ -84,6 +85,7 @@ class wfDiagnostic
|
|
84 |
'wafSubdirectoryInstall' => __('WAF subdirectory installation', 'wordfence'),
|
85 |
'wafAutoPrependFilePath' => __('wordfence-waf.php path', 'wordfence'),
|
86 |
'wafFilePermissions' => __('WAF File Permissions', 'wordfence'),
|
|
|
87 |
),
|
88 |
),
|
89 |
'MySQL' => array(
|
@@ -161,6 +163,15 @@ class wfDiagnostic
|
|
161 |
public function wfVersion() {
|
162 |
return array('test' => true, 'message' => WORDFENCE_VERSION . ' (' . WORDFENCE_BUILD_NUMBER . ')');
|
163 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
|
165 |
public function isPluginReadable() {
|
166 |
return is_readable(WORDFENCE_PATH);
|
@@ -180,7 +191,6 @@ class wfDiagnostic
|
|
180 |
WFWAF_LOG_PATH . 'ips.php',
|
181 |
WFWAF_LOG_PATH . 'config.php',
|
182 |
WFWAF_LOG_PATH . 'rules.php',
|
183 |
-
WFWAF_LOG_PATH . 'wafRules.rules',
|
184 |
);
|
185 |
$unreadable = array();
|
186 |
foreach ($files as $f) {
|
@@ -209,7 +219,6 @@ class wfDiagnostic
|
|
209 |
WFWAF_LOG_PATH . 'ips.php',
|
210 |
WFWAF_LOG_PATH . 'config.php',
|
211 |
WFWAF_LOG_PATH . 'rules.php',
|
212 |
-
WFWAF_LOG_PATH . 'wafRules.rules',
|
213 |
);
|
214 |
$unwritable = array();
|
215 |
foreach ($files as $f) {
|
@@ -347,6 +356,30 @@ class wfDiagnostic
|
|
347 |
}
|
348 |
return array('test' => true, 'infoOnly' => true, 'message' => __('0660 - using default', 'wordfence'));
|
349 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
|
351 |
public function processOwner() {
|
352 |
$disabledFunctions = explode(',', ini_get('disable_functions'));
|
58 |
'description' => __('General information about the Wordfence installation.', 'wordfence'),
|
59 |
'tests' => array(
|
60 |
'wfVersion' => __('Wordfence Version', 'wordfence'),
|
61 |
+
'geoIPVersion' => __('GeoIP Version', 'wordfence'),
|
62 |
),
|
63 |
),
|
64 |
'Filesystem' => array(
|
85 |
'wafSubdirectoryInstall' => __('WAF subdirectory installation', 'wordfence'),
|
86 |
'wafAutoPrependFilePath' => __('wordfence-waf.php path', 'wordfence'),
|
87 |
'wafFilePermissions' => __('WAF File Permissions', 'wordfence'),
|
88 |
+
'wafRecentlyRemoved' => __('Recently removed wflogs files', 'wordfence'),
|
89 |
),
|
90 |
),
|
91 |
'MySQL' => array(
|
163 |
public function wfVersion() {
|
164 |
return array('test' => true, 'message' => WORDFENCE_VERSION . ' (' . WORDFENCE_BUILD_NUMBER . ')');
|
165 |
}
|
166 |
+
|
167 |
+
public function geoIPVersion() {
|
168 |
+
return array('test' => true, 'infoOnly' => true, 'message' => wfUtils::geoIPVersion());
|
169 |
+
}
|
170 |
+
|
171 |
+
public function geoIPError() {
|
172 |
+
$error = wfUtils::last_error('geoip');
|
173 |
+
return array('test' => true, 'infoOnly' => true, 'message' => $error ? $error : __('None', 'wordfence'));
|
174 |
+
}
|
175 |
|
176 |
public function isPluginReadable() {
|
177 |
return is_readable(WORDFENCE_PATH);
|
191 |
WFWAF_LOG_PATH . 'ips.php',
|
192 |
WFWAF_LOG_PATH . 'config.php',
|
193 |
WFWAF_LOG_PATH . 'rules.php',
|
|
|
194 |
);
|
195 |
$unreadable = array();
|
196 |
foreach ($files as $f) {
|
219 |
WFWAF_LOG_PATH . 'ips.php',
|
220 |
WFWAF_LOG_PATH . 'config.php',
|
221 |
WFWAF_LOG_PATH . 'rules.php',
|
|
|
222 |
);
|
223 |
$unwritable = array();
|
224 |
foreach ($files as $f) {
|
356 |
}
|
357 |
return array('test' => true, 'infoOnly' => true, 'message' => __('0660 - using default', 'wordfence'));
|
358 |
}
|
359 |
+
|
360 |
+
public function wafRecentlyRemoved() {
|
361 |
+
$removalHistory = wfConfig::getJSON('diagnosticsWflogsRemovalHistory', array());
|
362 |
+
if (empty($removalHistory)) {
|
363 |
+
return array('test' => true, 'infoOnly' => true, 'message' => __('None', 'wordfence'));
|
364 |
+
}
|
365 |
+
|
366 |
+
$message = array();
|
367 |
+
foreach ($removalHistory as $r) {
|
368 |
+
$m = wfUtils::formatLocalTime('M j, Y', $r[0]) . ': (' . count($r[1]) . ')';
|
369 |
+
$r[1] = array_filter($r[1], array($this, '_filterOutNestedEntries'));
|
370 |
+
$m .= ' ' . implode(', ', array_slice($r[1], 0, 5));
|
371 |
+
if (count($r[1]) > 5) {
|
372 |
+
$m .= ', ...';
|
373 |
+
}
|
374 |
+
$message[] = $m;
|
375 |
+
}
|
376 |
+
|
377 |
+
return array('test' => true, 'infoOnly' => true, 'message' => implode("\n", $message));
|
378 |
+
}
|
379 |
+
|
380 |
+
private function _filterOutNestedEntries($a) {
|
381 |
+
return !is_array($a);
|
382 |
+
}
|
383 |
|
384 |
public function processOwner() {
|
385 |
$disabledFunctions = explode(',', ini_get('disable_functions'));
|
lib/wfUtils.php
CHANGED
@@ -1387,16 +1387,22 @@ class wfUtils {
|
|
1387 |
}
|
1388 |
|
1389 |
if (!class_exists('wfGeoIP2')) {
|
|
|
1390 |
require_once(dirname(__FILE__) . '/../models/common/wfGeoIP2.php');
|
|
|
1391 |
}
|
1392 |
|
1393 |
try {
|
|
|
1394 |
$geoip = @wfGeoIP2::shared();
|
|
|
|
|
1395 |
$code = @$geoip->countryCode($IP);
|
|
|
1396 |
return is_string($code) ? $code : '';
|
1397 |
}
|
1398 |
catch (Exception $e) {
|
1399 |
-
|
1400 |
}
|
1401 |
|
1402 |
return '';
|
@@ -1407,15 +1413,22 @@ class wfUtils {
|
|
1407 |
}
|
1408 |
|
1409 |
if (!class_exists('wfGeoIP2')) {
|
|
|
1410 |
require_once(dirname(__FILE__) . '/../models/common/wfGeoIP2.php');
|
|
|
1411 |
}
|
1412 |
|
1413 |
try {
|
|
|
1414 |
$geoip = @wfGeoIP2::shared();
|
1415 |
-
|
|
|
|
|
|
|
|
|
1416 |
}
|
1417 |
catch (Exception $e) {
|
1418 |
-
|
1419 |
}
|
1420 |
|
1421 |
return 0;
|
@@ -1465,6 +1478,63 @@ class wfUtils {
|
|
1465 |
public static function isRefererBlocked($refPattern){
|
1466 |
return fnmatch($refPattern, !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '', FNM_CASEFOLD);
|
1467 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1468 |
|
1469 |
/**
|
1470 |
* @param $startIP
|
1387 |
}
|
1388 |
|
1389 |
if (!class_exists('wfGeoIP2')) {
|
1390 |
+
wfUtils::error_clear_last();
|
1391 |
require_once(dirname(__FILE__) . '/../models/common/wfGeoIP2.php');
|
1392 |
+
wfUtils::check_and_log_last_error('geoip', 'GeoIP Error:');
|
1393 |
}
|
1394 |
|
1395 |
try {
|
1396 |
+
wfUtils::error_clear_last();
|
1397 |
$geoip = @wfGeoIP2::shared();
|
1398 |
+
wfUtils::check_and_log_last_error('geoip', 'GeoIP Error:');
|
1399 |
+
wfUtils::error_clear_last();
|
1400 |
$code = @$geoip->countryCode($IP);
|
1401 |
+
wfUtils::check_and_log_last_error('geoip', 'GeoIP Error:');
|
1402 |
return is_string($code) ? $code : '';
|
1403 |
}
|
1404 |
catch (Exception $e) {
|
1405 |
+
wfUtils::check_and_log_last_error('geoip', 'GeoIP Error:', $e->getMessage());
|
1406 |
}
|
1407 |
|
1408 |
return '';
|
1413 |
}
|
1414 |
|
1415 |
if (!class_exists('wfGeoIP2')) {
|
1416 |
+
wfUtils::error_clear_last();
|
1417 |
require_once(dirname(__FILE__) . '/../models/common/wfGeoIP2.php');
|
1418 |
+
wfUtils::check_and_log_last_error('geoip', 'GeoIP Error:');
|
1419 |
}
|
1420 |
|
1421 |
try {
|
1422 |
+
wfUtils::error_clear_last();
|
1423 |
$geoip = @wfGeoIP2::shared();
|
1424 |
+
wfUtils::check_and_log_last_error('geoip', 'GeoIP Error:');
|
1425 |
+
wfUtils::error_clear_last();
|
1426 |
+
$version = @$geoip->version();
|
1427 |
+
wfUtils::check_and_log_last_error('geoip', 'GeoIP Error:');
|
1428 |
+
return $version;
|
1429 |
}
|
1430 |
catch (Exception $e) {
|
1431 |
+
wfUtils::check_and_log_last_error('geoip', 'GeoIP Error:', $e->getMessage());
|
1432 |
}
|
1433 |
|
1434 |
return 0;
|
1478 |
public static function isRefererBlocked($refPattern){
|
1479 |
return fnmatch($refPattern, !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '', FNM_CASEFOLD);
|
1480 |
}
|
1481 |
+
|
1482 |
+
public static function error_clear_last() {
|
1483 |
+
if (function_exists('error_clear_last')) {
|
1484 |
+
error_clear_last();
|
1485 |
+
}
|
1486 |
+
else {
|
1487 |
+
// set error_get_last() to defined state by forcing an undefined variable error
|
1488 |
+
set_error_handler('wfUtils::_resetErrorsHandler', 0);
|
1489 |
+
@$undefinedVariable;
|
1490 |
+
restore_error_handler();
|
1491 |
+
}
|
1492 |
+
}
|
1493 |
+
|
1494 |
+
/**
|
1495 |
+
* Logs the error given or the last PHP error to our log, rate limiting if needed.
|
1496 |
+
*
|
1497 |
+
* @param string $limiter_key
|
1498 |
+
* @param string $label
|
1499 |
+
* @param null|string $error The error to log. If null, it will be the result of error_get_last
|
1500 |
+
* @param int $rate Logging will only occur once per $rate seconds.
|
1501 |
+
*/
|
1502 |
+
public static function check_and_log_last_error($limiter_key, $label, $error = null, $rate = 3600 /* 1 hour */) {
|
1503 |
+
if ($error === null) {
|
1504 |
+
$error = error_get_last();
|
1505 |
+
if ($error === null) {
|
1506 |
+
return;
|
1507 |
+
}
|
1508 |
+
else if ($error['file'] === __FILE__) {
|
1509 |
+
return;
|
1510 |
+
}
|
1511 |
+
$error = $error['message'];
|
1512 |
+
}
|
1513 |
+
|
1514 |
+
$rateKey = 'lastError_rate_' . $limiter_key;
|
1515 |
+
$previousKey = 'lastError_prev_' . $limiter_key;
|
1516 |
+
$previousError = wfConfig::getJSON($previousKey, array(0, false));
|
1517 |
+
if ($previousError[1] != $error) {
|
1518 |
+
if (wfConfig::getInt($rateKey) < time() - $rate) {
|
1519 |
+
wfConfig::set($rateKey, time());
|
1520 |
+
wfConfig::setJSON($previousKey, array(time(), $error));
|
1521 |
+
wordfence::status(2, 'error', $label . ' ' . $error);
|
1522 |
+
}
|
1523 |
+
}
|
1524 |
+
}
|
1525 |
+
|
1526 |
+
public static function last_error($limiter_key) {
|
1527 |
+
$previousKey = 'lastError_prev_' . $limiter_key;
|
1528 |
+
$previousError = wfConfig::getJSON($previousKey, array(0, false));
|
1529 |
+
if ($previousError[1]) {
|
1530 |
+
return wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $previousError[0]) . ': ' . $previousError[1];
|
1531 |
+
}
|
1532 |
+
return false;
|
1533 |
+
}
|
1534 |
+
|
1535 |
+
public static function _resetErrorsHandler($errno, $errstr, $errfile, $errline) {
|
1536 |
+
//Do nothing
|
1537 |
+
}
|
1538 |
|
1539 |
/**
|
1540 |
* @param $startIP
|
lib/wordfenceClass.php
CHANGED
@@ -285,6 +285,8 @@ class wordfence {
|
|
285 |
if ($next - time() > 3600 && wfConfig::get('scheduledScansEnabled')) {
|
286 |
wfScanEngine::startScan(false, wfScanner::SCAN_TYPE_QUICK);
|
287 |
}
|
|
|
|
|
288 |
}
|
289 |
public static function _scheduleRefreshUpdateNotification($upgrader, $options) {
|
290 |
$defer = false;
|
@@ -1832,7 +1834,8 @@ SQL
|
|
1832 |
}
|
1833 |
|
1834 |
try {
|
1835 |
-
|
|
|
1836 |
$lastPermissionsTemplateCheck = wfConfig::getInt('lastPermissionsTemplateCheck', 0);
|
1837 |
if (defined('WFWAF_LOG_PATH') && ($lastPermissionsTemplateCheck + 43200) < time()) { //Run no more frequently than every 12 hours
|
1838 |
$timestamp = preg_replace('/[^0-9]/', '', microtime(false)); //We avoid using tmpfile since it can potentially create one with different permissions than the defaults
|
@@ -1866,10 +1869,41 @@ SQL
|
|
1866 |
}
|
1867 |
|
1868 |
wfConfig::set('lastPermissionsTemplateCheck', time());
|
1869 |
-
}
|
1870 |
|
1871 |
-
|
1872 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1873 |
}
|
1874 |
}
|
1875 |
catch (Exception $e) {
|
@@ -2034,6 +2068,80 @@ SQL
|
|
2034 |
}
|
2035 |
}
|
2036 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2037 |
|
2038 |
public static function loginAction($username){
|
2039 |
if(sizeof($_POST) < 1){ return; } //only execute if login form is posted
|
@@ -2648,7 +2756,7 @@ SQL
|
|
2648 |
}
|
2649 |
if(wfConfig::get('loginSec_lockInvalidUsers')){
|
2650 |
if(strlen($username) > 0 && preg_match('/[^\r\s\n\t]+/', $username)){
|
2651 |
-
self::lockOutIP($IP, "Used an invalid username '" . $username . "' to try to sign in
|
2652 |
self::getLog()->logLogin('loginFailInvalidUsername', true, $username);
|
2653 |
}
|
2654 |
$customText = wpautop(wp_strip_all_tags(wfConfig::get('blockCustomText', '')));
|
285 |
if ($next - time() > 3600 && wfConfig::get('scheduledScansEnabled')) {
|
286 |
wfScanEngine::startScan(false, wfScanner::SCAN_TYPE_QUICK);
|
287 |
}
|
288 |
+
|
289 |
+
wfConfig::remove('lastPermissionsTemplateCheck');
|
290 |
}
|
291 |
public static function _scheduleRefreshUpdateNotification($upgrader, $options) {
|
292 |
$defer = false;
|
1834 |
}
|
1835 |
|
1836 |
try {
|
1837 |
+
$sapi = @php_sapi_name();
|
1838 |
+
if ($sapi != "cli") {
|
1839 |
$lastPermissionsTemplateCheck = wfConfig::getInt('lastPermissionsTemplateCheck', 0);
|
1840 |
if (defined('WFWAF_LOG_PATH') && ($lastPermissionsTemplateCheck + 43200) < time()) { //Run no more frequently than every 12 hours
|
1841 |
$timestamp = preg_replace('/[^0-9]/', '', microtime(false)); //We avoid using tmpfile since it can potentially create one with different permissions than the defaults
|
1869 |
}
|
1870 |
|
1871 |
wfConfig::set('lastPermissionsTemplateCheck', time());
|
|
|
1872 |
|
1873 |
+
@chmod(WFWAF_LOG_PATH, (wfWAFWordPress::permissions() | 0755));
|
1874 |
+
wfWAFWordPress::writeHtaccess();
|
1875 |
+
|
1876 |
+
$contents = self::_wflogsContents();
|
1877 |
+
if ($contents) {
|
1878 |
+
$validFiles = wfWAF::getInstance()->fileList();
|
1879 |
+
foreach ($validFiles as &$vf) {
|
1880 |
+
$vf = basename($vf);
|
1881 |
+
}
|
1882 |
+
$validFiles = array_filter($validFiles);
|
1883 |
+
|
1884 |
+
$previousWflogsFileList = wfConfig::getJSON('previousWflogsFileList', array());
|
1885 |
+
|
1886 |
+
$wflogs = realpath(WFWAF_LOG_PATH);
|
1887 |
+
$filesRemoved = array();
|
1888 |
+
foreach ($contents as $f) {
|
1889 |
+
if (!in_array($f, $validFiles) && in_array($f, $previousWflogsFileList)) {
|
1890 |
+
$fullPath = $f;
|
1891 |
+
$removed = self::_recursivelyRemoveWflogs($f);
|
1892 |
+
$filesRemoved = array_merge($filesRemoved, $removed);
|
1893 |
+
}
|
1894 |
+
}
|
1895 |
+
|
1896 |
+
$contents = self::_wflogsContents();
|
1897 |
+
wfConfig::setJSON('previousWflogsFileList', $contents);
|
1898 |
+
|
1899 |
+
if (!empty($filesRemoved)) {
|
1900 |
+
$removalHistory = wfConfig::getJSON('diagnosticsWflogsRemovalHistory', array());
|
1901 |
+
$removalHistory = array_slice($removalHistory, 0, 4);
|
1902 |
+
array_unshift($removalHistory, array(time(), $filesRemoved));
|
1903 |
+
wfConfig::setJSON('diagnosticsWflogsRemovalHistory', $removalHistory);
|
1904 |
+
}
|
1905 |
+
}
|
1906 |
+
}
|
1907 |
}
|
1908 |
}
|
1909 |
catch (Exception $e) {
|
2068 |
}
|
2069 |
}
|
2070 |
}
|
2071 |
+
|
2072 |
+
private static function _wflogsContents() {
|
2073 |
+
$dir = opendir(WFWAF_LOG_PATH);
|
2074 |
+
if ($dir) {
|
2075 |
+
$contents = array();
|
2076 |
+
while ($path = readdir($dir)) {
|
2077 |
+
if ($path == '.' || $path == '..') { continue; }
|
2078 |
+
$contents[] = $path;
|
2079 |
+
}
|
2080 |
+
closedir($dir);
|
2081 |
+
return $contents;
|
2082 |
+
}
|
2083 |
+
return false;
|
2084 |
+
}
|
2085 |
+
|
2086 |
+
/**
|
2087 |
+
* Removes a path within wflogs, recursing as necessary.
|
2088 |
+
*
|
2089 |
+
* @param string $file
|
2090 |
+
* @param array $processedDirs
|
2091 |
+
* @return array The list of removed files/folders.
|
2092 |
+
*/
|
2093 |
+
private static function _recursivelyRemoveWflogs($file, $processedDirs = array()) {
|
2094 |
+
if (preg_match('~(?:^|/|\\\\)\.\.(?:/|\\\\|$)~', $file)) {
|
2095 |
+
return array();
|
2096 |
+
}
|
2097 |
+
|
2098 |
+
if (stripos(WFWAF_LOG_PATH, 'wflogs') === false) { //Sanity check -- if not in a wflogs folder, user will have to do removal manually
|
2099 |
+
return array();
|
2100 |
+
}
|
2101 |
+
|
2102 |
+
$path = rtrim(WFWAF_LOG_PATH, '/') . '/' . $file;
|
2103 |
+
if (is_link($path)) {
|
2104 |
+
if (@unlink($path)) {
|
2105 |
+
return array($file);
|
2106 |
+
}
|
2107 |
+
return array();
|
2108 |
+
}
|
2109 |
+
|
2110 |
+
if (is_dir($path)) {
|
2111 |
+
$real = realpath($file);
|
2112 |
+
if (in_array($real, $processedDirs)) {
|
2113 |
+
return array();
|
2114 |
+
}
|
2115 |
+
$processedDirs[] = $real;
|
2116 |
+
|
2117 |
+
$count = 0;
|
2118 |
+
$dir = opendir($path);
|
2119 |
+
if ($dir) {
|
2120 |
+
$contents = array();
|
2121 |
+
while ($sub = readdir($dir)) {
|
2122 |
+
if ($sub == '.' || $sub == '..') { continue; }
|
2123 |
+
$contents[] = $sub;
|
2124 |
+
}
|
2125 |
+
closedir($dir);
|
2126 |
+
|
2127 |
+
$filesRemoved = array();
|
2128 |
+
foreach ($contents as $f) {
|
2129 |
+
$removed = self::_recursivelyRemoveWflogs($file . '/' . $f, $processedDirs);
|
2130 |
+
$filesRemoved = array($filesRemoved, $removed);
|
2131 |
+
}
|
2132 |
+
}
|
2133 |
+
|
2134 |
+
if (@rmdir($path)) {
|
2135 |
+
$filesRemoved[] = $file;
|
2136 |
+
}
|
2137 |
+
return $filesRemoved;
|
2138 |
+
}
|
2139 |
+
|
2140 |
+
if (@unlink($path)) {
|
2141 |
+
return array($file);
|
2142 |
+
}
|
2143 |
+
return array();
|
2144 |
+
}
|
2145 |
|
2146 |
public static function loginAction($username){
|
2147 |
if(sizeof($_POST) < 1){ return; } //only execute if login form is posted
|
2756 |
}
|
2757 |
if(wfConfig::get('loginSec_lockInvalidUsers')){
|
2758 |
if(strlen($username) > 0 && preg_match('/[^\r\s\n\t]+/', $username)){
|
2759 |
+
self::lockOutIP($IP, "Used an invalid username '" . $username . "' to try to sign in");
|
2760 |
self::getLog()->logLogin('loginFailInvalidUsername', true, $username);
|
2761 |
}
|
2762 |
$customText = wpautop(wp_strip_all_tags(wfConfig::get('blockCustomText', '')));
|
lib/wordfenceScanner.php
CHANGED
@@ -365,7 +365,8 @@ class wordfenceScanner {
|
|
365 |
|
366 |
$type = (isset($rule[4]) && !empty($rule[4])) ? $rule[4] : 'server';
|
367 |
$logOnly = (isset($rule[5]) && !empty($rule[5])) ? $rule[5] : false;
|
368 |
-
$commonStringIndexes = (isset($rule[8]) && is_array($rule[8])) ? $rule[8] : array();
|
|
|
369 |
if ($type == 'server' && !$treatAsBinary) { continue; }
|
370 |
else if (($type == 'both' || $type == 'browser') && $isJS) { $extraMsg = ''; }
|
371 |
else if (($type == 'both' || $type == 'browser') && !$treatAsBinary) { continue; }
|
@@ -398,7 +399,7 @@ class wordfenceScanner {
|
|
398 |
'ignoreP' => $this->path . $file,
|
399 |
'ignoreC' => $fileSum,
|
400 |
'shortMsg' => __('File appears to be malicious: ', 'wordfence') . esc_html($file),
|
401 |
-
'longMsg' =>
|
402 |
'data' => array_merge(array(
|
403 |
'file' => $file,
|
404 |
'shac' => $record->SHAC,
|
365 |
|
366 |
$type = (isset($rule[4]) && !empty($rule[4])) ? $rule[4] : 'server';
|
367 |
$logOnly = (isset($rule[5]) && !empty($rule[5])) ? $rule[5] : false;
|
368 |
+
$commonStringIndexes = (isset($rule[8]) && is_array($rule[8])) ? $rule[8] : array();
|
369 |
+
$customMessage = isset($rule[9]) ? $rule[9] : __('This file appears to be installed or modified by a hacker to perform malicious activity. If you know about this file you can choose to ignore it to exclude it from future scans.', 'wordfence');
|
370 |
if ($type == 'server' && !$treatAsBinary) { continue; }
|
371 |
else if (($type == 'both' || $type == 'browser') && $isJS) { $extraMsg = ''; }
|
372 |
else if (($type == 'both' || $type == 'browser') && !$treatAsBinary) { continue; }
|
399 |
'ignoreP' => $this->path . $file,
|
400 |
'ignoreC' => $fileSum,
|
401 |
'shortMsg' => __('File appears to be malicious: ', 'wordfence') . esc_html($file),
|
402 |
+
'longMsg' => $customMessage . ' ' . __('The matched text in this file is:', 'wordfence') . ' ' . '<strong style="color: #F00;" class="wf-split-word">' . wfUtils::potentialBinaryStringToHTML((wfUtils::strlen($matchString) > 200 ? wfUtils::substr($matchString, 0, 200) . '...' : $matchString)) . '</strong>' . '<br><br>' . sprintf(__('The issue type is: <strong>%s</strong>', 'wordfence'), esc_html($rule[7])) . '<br>' . sprintf(__('Description: <strong>%s</strong>', 'wordfence'), esc_html($rule[3])) . $extraMsg,
|
403 |
'data' => array_merge(array(
|
404 |
'file' => $file,
|
405 |
'shac' => $record->SHAC,
|
models/block/wfBlock.php
CHANGED
@@ -549,10 +549,10 @@ class wfBlock {
|
|
549 |
|
550 |
return $wpdb->query($wpdb->prepare("INSERT INTO `{$blocksTable}` (`type`, `IP`, `blockedTime`, `reason`, `lastAttempt`, `blockedHits`, `expiration`, `parameters`) VALUES (%d, %s, %d, %s, %d, %d, %d, NULL)", (int) $b['type'], wfUtils::inet_pton($ip), (int) $b['blockedTime'], $b['reason'], (int) $b['lastAttempt'], (int) $b['blockedHits'], self::DURATION_FOREVER)) !== false;
|
551 |
case self::TYPE_COUNTRY:
|
552 |
-
if (!isset($b['parameters'])) {
|
553 |
-
if (wfUtils::inet_pton($ip) != self::MARKER_COUNTRY) {
|
554 |
$parameters = @json_decode($b['parameters'], true);
|
555 |
-
if (!isset($parameters['blockLogin']) || !isset($parameters['blockSite']) || !isset($parameters['countries'])) {
|
556 |
$parameters['blockLogin'] = wfUtils::truthyToInt($parameters['blockLogin']);
|
557 |
$parameters['blockSite'] = wfUtils::truthyToInt($parameters['blockSite']);
|
558 |
|
@@ -567,10 +567,10 @@ class wfBlock {
|
|
567 |
|
568 |
return $wpdb->query($wpdb->prepare("INSERT INTO `{$blocksTable}` (`type`, `IP`, `blockedTime`, `reason`, `lastAttempt`, `blockedHits`, `expiration`, `parameters`) VALUES (%d, %s, %d, %s, %d, %d, %d, %s)", self::TYPE_COUNTRY, self::MARKER_COUNTRY, (int) $b['blockedTime'], $b['reason'], (int) $b['lastAttempt'], (int) $b['blockedHits'], self::DURATION_FOREVER, json_encode($parameters))) !== false;
|
569 |
case self::TYPE_PATTERN:
|
570 |
-
if (!isset($b['parameters'])) {
|
571 |
if (wfUtils::inet_pton($ip) != self::MARKER_PATTERN) { return false; }
|
572 |
$parameters = @json_decode($b['parameters'], true);
|
573 |
-
if (!isset($parameters['ipRange']) || !isset($parameters['hostname']) || !isset($parameters['userAgent']) || !isset($parameters['referrer'])) {
|
574 |
|
575 |
$hasOne = false;
|
576 |
if (!empty($parameters['ipRange'])) {
|
549 |
|
550 |
return $wpdb->query($wpdb->prepare("INSERT INTO `{$blocksTable}` (`type`, `IP`, `blockedTime`, `reason`, `lastAttempt`, `blockedHits`, `expiration`, `parameters`) VALUES (%d, %s, %d, %s, %d, %d, %d, NULL)", (int) $b['type'], wfUtils::inet_pton($ip), (int) $b['blockedTime'], $b['reason'], (int) $b['lastAttempt'], (int) $b['blockedHits'], self::DURATION_FOREVER)) !== false;
|
551 |
case self::TYPE_COUNTRY:
|
552 |
+
if (!isset($b['parameters'])) { return false; }
|
553 |
+
if (wfUtils::inet_pton($ip) != self::MARKER_COUNTRY) { return false; }
|
554 |
$parameters = @json_decode($b['parameters'], true);
|
555 |
+
if (!isset($parameters['blockLogin']) || !isset($parameters['blockSite']) || !isset($parameters['countries'])) { return false; }
|
556 |
$parameters['blockLogin'] = wfUtils::truthyToInt($parameters['blockLogin']);
|
557 |
$parameters['blockSite'] = wfUtils::truthyToInt($parameters['blockSite']);
|
558 |
|
567 |
|
568 |
return $wpdb->query($wpdb->prepare("INSERT INTO `{$blocksTable}` (`type`, `IP`, `blockedTime`, `reason`, `lastAttempt`, `blockedHits`, `expiration`, `parameters`) VALUES (%d, %s, %d, %s, %d, %d, %d, %s)", self::TYPE_COUNTRY, self::MARKER_COUNTRY, (int) $b['blockedTime'], $b['reason'], (int) $b['lastAttempt'], (int) $b['blockedHits'], self::DURATION_FOREVER, json_encode($parameters))) !== false;
|
569 |
case self::TYPE_PATTERN:
|
570 |
+
if (!isset($b['parameters'])) { return false; }
|
571 |
if (wfUtils::inet_pton($ip) != self::MARKER_PATTERN) { return false; }
|
572 |
$parameters = @json_decode($b['parameters'], true);
|
573 |
+
if (!isset($parameters['ipRange']) || !isset($parameters['hostname']) || !isset($parameters['userAgent']) || !isset($parameters['referrer'])) { return false; }
|
574 |
|
575 |
$hasOne = false;
|
576 |
if (!empty($parameters['ipRange'])) {
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: mmaunder
|
|
3 |
Tags: security, firewall, malware scanner, web application firewall, antivirus, block hackers, country blocking, clean hacked site, blacklist, waf, login security
|
4 |
Requires at least: 3.9
|
5 |
Requires PHP: 5.3
|
6 |
-
Tested up to:
|
7 |
-
Stable tag: 7.1.
|
8 |
|
9 |
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
|
10 |
|
@@ -171,6 +171,13 @@ Secure your website with Wordfence.
|
|
171 |
|
172 |
== Changelog ==
|
173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
= 7.1.16 =
|
175 |
* Improvement: Service whitelisting can now be selectively toggled on or off per service.
|
176 |
* Improvement: Updated bundled GeoIP database.
|
3 |
Tags: security, firewall, malware scanner, web application firewall, antivirus, block hackers, country blocking, clean hacked site, blacklist, waf, login security
|
4 |
Requires at least: 3.9
|
5 |
Requires PHP: 5.3
|
6 |
+
Tested up to: 5.0
|
7 |
+
Stable tag: 7.1.17
|
8 |
|
9 |
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
|
10 |
|
171 |
|
172 |
== Changelog ==
|
173 |
|
174 |
+
= 7.1.17 =
|
175 |
+
* Improvement: Increased frequency of filesystem permission check and update of the WAF config files.
|
176 |
+
* Improvement: More complete data removal when deactivating with remove tables and files checked.
|
177 |
+
* Improvement: Better diagnostics logging for GeoIP conflicts.
|
178 |
+
* Fix: Text fix in invalid username lockout message.
|
179 |
+
* Fix: PHP 7.3 syntax compatibility fixes.
|
180 |
+
|
181 |
= 7.1.16 =
|
182 |
* Improvement: Service whitelisting can now be selectively toggled on or off per service.
|
183 |
* Improvement: Updated bundled GeoIP database.
|
vendor/wordfence/wf-waf/src/lib/storage.php
CHANGED
@@ -57,6 +57,8 @@ interface wfWAFStorageInterface {
|
|
57 |
public function unsetConfig($key, $category = '');
|
58 |
|
59 |
public function uninstall();
|
|
|
|
|
60 |
|
61 |
public function isInLearningMode();
|
62 |
|
57 |
public function unsetConfig($key, $category = '');
|
58 |
|
59 |
public function uninstall();
|
60 |
+
|
61 |
+
//optional public function fileList();
|
62 |
|
63 |
public function isInLearningMode();
|
64 |
|
vendor/wordfence/wf-waf/src/lib/storage/file.php
CHANGED
@@ -668,6 +668,36 @@ class wfWAFStorageFile implements wfWAFStorageInterface {
|
|
668 |
@unlink($this->getRulesDSLCacheFile());
|
669 |
}
|
670 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
671 |
public function removeConfigFiles() {
|
672 |
@unlink($this->getConfigFile());
|
673 |
$configDir = dirname($this->getConfigFile());
|
668 |
@unlink($this->getRulesDSLCacheFile());
|
669 |
}
|
670 |
|
671 |
+
public function fileList() {
|
672 |
+
$fileList = array();
|
673 |
+
$fileList[] = $this->getAttackDataFile();
|
674 |
+
$fileList[] = $this->getIPCacheFile();
|
675 |
+
if (defined('WFWAF_DEBUG') && WFWAF_DEBUG) {
|
676 |
+
$fileList[] = $this->getRulesDSLCacheFile();
|
677 |
+
}
|
678 |
+
$fileList[] = $this->getConfigFile();
|
679 |
+
$configDir = dirname($this->getConfigFile());
|
680 |
+
$dir = opendir($configDir);
|
681 |
+
if ($dir) {
|
682 |
+
$escapedPath = preg_quote($this->getConfigFile(), '/');
|
683 |
+
$components = explode('\\/', $escapedPath);
|
684 |
+
$pattern = $components[count($components) - 1];
|
685 |
+
if (preg_match('/^(.+?)(\\\..+$|$)/i', $pattern, $matches)) {
|
686 |
+
$pattern = $matches[1] . '\\-[a-z0-9]+' . $matches[2]; //Results in a pattern like config\-[a-z0-9]\.php
|
687 |
+
}
|
688 |
+
|
689 |
+
while ($path = readdir($dir)) {
|
690 |
+
if ($path == '.' || $path == '..') { continue; }
|
691 |
+
if (is_dir($configDir . '/' . $path)) { continue; }
|
692 |
+
if (preg_match('/^' . $pattern . '$/i', $path)) {
|
693 |
+
$fileList[] = $configDir . '/' . $path;
|
694 |
+
}
|
695 |
+
}
|
696 |
+
closedir($dir);
|
697 |
+
}
|
698 |
+
return $fileList;
|
699 |
+
}
|
700 |
+
|
701 |
public function removeConfigFiles() {
|
702 |
@unlink($this->getConfigFile());
|
703 |
$configDir = dirname($this->getConfigFile());
|
vendor/wordfence/wf-waf/src/lib/waf.php
CHANGED
@@ -726,7 +726,7 @@ if (!defined('WFWAF_VERSION')) {
|
|
726 |
%s?>
|
727 |
PHP
|
728 |
, $this->buildRuleSet($rules)), 'rules');
|
729 |
-
if (!empty($ruleString) && !
|
730 |
wfWAFStorageFile::atomicFilePutContents($this->getStorageEngine()->getRulesDSLCacheFile(), $ruleString, 'rules');
|
731 |
}
|
732 |
|
@@ -1367,6 +1367,14 @@ HTML
|
|
1367 |
@unlink($this->getCompiledRulesFile());
|
1368 |
$this->getStorageEngine()->uninstall();
|
1369 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1370 |
|
1371 |
/**
|
1372 |
* @param int $ruleID
|
726 |
%s?>
|
727 |
PHP
|
728 |
, $this->buildRuleSet($rules)), 'rules');
|
729 |
+
if (!empty($ruleString) && WFWAF_DEBUG && !file_exists($this->getStorageEngine()->getRulesDSLCacheFile())) {
|
730 |
wfWAFStorageFile::atomicFilePutContents($this->getStorageEngine()->getRulesDSLCacheFile(), $ruleString, 'rules');
|
731 |
}
|
732 |
|
1367 |
@unlink($this->getCompiledRulesFile());
|
1368 |
$this->getStorageEngine()->uninstall();
|
1369 |
}
|
1370 |
+
|
1371 |
+
public function fileList() {
|
1372 |
+
$fileList = array($this->getCompiledRulesFile());
|
1373 |
+
if (method_exists($this->getStorageEngine(), 'fileList')) {
|
1374 |
+
$fileList = array_merge($fileList, $this->getStorageEngine()->fileList());
|
1375 |
+
}
|
1376 |
+
return $fileList;
|
1377 |
+
}
|
1378 |
|
1379 |
/**
|
1380 |
* @param int $ruleID
|
waf/bootstrap.php
CHANGED
@@ -512,8 +512,79 @@ class wfWAFWordPress extends wfWAF {
|
|
512 |
|
513 |
public function uninstall() {
|
514 |
parent::uninstall();
|
515 |
-
@unlink(rtrim(WFWAF_LOG_PATH
|
516 |
-
@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
517 |
}
|
518 |
|
519 |
/**
|
@@ -560,6 +631,20 @@ class wfWAFWordPress extends wfWAF {
|
|
560 |
}
|
561 |
return $_cachedPermissions;
|
562 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
563 |
}
|
564 |
|
565 |
if (!defined('WFWAF_LOG_PATH')) {
|
@@ -571,17 +656,7 @@ if (!defined('WFWAF_LOG_PATH')) {
|
|
571 |
if (!is_dir(WFWAF_LOG_PATH)) {
|
572 |
@mkdir(WFWAF_LOG_PATH, (wfWAFWordPress::permissions() | 0755));
|
573 |
@chmod(WFWAF_LOG_PATH, (wfWAFWordPress::permissions() | 0755));
|
574 |
-
|
575 |
-
<IfModule mod_authz_core.c>
|
576 |
-
Require all denied
|
577 |
-
</IfModule>
|
578 |
-
<IfModule !mod_authz_core.c>
|
579 |
-
Order deny,allow
|
580 |
-
Deny from all
|
581 |
-
</IfModule>
|
582 |
-
APACHE
|
583 |
-
);
|
584 |
-
@chmod(rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess', (wfWAFWordPress::permissions() | 0444));
|
585 |
}
|
586 |
|
587 |
wfWAF::setSharedStorageEngine(new wfWAFStorageFile(WFWAF_LOG_PATH . 'attack-data.php', WFWAF_LOG_PATH . 'ips.php', WFWAF_LOG_PATH . 'config.php', WFWAF_LOG_PATH . 'wafRules.rules'));
|
512 |
|
513 |
public function uninstall() {
|
514 |
parent::uninstall();
|
515 |
+
@unlink(rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess');
|
516 |
+
@unlink(rtrim(WFWAF_LOG_PATH, '/') . '/template.php');
|
517 |
+
@unlink(rtrim(WFWAF_LOG_PATH, '/') . '/GeoLite2-Country.mmdb');
|
518 |
+
|
519 |
+
self::_recursivelyRemoveWflogs(''); //Removes any remaining files and the directory itself
|
520 |
+
}
|
521 |
+
|
522 |
+
/**
|
523 |
+
* Removes a path within wflogs, recursing as necessary.
|
524 |
+
*
|
525 |
+
* @param string $file
|
526 |
+
* @param array $processedDirs
|
527 |
+
* @return array The list of removed files/folders.
|
528 |
+
*/
|
529 |
+
private static function _recursivelyRemoveWflogs($file, $processedDirs = array()) {
|
530 |
+
if (preg_match('~(?:^|/|\\\\)\.\.(?:/|\\\\|$)~', $file)) {
|
531 |
+
return array();
|
532 |
+
}
|
533 |
+
|
534 |
+
if (stripos(WFWAF_LOG_PATH, 'wflogs') === false) { //Sanity check -- if not in a wflogs folder, user will have to do removal manually
|
535 |
+
return array();
|
536 |
+
}
|
537 |
+
|
538 |
+
$path = rtrim(WFWAF_LOG_PATH, '/') . '/' . $file;
|
539 |
+
if (is_link($path)) {
|
540 |
+
if (@unlink($path)) {
|
541 |
+
return array($file);
|
542 |
+
}
|
543 |
+
return array();
|
544 |
+
}
|
545 |
+
|
546 |
+
if (is_dir($path)) {
|
547 |
+
$real = realpath($file);
|
548 |
+
if (in_array($real, $processedDirs)) {
|
549 |
+
return array();
|
550 |
+
}
|
551 |
+
$processedDirs[] = $real;
|
552 |
+
|
553 |
+
$count = 0;
|
554 |
+
$dir = opendir($path);
|
555 |
+
if ($dir) {
|
556 |
+
$contents = array();
|
557 |
+
while ($sub = readdir($dir)) {
|
558 |
+
if ($sub == '.' || $sub == '..') { continue; }
|
559 |
+
$contents[] = $sub;
|
560 |
+
}
|
561 |
+
closedir($dir);
|
562 |
+
|
563 |
+
$filesRemoved = array();
|
564 |
+
foreach ($contents as $f) {
|
565 |
+
$removed = self::_recursivelyRemoveWflogs($file . '/' . $f, $processedDirs);
|
566 |
+
$filesRemoved = array($filesRemoved, $removed);
|
567 |
+
}
|
568 |
+
}
|
569 |
+
|
570 |
+
if (@rmdir($path)) {
|
571 |
+
$filesRemoved[] = $file;
|
572 |
+
}
|
573 |
+
return $filesRemoved;
|
574 |
+
}
|
575 |
+
|
576 |
+
if (@unlink($path)) {
|
577 |
+
return array($file);
|
578 |
+
}
|
579 |
+
return array();
|
580 |
+
}
|
581 |
+
|
582 |
+
public function fileList() {
|
583 |
+
$fileList = parent::fileList();
|
584 |
+
$fileList[] = rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess';
|
585 |
+
$fileList[] = rtrim(WFWAF_LOG_PATH, '/') . '/template.php';
|
586 |
+
$fileList[] = rtrim(WFWAF_LOG_PATH, '/') . '/GeoLite2-Country.mmdb';
|
587 |
+
return $fileList;
|
588 |
}
|
589 |
|
590 |
/**
|
631 |
}
|
632 |
return $_cachedPermissions;
|
633 |
}
|
634 |
+
|
635 |
+
public static function writeHtaccess() {
|
636 |
+
@file_put_contents(rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess', <<<APACHE
|
637 |
+
<IfModule mod_authz_core.c>
|
638 |
+
Require all denied
|
639 |
+
</IfModule>
|
640 |
+
<IfModule !mod_authz_core.c>
|
641 |
+
Order deny,allow
|
642 |
+
Deny from all
|
643 |
+
</IfModule>
|
644 |
+
APACHE
|
645 |
+
);
|
646 |
+
@chmod(rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess', (wfWAFWordPress::permissions() | 0444));
|
647 |
+
}
|
648 |
}
|
649 |
|
650 |
if (!defined('WFWAF_LOG_PATH')) {
|
656 |
if (!is_dir(WFWAF_LOG_PATH)) {
|
657 |
@mkdir(WFWAF_LOG_PATH, (wfWAFWordPress::permissions() | 0755));
|
658 |
@chmod(WFWAF_LOG_PATH, (wfWAFWordPress::permissions() | 0755));
|
659 |
+
wfWAFWordPress::writeHtaccess();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
660 |
}
|
661 |
|
662 |
wfWAF::setSharedStorageEngine(new wfWAFStorageFile(WFWAF_LOG_PATH . 'attack-data.php', WFWAF_LOG_PATH . 'ips.php', WFWAF_LOG_PATH . 'config.php', WFWAF_LOG_PATH . 'wafRules.rules'));
|
wordfence.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Wordfence Security
|
|
4 |
Plugin URI: http://www.wordfence.com/
|
5 |
Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
|
6 |
Author: Wordfence
|
7 |
-
Version: 7.1.
|
8 |
Author URI: http://www.wordfence.com/
|
9 |
Network: true
|
10 |
*/
|
@@ -14,8 +14,8 @@ if(defined('WP_INSTALLING') && WP_INSTALLING){
|
|
14 |
if (!defined('ABSPATH')) {
|
15 |
exit;
|
16 |
}
|
17 |
-
define('WORDFENCE_VERSION', '7.1.
|
18 |
-
define('WORDFENCE_BUILD_NUMBER', '
|
19 |
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
|
20 |
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
|
21 |
|
4 |
Plugin URI: http://www.wordfence.com/
|
5 |
Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
|
6 |
Author: Wordfence
|
7 |
+
Version: 7.1.17
|
8 |
Author URI: http://www.wordfence.com/
|
9 |
Network: true
|
10 |
*/
|
14 |
if (!defined('ABSPATH')) {
|
15 |
exit;
|
16 |
}
|
17 |
+
define('WORDFENCE_VERSION', '7.1.17');
|
18 |
+
define('WORDFENCE_BUILD_NUMBER', '1541524007');
|
19 |
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
|
20 |
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
|
21 |
|