Wordfence Security – Firewall & Malware Scan - Version 1.4.4

Version Description

  • WordPress Multi-site support added. Currently in Beta. Tested with subdomains, not subdirectories, but it should work great on both.
  • Main changes are moving menus to the Network Admin area, preventing individual blogs from enabling the plugin and dealing with database prefix issues.
Download this release

Release Info

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

Code changes from version 1.4.3 to 1.4.4

lib/dropAll.php CHANGED
@@ -1,8 +1,8 @@
1
<?php
2
require_once('wfSchema.php');
3
if((! isset($_SERVER)) || isset($_SERVER['REQUEST_URI'])){ echo "Running under web interface. Exiting.\n"; exit(0); }
4
- if(! (isset($argv[1]) && isset($argv[2]) && isset($argv[3]))){ echo "Usage: {$argv[0]} <DB username> <DB password> <DB name>\n"; exit(); } $s = new wfSchema('localhost', $argv[1], $argv[2], $argv[3]);
5
6
- $s->dropAll();
7
8
?>
1
<?php
2
require_once('wfSchema.php');
3
if((! isset($_SERVER)) || isset($_SERVER['REQUEST_URI'])){ echo "Running under web interface. Exiting.\n"; exit(0); }
4
+ if(! (isset($argv[1]) && isset($argv[2]) && isset($argv[3]) && isset($argv[4])) ){ echo "Usage: {$argv[0]} <DB username> <DB password> <DB name> <prefix>\n"; exit(); } $s = new wfSchema('localhost', $argv[1], $argv[2], $argv[3]);
5
6
+ $s->dropAll($argv[4]);
7
8
?>
lib/wfConfig.php CHANGED
@@ -411,7 +411,7 @@ class wfConfig {
411
private static function table(){
412
if(! self::$table){
413
global $wpdb;
414
- self::$table = $wpdb->prefix . 'wfConfig';
415
}
416
return self::$table;
417
}
411
private static function table(){
412
if(! self::$table){
413
global $wpdb;
414
+ self::$table = $wpdb->base_prefix . 'wfConfig';
415
}
416
return self::$table;
417
}
lib/wfCrawl.php CHANGED
@@ -10,7 +10,7 @@ class wfCrawl {
10
return false;
11
}
12
public static function verifyCrawlerPTR($hostPattern, $IP){
13
- global $wpdb; $table = $wpdb->prefix . 'wfCrawlers';
14
$db = new wfDB();
15
$IPn = wfUtils::inet_aton($IP);
16
$status = $db->querySingle("select status from $table where IP=%s and patternSig=UNHEX(MD5('%s')) and lastUpdate > unix_timestamp() - %d", $IPn, $hostPattern, WORDFENCE_CRAWLER_VERIFY_CACHE_TIME);
10
return false;
11
}
12
public static function verifyCrawlerPTR($hostPattern, $IP){
13
+ global $wpdb; $table = $wpdb->base_prefix . 'wfCrawlers';
14
$db = new wfDB();
15
$IPn = wfUtils::inet_aton($IP);
16
$status = $db->querySingle("select status from $table where IP=%s and patternSig=UNHEX(MD5('%s')) and lastUpdate > unix_timestamp() - %d", $IPn, $hostPattern, WORDFENCE_CRAWLER_VERIFY_CACHE_TIME);
lib/wfIssues.php CHANGED
@@ -10,7 +10,7 @@ class wfIssues {
10
public $totalWarningIssues = 0;
11
public function __construct(){
12
global $wpdb;
13
- $this->issuesTable = $wpdb->prefix . 'wfIssues';
14
}
15
public function addIssue($type, $severity,
16
10
public $totalWarningIssues = 0;
11
public function __construct(){
12
global $wpdb;
13
+ $this->issuesTable = $wpdb->base_prefix . 'wfIssues';
14
}
15
public function addIssue($type, $severity,
16
lib/wfLog.php CHANGED
@@ -14,17 +14,17 @@ class wfLog {
14
$this->apiKey = $apiKey;
15
$this->wp_version = $wp_version;
16
global $wpdb;
17
- $this->hitsTable = $wpdb->prefix . 'wfHits';
18
- $this->loginsTable = $wpdb->prefix . 'wfLogins';
19
- $this->locsTable = $wpdb->prefix . 'wfLocs';
20
- $this->blocksTable = $wpdb->prefix . 'wfBlocks';
21
- $this->lockOutTable = $wpdb->prefix . 'wfLockedOut';
22
- $this->leechTable = $wpdb->prefix . 'wfLeechers';
23
- $this->badLeechersTable = $wpdb->prefix . 'wfBadLeechers';
24
- $this->scanTable = $wpdb->prefix . 'wfScanners';
25
- $this->reverseTable = $wpdb->prefix . 'wfReverseCache';
26
- $this->throttleTable = $wpdb->prefix . 'wfThrottleLog';
27
- $this->statusTable = $wpdb->prefix . 'wfStatus';
28
}
29
public function logLogin($action, $fail, $username){
30
$user = get_user_by('login', $username);
@@ -75,7 +75,7 @@ class wfLog {
75
$this->takeBlockingAction('maxGlobalRequests', "Exceeded the maximum global requests per minute for crawlers or humans.");
76
}
77
if($type == '404'){
78
- global $wpdb; $p = $wpdb->prefix;
79
if(wfConfig::get('other_WFNet')){
80
$this->getDB()->query("insert IGNORE into $p"."wfNet404s (sig, ctime, URI) values (UNHEX(MD5('%s')), unix_timestamp(), '%s')", $_SERVER['REQUEST_URI'], $_SERVER['REQUEST_URI']);
81
}
14
$this->apiKey = $apiKey;
15
$this->wp_version = $wp_version;
16
global $wpdb;
17
+ $this->hitsTable = $wpdb->base_prefix . 'wfHits';
18
+ $this->loginsTable = $wpdb->base_prefix . 'wfLogins';
19
+ $this->locsTable = $wpdb->base_prefix . 'wfLocs';
20
+ $this->blocksTable = $wpdb->base_prefix . 'wfBlocks';
21
+ $this->lockOutTable = $wpdb->base_prefix . 'wfLockedOut';
22
+ $this->leechTable = $wpdb->base_prefix . 'wfLeechers';
23
+ $this->badLeechersTable = $wpdb->base_prefix . 'wfBadLeechers';
24
+ $this->scanTable = $wpdb->base_prefix . 'wfScanners';
25
+ $this->reverseTable = $wpdb->base_prefix . 'wfReverseCache';
26
+ $this->throttleTable = $wpdb->base_prefix . 'wfThrottleLog';
27
+ $this->statusTable = $wpdb->base_prefix . 'wfStatus';
28
}
29
public function logLogin($action, $fail, $username){
30
$user = get_user_by('login', $username);
75
$this->takeBlockingAction('maxGlobalRequests', "Exceeded the maximum global requests per minute for crawlers or humans.");
76
}
77
if($type == '404'){
78
+ global $wpdb; $p = $wpdb->base_prefix;
79
if(wfConfig::get('other_WFNet')){
80
$this->getDB()->query("insert IGNORE into $p"."wfNet404s (sig, ctime, URI) values (UNHEX(MD5('%s')), unix_timestamp(), '%s')", $_SERVER['REQUEST_URI'], $_SERVER['REQUEST_URI']);
81
}
lib/wfModTracker.php CHANGED
@@ -9,7 +9,7 @@ class wfModTracker {
9
private $anyFilesChangedCached = false;
10
public function __construct(){
11
global $wpdb;
12
- $this->changesTable = $wpdb->prefix . 'wfFileChanges';
13
$this->status(2, 'info', "Getting file change DB handle");
14
$this->db = new wfDB();
15
$this->status(2, 'info', "Starting theme change check");
@@ -29,7 +29,7 @@ class wfModTracker {
29
wfConfig::set('wfmdt_pluginSum', '');
30
$db = new wfDB();
31
global $wpdb;
32
- $db->query("delete from " . $wpdb->prefix . 'wfFileChanges');
33
}
34
public function filesModifiedInCore(){ if(wfConfig::get('wfmdt_coreSum') != $this->coreSum){ return true; } else { return false; } }
35
public function filesModifiedInThemes(){ if(wfConfig::get('wfmdt_themeSum') != $this->themeSum){ return true; } else { return false; } }
9
private $anyFilesChangedCached = false;
10
public function __construct(){
11
global $wpdb;
12
+ $this->changesTable = $wpdb->base_prefix . 'wfFileChanges';
13
$this->status(2, 'info', "Getting file change DB handle");
14
$this->db = new wfDB();
15
$this->status(2, 'info', "Starting theme change check");
29
wfConfig::set('wfmdt_pluginSum', '');
30
$db = new wfDB();
31
global $wpdb;
32
+ $db->query("delete from " . $wpdb->base_prefix . 'wfFileChanges');
33
}
34
public function filesModifiedInCore(){ if(wfConfig::get('wfmdt_coreSum') != $this->coreSum){ return true; } else { return false; } }
35
public function filesModifiedInThemes(){ if(wfConfig::get('wfmdt_themeSum') != $this->themeSum){ return true; } else { return false; } }
lib/wfSchema.php CHANGED
@@ -144,12 +144,12 @@ class wfSchema {
144
} else {
145
global $wpdb;
146
$this->db = new wfDB();
147
- $this->prefix = $wpdb->prefix;
148
}
149
}
150
- public function dropAll(){
151
foreach($this->tables as $table => $def){
152
- $this->db->query("drop table if exists " . $this->prefix . $table);
153
}
154
}
155
public function createAll(){
144
} else {
145
global $wpdb;
146
$this->db = new wfDB();
147
+ $this->prefix = $wpdb->base_prefix;
148
}
149
}
150
+ public function dropAll($prefix){
151
foreach($this->tables as $table => $def){
152
+ $this->db->query("drop table if exists " . $prefix . $table);
153
}
154
}
155
public function createAll(){
lib/wfUtils.php CHANGED
@@ -143,6 +143,12 @@ class wfUtils {
143
return $wp_version;
144
}
145
}
146
}
147
148
143
return $wp_version;
144
}
145
}
146
+ public static function isAdminPageMU(){
147
+ if(preg_match('/^[\/a-zA-Z0-9\-\_\s\+\~\!\^\.]*\/wp-admin\/network\//', $_SERVER['REQUEST_URI'])){
148
+ return true;
149
+ }
150
+ return false;
151
+ }
152
}
153
154
lib/wordfenceClass.php CHANGED
@@ -23,6 +23,9 @@ class wordfence {
23
private static $wfLog = false;
24
private static $hitID = 0;
25
public static function installPlugin(){
26
$schema = new wfSchema();
27
$schema->createAll(); //if not exists
28
wfConfig::setDefaults(); //If not set
@@ -32,10 +35,13 @@ class wordfence {
32
if( !wp_next_scheduled( 'wordfence_hourly_cron' )){
33
wp_schedule_event(time(), 'hourly', 'wordfence_daily_cron');
34
}
35
-
36
}
37
public static function hourlyCron(){
38
- global $wpdb; $p = $wpdb->prefix;
39
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
40
$patData = $api->call('get_known_vuln_pattern');
41
if(is_array($patData) && $patData['pat']){
@@ -85,7 +91,7 @@ class wordfence {
85
}
86
public static function dailyCron(){
87
$wfdb = new wfDB();
88
- global $wpdb; $p = $wpdb->prefix;
89
$wfdb->query("delete from $p"."wfLocs where ctime < unix_timestamp() - %d", WORDFENCE_MAX_IPLOC_AGE);
90
$wfdb->query("truncate table $p"."wfBadLeechers"); //only uses date that's less than 1 minute old
91
$wfdb->query("delete from $p"."wfBlocks where blockedTime + %s < unix_timestamp()", wfConfig::get('blockedTime'));
@@ -136,6 +142,10 @@ class wordfence {
136
137
}
138
public static function install_actions(){
139
add_action('wordfence_daily_cron', 'wordfence::dailyCron');
140
add_action('wordfence_hourly_cron', 'wordfence::hourlyCron');
141
add_action('plugins_loaded', 'wordfence::veryFirstAction');
@@ -160,11 +170,15 @@ class wordfence {
160
add_filter('get_the_generator_rdf', 'wordfence::genFilter', 99, 2);
161
add_filter('get_the_generator_comment', 'wordfence::genFilter', 99, 2);
162
add_filter('get_the_generator_export', 'wordfence::genFilter', 99, 2);
163
-
164
if(is_admin()){
165
- //both functions check if user is admin and we can't do that check now because user object doesn't exist.
166
add_action('admin_init', 'wordfence::admin_init');
167
- add_action('admin_menu', 'wordfence::admin_menus');
168
}
169
}
170
public static function ajaxReceiver(){
@@ -344,7 +358,7 @@ class wordfence {
344
$content = "SITE: " . site_url() . "\nWP VERSION: " . wfUtils::getWPVersion() . "\nAPI KEY: " . wfConfig::get('apiKey') . "\nADMIN EMAIL: " . get_option('admin_email') . "\nLOG:\n\n";
345
$wfdb = new wfDB();
346
global $wpdb;
347
- $p = $wpdb->prefix;
348
$q = $wfdb->query("select ctime, level, type, msg from $p"."wfStatus order by ctime desc limit 10000");
349
while($r = mysql_fetch_assoc($q)){
350
if($r['type'] == 'error'){
@@ -447,7 +461,7 @@ class wordfence {
447
if(! $opts['other_WFNet']){
448
$wfdb = new wfDB();
449
global $wpdb;
450
- $p = $wpdb->prefix;
451
$wfdb->query("delete from $p"."wfBlocks where wfsn=1");
452
}
453
foreach($opts as $key => $val){
@@ -559,7 +573,7 @@ class wordfence {
559
public static function ajax_ticker_callback(){
560
$wfdb = new wfDB();
561
global $wpdb;
562
- $p = $wpdb->prefix;
563
564
$serverTime = $wfdb->querySingle("select unix_timestamp()");
565
$issues = new wfIssues();
@@ -1012,12 +1026,16 @@ class wordfence {
1012
require 'menu_scan.php';
1013
}
1014
public static function isAdmin(){
1015
- foreach(array('update_core', 'activate_plugins', 'add_users', 'create_users', 'create_users', 'install_themes') as $capability){
1016
- if(! current_user_can($capability)){
1017
- return false;
1018
}
1019
}
1020
- return true;
1021
}
1022
public static function status($level /* 1 has highest visibility */, $type /* info|error */, $msg){
1023
if($type != 'info' && $type != 'error'){ error_log("Invalid status type: $type"); return; }
23
private static $wfLog = false;
24
private static $hitID = 0;
25
public static function installPlugin(){
26
+ if(is_multisite() && @$_GET['networkwide'] != 1){
27
+ die("Sorry but you can't activate Wordfence on an individual site when WordPress MultiSite is enabled. Only the Network Admin can enable Wordfence and only they have access to administer Wordfence.");
28
+ }
29
$schema = new wfSchema();
30
$schema->createAll(); //if not exists
31
wfConfig::setDefaults(); //If not set
35
if( !wp_next_scheduled( 'wordfence_hourly_cron' )){
36
wp_schedule_event(time(), 'hourly', 'wordfence_daily_cron');
37
}
38
+ update_option('wordfenceActivated', 1);
39
+ }
40
+ public static function uninstallPlugin(){
41
+ update_option('wordfenceActivated', 0);
42
}
43
public static function hourlyCron(){
44
+ global $wpdb; $p = $wpdb->base_prefix;
45
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
46
$patData = $api->call('get_known_vuln_pattern');
47
if(is_array($patData) && $patData['pat']){
91
}
92
public static function dailyCron(){
93
$wfdb = new wfDB();
94
+ global $wpdb; $p = $wpdb->base_prefix;
95
$wfdb->query("delete from $p"."wfLocs where ctime < unix_timestamp() - %d", WORDFENCE_MAX_IPLOC_AGE);
96
$wfdb->query("truncate table $p"."wfBadLeechers"); //only uses date that's less than 1 minute old
97
$wfdb->query("delete from $p"."wfBlocks where blockedTime + %s < unix_timestamp()", wfConfig::get('blockedTime'));
142
143
}
144
public static function install_actions(){
145
+ if(defined('MULTISITE')){
146
+ global $blog_id;
147
+ if($blog_id == 1 && get_option('wordfenceActivated') != 1){ return; } //Because the plugin is active once installed, even before it's network activated, for site 1 (WordPress team, why?!)
148
+ }
149
add_action('wordfence_daily_cron', 'wordfence::dailyCron');
150
add_action('wordfence_hourly_cron', 'wordfence::hourlyCron');
151
add_action('plugins_loaded', 'wordfence::veryFirstAction');
170
add_filter('get_the_generator_rdf', 'wordfence::genFilter', 99, 2);
171
add_filter('get_the_generator_comment', 'wordfence::genFilter', 99, 2);
172
add_filter('get_the_generator_export', 'wordfence::genFilter', 99, 2);
173
if(is_admin()){
174
add_action('admin_init', 'wordfence::admin_init');
175
+ if(is_multisite()){
176
+ if(wfUtils::isAdminPageMU()){
177
+ add_action('network_admin_menu', 'wordfence::admin_menus');
178
+ } //else don't show menu
179
+ } else {
180
+ add_action('admin_menu', 'wordfence::admin_menus');
181
+ }
182
}
183
}
184
public static function ajaxReceiver(){
358
$content = "SITE: " . site_url() . "\nWP VERSION: " . wfUtils::getWPVersion() . "\nAPI KEY: " . wfConfig::get('apiKey') . "\nADMIN EMAIL: " . get_option('admin_email') . "\nLOG:\n\n";
359
$wfdb = new wfDB();
360
global $wpdb;
361
+ $p = $wpdb->base_prefix;
362
$q = $wfdb->query("select ctime, level, type, msg from $p"."wfStatus order by ctime desc limit 10000");
363
while($r = mysql_fetch_assoc($q)){
364
if($r['type'] == 'error'){
461
if(! $opts['other_WFNet']){
462
$wfdb = new wfDB();
463
global $wpdb;
464
+ $p = $wpdb->base_prefix;
465
$wfdb->query("delete from $p"."wfBlocks where wfsn=1");
466
}
467
foreach($opts as $key => $val){
573
public static function ajax_ticker_callback(){
574
$wfdb = new wfDB();
575
global $wpdb;
576
+ $p = $wpdb->base_prefix;
577
578
$serverTime = $wfdb->querySingle("select unix_timestamp()");
579
$issues = new wfIssues();
1026
require 'menu_scan.php';
1027
}
1028
public static function isAdmin(){
1029
+ if(is_multisite()){
1030
+ if(current_user_can('manage_network')){
1031
+ return true;
1032
+ }
1033
+ } else {
1034
+ if(current_user_can('update_core')){
1035
+ return true;
1036
}
1037
}
1038
+ return false;
1039
}
1040
public static function status($level /* 1 has highest visibility */, $type /* info|error */, $msg){
1041
if($type != 'info' && $type != 'error'){ error_log("Invalid status type: $type"); return; }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: mmaunder
3
Tags: wordpress, security, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure
4
Requires at least: 3.3.1
5
Tested up to: 3.3.2
6
- Stable tag: 1.4.3
7
8
Wordfence Security is a free enterprise class security plugin that includes a firewall, virus scanning, real-time traffic with geolocation and more.
9
@@ -11,6 +11,8 @@ Wordfence Security is a free enterprise class security plugin that includes a fi
11
12
Wordfence Security is a free enterprise class security plugin that includes a firewall and anti-virus scanning for WordPress websites.
13
14
[Remember to visit our support forums if you have questions or comments.](http://wordfence.com/forums/)
15
16
Wordfence is 100% free. You need to sign up on Wordfence.com to get a free API key.
@@ -19,6 +21,7 @@ We also offer a Premium API key that adds additional scanning capabilities. See
19
Wordfence:
20
21
* Scans core files against repository versions to check their integrity.
22
* Premium API key also scans themes and plugins against repository versions. This is currently the only difference between free and premium API keys.
23
* See how files have changed. Optionally repair changed files.
24
* Scans for signatures of over 44,000 known malware variants that are known security threats.
@@ -54,6 +57,17 @@ To install Wordfence Security and start protecting your WordPress website:
54
1. Optionally change your security level or click the advanced options link to see individual security scanning and protection options.
55
1. Click the "Live Traffic" menu option to watch your site activity in real-time.
56
57
== Frequently Asked Questions ==
58
59
[Remember to visit our support forums if you have questions or comments.](http://wordfence.com/forums/)
@@ -64,6 +78,10 @@ Wordfence securely contacts our servers when doing a security scan. These includ
64
against the official versions to see if security has been compromised, checking if URL's in your comments, posts and files are on any known list of dangerous URL's and checking
65
if any of your file signatures match a large list of known malware files that constitute a security threat.
66
67
= Will Wordfence slow my site down? =
68
69
We have spent a lot of time making sure Wordfence runs very quickly and securely. Wordfence uses its own database
@@ -134,6 +152,10 @@ or a theme, because often these have been updated to fix a security hole.
134
5. If you're technically minded, this is the under-the-hood view of Wordfence options where you can fine-tune your security settings.
135
136
== Changelog ==
137
= 1.4.3 =
138
* Improved diagnistic information on binary and regular API calls for better debugging.
139
* Changed ticker to only show activity with level < 3
3
Tags: wordpress, security, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure
4
Requires at least: 3.3.1
5
Tested up to: 3.3.2
6
+ Stable tag: 1.4.4
7
8
Wordfence Security is a free enterprise class security plugin that includes a firewall, virus scanning, real-time traffic with geolocation and more.
9
11
12
Wordfence Security is a free enterprise class security plugin that includes a firewall and anti-virus scanning for WordPress websites.
13
14
+ Wordfence is now Multi-Site compatible. Support for Multi-Site is currently in Beta. Please visit our forums to report any issues.
15
+
16
[Remember to visit our support forums if you have questions or comments.](http://wordfence.com/forums/)
17
18
Wordfence is 100% free. You need to sign up on Wordfence.com to get a free API key.
21
Wordfence:
22
23
* Scans core files against repository versions to check their integrity.
24
+ * WordPress Multi-Site (or WordPress MU in the older parlance) compatible (beta).
25
* Premium API key also scans themes and plugins against repository versions. This is currently the only difference between free and premium API keys.
26
* See how files have changed. Optionally repair changed files.
27
* Scans for signatures of over 44,000 known malware variants that are known security threats.
57
1. Optionally change your security level or click the advanced options link to see individual security scanning and protection options.
58
1. Click the "Live Traffic" menu option to watch your site activity in real-time.
59
60
+ To install Wordfence on WordPress Multi-Site installations (support is currently in Beta):
61
+
62
+ 1. Install Wordfence via the plugin directory or by uploading the ZIP file.
63
+ 1. Network Activate Wordfence. This step is important because until you network activate it, your sites will see the plugin option on their plugins menu. Once activated that option dissapears. If one of your users manages to sneak in and try to activate Wordfence between you installing Wordfence and network activating it, don't worry because they won't be allowed to activate the plugin. It will generate a warning and won't activate for an individual site.
64
+ 1. Now that Wordfence is network activated it will appear on your Network Admin menu. Wordfence will not appear on any individual site's menu.
65
+ 1. Enter your API key to start your first scan.
66
+ 1. Wordfence will scan all files in your WordPress installation including those in the blogs.dir directory of your individual sites.
67
+ 1. Live Traffic will appear for ALL sites in your network. If you have a heavily trafficed system you may want to disable live traffic which will stop logging to the DB.
68
+ 1. Firewall rules and login rules apply to the WHOLE system. So if you fail a login on site1.example.com and site2.example.com it counts as 2 failures. Crawler traffic is counted between blogs, so if you hit three sites in the network, all the hits are totalled and that counts as the rate you're accessing the system.
69
+ 1. Wordfence has been tested with subdomains, not with subdirectories yet, but it should work. Please report all bugs and we'll fix them as fast as we can.
70
+
71
== Frequently Asked Questions ==
72
73
[Remember to visit our support forums if you have questions or comments.](http://wordfence.com/forums/)
78
against the official versions to see if security has been compromised, checking if URL's in your comments, posts and files are on any known list of dangerous URL's and checking
79
if any of your file signatures match a large list of known malware files that constitute a security threat.
80
81
+ = Does Wordfence support Multi-Site installations? =
82
+
83
+ Yes. WordPress MU or Multi-Site as it's called now is supported and support is currently in beta. See the installation tab for more info.
84
+
85
= Will Wordfence slow my site down? =
86
87
We have spent a lot of time making sure Wordfence runs very quickly and securely. Wordfence uses its own database
152
5. If you're technically minded, this is the under-the-hood view of Wordfence options where you can fine-tune your security settings.
153
154
== Changelog ==
155
+ = 1.4.4 =
156
+ * WordPress Multi-site support added. Currently in Beta. Tested with subdomains, not subdirectories, but it should work great on both.
157
+ * Main changes are moving menus to the Network Admin area, preventing individual blogs from enabling the plugin and dealing with database prefix issues.
158
+
159
= 1.4.3 =
160
* Improved diagnistic information on binary and regular API calls for better debugging.
161
* Changed ticker to only show activity with level < 3
visitor.php CHANGED
@@ -22,7 +22,7 @@ function wfVisitor(){
22
$hid = wfUtils::decrypt($hid);
23
if(! preg_match('/^\d+#x2F;', $hid)){ exit(); }
24
$db = new wfDB();
25
- global $wpdb; $p = $wpdb->prefix;
26
$db->query("update $p"."wfHits set jsRun=1 where id=%d", $hid);
27
exit();
28
}
22
$hid = wfUtils::decrypt($hid);
23
if(! preg_match('/^\d+#x2F;', $hid)){ exit(); }
24
$db = new wfDB();
25
+ global $wpdb; $p = $wpdb->base_prefix;
26
$db->query("update $p"."wfHits set jsRun=1 where id=%d", $hid);
27
exit();
28
}
wordfence.php CHANGED
@@ -4,12 +4,13 @@ Plugin Name: Wordfence Security
4
Plugin URI: http://wordfence.com/
5
Description: WordPress Security - Anti-virus and Firewall security plugin for WordPress
6
Author: Mark Maunder
7
- Version: 1.4.3
8
Author URI: http://wordfence.com/
9
*/
10
require_once('lib/wordfenceConstants.php');
11
require_once('lib/wordfenceClass.php');
12
register_activation_hook(WP_PLUGIN_DIR . '/wordfence/wordfence.php', 'wordfence::installPlugin');
13
wordfence::install_actions();
14
15
4
Plugin URI: http://wordfence.com/
5
Description: WordPress Security - Anti-virus and Firewall security plugin for WordPress
6
Author: Mark Maunder
7
+ Version: 1.4.4
8
Author URI: http://wordfence.com/
9
*/
10
require_once('lib/wordfenceConstants.php');
11
require_once('lib/wordfenceClass.php');
12
register_activation_hook(WP_PLUGIN_DIR . '/wordfence/wordfence.php', 'wordfence::installPlugin');
13
+ register_deactivation_hook(WP_PLUGIN_DIR . '/wordfence/wordfence.php', 'wordfence::uninstallPlugin');
14
wordfence::install_actions();
15
16