PluginProbe ʕ •ᴥ•ʔ
Wordfence Security – Firewall, Malware Scan, and Login Security / 3.0.3
Wordfence Security – Firewall, Malware Scan, and Login Security v3.0.3
8.2.2 8.2.1 8.2.0 3.7.1 3.7.2 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.8.8 3.8.9 3.9.1 4.0.1 4.0.2 4.0.3 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.0.9 5.1.1 5.1.2 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.2.1 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.1 5.3.10 5.3.11 5.3.12 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.3.8 5.3.9 6.0.1 6.0.10 6.0.11 6.0.12 6.0.14 6.0.15 6.0.16 6.0.17 6.0.18 6.0.19 6.0.2 6.0.20 6.0.21 6.0.22 6.0.23 6.0.24 6.0.25 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.0.8 6.0.9 6.1.1 6.1.10 6.1.11 6.1.12 6.1.14 6.1.15 6.1.16 6.1.17 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6 6.1.7 6.1.8 6.1.9 6.2.0 6.2.1 6.2.10 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.2.8 6.2.9 6.3.0 6.3.1 6.3.10 6.3.11 6.3.12 6.3.14 6.3.15 6.3.16 6.3.17 6.3.18 6.3.19 6.3.2 6.3.20 6.3.21 6.3.22 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.3.8 6.3.9 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1.0 7.1.1 7.1.10 7.1.11 7.1.12 7.1.14 7.1.15 7.1.16 7.1.17 7.1.18 7.1.19 7.1.2 7.1.20 7.1.3 7.1.4 7.1.5 7.1.6 7.1.7 7.1.8 7.1.9 7.10.0 7.10.1 7.10.2 7.10.3 7.10.4 7.10.5 7.10.6 7.10.7 7.11.0 7.11.1 7.11.2 7.11.3 7.11.4 7.11.5 7.11.6 7.11.7 7.2.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3.1 7.3.2 7.3.3 7.3.4 7.3.5 7.3.6 7.4.0 7.4.1 7.4.10 7.4.11 7.4.12 7.4.14 7.4.2 7.4.3 trunk 7.4.4 1.1 7.4.5 1.2 7.4.6 1.3 7.4.7 1.3.1 7.4.8 1.3.2 7.4.9 1.3.3 7.5.0 1.4.2 7.5.1 1.4.3 7.5.10 1.4.4 7.5.11 1.4.5 7.5.2 1.4.6 7.5.3 1.4.7 7.5.4 1.4.8 7.5.5 1.5.1 7.5.6 1.5.2 7.5.7 1.5.3 7.5.8 1.5.4 7.5.9 1.5.5 7.6.0 1.5.6 7.6.1 2.0.1 7.6.2 2.0.2 7.7.0 2.0.3 7.7.1 2.0.5 7.8.0 2.0.6 7.8.1 2.0.7 7.8.2 2.1.0 7.9.0 2.1.1 7.9.1 2.1.2 7.9.2 2.1.3 7.9.3 2.1.4 8.0.0 2.1.5 8.0.1 3.0.2 8.0.2 3.0.3 8.0.3 3.0.4 8.0.4 3.0.5 8.0.5 3.0.6 8.1.0 3.0.7 8.1.1 3.0.8 8.1.2 3.0.9 8.1.3 3.1.0 8.1.4 3.1.1 v1.4.1 3.1.2 3.1.4 3.1.6 3.2.1 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.1 3.4.4 3.4.5 3.5.1 3.5.2 3.6.1 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.6.9
wordfence / lib / wfIssues.php
wordfence / lib Last commit date
Diff 13 years ago .htaccess 14 years ago Diff.php 13 years ago IPTraf.php 13 years ago diffResult.php 13 years ago email_genericAlert.php 13 years ago email_newIssues.php 14 years ago email_unlockRequest.php 14 years ago menu_activity.php 14 years ago menu_blockedIPs.php 13 years ago menu_options.php 13 years ago menu_scan.php 13 years ago sysinfo.php 13 years ago viewFullActivityLog.php 13 years ago wf503.php 13 years ago wfAPI.php 13 years ago wfAction.php 14 years ago wfArray.php 13 years ago wfBrowscap.php 14 years ago wfBrowscapCache.php 14 years ago wfConfig.php 13 years ago wfCrawl.php 13 years ago wfDB.php 13 years ago wfDict.php 14 years ago wfIssues.php 13 years ago wfLockedOut.php 14 years ago wfLog.php 13 years ago wfModTracker.php 14 years ago wfRate.php 14 years ago wfScanEngine.php 13 years ago wfSchema.php 13 years ago wfUnlockMsg.php 14 years ago wfUtils.php 13 years ago wfViewResult.php 13 years ago wordfenceClass.php 13 years ago wordfenceConstants.php 13 years ago wordfenceHash.php 13 years ago wordfenceScanner.php 13 years ago wordfenceURLHoover.php 13 years ago
wfIssues.php
254 lines
1 <?php
2 require_once('wfUtils.php');
3 class wfIssues {
4 private $db = false;
5
6 //Properties that are serialized on sleep:
7 private $updateCalled = false;
8 private $issuesTable = '';
9 private $newIssues = array();
10 public $totalIssues = 0;
11 public $totalCriticalIssues = 0;
12 public $totalWarningIssues = 0;
13 public function __sleep(){ //Same order here as vars above
14 return array('updateCalled', 'issuesTable', 'newIssues', 'totalIssues', 'totalCriticalIssues', 'totalWarningIssues');
15 }
16 public function __construct(){
17 global $wpdb;
18 $this->issuesTable = $wpdb->base_prefix . 'wfIssues';
19 }
20 public function __wakeup(){
21 $this->db = new wfDB();
22 }
23 public function addIssue($type, $severity,
24
25 $ignoreP, /* some piece of data used for md5 for permanent ignores */
26 $ignoreC, /* some piece of data used for md5 for ignoring until something changes */
27 $shortMsg, $longMsg, $templateData
28 ){
29
30
31 $ignoreP = md5($ignoreP);
32 $ignoreC = md5($ignoreC);
33 $rec = $this->getDB()->querySingleRec("select status, ignoreP, ignoreC from " . $this->issuesTable . " where (ignoreP='%s' OR ignoreC='%s')", $ignoreP, $ignoreC);
34 if($rec){
35 if($rec['status'] == 'new' && ($rec['ignoreC'] == $ignoreC || $rec['ignoreP'] == $ignoreP)){ return false; }
36 if($rec['status'] == 'ignoreC' && $rec['ignoreC'] == $ignoreC){ return false; }
37 if($rec['status'] == 'ignoreP' && $rec['ignoreP'] == $ignoreP){ return false; }
38 }
39
40 if($severity == 1){
41 $this->totalCriticalIssues++;
42 } else if($severity == 2){
43 $this->totalWarningIssues++;
44 }
45 $this->totalIssues++;
46 $this->newIssues[] = array(
47 'type' => $type,
48 'severity' => $severity,
49 'ignoreP' => $ignoreP,
50 'ignoreC' => $ignoreC,
51 'shortMsg' => $shortMsg,
52 'longMsg' => $longMsg,
53 'tmplData' => $templateData
54 );
55
56 $this->getDB()->query("insert into " . $this->issuesTable . " (time, status, type, severity, ignoreP, ignoreC, shortMsg, longMsg, data) values (unix_timestamp(), '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s')",
57 'new',
58 $type,
59 $severity,
60 $ignoreP,
61 $ignoreC,
62 $shortMsg,
63 $longMsg,
64 serialize($templateData)
65 );
66 return true;
67 }
68 public function deleteIgnored(){
69 $this->getDB()->query("delete from " . $this->issuesTable . " where status='ignoreP' or status='ignoreC'");
70 }
71 public function deleteNew(){
72 $this->getDB()->query("delete from " . $this->issuesTable . " where status='new'");
73 }
74 public function ignoreAllNew(){
75 $this->getDB()->query("update " . $this->issuesTable . " set status='ignoreC' where status='new'");
76 }
77 public function emailNewIssues(){
78 $level = wfConfig::getAlertLevel();
79 $emails = wfConfig::getAlertEmails();
80 $subject = "[Wordfence Alert] Problems found on " . get_bloginfo('name', 'raw');
81
82 if(sizeof($emails) < 1){ return; }
83 if($level < 1){ return; }
84 if($level == 2 && $this->totalCriticalIssues < 1 && $this->totalWarningIssues < 1){ return; }
85 if($level == 1 && $this->totalCriticalIssues < 1){ return; }
86 $emailedIssues = wfConfig::get_ser('emailedIssuesList', array());
87 if(! is_array($emailedIssues)){
88 $emailedIssues = array();
89 }
90 $finalIssues = array();
91 foreach($this->newIssues as $newIssue){
92 $alreadyEmailed = false;
93 foreach($emailedIssues as $emailedIssue){
94 if($newIssue['ignoreP'] == $emailedIssue['ignoreP'] || $newIssue['ignoreC'] == $emailedIssue['ignoreC']){
95 $alreadyEmailed = true;
96 break;
97 }
98 }
99 if(! $alreadyEmailed){
100 $finalIssues[] = $newIssue;
101 }
102 }
103 if(sizeof($finalIssues) < 1){ return; }
104
105 $totalWarningIssues = 0;
106 $totalCriticalIssues = 0;
107 foreach($finalIssues as $i){
108 $emailedIssues[] = array( 'ignoreC' => $i['ignoreC'], 'ignoreP' => $i['ignoreP'] );
109 if($i['severity'] == 1){
110 $totalCriticalIssues++;
111 } else if($i['severity'] == 2){
112 $totalWarningIssues++;
113 }
114 }
115 wfConfig::set_ser('emailedIssuesList', $emailedIssues);
116 if($level == 2 && $totalCriticalIssues < 1 && $totalWarningIssues < 1){ return; }
117 if($level == 1 && $totalCriticalIssues < 1){ return; }
118 $content = wfUtils::tmpl('email_newIssues.php', array(
119 'issues' => $finalIssues,
120 'totalCriticalIssues' => $totalCriticalIssues,
121 'totalWarningIssues' => $totalWarningIssues,
122 'level' => $level
123 ));
124 wp_mail(implode(',', $emails), $subject, $content);
125 }
126 public function deleteIssue($id){
127 $this->getDB()->query("delete from " . $this->issuesTable . " where id=%d", $id);
128 }
129 public function updateIssue($id, $status){ //ignoreC, ignoreP, delete or new
130 $currentStatus = $this->getDB()->querySingle("select status from " . $this->issuesTable . " where id=%d", $id);
131 if($status == 'delete'){
132 $this->getDB()->query("delete from " . $this->issuesTable . " where id=%d", $id);
133 } else if($status == 'ignoreC' || $status == 'ignoreP' || $status == 'new'){
134 $this->getDB()->query("update " . $this->issuesTable . " set status='%s' where id=%d", $status, $id);
135 }
136 }
137 public function getIssueByID($id){
138 $rec = $this->getDB()->querySingleRec("select * from " . $this->issuesTable . " where id=%d", $id);
139 $rec['data'] = unserialize($rec['data']);
140 return $rec;
141 }
142 public function getIssues(){
143 $issues = wfConfig::get('wf_issues', array());
144 $ret = array(
145 'new' => array(),
146 'ignored' => array()
147 );
148 $q1 = $this->getDB()->query("select * from " . $this->issuesTable . " order by time desc");
149 while($i = mysql_fetch_assoc($q1)){
150 $i['data'] = unserialize($i['data']);
151 $i['timeAgo'] = wfUtils::makeTimeAgo(time() - $i['time']);
152 if($i['status'] == 'new'){
153 $ret['new'][] = $i;
154 } else if($i['status'] == 'ignoreP' || $i['status'] == 'ignoreC'){
155 $ret['ignored'][] = $i;
156 } else {
157 error_log("Issue has bad status: " . $i['status']);
158 continue;
159 }
160 }
161 foreach($ret as $status => &$issueList){
162 for($i = 0; $i < sizeof($issueList); $i++){
163 if($issueList[$i]['type'] == 'file'){
164 $localFile = ABSPATH . '/' . preg_replace('/^[\.\/]+/', '', $issueList[$i]['data']['file']);
165 if(file_exists($localFile)){
166 $issueList[$i]['data']['fileExists'] = true;
167 } else {
168 $issueList[$i]['data']['fileExists'] = '';
169 }
170 }
171 $issueList[$i]['issueIDX'] = $i;
172 }
173 }
174 return $ret; //array of lists of issues by status
175 }
176 public function updateSummaryItem($key, $val){
177 $arr = wfConfig::get_ser('wf_summaryItems', array());
178 $arr[$key] = $val;
179 $arr['lastUpdate'] = time();
180 wfConfig::set_ser('wf_summaryItems', $arr);
181 }
182 public function getSummaryItem($key){
183 $arr = wfConfig::get_ser('wf_summaryItems', array());
184 if(array_key_exists($key, $arr)){
185 return $arr[$key];
186 } else { return ''; }
187 }
188 public function summaryUpdateRequired(){
189 $last = $this->getSummaryItem('lastUpdate');
190 if( (! $last) || (time() - $last > (86400 * 7))){
191 return true;
192 }
193 return false;
194 }
195 public function getSummaryItems(){
196 if(! $this->updateCalled){
197 $this->updateCalled = true;
198 $this->updateSummaryItems();
199 }
200 $arr = wfConfig::get_ser('wf_summaryItems', array());
201 //$arr['scanTimeAgo'] = wfUtils::makeTimeAgo(sprintf('%.0f', time() - $arr['scanTime']));
202 $arr['scanRunning'] = wfUtils::isScanRunning() ? '1' : '0';
203 $arr['scheduledScansEnabled'] = wfConfig::get('scheduledScansEnabled');
204 $secsToGo = wp_next_scheduled('wordfence_scheduled_scan') - time();
205 if($secsToGo < 1){
206 $nextRun = 'now';
207 } else {
208 $nextRun = wfUtils::makeTimeAgo($secsToGo) . ' from now';
209 }
210 $arr['nextRun'] = $nextRun;
211
212 $arr['totalCritical'] = $this->getDB()->querySingle("select count(*) as cnt from " . $this->issuesTable . " where status='new' and severity=1");
213 $arr['totalWarning'] = $this->getDB()->querySingle("select count(*) as cnt from " . $this->issuesTable . " where status='new' and severity=2");
214
215 return $arr;
216 }
217 private function updateSummaryItems(){
218 global $wpdb;
219 $dat = array();
220 $users = $wpdb->get_col($wpdb->prepare("SELECT $wpdb->users.ID FROM $wpdb->users"));
221 $dat['totalUsers'] = sizeof($users);
222 $res1 = $wpdb->get_col($wpdb->prepare("SELECT count(*) as cnt FROM $wpdb->posts where post_type='page' and post_status NOT IN ('auto-draft')")); $dat['totalPages'] = $res1['0'];
223 $res1 = $wpdb->get_col($wpdb->prepare("SELECT count(*) as cnt FROM $wpdb->posts where post_type='post' and post_status NOT IN ('auto-draft')")); $dat['totalPosts'] = $res1['0'];
224 $res1 = $wpdb->get_col($wpdb->prepare("SELECT count(*) as cnt FROM $wpdb->comments")); $dat['totalComments'] = $res1['0'];
225 $res1 = $wpdb->get_col($wpdb->prepare("SELECT count(*) as cnt FROM $wpdb->term_taxonomy where taxonomy='category'")); $dat['totalCategories'] = $res1['0'];
226 $res1 = $wpdb->get_col($wpdb->prepare("show tables")); $dat['totalTables'] = sizeof($res1);
227 $totalRows = 0;
228 foreach($res1 as $table){
229 $res2 = $wpdb->get_col($wpdb->prepare("select count(*) from $table"));
230 $totalRows += $res2[0];
231 }
232 $dat['totalRows'] = $totalRows;
233 $arr = wfConfig::get_ser('wf_summaryItems', array());
234 foreach($dat as $key => $val){
235 $arr[$key] = $val;
236 }
237 wfConfig::set_ser('wf_summaryItems', $arr);
238 }
239 public function setScanTimeNow(){
240 $this->updateSummaryItem('scanTime', microtime(true));
241 }
242 public function getScanTime(){
243 return $this->getSummaryItem('scanTime');
244 }
245 private function getDB(){
246 if(! $this->db){
247 $this->db = new wfDB();
248 }
249 return $this->db;
250 }
251 }
252
253 ?>
254