Wordfence Security – Firewall & Malware Scan - Version 7.3.4

Version Description

  • June 17, 2019 =
  • Improvement: Added security events and alerting features built into Wordfence Central.
Download this release

Release Info

Developer wfmatt
Plugin Icon 128x128 Wordfence Security – Firewall & Malware Scan
Version 7.3.4
Comparing to
See all releases

Code changes from version 7.3.3 to 7.3.4

Files changed (64) hide show
  1. css/{activity-report-widget.1560275180.css → activity-report-widget.1560795818.css} +0 -0
  2. css/{diff.1560275180.css → diff.1560795818.css} +0 -0
  3. css/{dt_table.1560275180.css → dt_table.1560795818.css} +0 -0
  4. css/{fullLog.1560275180.css → fullLog.1560795818.css} +0 -0
  5. css/{iptraf.1560275180.css → iptraf.1560795818.css} +0 -0
  6. css/{jquery-ui-timepicker-addon.1560275180.css → jquery-ui-timepicker-addon.1560795818.css} +0 -0
  7. css/{jquery-ui.min.1560275180.css → jquery-ui.min.1560795818.css} +0 -0
  8. css/{jquery-ui.structure.min.1560275180.css → jquery-ui.structure.min.1560795818.css} +0 -0
  9. css/{jquery-ui.theme.min.1560275180.css → jquery-ui.theme.min.1560795818.css} +0 -0
  10. css/{main.1560275180.css → main.1560795818.css} +0 -0
  11. css/{phpinfo.1560275180.css → phpinfo.1560795818.css} +0 -0
  12. css/{wf-adminbar.1560275180.css → wf-adminbar.1560795818.css} +0 -0
  13. css/{wf-colorbox.1560275180.css → wf-colorbox.1560795818.css} +0 -0
  14. css/{wf-font-awesome.1560275180.css → wf-font-awesome.1560795818.css} +0 -0
  15. css/{wf-global.1560275180.css → wf-global.1560795818.css} +0 -0
  16. css/{wf-ionicons.1560275180.css → wf-ionicons.1560795818.css} +0 -0
  17. css/{wf-onboarding.1560275180.css → wf-onboarding.1560795818.css} +0 -0
  18. css/{wf-roboto-font.1560275180.css → wf-roboto-font.1560795818.css} +0 -0
  19. css/{wfselect2.min.1560275180.css → wfselect2.min.1560795818.css} +0 -0
  20. css/{wordfenceBox.1560275180.css → wordfenceBox.1560795818.css} +0 -0
  21. js/{Chart.bundle.min.1560275180.js → Chart.bundle.min.1560795818.js} +0 -0
  22. js/{admin.1560275180.js → admin.1560795818.js} +0 -0
  23. js/{admin.ajaxWatcher.1560275180.js → admin.ajaxWatcher.1560795818.js} +0 -0
  24. js/{admin.liveTraffic.1560275180.js → admin.liveTraffic.1560795818.js} +0 -0
  25. js/{date.1560275180.js → date.1560795818.js} +0 -0
  26. js/{jquery-ui-timepicker-addon.1560275180.js → jquery-ui-timepicker-addon.1560795818.js} +0 -0
  27. js/{jquery.colorbox-min.1560275180.js → jquery.colorbox-min.1560795818.js} +0 -0
  28. js/{jquery.colorbox.1560275180.js → jquery.colorbox.1560795818.js} +0 -0
  29. js/{jquery.dataTables.min.1560275180.js → jquery.dataTables.min.1560795818.js} +0 -0
  30. js/{jquery.qrcode.min.1560275180.js → jquery.qrcode.min.1560795818.js} +0 -0
  31. js/{jquery.tmpl.min.1560275180.js → jquery.tmpl.min.1560795818.js} +0 -0
  32. js/{jquery.tools.min.1560275180.js → jquery.tools.min.1560795818.js} +0 -0
  33. js/{knockout-3.3.0.1560275180.js → knockout-3.3.0.1560795818.js} +0 -0
  34. js/{wfdashboard.1560275180.js → wfdashboard.1560795818.js} +0 -0
  35. js/{wfdropdown.1560275180.js → wfdropdown.1560795818.js} +0 -0
  36. js/{wfglobal.1560275180.js → wfglobal.1560795818.js} +0 -0
  37. js/{wfpopover.1560275180.js → wfpopover.1560795818.js} +0 -0
  38. js/{wfselect2.min.1560275180.js → wfselect2.min.1560795818.js} +0 -0
  39. lib/wfAlerts.php +258 -0
  40. lib/wfCentralAPI.php +55 -1
  41. lib/wfConfig.php +17 -8
  42. lib/wfLog.php +25 -12
  43. lib/wordfenceClass.php +68 -41
  44. modules/login-security/css/{admin-global.1560275180.css → admin-global.1560795818.css} +0 -0
  45. modules/login-security/css/{admin.1560275180.css → admin.1560795818.css} +0 -0
  46. modules/login-security/css/{colorbox.1560275180.css → colorbox.1560795818.css} +0 -0
  47. modules/login-security/css/{font-awesome.1560275180.css → font-awesome.1560795818.css} +0 -0
  48. modules/login-security/css/{ionicons.1560275180.css → ionicons.1560795818.css} +0 -0
  49. modules/login-security/css/{jquery-ui-timepicker-addon.1560275180.css → jquery-ui-timepicker-addon.1560795818.css} +0 -0
  50. modules/login-security/css/{jquery-ui.min.1560275180.css → jquery-ui.min.1560795818.css} +0 -0
  51. modules/login-security/css/{jquery-ui.structure.min.1560275180.css → jquery-ui.structure.min.1560795818.css} +0 -0
  52. modules/login-security/css/{jquery-ui.theme.min.1560275180.css → jquery-ui.theme.min.1560795818.css} +0 -0
  53. modules/login-security/css/{login.1560275180.css → login.1560795818.css} +0 -0
  54. modules/login-security/js/{admin-global.1560275180.js → admin-global.1560795818.js} +0 -0
  55. modules/login-security/js/{admin.1560275180.js → admin.1560795818.js} +0 -0
  56. modules/login-security/js/{jquery-ui-timepicker-addon.1560275180.js → jquery-ui-timepicker-addon.1560795818.js} +0 -0
  57. modules/login-security/js/{jquery.colorbox.1560275180.js → jquery.colorbox.1560795818.js} +0 -0
  58. modules/login-security/js/{jquery.colorbox.min.1560275180.js → jquery.colorbox.min.1560795818.js} +0 -0
  59. modules/login-security/js/{jquery.qrcode.min.1560275180.js → jquery.qrcode.min.1560795818.js} +0 -0
  60. modules/login-security/js/{jquery.tmpl.min.1560275180.js → jquery.tmpl.min.1560795818.js} +0 -0
  61. modules/login-security/js/{login.1560275180.js → login.1560795818.js} +0 -0
  62. modules/login-security/wordfence-login-security.php +1 -1
  63. readme.txt +6 -1
  64. wordfence.php +3 -3
css/{activity-report-widget.1560275180.css → activity-report-widget.1560795818.css} RENAMED
File without changes
css/{diff.1560275180.css → diff.1560795818.css} RENAMED
File without changes
css/{dt_table.1560275180.css → dt_table.1560795818.css} RENAMED
File without changes
css/{fullLog.1560275180.css → fullLog.1560795818.css} RENAMED
File without changes
css/{iptraf.1560275180.css → iptraf.1560795818.css} RENAMED
File without changes
css/{jquery-ui-timepicker-addon.1560275180.css → jquery-ui-timepicker-addon.1560795818.css} RENAMED
File without changes
css/{jquery-ui.min.1560275180.css → jquery-ui.min.1560795818.css} RENAMED
File without changes
css/{jquery-ui.structure.min.1560275180.css → jquery-ui.structure.min.1560795818.css} RENAMED
File without changes
css/{jquery-ui.theme.min.1560275180.css → jquery-ui.theme.min.1560795818.css} RENAMED
File without changes
css/{main.1560275180.css → main.1560795818.css} RENAMED
File without changes
css/{phpinfo.1560275180.css → phpinfo.1560795818.css} RENAMED
File without changes
css/{wf-adminbar.1560275180.css → wf-adminbar.1560795818.css} RENAMED
File without changes
css/{wf-colorbox.1560275180.css → wf-colorbox.1560795818.css} RENAMED
File without changes
css/{wf-font-awesome.1560275180.css → wf-font-awesome.1560795818.css} RENAMED
File without changes
css/{wf-global.1560275180.css → wf-global.1560795818.css} RENAMED
File without changes
css/{wf-ionicons.1560275180.css → wf-ionicons.1560795818.css} RENAMED
File without changes
css/{wf-onboarding.1560275180.css → wf-onboarding.1560795818.css} RENAMED
File without changes
css/{wf-roboto-font.1560275180.css → wf-roboto-font.1560795818.css} RENAMED
File without changes
css/{wfselect2.min.1560275180.css → wfselect2.min.1560795818.css} RENAMED
File without changes
css/{wordfenceBox.1560275180.css → wordfenceBox.1560795818.css} RENAMED
File without changes
js/{Chart.bundle.min.1560275180.js → Chart.bundle.min.1560795818.js} RENAMED
File without changes
js/{admin.1560275180.js → admin.1560795818.js} RENAMED
File without changes
js/{admin.ajaxWatcher.1560275180.js → admin.ajaxWatcher.1560795818.js} RENAMED
File without changes
js/{admin.liveTraffic.1560275180.js → admin.liveTraffic.1560795818.js} RENAMED
File without changes
js/{date.1560275180.js → date.1560795818.js} RENAMED
File without changes
js/{jquery-ui-timepicker-addon.1560275180.js → jquery-ui-timepicker-addon.1560795818.js} RENAMED
File without changes
js/{jquery.colorbox-min.1560275180.js → jquery.colorbox-min.1560795818.js} RENAMED
File without changes
js/{jquery.colorbox.1560275180.js → jquery.colorbox.1560795818.js} RENAMED
File without changes
js/{jquery.dataTables.min.1560275180.js → jquery.dataTables.min.1560795818.js} RENAMED
File without changes
js/{jquery.qrcode.min.1560275180.js → jquery.qrcode.min.1560795818.js} RENAMED
File without changes
js/{jquery.tmpl.min.1560275180.js → jquery.tmpl.min.1560795818.js} RENAMED
File without changes
js/{jquery.tools.min.1560275180.js → jquery.tools.min.1560795818.js} RENAMED
File without changes
js/{knockout-3.3.0.1560275180.js → knockout-3.3.0.1560795818.js} RENAMED
File without changes
js/{wfdashboard.1560275180.js → wfdashboard.1560795818.js} RENAMED
File without changes
js/{wfdropdown.1560275180.js → wfdropdown.1560795818.js} RENAMED
File without changes
js/{wfglobal.1560275180.js → wfglobal.1560795818.js} RENAMED
File without changes
js/{wfpopover.1560275180.js → wfpopover.1560795818.js} RENAMED
File without changes
js/{wfselect2.min.1560275180.js → wfselect2.min.1560795818.js} RENAMED
File without changes
lib/wfAlerts.php ADDED
@@ -0,0 +1,258 @@
1
+ <?php
2
+
3
+ abstract class wfBaseAlert {
4
+
5
+ public abstract function send();
6
+ }
7
+
8
+ class wfBlockAlert extends wfBaseAlert {
9
+
10
+ private $IP;
11
+ private $reason;
12
+ private $secsToGo;
13
+
14
+
15
+ /**
16
+ * wfBlockAlert constructor.
17
+ * @param $IP
18
+ * @param $reason
19
+ * @param $secsToGo
20
+ */
21
+ public function __construct($IP, $reason, $secsToGo) {
22
+ $this->IP = $IP;
23
+ $this->reason = $reason;
24
+ $this->secsToGo = $secsToGo;
25
+ }
26
+
27
+ public function send() {
28
+ if (wfConfig::get('alertOn_block')) {
29
+ $message = sprintf(__('Wordfence has blocked IP address %s.', 'wordfence'), $this->IP) . "\n";
30
+ $message .= sprintf(__('The reason is: "%s".', 'wordfence'), $this->reason);
31
+ if ($this->secsToGo > 0) {
32
+ $message .= "\n" . sprintf(__('The duration of the block is %s.', 'wordfence'), wfUtils::makeDuration($this->secsToGo, true));
33
+ }
34
+ wordfence::alert(sprintf(__('Blocking IP %s', 'wordfence'), $this->IP), $message, $this->IP);
35
+ }
36
+ }
37
+
38
+ }
39
+
40
+ class wfAutoUpdatedAlert extends wfBaseAlert {
41
+
42
+ private $version;
43
+
44
+ /**
45
+ * @param $version
46
+ */
47
+ public function __construct($version) {
48
+ $this->version = $version;
49
+ }
50
+
51
+ public function send() {
52
+ if (wfConfig::get('alertOn_update') == '1' && $this->version) {
53
+ wordfence::alert("Wordfence Upgraded to version " . $this->version, "Your Wordfence installation has been upgraded to version " . $this->version, '127.0.0.1');
54
+ }
55
+ }
56
+
57
+ }
58
+
59
+ class wfWafDeactivatedAlert extends wfBaseAlert {
60
+
61
+ private $username;
62
+ private $IP;
63
+
64
+ /**
65
+ * @param $username
66
+ * @param $IP
67
+ */
68
+ public function __construct($username, $IP) {
69
+ $this->username = $username;
70
+ $this->IP = $IP;
71
+ }
72
+
73
+ public function send() {
74
+ if (wfConfig::get('alertOn_wafDeactivated')) {
75
+ wordfence::alert(__('Wordfence WAF Deactivated', 'wordfence'), sprintf(__('A user with username "%s" deactivated the Wordfence Web Application Firewall on your WordPress site.', 'wordfence'), $this->username), $this->IP);
76
+ }
77
+ }
78
+
79
+ }
80
+
81
+ class wfWordfenceDeactivatedAlert extends wfBaseAlert {
82
+ private $username;
83
+ private $IP;
84
+
85
+ /**
86
+ * @param $username
87
+ * @param $IP
88
+ */
89
+ public function __construct($username, $IP) {
90
+ $this->username = $username;
91
+ $this->IP = $IP;
92
+ }
93
+
94
+ public function send() {
95
+ if (wfConfig::get('alertOn_wordfenceDeactivated')) {
96
+ wordfence::alert("Wordfence Deactivated", "A user with username \"$this->username\" deactivated Wordfence on your WordPress site.", $this->IP);
97
+ }
98
+ }
99
+
100
+ }
101
+
102
+ class wfLostPasswdFormAlert extends wfBaseAlert {
103
+
104
+ private $user;
105
+ private $IP;
106
+
107
+ /**
108
+ * @param $user
109
+ * @param $IP
110
+ */
111
+ public function __construct($user, $IP) {
112
+ $this->user = $user;
113
+ $this->IP = $IP;
114
+ }
115
+
116
+ public function send() {
117
+ if (wfConfig::get('alertOn_lostPasswdForm')) {
118
+ wordfence::alert("Password recovery attempted", "Someone tried to recover the password for user with email address: " . wp_kses($this->user->user_email, array()), $this->IP);
119
+ }
120
+ }
121
+
122
+ }
123
+
124
+ class wfLoginLockoutAlert extends wfBaseAlert {
125
+
126
+ private $IP;
127
+ private $reason;
128
+
129
+ /**
130
+ * @param $IP
131
+ * @param $reason
132
+ */
133
+ public function __construct($IP, $reason) {
134
+ $this->IP = $IP;
135
+ $this->reason = $reason;
136
+ }
137
+
138
+ public function send() {
139
+ if (wfConfig::get('alertOn_loginLockout')) {
140
+ $message = sprintf(__('A user with IP addr %s has been locked out from signing in or using the password recovery form for the following reason: %s.', 'wordfence'), $this->IP, $this->reason);
141
+ if (wfBlock::lockoutDuration() > 0) {
142
+ $message .= "\n" . sprintf(__('The duration of the lockout is %s.', 'wordfence'), wfUtils::makeDuration(wfBlock::lockoutDuration(), true));
143
+ }
144
+ wordfence::alert(__('User locked out from signing in', 'wordfence'), $message, $this->IP);
145
+ }
146
+ }
147
+ }
148
+
149
+ class wfAdminLoginAlert extends wfBaseAlert {
150
+
151
+ private $cookieName;
152
+ private $username;
153
+ private $IP;
154
+ private $cookieValue;
155
+
156
+ /**
157
+ * @param $cookieName
158
+ * @param $cookieValue
159
+ * @param $username
160
+ * @param $IP
161
+ */
162
+ public function __construct($cookieName, $cookieValue, $username, $IP) {
163
+ $this->cookieName = $cookieName;
164
+ $this->cookieValue = $cookieValue;
165
+ $this->username = $username;
166
+ $this->IP = $IP;
167
+ }
168
+
169
+ public function send() {
170
+ if (wfConfig::get('alertOn_adminLogin')) {
171
+ $shouldAlert = true;
172
+ if (wfConfig::get('alertOn_firstAdminLoginOnly') && isset($_COOKIE[$this->cookieName])) {
173
+ $shouldAlert = !hash_equals($this->cookieValue, $_COOKIE[$this->cookieName]);
174
+ }
175
+
176
+ if ($shouldAlert) {
177
+ wordfence::alert("Admin Login", "A user with username \"$this->username\" who has administrator access signed in to your WordPress site.", $this->IP);
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+ class wfNonAdminLoginAlert extends wfBaseAlert {
184
+
185
+ private $cookieName;
186
+ private $username;
187
+ private $IP;
188
+ private $cookieValue;
189
+
190
+ /**
191
+ * @param $cookieName
192
+ * @param $cookieValue
193
+ * @param $username
194
+ * @param $IP
195
+ */
196
+ public function __construct($cookieName, $cookieValue, $username, $IP) {
197
+ $this->cookieName = $cookieName;
198
+ $this->cookieValue = $cookieValue;
199
+ $this->username = $username;
200
+ $this->IP = $IP;
201
+ }
202
+
203
+ public function send() {
204
+ if (wfConfig::get('alertOn_nonAdminLogin')) {
205
+ $shouldAlert = true;
206
+ if (wfConfig::get('alertOn_firstNonAdminLoginOnly') && isset($_COOKIE[$this->cookieName])) {
207
+ $shouldAlert = !hash_equals($this->cookieValue, $_COOKIE[$this->cookieName]);
208
+ }
209
+
210
+ if ($shouldAlert) {
211
+ wordfence::alert("User login", "A non-admin user with username \"$this->username\" signed in to your WordPress site.", $this->IP);
212
+ }
213
+ }
214
+ }
215
+ }
216
+
217
+ class wfBreachLoginAlert extends wfBaseAlert {
218
+
219
+ private $username;
220
+ private $lostPasswordUrl;
221
+ private $supportUrl;
222
+ private $IP;
223
+
224
+ /**
225
+ * @param $username
226
+ * @param $lostPasswordUrl
227
+ * @param $supportUrl
228
+ * @param $IP
229
+ */
230
+ public function __construct($username, $lostPasswordUrl, $supportUrl, $IP) {
231
+ $this->username = $username;
232
+ $this->lostPasswordUrl = $lostPasswordUrl;
233
+ $this->supportUrl = $supportUrl;
234
+ $this->IP = $IP;
235
+ }
236
+
237
+ public function send() {
238
+ if (wfConfig::get('alertOn_breachLogin')) {
239
+ wordfence::alert(__('User login blocked for insecure password', 'wordfence'), sprintf(__('A user with username "%s" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%s) to reactivate this account. Learn More: %s', 'wordfence'), $this->username, $this->lostPasswordUrl, $this->supportUrl), $this->IP);
240
+ }
241
+ }
242
+ }
243
+
244
+ class wfIncreasedAttackRateAlert extends wfBaseAlert {
245
+
246
+ private $message;
247
+
248
+ /**
249
+ * @param $message
250
+ */
251
+ public function __construct($message) {
252
+ $this->message = $message;
253
+ }
254
+
255
+ public function send() {
256
+ wordfence::alert('Increased Attack Rate', $this->message, false);
257
+ }
258
+ }
lib/wfCentralAPI.php CHANGED
@@ -47,7 +47,6 @@ class wfCentralAPIRequest {
47
if (empty($args['headers'])) {
48
$args['headers'] = array();
49
}
50
- $args['cookies']['XDEBUG_SESSION'] = 'XDEBUG_ECLIPSE';
51
52
$token = $this->getToken();
53
if ($token) {
@@ -501,4 +500,59 @@ class wfCentral {
501
}
502
return false;
503
}
504
}
47
if (empty($args['headers'])) {
48
$args['headers'] = array();
49
}
50
51
$token = $this->getToken();
52
if ($token) {
500
}
501
return false;
502
}
503
+
504
+ /**
505
+ * @param string $event
506
+ * @param array $data
507
+ * @param callable|null $alertCallback
508
+ */
509
+ public static function sendSecurityEvent($event, $data = array(), $alertCallback = null) {
510
+ $alerted = false;
511
+ if (!self::pluginAlertingDisabled() && is_callable($alertCallback)) {
512
+ call_user_func($alertCallback);
513
+ $alerted = true;
514
+ }
515
+
516
+ $siteID = wfConfig::get('wordfenceCentralSiteID');
517
+ $request = new wfCentralAuthenticatedAPIRequest('/site/' . $siteID . '/security-events', 'POST', array(
518
+ 'data' => array(
519
+ array(
520
+ 'type' => 'security-event',
521
+ 'attributes' => array(
522
+ 'type' => $event,
523
+ 'data' => $data,
524
+ 'event_time' => microtime(true),
525
+ ),
526
+ ),
527
+ ),
528
+ ));
529
+ try {
530
+ // Attempt to send the security event to Central.
531
+ $response = $request->execute();
532
+ } catch (wfCentralAPIException $e) {
533
+ // If we didn't alert previously, notify the user now in the event Central is down.
534
+ if (!$alerted && is_callable($alertCallback)) {
535
+ call_user_func($alertCallback);
536
+ }
537
+ }
538
+ }
539
+
540
+ /**
541
+ * @param $event
542
+ * @param array $data
543
+ * @param callable|null $alertCallback
544
+ */
545
+ public static function sendAlertCallback($event, $data = array(), $alertCallback = null) {
546
+ if (is_callable($alertCallback)) {
547
+ call_user_func($alertCallback);
548
+ }
549
+ }
550
+
551
+ public static function pluginAlertingDisabled() {
552
+ if (!self::isConnected()) {
553
+ return false;
554
+ }
555
+
556
+ return wfConfig::get('wordfenceCentralPluginAlertingDisabled', false);
557
+ }
558
}
lib/wfConfig.php CHANGED
@@ -231,6 +231,7 @@ class wfConfig {
231
private static $wfCentralInternalConfig = array(
232
'wordfenceCentralUserSiteAuthGrant',
233
'wordfenceCentralConnected',
234
);
235
236
public static function setDefaults() {
@@ -989,9 +990,14 @@ class wfConfig {
989
$upret = $upgrader->upgrade(WORDFENCE_BASENAME);
990
if($upret){
991
$cont = file_get_contents(WORDFENCE_FCPATH);
992
- if(wfConfig::get('alertOn_update') == '1' && preg_match('/Version: (\d+\.\d+\.\d+)/', $cont, $matches) ){
993
- wordfence::alert("Wordfence Upgraded to version " . $matches[1], "Your Wordfence installation has been upgraded to version " . $matches[1], '127.0.0.1');
994
- }
995
wfConfig::set('autoUpdateAttempts', 0);
996
}
997
$output = @ob_get_contents();
@@ -1328,11 +1334,14 @@ Options -ExecCGI
1328
$firewall->syncStatus(true);
1329
1330
if ($value == wfFirewall::FIREWALL_MODE_DISABLED) {
1331
- if (wfConfig::get('alertOn_wafDeactivated')) {
1332
- $currentUser = wp_get_current_user();
1333
- $username = $currentUser->user_login;
1334
- wordfence::alert(__('Wordfence WAF Deactivated', 'wordfence'), sprintf(__('A user with username "%s" deactivated the Wordfence Web Application Firewall on your WordPress site.', 'wordfence'), $username), wfUtils::getIP());
1335
- }
1336
}
1337
1338
$saved = true;
231
private static $wfCentralInternalConfig = array(
232
'wordfenceCentralUserSiteAuthGrant',
233
'wordfenceCentralConnected',
234
+ 'wordfenceCentralPluginAlertingDisabled',
235
);
236
237
public static function setDefaults() {
990
$upret = $upgrader->upgrade(WORDFENCE_BASENAME);
991
if($upret){
992
$cont = file_get_contents(WORDFENCE_FCPATH);
993
+ preg_match('/Version: (\d+\.\d+\.\d+)/', $cont, $matches);
994
+ $version = !empty($matches) ? $matches[1] : null;
995
+ $alertCallback = array(new wfAutoUpdatedAlert($version), 'send');
996
+ do_action('wordfence_security_event', 'autoUpdate', array(
997
+ 'version' => $version,
998
+ 'ip' => wfUtils::getIP(),
999
+ ), $alertCallback);
1000
+
1001
wfConfig::set('autoUpdateAttempts', 0);
1002
}
1003
$output = @ob_get_contents();
1334
$firewall->syncStatus(true);
1335
1336
if ($value == wfFirewall::FIREWALL_MODE_DISABLED) {
1337
+ $currentUser = wp_get_current_user();
1338
+ $username = $currentUser->user_login;
1339
+
1340
+ $alertCallback = array(new wfWafDeactivatedAlert($username, wfUtils::getIP()), 'send');
1341
+ do_action('wordfence_security_event', 'wafDeactivated', array(
1342
+ 'username' => $username,
1343
+ 'ip' => wfUtils::getIP(),
1344
+ ), $alertCallback);
1345
}
1346
1347
$saved = true;
lib/wfLog.php CHANGED
@@ -632,26 +632,30 @@ class wfLog {
632
wfBlock::createRateBlock($reason, $IP, $secsToGo);
633
wfActivityReport::logBlockedIP($IP, null, 'throttle');
634
$this->tagRequestForBlock($reason);
635
-
636
- if (wfConfig::get('alertOn_block')) {
637
- $message = sprintf(__('Wordfence has blocked IP address %s.', 'wordfence'), $IP) . "\n";
638
- $message .= sprintf(__('The reason is: "%s".', 'wordfence'), $reason);
639
- if ($secsToGo > 0) {
640
- $message .= "\n" . sprintf(__('The duration of the block is %s.', 'wordfence'), wfUtils::makeDuration($secsToGo, true));
641
- }
642
- wordfence::alert(sprintf(__('Blocking IP %s', 'wordfence'), $IP), $message, $IP);
643
- }
644
wordfence::status(2, 'info', sprintf(__('Blocking IP %s. %s', 'wordfence'), $IP, $reason));
645
}
646
else if ($action == 'throttle') { //Rate limited - throttle
647
$secsToGo = wfBlock::rateLimitThrottleDuration();
648
wfBlock::createRateThrottle($reason, $IP, $secsToGo);
649
wfActivityReport::logBlockedIP($IP, null, 'throttle');
650
-
651
wordfence::status(2, 'info', sprintf(__('Throttling IP %s. %s', 'wordfence'), $IP, $reason));
652
wfConfig::inc('totalIPsThrottled');
653
}
654
- $this->do503($secsToGo, $reason);
655
}
656
657
return;
@@ -669,8 +673,17 @@ class wfLog {
669
return false;
670
}
671
672
- public function do503($secsToGo, $reason){
673
$this->initLogRequest();
674
$this->currentRequest->statusCode = 503;
675
if (!$this->currentRequest->action) {
676
$this->currentRequest->action = 'blocked:wordfence';
632
wfBlock::createRateBlock($reason, $IP, $secsToGo);
633
wfActivityReport::logBlockedIP($IP, null, 'throttle');
634
$this->tagRequestForBlock($reason);
635
+
636
+ $alertCallback = array(new wfBlockAlert($IP, $reason, $secsToGo), 'send');
637
+
638
+ do_action('wordfence_security_event', 'block', array(
639
+ 'ip' => $IP,
640
+ 'reason' => $reason,
641
+ 'duration' => $secsToGo,
642
+ ), $alertCallback);
643
wordfence::status(2, 'info', sprintf(__('Blocking IP %s. %s', 'wordfence'), $IP, $reason));
644
}
645
else if ($action == 'throttle') { //Rate limited - throttle
646
$secsToGo = wfBlock::rateLimitThrottleDuration();
647
wfBlock::createRateThrottle($reason, $IP, $secsToGo);
648
wfActivityReport::logBlockedIP($IP, null, 'throttle');
649
+
650
+ do_action('wordfence_security_event', 'throttle', array(
651
+ 'ip' => $IP,
652
+ 'reason' => $reason,
653
+ 'duration' => $secsToGo,
654
+ ));
655
wordfence::status(2, 'info', sprintf(__('Throttling IP %s. %s', 'wordfence'), $IP, $reason));
656
wfConfig::inc('totalIPsThrottled');
657
}
658
+ $this->do503($secsToGo, $reason, false);
659
}
660
661
return;
673
return false;
674
}
675
676
+ public function do503($secsToGo, $reason, $sendEventToCentral = true){
677
$this->initLogRequest();
678
+
679
+ if ($sendEventToCentral) {
680
+ do_action('wordfence_security_event', 'block', array(
681
+ 'ip' => wfUtils::inet_ntop($this->currentRequest->IP),
682
+ 'reason' => $this->currentRequest->actionDescription ? $this->currentRequest->actionDescription : $reason,
683
+ 'duration' => $secsToGo,
684
+ ));
685
+ }
686
+
687
$this->currentRequest->statusCode = 503;
688
if (!$this->currentRequest->action) {
689
$this->currentRequest->action = 'blocked:wordfence';
lib/wordfenceClass.php CHANGED
@@ -41,6 +41,7 @@ require_once(dirname(__FILE__) . '/wfVersionCheckController.php');
41
require_once(dirname(__FILE__) . '/wfDateLocalization.php');
42
require_once(dirname(__FILE__) . '/wfAdminNoticeQueue.php');
43
require_once(dirname(__FILE__) . '/wfModuleController.php');
44
45
if (version_compare(phpversion(), '5.3', '>=')) {
46
require_once(dirname(__FILE__) . '/WFLSPHP52Compatability.php');
@@ -95,11 +96,13 @@ class wordfence {
95
}
96
public static function uninstallPlugin(){
97
//Send admin alert
98
- if (wfConfig::get('alertOn_wordfenceDeactivated')) {
99
- $currentUser = wp_get_current_user();
100
- $username = $currentUser->user_login;
101
- wordfence::alert("Wordfence Deactivated", "A user with username \"$username\" deactivated Wordfence on your WordPress site.", wfUtils::getIP());
102
- }
103
104
//Check if caching is enabled and if it is, disable it and fix the .htaccess file.
105
wfCache::removeCaching();
@@ -1310,6 +1313,11 @@ SQL
1310
1311
add_action('rest_api_init', 'wordfence::initRestAPI');
1312
1313
}
1314
public static function _pluginPageActionLinks($links) {
1315
if (!wfConfig::get('isPaid')) {
@@ -1664,9 +1672,12 @@ SQL
1664
}
1665
1666
if($user){
1667
- if(wfConfig::get('alertOn_lostPasswdForm')){
1668
- wordfence::alert("Password recovery attempted", "Someone tried to recover the password for user with email address: " . wp_kses($user->user_email, array()), $IP);
1669
- }
1670
}
1671
if(wfConfig::get('loginSecurityEnabled')){
1672
$tKey = 'wffgt_' . bin2hex(wfUtils::inet_pton($IP));
@@ -1687,13 +1698,13 @@ SQL
1687
public static function lockOutIP($IP, $reason) {
1688
wfBlock::createLockout($reason, $IP, wfBlock::lockoutDuration(), time(), time(), 1);
1689
self::getLog()->tagRequestForLockout($reason);
1690
- if (wfConfig::get('alertOn_loginLockout')) {
1691
- $message = sprintf(__('A user with IP addr %s has been locked out from signing in or using the password recovery form for the following reason: %s.', 'wordfence'), $IP, $reason);
1692
- if (wfBlock::lockoutDuration() > 0) {
1693
- $message .= "\n" . sprintf(__('The duration of the lockout is %s.', 'wordfence'), wfUtils::makeDuration(wfBlock::lockoutDuration(), true));
1694
- }
1695
- wordfence::alert(__('User locked out from signing in', 'wordfence'), $message, $IP);
1696
- }
1697
}
1698
1699
public static function veryFirstAction() {
@@ -2402,27 +2413,26 @@ SQL
2402
$cookiename = 'wf_loginalerted_' . hash_hmac('sha256', wfUtils::getIP() . '|' . $user->ID, $salt);
2403
$cookievalue = hash_hmac('sha256', $user->user_login, $salt);
2404
if(wfUtils::isAdmin($userID)){
2405
- if(wfConfig::get('alertOn_adminLogin')){
2406
- $shouldAlert = true;
2407
- if (wfConfig::get('alertOn_firstAdminLoginOnly') && isset($_COOKIE[$cookiename])) {
2408
- $shouldAlert = !hash_equals($cookievalue, $_COOKIE[$cookiename]);
2409
- }
2410
-
2411
- if ($shouldAlert) {
2412
- wordfence::alert("Admin Login", "A user with username \"$username\" who has administrator access signed in to your WordPress site.", wfUtils::getIP());
2413
- }
2414
}
2415
} else {
2416
- if(wfConfig::get('alertOn_nonAdminLogin')){
2417
- $shouldAlert = true;
2418
- if (wfConfig::get('alertOn_firstNonAdminLoginOnly') && isset($_COOKIE[$cookiename])) {
2419
- $shouldAlert = !hash_equals($cookievalue, $_COOKIE[$cookiename]);
2420
- }
2421
-
2422
- if ($shouldAlert) {
2423
- wordfence::alert("User login", "A non-admin user with username \"$username\" signed in to your WordPress site.", wfUtils::getIP());
2424
- }
2425
}
2426
}
2427
2428
if (wfConfig::get('alertOn_firstAdminLoginOnly') || wfConfig::get('alertOn_firstNonAdminLoginOnly')) {
@@ -2922,9 +2932,14 @@ SQL
2922
else {
2923
$username = $authUser->user_login;
2924
self::getLog()->logLogin('loginFailValidUsername', 1, $username);
2925
- if (wfConfig::get('alertOn_breachLogin')) {
2926
- wordfence::alert(__('User login blocked for insecure password', 'wordfence'), sprintf(__('A user with username "%s" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%s) to reactivate this account. Learn More: %s', 'wordfence'), $username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), wfUtils::getIP());
2927
- }
2928
2929
remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
2930
self::$authError = new WP_Error('breached_password', sprintf(__('<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">reset your password</a> to reactivate your account. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>'), wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
@@ -2951,10 +2966,15 @@ SQL
2951
else {
2952
$username = $authUser->user_login;
2953
self::getLog()->logLogin('loginFailValidUsername', 1, $username);
2954
- if (wfConfig::get('alertOn_breachLogin')) {
2955
- wordfence::alert(__('User login blocked for insecure password', 'wordfence'), sprintf(__('A user with username "%s" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%s) to reactivate this account. Learn More: %s', 'wordfence'), $username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), wfUtils::getIP());
2956
- }
2957
-
2958
remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
2959
self::$authError = new WP_Error('breached_password', sprintf(__('<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">reset your password</a> to reactivate your account. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>'), wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
2960
return self::$authError;
@@ -7875,7 +7895,14 @@ ALERTMSG;
7875
$message .= $date . $ip . $attackMessage . "\n";
7876
}
7877
7878
- self::alert('Increased Attack Rate', $message, false);
7879
wfConfig::set('wafAlertLastSendTime', time());
7880
}
7881
}
41
require_once(dirname(__FILE__) . '/wfDateLocalization.php');
42
require_once(dirname(__FILE__) . '/wfAdminNoticeQueue.php');
43
require_once(dirname(__FILE__) . '/wfModuleController.php');
44
+ require_once(dirname(__FILE__) . '/wfAlerts.php');
45
46
if (version_compare(phpversion(), '5.3', '>=')) {
47
require_once(dirname(__FILE__) . '/WFLSPHP52Compatability.php');
96
}
97
public static function uninstallPlugin(){
98
//Send admin alert
99
+ $currentUser = wp_get_current_user();
100
+ $username = $currentUser->user_login;
101
+ $alertCallback = array(new wfWordfenceDeactivatedAlert($username, wfUtils::getIP()), 'send');
102
+ do_action('wordfence_security_event', 'wordfenceDeactivated', array(
103
+ 'username' => $username,
104
+ 'ip' => wfUtils::getIP(),
105
+ ), $alertCallback);
106
107
//Check if caching is enabled and if it is, disable it and fix the .htaccess file.
108
wfCache::removeCaching();
1313
1314
add_action('rest_api_init', 'wordfence::initRestAPI');
1315
1316
+ if (wfCentral::isConnected()) {
1317
+ add_action('wordfence_security_event', 'wfCentral::sendSecurityEvent', 10, 3);
1318
+ } else {
1319
+ add_action('wordfence_security_event', 'wfCentral::sendAlertCallback', 10, 3);
1320
+ }
1321
}
1322
public static function _pluginPageActionLinks($links) {
1323
if (!wfConfig::get('isPaid')) {
1672
}
1673
1674
if($user){
1675
+ $alertCallback = array(new wfLostPasswdFormAlert($user, wfUtils::getIP()), 'send');
1676
+ do_action('wordfence_security_event', 'lostPasswdForm', array(
1677
+ 'email' => $user->user_email,
1678
+ 'ip' => wfUtils::getIP(),
1679
+ ), $alertCallback);
1680
+
1681
}
1682
if(wfConfig::get('loginSecurityEnabled')){
1683
$tKey = 'wffgt_' . bin2hex(wfUtils::inet_pton($IP));
1698
public static function lockOutIP($IP, $reason) {
1699
wfBlock::createLockout($reason, $IP, wfBlock::lockoutDuration(), time(), time(), 1);
1700
self::getLog()->tagRequestForLockout($reason);
1701
+ $alertCallback = array(new wfLoginLockoutAlert($IP, $reason), 'send');
1702
+ do_action('wordfence_security_event', 'loginLockout', array(
1703
+ 'ip' => $IP,
1704
+ 'reason' => $reason,
1705
+ 'duration' => wfBlock::lockoutDuration(),
1706
+ ), $alertCallback);
1707
+
1708
}
1709
1710
public static function veryFirstAction() {
2413
$cookiename = 'wf_loginalerted_' . hash_hmac('sha256', wfUtils::getIP() . '|' . $user->ID, $salt);
2414
$cookievalue = hash_hmac('sha256', $user->user_login, $salt);
2415
if(wfUtils::isAdmin($userID)){
2416
+ $securityEvent = 'adminLoginNewLocation';
2417
+ if (isset($_COOKIE[$cookiename]) && hash_equals($cookievalue, $_COOKIE[$cookiename])) {
2418
+ $securityEvent = 'adminLogin';
2419
}
2420
+ $alertCallback = array(new wfAdminLoginAlert($cookiename, $cookievalue, $username, wfUtils::getIP()), 'send');
2421
+ do_action('wordfence_security_event', $securityEvent, array(
2422
+ 'username' => $username,
2423
+ 'ip' => wfUtils::getIP(),
2424
+ ), $alertCallback);
2425
+
2426
} else {
2427
+ $securityEvent = 'nonAdminLoginNewLocation';
2428
+ if (isset($_COOKIE[$cookiename]) && hash_equals($cookievalue, $_COOKIE[$cookiename])) {
2429
+ $securityEvent = 'nonAdminLogin';
2430
}
2431
+ $alertCallback = array(new wfNonAdminLoginAlert($cookiename, $cookievalue, $username, wfUtils::getIP()), 'send');
2432
+ do_action('wordfence_security_event', $securityEvent, array(
2433
+ 'username' => $username,
2434
+ 'ip' => wfUtils::getIP(),
2435
+ ), $alertCallback);
2436
}
2437
2438
if (wfConfig::get('alertOn_firstAdminLoginOnly') || wfConfig::get('alertOn_firstNonAdminLoginOnly')) {
2932
else {
2933
$username = $authUser->user_login;
2934
self::getLog()->logLogin('loginFailValidUsername', 1, $username);
2935
+ $alertCallback = array(new wfBreachLoginAlert($username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD), wfUtils::getIP()), 'send');
2936
+
2937
+ do_action('wordfence_security_event', 'breachLogin', array(
2938
+ 'username' => $username,
2939
+ 'resetPasswordURL' => wp_lostpassword_url(),
2940
+ 'supportURL' => wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD),
2941
+ 'ip' => wfUtils::getIP(),
2942
+ ), $alertCallback);
2943
2944
remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
2945
self::$authError = new WP_Error('breached_password', sprintf(__('<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">reset your password</a> to reactivate your account. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>'), wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
2966
else {
2967
$username = $authUser->user_login;
2968
self::getLog()->logLogin('loginFailValidUsername', 1, $username);
2969
+ $alertCallback = array(new wfBreachLoginAlert($username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD), wfUtils::getIP()), 'send');
2970
+
2971
+ do_action('wordfence_security_event', 'breachLogin', array(
2972
+ 'username' => $username,
2973
+ 'resetPasswordURL' => wp_lostpassword_url(),
2974
+ 'supportURL' => wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD),
2975
+ 'ip' => wfUtils::getIP(),
2976
+ ), $alertCallback);
2977
+
2978
remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
2979
self::$authError = new WP_Error('breached_password', sprintf(__('<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">reset your password</a> to reactivate your account. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>'), wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
2980
return self::$authError;
7895
$message .= $date . $ip . $attackMessage . "\n";
7896
}
7897
7898
+ $alertCallback = array(new wfIncreasedAttackRateAlert($message), 'send');
7899
+ do_action('wordfence_security_event', 'increasedAttackRate', array(
7900
+ 'attackCount' => $attackCount,
7901
+ 'attackTable' => $attackTable,
7902
+ 'duration' => $alertInterval,
7903
+ 'ip' => wfUtils::getIP(),
7904
+ ), $alertCallback);
7905
+
7906
wfConfig::set('wafAlertLastSendTime', time());
7907
}
7908
}
modules/login-security/css/{admin-global.1560275180.css → admin-global.1560795818.css} RENAMED
File without changes
modules/login-security/css/{admin.1560275180.css → admin.1560795818.css} RENAMED
File without changes
modules/login-security/css/{colorbox.1560275180.css → colorbox.1560795818.css} RENAMED
File without changes
modules/login-security/css/{font-awesome.1560275180.css → font-awesome.1560795818.css} RENAMED
File without changes
modules/login-security/css/{ionicons.1560275180.css → ionicons.1560795818.css} RENAMED
File without changes
modules/login-security/css/{jquery-ui-timepicker-addon.1560275180.css → jquery-ui-timepicker-addon.1560795818.css} RENAMED
File without changes
modules/login-security/css/{jquery-ui.min.1560275180.css → jquery-ui.min.1560795818.css} RENAMED
File without changes
modules/login-security/css/{jquery-ui.structure.min.1560275180.css → jquery-ui.structure.min.1560795818.css} RENAMED
File without changes
modules/login-security/css/{jquery-ui.theme.min.1560275180.css → jquery-ui.theme.min.1560795818.css} RENAMED
File without changes
modules/login-security/css/{login.1560275180.css → login.1560795818.css} RENAMED
File without changes
modules/login-security/js/{admin-global.1560275180.js → admin-global.1560795818.js} RENAMED
File without changes
modules/login-security/js/{admin.1560275180.js → admin.1560795818.js} RENAMED
File without changes
modules/login-security/js/{jquery-ui-timepicker-addon.1560275180.js → jquery-ui-timepicker-addon.1560795818.js} RENAMED
File without changes
modules/login-security/js/{jquery.colorbox.1560275180.js → jquery.colorbox.1560795818.js} RENAMED
File without changes
modules/login-security/js/{jquery.colorbox.min.1560275180.js → jquery.colorbox.min.1560795818.js} RENAMED
File without changes
modules/login-security/js/{jquery.qrcode.min.1560275180.js → jquery.qrcode.min.1560795818.js} RENAMED
File without changes
modules/login-security/js/{jquery.tmpl.min.1560275180.js → jquery.tmpl.min.1560795818.js} RENAMED
File without changes
modules/login-security/js/{login.1560275180.js → login.1560795818.js} RENAMED
File without changes
modules/login-security/wordfence-login-security.php CHANGED
@@ -27,7 +27,7 @@ else {
27
define('WORDFENCE_LS_FROM_CORE', ($wfCoreActive && isset($wfCoreLoading) && $wfCoreLoading));
28
29
define('WORDFENCE_LS_VERSION', '1.0.2');
30
- define('WORDFENCE_LS_BUILD_NUMBER', '1560275180');
31
32
if (!WORDFENCE_LS_FROM_CORE) {
33
global $wp_plugin_paths;
27
define('WORDFENCE_LS_FROM_CORE', ($wfCoreActive && isset($wfCoreLoading) && $wfCoreLoading));
28
29
define('WORDFENCE_LS_VERSION', '1.0.2');
30
+ define('WORDFENCE_LS_BUILD_NUMBER', '1560795818');
31
32
if (!WORDFENCE_LS_FROM_CORE) {
33
global $wp_plugin_paths;
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: security, firewall, malware scanner, web application firewall, two factor
4
Requires at least: 3.9
5
Requires PHP: 5.3
6
Tested up to: 5.2
7
- Stable tag: 7.3.3
8
9
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
10
@@ -41,6 +41,8 @@ Wordfence includes an endpoint firewall and malware scanner that were built from
41
* Wordfence Central is a powerful and efficient way to manage the security for multiple sites in one place.
42
* Efficiently assess the security status of all your websites in one view. View detailed security findings without leaving Wordfence Central.
43
* Powerful templates make configuring Wordfence a breeze.
44
* Free to use for unlimited sites.
45
46
#### SECURITY TOOLS
@@ -183,6 +185,9 @@ Secure your website with Wordfence.
183
184
== Changelog ==
185
186
= 7.3.3 - June 11, 2019 =
187
* Improvement: Added support for managing the login security settings to Wordfence Central.
188
* Improvement: Updated the bundled root CA certificate store.
4
Requires at least: 3.9
5
Requires PHP: 5.3
6
Tested up to: 5.2
7
+ Stable tag: 7.3.4
8
9
Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
10
41
* Wordfence Central is a powerful and efficient way to manage the security for multiple sites in one place.
42
* Efficiently assess the security status of all your websites in one view. View detailed security findings without leaving Wordfence Central.
43
* Powerful templates make configuring Wordfence a breeze.
44
+ * Highly configurable alerts can be delivered via email, SMS or Slack. Improve the signal to noise ratio by leveraging severity level options and a daily digest option.
45
+ * Track and alert on important security events including administrator logins, breached password usage and surges in attack activity.
46
* Free to use for unlimited sites.
47
48
#### SECURITY TOOLS
185
186
== Changelog ==
187
188
+ = 7.3.4 - June 17, 2019 =
189
+ * Improvement: Added security events and alerting features built into Wordfence Central.
190
+
191
= 7.3.3 - June 11, 2019 =
192
* Improvement: Added support for managing the login security settings to Wordfence Central.
193
* Improvement: Updated the bundled root CA certificate store.
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.3.3
8
Author URI: http://www.wordfence.com/
9
Network: true
10
*/
@@ -15,8 +15,8 @@ if(defined('WP_INSTALLING') && WP_INSTALLING){
15
if (!defined('ABSPATH')) {
16
exit;
17
}
18
- define('WORDFENCE_VERSION', '7.3.3');
19
- define('WORDFENCE_BUILD_NUMBER', '1560275180');
20
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
21
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
22
4
Plugin URI: http://www.wordfence.com/
5
Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
6
Author: Wordfence
7
+ Version: 7.3.4
8
Author URI: http://www.wordfence.com/
9
Network: true
10
*/
15
if (!defined('ABSPATH')) {
16
exit;
17
}
18
+ define('WORDFENCE_VERSION', '7.3.4');
19
+ define('WORDFENCE_BUILD_NUMBER', '1560795818');
20
define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
21
basename(dirname(__FILE__)) . '/' . basename(__FILE__));
22