Version Description
- Email to send security alerts to is now configured at the same time an API key is entered.
- phpinfo is emailed along with activity log when user requests to send us activity log so that we can see things like PHP max execution time and other relevant data
- Now writing individual files to activity log during security scans for better diagnostics.
- Login security message.
- Updated readme.txt FAQ and description.
- Fixed bug where sites with self signed SSL security certificate never start scan because cert fails security check.
- Increased API curl timeout to 300 for slower hosts that seem affected during URL security scans.
Download this release
Release Info
Developer | mmaunder |
Plugin | Wordfence Security – Firewall & Malware Scan |
Version | 1.4.2 |
Comparing to | |
See all releases |
Code changes from version v1.4.1 to 1.4.2
- js/admin.js +3 -2
- lib/menu_config.php +2 -1
- lib/wfAPI.php +2 -2
- lib/wordfenceClass.php +85 -13
- lib/wordfenceHash.php +3 -1
- readme.txt +89 -41
- wfscan.php +20 -5
- wordfence.php +3 -3
js/admin.js
CHANGED
@@ -185,7 +185,8 @@ window['wordfenceAdmin'] = {
|
|
185 |
activateWF: function(key){
|
186 |
jQuery('.wfAjax24').show();
|
187 |
this.ajax('wordfence_activate', {
|
188 |
-
key:
|
|
|
189 |
},
|
190 |
function(res){
|
191 |
jQuery('.wfAjax24').hide();
|
@@ -449,7 +450,7 @@ window['wordfenceAdmin'] = {
|
|
449 |
});
|
450 |
},
|
451 |
emailActivityLog: function(){
|
452 |
-
this.colorbox('400px', 'Email Wordfence Activity Log', "Enter the email address you would like to send the Wordfence activity log to. Note that the activity log may contain thousands of lines of data. This log is usually only sent to a member of the Wordfence support team.<br /><br /><input type='text' size='20' id='wfALogRecip' /><input type='button' value='Send' onclick=\"WFAD.completeEmailActivityLog();\" /><input type='button' value='Cancel' onclick='jQuery.colorbox.close();' /><br /><br />");
|
453 |
},
|
454 |
completeEmailActivityLog: function(){
|
455 |
jQuery.colorbox.close();
|
185 |
activateWF: function(key){
|
186 |
jQuery('.wfAjax24').show();
|
187 |
this.ajax('wordfence_activate', {
|
188 |
+
key: jQuery('#wordfenceKey').val(),
|
189 |
+
email: jQuery('#email').val()
|
190 |
},
|
191 |
function(res){
|
192 |
jQuery('.wfAjax24').hide();
|
450 |
});
|
451 |
},
|
452 |
emailActivityLog: function(){
|
453 |
+
this.colorbox('400px', 'Email Wordfence Activity Log', "Enter the email address you would like to send the Wordfence activity log to. Note that the activity log may contain thousands of lines of data. This log is usually only sent to a member of the Wordfence support team. It also contains your PHP configuration from the phpinfo() function for diagnostic data.<br /><br /><input type='text' value='support@wordfence.com' size='20' id='wfALogRecip' /><input type='button' value='Send' onclick=\"WFAD.completeEmailActivityLog();\" /><input type='button' value='Cancel' onclick='jQuery.colorbox.close();' /><br /><br />");
|
454 |
},
|
455 |
completeEmailActivityLog: function(){
|
456 |
jQuery.colorbox.close();
|
lib/menu_config.php
CHANGED
@@ -2,9 +2,10 @@
|
|
2 |
<div class="wordfence-lock-icon wordfence-icon32"><br /></div><h2>Welcome to Wordfence</h2>
|
3 |
<table class="form-table">
|
4 |
<tr><th><nobr>Enter your Wordfence API key:</nobr></th><td><input type="text" id="wordfenceKey" size="30" value="" /> (<a href="http://wordfence.com/signup-step2/" target="_blank">click here to get a free API key</a>)</td></tr>
|
|
|
5 |
<tr><td colspan="2">
|
6 |
<table border="0" cellpadding="0" cellspacing="0"><tr><td>
|
7 |
-
<input type="button" name="submit" id="submit" class="button-primary" value="Save Changes and Activate Wordfence" onclick="wordfenceAdmin.activateWF(
|
8 |
</td><td>
|
9 |
<div class="wfAjax24"></div>
|
10 |
</td></tr></table>
|
2 |
<div class="wordfence-lock-icon wordfence-icon32"><br /></div><h2>Welcome to Wordfence</h2>
|
3 |
<table class="form-table">
|
4 |
<tr><th><nobr>Enter your Wordfence API key:</nobr></th><td><input type="text" id="wordfenceKey" size="30" value="" /> (<a href="http://wordfence.com/signup-step2/" target="_blank">click here to get a free API key</a>)</td></tr>
|
5 |
+
<tr><th><nobr>Enter an email to send alerts to:</nobr></th><td><input type="text" id="email" size="30" value="<?php echo htmlspecialchars(get_option('admin_email')); ?>" /></td></tr>
|
6 |
<tr><td colspan="2">
|
7 |
<table border="0" cellpadding="0" cellspacing="0"><tr><td>
|
8 |
+
<input type="button" name="submit" id="submit" class="button-primary" value="Save Changes and Activate Wordfence" onclick="wordfenceAdmin.activateWF(); return false;" />
|
9 |
</td><td>
|
10 |
<div class="wfAjax24"></div>
|
11 |
</td></tr></table>
|
lib/wfAPI.php
CHANGED
@@ -52,7 +52,7 @@ class wfAPI {
|
|
52 |
$this->curlDataWritten = 0;
|
53 |
$this->curlContent = "";
|
54 |
$curl = curl_init($url);
|
55 |
-
curl_setopt ($curl, CURLOPT_TIMEOUT,
|
56 |
curl_setopt ($curl, CURLOPT_USERAGENT, "Wordfence.com UA " . WORDFENCE_VERSION);
|
57 |
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
|
58 |
curl_setopt ($curl, CURLOPT_HEADER, 0);
|
@@ -91,7 +91,7 @@ class wfAPI {
|
|
91 |
$this->errorMsg = false;
|
92 |
$url = WORDFENCE_API_URL . '/v' . WORDFENCE_VERSION . '/?' . $this->makeAPIQueryString() . '&action=' . $func;
|
93 |
$curl = curl_init($url);
|
94 |
-
curl_setopt ($curl, CURLOPT_TIMEOUT,
|
95 |
//curl_setopt($curl, CURLOPT_VERBOSE, true);
|
96 |
curl_setopt ($curl, CURLOPT_USERAGENT, "Wordfence");
|
97 |
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
|
52 |
$this->curlDataWritten = 0;
|
53 |
$this->curlContent = "";
|
54 |
$curl = curl_init($url);
|
55 |
+
curl_setopt ($curl, CURLOPT_TIMEOUT, 300);
|
56 |
curl_setopt ($curl, CURLOPT_USERAGENT, "Wordfence.com UA " . WORDFENCE_VERSION);
|
57 |
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
|
58 |
curl_setopt ($curl, CURLOPT_HEADER, 0);
|
91 |
$this->errorMsg = false;
|
92 |
$url = WORDFENCE_API_URL . '/v' . WORDFENCE_VERSION . '/?' . $this->makeAPIQueryString() . '&action=' . $func;
|
93 |
$curl = curl_init($url);
|
94 |
+
curl_setopt ($curl, CURLOPT_TIMEOUT, 300);
|
95 |
//curl_setopt($curl, CURLOPT_VERBOSE, true);
|
96 |
curl_setopt ($curl, CURLOPT_USERAGENT, "Wordfence");
|
97 |
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
|
lib/wordfenceClass.php
CHANGED
@@ -149,6 +149,7 @@ class wordfence {
|
|
149 |
add_action('wp_logout','wordfence::logoutAction');
|
150 |
add_action('profile_update', 'wordfence::profileUpdateAction', '99', 2);
|
151 |
add_action('lostpassword_post', 'wordfence::lostPasswordPost', '1');
|
|
|
152 |
add_filter('pre_comment_approved', 'wordfence::preCommentApprovedFilter', '99', 2);
|
153 |
add_filter('authenticate', 'wordfence::authenticateFilter', 99, 3);
|
154 |
//html|xhtml|atom|rss2|rdf|comment|export
|
@@ -352,6 +353,14 @@ class wordfence {
|
|
352 |
$content .= date(DATE_RFC822, $r['ctime']) . '::' . sprintf('%.4f', $r['ctime']) . ':' . $r['level'] . ':' . $r['type'] . '::' . $r['msg'] . "\n";
|
353 |
}
|
354 |
$content .= "\n\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
355 |
wp_mail($_POST['email'], "Wordfence Activity Log", $content);
|
356 |
return array('ok' => 1);
|
357 |
}
|
@@ -653,13 +662,18 @@ class wordfence {
|
|
653 |
);
|
654 |
}
|
655 |
public static function ajax_activate_callback(){
|
656 |
-
$key = $_POST['key'];
|
657 |
-
$
|
658 |
$key = preg_replace('/[^a-fA-F0-9]+/', '', $key);
|
659 |
if(strlen($key) < 10){
|
660 |
return array("errorAlert" => "You entered an invalid API key." );
|
661 |
}
|
|
|
|
|
|
|
|
|
662 |
wfConfig::set('apiKey', $key);
|
|
|
663 |
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
664 |
$result = $api->call('activate', array(), array());
|
665 |
if($api->errorMsg){
|
@@ -668,30 +682,61 @@ class wordfence {
|
|
668 |
}
|
669 |
if($result['ok'] && $result['isPaid']){
|
670 |
wfConfig::set('isPaid', $result['isPaid']);
|
671 |
-
self::startScan();
|
672 |
-
|
|
|
|
|
|
|
|
|
673 |
} else {
|
674 |
return array('errorAlert' => "An unknown error occured trying to activate Wordfence. Please try again in a few minutes." );
|
675 |
}
|
676 |
}
|
677 |
public static function ajax_scan_callback(){
|
678 |
-
self::startScan();
|
679 |
-
|
|
|
|
|
|
|
|
|
680 |
}
|
681 |
public static function startScan(){
|
682 |
$cron_url = plugins_url('wordfence/wfscan.php');
|
683 |
$cronKey = wfUtils::bigRandomHex();
|
684 |
wfConfig::set('currentCronKey', time() . ',' . $cronKey);
|
685 |
$result = wp_remote_post( $cron_url, array(
|
686 |
-
'timeout' => 0.
|
687 |
-
'blocking' =>
|
688 |
-
'sslverify' =>
|
689 |
'headers' => array(
|
690 |
'x-wordfence-cronkey' => $cronKey
|
691 |
)
|
692 |
) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
693 |
//If the currentCronKey was eaten, then cron executed so return
|
694 |
-
wfConfig::clearCache(); if(! wfConfig::get('currentCronKey')){ return; }
|
695 |
|
696 |
//This second request is for hosts that don't know their own name. i.e. they don't have example.com in their hosts file or DNS pointing to their own IP address or loopback address. So we throw a hail mary to loopback.
|
697 |
usleep(200000);
|
@@ -702,16 +747,40 @@ class wordfence {
|
|
702 |
if(preg_match('/^https?:\/\/([^\/]+)/i', site_url(), $matches)){
|
703 |
$host = $matches[1];
|
704 |
$result = wp_remote_post( $cron_url, array(
|
705 |
-
'timeout' => 0.
|
706 |
-
'blocking' =>
|
707 |
-
'sslverify' =>
|
708 |
'headers' => array(
|
709 |
'x-wordfence-cronkey' => $cronKey,
|
710 |
'Host' => $host
|
711 |
)
|
712 |
) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
713 |
}
|
714 |
}
|
|
|
715 |
}
|
716 |
public static function templateRedir(){
|
717 |
$wfLog = self::getLog();
|
@@ -1037,5 +1106,8 @@ class wordfence {
|
|
1037 |
}
|
1038 |
return self::$wfLog;
|
1039 |
}
|
|
|
|
|
|
|
1040 |
}
|
1041 |
?>
|
149 |
add_action('wp_logout','wordfence::logoutAction');
|
150 |
add_action('profile_update', 'wordfence::profileUpdateAction', '99', 2);
|
151 |
add_action('lostpassword_post', 'wordfence::lostPasswordPost', '1');
|
152 |
+
add_action('login_form', 'wordfence::loginForm', '1');
|
153 |
add_filter('pre_comment_approved', 'wordfence::preCommentApprovedFilter', '99', 2);
|
154 |
add_filter('authenticate', 'wordfence::authenticateFilter', 99, 3);
|
155 |
//html|xhtml|atom|rss2|rdf|comment|export
|
353 |
$content .= date(DATE_RFC822, $r['ctime']) . '::' . sprintf('%.4f', $r['ctime']) . ':' . $r['level'] . ':' . $r['type'] . '::' . $r['msg'] . "\n";
|
354 |
}
|
355 |
$content .= "\n\n";
|
356 |
+
|
357 |
+
ob_start();
|
358 |
+
phpinfo();
|
359 |
+
$phpinfo = ob_get_contents();
|
360 |
+
ob_get_clean();
|
361 |
+
|
362 |
+
$content .= $phpinfo;
|
363 |
+
|
364 |
wp_mail($_POST['email'], "Wordfence Activity Log", $content);
|
365 |
return array('ok' => 1);
|
366 |
}
|
662 |
);
|
663 |
}
|
664 |
public static function ajax_activate_callback(){
|
665 |
+
$key = trim($_POST['key']);
|
666 |
+
$email = trim($_POST['email']);
|
667 |
$key = preg_replace('/[^a-fA-F0-9]+/', '', $key);
|
668 |
if(strlen($key) < 10){
|
669 |
return array("errorAlert" => "You entered an invalid API key." );
|
670 |
}
|
671 |
+
if(! preg_match('/.+\@.+/', $email)){
|
672 |
+
return array("errorAlert" => "Please enter a valid email address where Wordfence can send alerts.");
|
673 |
+
}
|
674 |
+
|
675 |
wfConfig::set('apiKey', $key);
|
676 |
+
wfConfig::set('alertEmails', $email);
|
677 |
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
678 |
$result = $api->call('activate', array(), array());
|
679 |
if($api->errorMsg){
|
682 |
}
|
683 |
if($result['ok'] && $result['isPaid']){
|
684 |
wfConfig::set('isPaid', $result['isPaid']);
|
685 |
+
$err = self::startScan();
|
686 |
+
if($err){
|
687 |
+
return array('errorMsg' => $err);
|
688 |
+
} else {
|
689 |
+
return array("ok" => 1);
|
690 |
+
}
|
691 |
} else {
|
692 |
return array('errorAlert' => "An unknown error occured trying to activate Wordfence. Please try again in a few minutes." );
|
693 |
}
|
694 |
}
|
695 |
public static function ajax_scan_callback(){
|
696 |
+
$err = self::startScan();
|
697 |
+
if($err){
|
698 |
+
return array('errorMsg' => $err);
|
699 |
+
} else {
|
700 |
+
return array("ok" => 1);
|
701 |
+
}
|
702 |
}
|
703 |
public static function startScan(){
|
704 |
$cron_url = plugins_url('wordfence/wfscan.php');
|
705 |
$cronKey = wfUtils::bigRandomHex();
|
706 |
wfConfig::set('currentCronKey', time() . ',' . $cronKey);
|
707 |
$result = wp_remote_post( $cron_url, array(
|
708 |
+
'timeout' => 0.5,
|
709 |
+
'blocking' => true,
|
710 |
+
'sslverify' => false,
|
711 |
'headers' => array(
|
712 |
'x-wordfence-cronkey' => $cronKey
|
713 |
)
|
714 |
) );
|
715 |
+
if(is_wp_error($result) && sizeof($result->errors) > 0){
|
716 |
+
$errs = "";
|
717 |
+
$isTimeout = false;
|
718 |
+
foreach($result->errors as $key => $val){
|
719 |
+
$errs .= $key . ": ";
|
720 |
+
foreach($val as $e){
|
721 |
+
$errs .= $e . ' ';
|
722 |
+
if(preg_match('/timed/i', $e)){
|
723 |
+
$isTimeout = true;
|
724 |
+
}
|
725 |
+
}
|
726 |
+
}
|
727 |
+
if(! $isTimeout){
|
728 |
+
return "Error connecting to Wordfence scanning system: " . $errs;
|
729 |
+
}
|
730 |
+
}
|
731 |
+
if((! is_wp_error($result)) && is_array($result) && $result['body'] && strstr($result['body'], '{') !== false){
|
732 |
+
$resp = json_decode($result['body'], true);
|
733 |
+
if($resp['errorMsg']){
|
734 |
+
return $resp['errorMsg'];
|
735 |
+
}
|
736 |
+
}
|
737 |
+
|
738 |
//If the currentCronKey was eaten, then cron executed so return
|
739 |
+
wfConfig::clearCache(); if(! wfConfig::get('currentCronKey')){ return false; }
|
740 |
|
741 |
//This second request is for hosts that don't know their own name. i.e. they don't have example.com in their hosts file or DNS pointing to their own IP address or loopback address. So we throw a hail mary to loopback.
|
742 |
usleep(200000);
|
747 |
if(preg_match('/^https?:\/\/([^\/]+)/i', site_url(), $matches)){
|
748 |
$host = $matches[1];
|
749 |
$result = wp_remote_post( $cron_url, array(
|
750 |
+
'timeout' => 0.5,
|
751 |
+
'blocking' => true,
|
752 |
+
'sslverify' => false,
|
753 |
'headers' => array(
|
754 |
'x-wordfence-cronkey' => $cronKey,
|
755 |
'Host' => $host
|
756 |
)
|
757 |
) );
|
758 |
+
if(is_wp_error($result) && sizeof($result->errors) > 0){
|
759 |
+
$errs = "";
|
760 |
+
$isTimeout = false;
|
761 |
+
foreach($result->errors as $key => $val){
|
762 |
+
$errs .= $key . ": ";
|
763 |
+
foreach($val as $e){
|
764 |
+
$errs .= $e . ' ';
|
765 |
+
if(preg_match('/timed/i', $e)){
|
766 |
+
$isTimeout = true;
|
767 |
+
}
|
768 |
+
}
|
769 |
+
}
|
770 |
+
if(! $isTimeout){
|
771 |
+
return "Error connecting to Wordfence scanning system: " . $errs;
|
772 |
+
}
|
773 |
+
}
|
774 |
+
if((! is_wp_error($result)) && is_array($result) && $result['body'] && strstr($result['body'], '{') !== false){
|
775 |
+
$resp = json_decode($result['body'], true);
|
776 |
+
if($resp['errorMsg']){
|
777 |
+
return $resp['errorMsg'];
|
778 |
+
}
|
779 |
+
}
|
780 |
+
|
781 |
}
|
782 |
}
|
783 |
+
return false;
|
784 |
}
|
785 |
public static function templateRedir(){
|
786 |
$wfLog = self::getLog();
|
1106 |
}
|
1107 |
return self::$wfLog;
|
1108 |
}
|
1109 |
+
public static function loginForm(){
|
1110 |
+
echo "<p><a href='http://www.wordfence.com/' target='_blank'>WordPress Security powered by Wordfence</a><br /><br /><br /></p>";
|
1111 |
+
}
|
1112 |
}
|
1113 |
?>
|
lib/wordfenceHash.php
CHANGED
@@ -43,7 +43,6 @@ class wordfenceHash {
|
|
43 |
if(is_file($file)){
|
44 |
$this->processFile($file);
|
45 |
} else if(is_dir($file)) {
|
46 |
-
wordfence::status(2, 'info', "Traversing into dir $file");
|
47 |
$this->_dirHash($file);
|
48 |
}
|
49 |
}
|
@@ -56,6 +55,7 @@ class wordfenceHash {
|
|
56 |
private function processFile($file){
|
57 |
$wfHash = $this->wfHash($file, true);
|
58 |
if($wfHash){
|
|
|
59 |
$this->hashes[substr($file, $this->striplen)] = $wfHash;
|
60 |
//Now that we know we can open the file, lets update stats
|
61 |
if(preg_match('/\.(?:js|html|htm|css)$/i', $file)){
|
@@ -65,6 +65,8 @@ class wordfenceHash {
|
|
65 |
}
|
66 |
$this->totalFiles++;
|
67 |
$this->totalData += filesize($file);
|
|
|
|
|
68 |
}
|
69 |
}
|
70 |
public function wfHash($file, $binary = true){
|
43 |
if(is_file($file)){
|
44 |
$this->processFile($file);
|
45 |
} else if(is_dir($file)) {
|
|
|
46 |
$this->_dirHash($file);
|
47 |
}
|
48 |
}
|
55 |
private function processFile($file){
|
56 |
$wfHash = $this->wfHash($file, true);
|
57 |
if($wfHash){
|
58 |
+
wordfence::status(2, 'info', "Examined file: $file");
|
59 |
$this->hashes[substr($file, $this->striplen)] = $wfHash;
|
60 |
//Now that we know we can open the file, lets update stats
|
61 |
if(preg_match('/\.(?:js|html|htm|css)$/i', $file)){
|
65 |
}
|
66 |
$this->totalFiles++;
|
67 |
$this->totalData += filesize($file);
|
68 |
+
} else {
|
69 |
+
wordfence::status(2, 'error', "Could not gen hash for file: $file");
|
70 |
}
|
71 |
}
|
72 |
public function wfHash($file, $binary = true){
|
readme.txt
CHANGED
@@ -1,17 +1,17 @@
|
|
1 |
-
===
|
2 |
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.
|
7 |
|
8 |
-
Wordfence is a free enterprise class security plugin that includes a firewall
|
9 |
|
10 |
== Description ==
|
11 |
|
12 |
-
|
13 |
|
14 |
-
|
15 |
|
16 |
Wordfence is 100% free. You need to sign up on Wordfence.com to get a free API key.
|
17 |
We also offer a Premium API key that adds additional scanning capabilities. See below for details.
|
@@ -21,80 +21,128 @@ Wordfence:
|
|
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.
|
25 |
-
* Continuously scans for
|
26 |
-
* Scans for heuristics of backdoors, trojans and
|
27 |
-
* Checks the strength of all user and admin passwords.
|
28 |
* Monitor for unauthorized DNS changes.
|
29 |
-
*
|
30 |
-
*
|
31 |
-
*
|
32 |
-
*
|
33 |
-
*
|
34 |
-
*
|
35 |
-
*
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
39 |
|
40 |
== Installation ==
|
41 |
|
42 |
-
|
43 |
|
44 |
-
|
45 |
|
46 |
-
1. Install Wordfence automatically or by uploading the ZIP file.
|
47 |
-
1. Activate the plugin through the 'Plugins' menu in WordPress.
|
48 |
-
1. Visit [Wordfence.com to get an API key](http://wordfence.com/)
|
49 |
1. Go to the Wordfence menu option that appears on the left or your site's admin section.
|
50 |
1. Enter your API key and click the button.
|
51 |
-
1. Wordfence is now activated.
|
52 |
-
1. Visit the Wordfence options page to enter your email address so that you can receive email alerts.
|
53 |
-
1. Optionally change your security level or click the advanced options link to see
|
54 |
1. Click the "Live Traffic" menu option to watch your site activity in real-time.
|
55 |
|
56 |
== Frequently Asked Questions ==
|
57 |
|
58 |
[Remember to visit our support forums if you have questions or comments.](http://wordfence.com/forums/)
|
59 |
|
60 |
-
= Why does Wordfence need an API key? =
|
61 |
|
62 |
-
Wordfence contacts our servers
|
63 |
-
against the official versions, checking if URL's in your comments, posts and files are on any known list of dangerous URL's
|
64 |
-
if any of your file signatures match a large list of known malware files
|
65 |
|
66 |
= Will Wordfence slow my site down? =
|
67 |
|
68 |
-
We have spent a lot of time making sure Wordfence runs very quickly. Wordfence uses its own database
|
69 |
tables and advanced mysql features to ensure it runs as fast as possible. The creators of Wordfence
|
70 |
also run a large scale real-time analytics product and much of the technology and knowledge from
|
71 |
our real-time analytics products is built into Wordfence.
|
72 |
|
73 |
= How often is Wordfence updated? =
|
74 |
|
75 |
-
Wordfence
|
76 |
-
|
77 |
-
that
|
78 |
-
security issues that Wordfence will scan for.
|
79 |
|
80 |
= What if I need support? =
|
81 |
|
82 |
All our paid customers receive priority support. Excellent customer service is a key part
|
83 |
-
of being a Wordfence member.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
-
=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
-
Yes! Simply visit the Options page, click on advanced options and enable or disable the features you want.
|
88 |
|
89 |
== Screenshots ==
|
90 |
|
91 |
-
1. The home screen of Wordfence where you can see a summary, manage issues and do a manual scan.
|
92 |
2. The Live Traffic view of Wordfence where you can see real-time activity on your site.
|
93 |
-
3. The "Blocked IPs" page where you can manage blocked IP's, locked out IP's and see recently throttled IPs.
|
94 |
4. The basic view of Wordfence options. There is very little to configure other than your alert email address and security level.
|
95 |
5. If you're technically minded, this is the under-the-hood view of Wordfence options where you can fine-tune your security settings.
|
96 |
|
97 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
= 1.4.1 =
|
99 |
* This is a major release, please upgrade immediately.
|
100 |
* Only scan files in the WordPress ABSPATH root directory and known WordPress subdirectories. Prevents potentially massive scans on hosts that have large dirs off their wordpress root.
|
1 |
+
=== Wordfence Security ===
|
2 |
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.2
|
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 |
|
10 |
== Description ==
|
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.
|
17 |
We also offer a Premium API key that adds additional scanning capabilities. See below for details.
|
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.
|
25 |
+
* Continuously scans for malware and phishing URL's in all your comments, posts and files that are security threats.
|
26 |
+
* Scans for heuristics of backdoors, trojans, suspicious code and other security issues.
|
27 |
+
* Checks the strength of all user and admin passwords to enhance login security.
|
28 |
* Monitor for unauthorized DNS changes.
|
29 |
+
* Includes a firewall to block common security threats like fake Googlebots, malicious scans from hackers and botnets.
|
30 |
+
* Rate limit or block security threats like aggressive crawlers, scrapers and bots doing security scans for vulnerabilities in your site.
|
31 |
+
* Choose whether you want to block or throttle users and robots who break your security rules.
|
32 |
+
* Includes login security to lock out brute force hacks and to stop WordPress from revealing info that will compromise security.
|
33 |
+
* See all your traffic in real-time, including robots, humans, 404 errors, logins and logouts and who is consuming most of your content. Enhances your situational awareness of which security threats your site is facing.
|
34 |
+
* A real-time view of all traffic including automated bots that often constitute security threats that Javascript analytics packages never show you.
|
35 |
+
* Real-time traffic includes reverse DNS and city-level geolocation. Know which geographic area security threats originate from.
|
36 |
+
* Monitors disk space which is related to security because many DDoS attacks attempt to consume all disk space to create denial of service.
|
37 |
+
|
38 |
+
Wordfence Security is full-featured and constantly updated by our team to incorporate the latest security features and to hunt for the
|
39 |
+
newest security threats to your WordPress website.
|
40 |
|
41 |
== Installation ==
|
42 |
|
43 |
+
To install Wordfence Security and start protecting your WordPress website:
|
44 |
|
45 |
+
[Remember to visit our support forums if you have questions or comments.](http://wordfence.com/forums/)
|
46 |
|
47 |
+
1. Install Wordfence Security automatically or by uploading the ZIP file.
|
48 |
+
1. Activate the security plugin through the 'Plugins' menu in WordPress.
|
49 |
+
1. Visit [Wordfence.com to get an API key](http://wordfence.com/) which you need to security scans.
|
50 |
1. Go to the Wordfence menu option that appears on the left or your site's admin section.
|
51 |
1. Enter your API key and click the button.
|
52 |
+
1. Wordfence is now activated. Your first security scan will start automatically and scheduled security scanning will also be enabled.
|
53 |
+
1. Visit the Wordfence options page to enter your email address so that you can receive email security alerts.
|
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/)
|
60 |
|
61 |
+
= Why does Wordfence Security need an API key? =
|
62 |
|
63 |
+
Wordfence securely contacts our servers when doing a security scan. These include: comparing the hashes of your core, theme and plugin files
|
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
|
70 |
tables and advanced mysql features to ensure it runs as fast as possible. The creators of Wordfence
|
71 |
also run a large scale real-time analytics product and much of the technology and knowledge from
|
72 |
our real-time analytics products is built into Wordfence.
|
73 |
|
74 |
= How often is Wordfence updated? =
|
75 |
|
76 |
+
The Wordfence security plugin is frequently updated and we update the code on our security scanning servers
|
77 |
+
more frequently. Our cloud servers are continually updated with the latest known security threats and vulnerabilities so
|
78 |
+
that we can blog any security threat as soon as it emerges in the wild.
|
|
|
79 |
|
80 |
= What if I need support? =
|
81 |
|
82 |
All our paid customers receive priority support. Excellent customer service is a key part
|
83 |
+
of being a Wordfence member. You can also [visit our support forums where we provide free support for all Wordfence users](http://wordfence.com/forums/) and answer any security releated questions you may have.
|
84 |
+
|
85 |
+
= Can I disable certain security features of Wordfence? =
|
86 |
+
|
87 |
+
Yes! Simply visit the Options page, click on advanced options and enable or disable the security features you want.
|
88 |
+
|
89 |
+
= What if my site security has already been compromised by a hacker? =
|
90 |
+
|
91 |
+
Wordfence is the only security plugin that is able to repair core files, themes and plugins on sites where security is already compromised.
|
92 |
+
However, please note that site security can not be assured unless you do a full reinstall if your site has been hacked. We recommend you only
|
93 |
+
use Wordfence to get your site into a running state in order to recover the data you need to do a full reinstall. A full reinstall is the only
|
94 |
+
way to ensure site security once you have been hacked.
|
95 |
|
96 |
+
= How will I be alerted that my site has a security problem? =
|
97 |
+
|
98 |
+
Wordfence sends security alerts via email. Once you install Wordfence, you will configure a list of email addresses where security alerts will be sent.
|
99 |
+
When you receive a security alert, make sure you deal with it promptly to ensure your site stays secure.
|
100 |
+
|
101 |
+
= My WordPress site is behind a firewall. Doesn't that make it secure? =
|
102 |
+
|
103 |
+
If your site is accessible from the web, it means that people you don't know can execute PHP code on your site.
|
104 |
+
They have to be able to execute PHP code, like the core WordPress code, in order for your site to work.
|
105 |
+
Most WordPress security threats allow a hacker to execute PHP code on your website. The challenge hackers
|
106 |
+
face is how to get their malicious PHP code onto your site to compromise your security. There
|
107 |
+
are many upload mechanisms that WordPress itself, themes and plugins offer and the vast majority of these
|
108 |
+
are secure. However, every now and then a hacker discovers an upload mechanism that is not secure or
|
109 |
+
a way of fooling your site into allowing an upload. That is usually when security is compromised. Even
|
110 |
+
though your site is behind a commercial firewall, it still accepts web requests that include uploads and executes PHP code
|
111 |
+
and as long as it does that, it may become face a security vulnerability at some point.
|
112 |
+
|
113 |
+
= Will Wordfence protect me against the Timthumb security problem? =
|
114 |
+
|
115 |
+
The timthumb security exploit occured in 2011 and all good plugins and themes now use an updated
|
116 |
+
version of timthumb (which the creator of Wordfence wrote and donated to the timthumb author) which closes the security hole that
|
117 |
+
caused the problem. However we do scan for old version of timthumb for good measure to make sure they don't
|
118 |
+
cause a security hole on your site.
|
119 |
+
|
120 |
+
= People keep telling me that WordPress itself has security problems. Is that true? =
|
121 |
+
|
122 |
+
In general, no it's not. The WordPress team work very hard to keep the awesome software they have produced secure and in the
|
123 |
+
rare cases when a security hole is found, they fix it very quickly. Most responsible plugin authors also fix security holes
|
124 |
+
as soon as they are told about them. That's why Wordfence will warn you if you're running an old version of WordPress, a plugin
|
125 |
+
or a theme, because often these have been updated to fix a security hole.
|
126 |
|
|
|
127 |
|
128 |
== Screenshots ==
|
129 |
|
130 |
+
1. The home screen of Wordfence where you can see a summary, manage security issues and do a manual security scan.
|
131 |
2. The Live Traffic view of Wordfence where you can see real-time activity on your site.
|
132 |
+
3. The "Blocked IPs" page where you can manage blocked IP's, locked out IP's and see recently throttled IPs that violated security rules.
|
133 |
4. The basic view of Wordfence options. There is very little to configure other than your alert email address and security level.
|
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.2 =
|
138 |
+
* Email to send security alerts to is now configured at the same time an API key is entered.
|
139 |
+
* phpinfo is emailed along with activity log when user requests to send us activity log so that we can see things like PHP max execution time and other relevant data
|
140 |
+
* Now writing individual files to activity log during security scans for better diagnostics.
|
141 |
+
* Login security message.
|
142 |
+
* Updated readme.txt FAQ and description.
|
143 |
+
* Fixed bug where sites with self signed SSL security certificate never start scan because cert fails security check.
|
144 |
+
* Increased API curl timeout to 300 for slower hosts that seem affected during URL security scans.
|
145 |
+
|
146 |
= 1.4.1 =
|
147 |
* This is a major release, please upgrade immediately.
|
148 |
* Only scan files in the WordPress ABSPATH root directory and known WordPress subdirectories. Prevents potentially massive scans on hosts that have large dirs off their wordpress root.
|
wfscan.php
CHANGED
@@ -20,17 +20,28 @@ require_once('lib/wfScanEngine.php');
|
|
20 |
|
21 |
class wfScan {
|
22 |
public static function wfScanMain(){
|
23 |
-
if(! $_SERVER['HTTP_X_WORDFENCE_CRONKEY']){
|
24 |
-
|
25 |
-
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
wfConfig::set('currentCronKey', '');
|
28 |
ini_set('max_execution_time', 1800); //30 mins
|
29 |
self::becomeAdmin();
|
30 |
|
31 |
$scanRunning = wfConfig::get('wf_scanRunning');
|
32 |
if($scanRunning && time() - $scanRunning < WORDFENCE_MAX_SCAN_TIME){
|
33 |
-
|
34 |
}
|
35 |
wfConfig::set('wf_scanRunning', time());
|
36 |
register_shutdown_function('wfScan::clearScan');
|
@@ -39,6 +50,10 @@ class wfScan {
|
|
39 |
$scan->go();
|
40 |
wfConfig::set('wf_scanRunning', '');
|
41 |
}
|
|
|
|
|
|
|
|
|
42 |
public static function becomeAdmin(){
|
43 |
global $wpdb;
|
44 |
$ws = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users");
|
20 |
|
21 |
class wfScan {
|
22 |
public static function wfScanMain(){
|
23 |
+
if(! $_SERVER['HTTP_X_WORDFENCE_CRONKEY']){
|
24 |
+
self::errorExit("The Wordfence scanner did not receive the x_wordfence_cronkey secure header.");
|
25 |
+
}
|
26 |
+
$currentCronKey = wfConfig::get('currentCronKey', false);
|
27 |
+
if(! $currentCronKey){
|
28 |
+
self::errorExit("Wordfence could not find a saved cron key to start the scan.");
|
29 |
+
}
|
30 |
+
|
31 |
+
$savedKey = explode(',',$currentCronKey);
|
32 |
+
if(time() - $savedKey[0] > 60){
|
33 |
+
self::errorExit("The key used to start a scan has expired.");
|
34 |
+
} //keys only last 60 seconds and are used within milliseconds of creation
|
35 |
+
if($savedKey[1] != $_SERVER['HTTP_X_WORDFENCE_CRONKEY']){
|
36 |
+
self::errorExit("Wordfence could not start a scan because the cron key does not match the saved key.");
|
37 |
+
}
|
38 |
wfConfig::set('currentCronKey', '');
|
39 |
ini_set('max_execution_time', 1800); //30 mins
|
40 |
self::becomeAdmin();
|
41 |
|
42 |
$scanRunning = wfConfig::get('wf_scanRunning');
|
43 |
if($scanRunning && time() - $scanRunning < WORDFENCE_MAX_SCAN_TIME){
|
44 |
+
self::errorExit("There is already a scan running.");
|
45 |
}
|
46 |
wfConfig::set('wf_scanRunning', time());
|
47 |
register_shutdown_function('wfScan::clearScan');
|
50 |
$scan->go();
|
51 |
wfConfig::set('wf_scanRunning', '');
|
52 |
}
|
53 |
+
private static function errorExit($msg){
|
54 |
+
echo json_encode(array('errorMsg' => $msg));
|
55 |
+
exit();
|
56 |
+
}
|
57 |
public static function becomeAdmin(){
|
58 |
global $wpdb;
|
59 |
$ws = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users");
|
wordfence.php
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
-
Plugin Name: Wordfence
|
4 |
Plugin URI: http://wordfence.com/
|
5 |
-
Description: WordPress Security - Anti-virus and Firewall for WordPress
|
6 |
Author: Mark Maunder
|
7 |
-
Version: 1.4.
|
8 |
Author URI: http://wordfence.com/
|
9 |
*/
|
10 |
require_once('lib/wordfenceConstants.php');
|
1 |
<?php
|
2 |
/*
|
3 |
+
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.2
|
8 |
Author URI: http://wordfence.com/
|
9 |
*/
|
10 |
require_once('lib/wordfenceConstants.php');
|