PluginProbe ʕ •ᴥ•ʔ
Wordfence Security – Firewall, Malware Scan, and Login Security / 7.4.4
Wordfence Security – Firewall, Malware Scan, and Login Security v7.4.4
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 / waf / wfWAFIPBlocksController.php
wordfence / waf Last commit date
.htaccess 7 years ago bootstrap.php 6 years ago wfWAFGeoIP2.php 7 years ago wfWAFIPBlocksController.php 6 years ago wfWAFUserIPRange.php 7 years ago
wfWAFIPBlocksController.php
530 lines
1 <?php
2 if (!defined('WFWAF_RUN_COMPLETE')) {
3
4 class wfWAFIPBlocksController
5 {
6 const WFWAF_BLOCK_UAREFIPRANGE = 'UA/Referrer/IP Range not allowed';
7 const WFWAF_BLOCK_COUNTRY = 'blocked access via country blocking';
8 const WFWAF_BLOCK_COUNTRY_REDIR = 'blocked access via country blocking and redirected to URL';
9 const WFWAF_BLOCK_COUNTRY_BYPASS_REDIR = 'redirected to bypass URL';
10 const WFWAF_BLOCK_WFSN = 'Blocked by Wordfence Security Network';
11 const WFWAF_BLOCK_BADPOST = 'POST received with blank user-agent and referer';
12 const WFWAF_BLOCK_BANNEDURL = 'Accessed a banned URL.';
13 const WFWAF_BLOCK_FAKEGOOGLE = 'Fake Google crawler automatically blocked';
14 const WFWAF_BLOCK_LOGINSEC = 'Blocked by login security setting.';
15 const WFWAF_BLOCK_LOGINSEC_FORGOTPASSWD = 'Exceeded the maximum number of tries to recover their password'; //substring search
16 const WFWAF_BLOCK_LOGINSEC_FAILURES = 'Exceeded the maximum number of login failures'; //substring search
17 const WFWAF_BLOCK_THROTTLEGLOBAL = 'Exceeded the maximum global requests per minute for crawlers or humans.';
18 const WFWAF_BLOCK_THROTTLESCAN = 'Exceeded the maximum number of 404 requests per minute for a known security vulnerability.';
19 const WFWAF_BLOCK_THROTTLECRAWLER = 'Exceeded the maximum number of requests per minute for crawlers.';
20 const WFWAF_BLOCK_THROTTLECRAWLERNOTFOUND = 'Exceeded the maximum number of page not found errors per minute for a crawler.';
21 const WFWAF_BLOCK_THROTTLEHUMAN = 'Exceeded the maximum number of page requests per minute for humans.';
22 const WFWAF_BLOCK_THROTTLEHUMANNOTFOUND = 'Exceeded the maximum number of page not found errors per minute for humans.';
23
24 protected static $_currentController = null;
25
26 public static function currentController() {
27 if (self::$_currentController === null) {
28 self::$_currentController = new wfWAFIPBlocksController();
29 }
30 return self::$_currentController;
31 }
32
33 public static function setCurrentController($currentController) {
34 self::$_currentController = $currentController;
35 }
36
37 /**
38 * Schedules a config sync to happen at the end of the current process's execution.
39 */
40 public static function setNeedsSynchronizeConfigSettings() {
41 static $willSynchronize = false;
42 if (!$willSynchronize) {
43 $willSynchronize = true;
44 register_shutdown_function('wfWAFIPBlocksController::synchronizeConfigSettings');
45 }
46 }
47
48 public static function synchronizeConfigSettings() {
49 if (!class_exists('wfConfig') || !wfConfig::tableExists() || !wfWAF::getInstance()) { // Ensure this is only called when WordPress and the plugin are fully loaded
50 return;
51 }
52
53 static $isSynchronizing = false;
54 if ($isSynchronizing) {
55 return;
56 }
57 $isSynchronizing = true;
58
59 // Pattern Blocks
60 $blocks = wfBlock::patternBlocks(true);
61 $patternBlocks = array();
62 foreach ($blocks as $b) {
63 $patternBlocks[] = array('id' => $b->id, 'ipRange' => $b->ipRange, 'hostnamePattern' => $b->hostname, 'uaPattern' => $b->userAgent, 'refPattern' => $b->referrer, 'expiration' => $b->expiration);
64 }
65
66 // Country Blocks
67 $countryBlocks = array();
68 $countryBlockEntries = wfBlock::countryBlocks(true);
69 $countryBlocks['blocks'] = array();
70 foreach ($countryBlockEntries as $b) {
71 $reason = __('Access from your area has been temporarily limited for security reasons', 'wordfence');
72
73 $countryBlocks['blocks'][] = array(
74 'id' => $b->id,
75 'countries' => $b->countries,
76 'blockLogin' => $b->blockLogin,
77 'blockSite' => $b->blockSite,
78 'reason' => $reason,
79 'expiration' => $b->expiration,
80 );
81 }
82 $countryBlocks['action'] = wfConfig::get('cbl_action', false);
83 $countryBlocks['loggedInBlocked'] = wfConfig::get('cbl_loggedInBlocked', false);
84 $countryBlocks['bypassRedirURL'] = wfConfig::get('cbl_bypassRedirURL', '');
85 $countryBlocks['bypassRedirDest'] = wfConfig::get('cbl_bypassRedirDest', '');
86 $countryBlocks['bypassViewURL'] = wfConfig::get('cbl_bypassViewURL', '');
87 $countryBlocks['redirURL'] = wfConfig::get('cbl_redirURL', '');
88 $countryBlocks['cookieVal'] = wfBlock::countryBlockingBypassCookieValue();
89
90 //Other Blocks
91 $otherBlocks = array('blockedTime' => wfConfig::get('blockedTime', 0));
92 $otherBlockEntries = wfBlock::ipBlocks(true);
93 $otherBlocks['blocks'] = array();
94 foreach ($otherBlockEntries as $b) {
95 $reason = $b->reason;
96 if ($b->type == wfBlock::TYPE_IP_MANUAL || $b->type == wfBlock::TYPE_IP_AUTOMATIC_PERMANENT) {
97 $reason = __('Manual block by administrator', 'wordfence');
98 }
99
100 $otherBlocks['blocks'][] = array(
101 'id' => $b->id,
102 'IP' => base64_encode(wfUtils::inet_pton($b->ip)),
103 'reason' => $reason,
104 'expiration' => $b->expiration,
105 );
106 }
107
108 //Lockouts
109 $lockoutEntries = wfBlock::lockouts(true);
110 $lockoutSecs = wfConfig::get('loginSec_lockoutMins') * 60;
111 $lockouts = array('lockedOutTime' => $lockoutSecs, 'lockouts' => array());
112 foreach ($lockoutEntries as $l) {
113 $lockouts['lockouts'][] = array(
114 'id' => $l->id,
115 'IP' => base64_encode(wfUtils::inet_pton($l->ip)),
116 'reason' => $l->reason,
117 'expiration' => $l->expiration,
118 );
119 }
120
121 // Save it
122 try {
123 $patternBlocksJSON = wfWAFUtils::json_encode($patternBlocks);
124 wfWAF::getInstance()->getStorageEngine()->setConfig('patternBlocks', $patternBlocksJSON, 'synced');
125 $countryBlocksJSON = wfWAFUtils::json_encode($countryBlocks);
126 wfWAF::getInstance()->getStorageEngine()->setConfig('countryBlocks', $countryBlocksJSON, 'synced');
127 $otherBlocksJSON = wfWAFUtils::json_encode($otherBlocks);
128 wfWAF::getInstance()->getStorageEngine()->setConfig('otherBlocks', $otherBlocksJSON, 'synced');
129 $lockoutsJSON = wfWAFUtils::json_encode($lockouts);
130 wfWAF::getInstance()->getStorageEngine()->setConfig('lockouts', $lockoutsJSON, 'synced');
131
132 wfWAF::getInstance()->getStorageEngine()->setConfig('advancedBlockingEnabled', wfConfig::get('firewallEnabled'), 'synced');
133 wfWAF::getInstance()->getStorageEngine()->setConfig('disableWAFIPBlocking', wfConfig::get('disableWAFIPBlocking'), 'synced');
134 }
135 catch (Exception $e) {
136 // Do nothing
137 }
138 $isSynchronizing = false;
139 }
140
141 /**
142 * @param wfWAFRequest $request
143 * @return bool|string If not blocked, returns false. Otherwise a string of the reason it was blocked or true.
144 */
145 public function shouldBlockRequest($request) {
146 // Checking the user whitelist is done before reaching this call
147
148 $ip = $request->getIP();
149
150 //Check the system whitelist
151 if ($this->checkForWhitelisted($ip)) {
152 return false;
153 }
154
155 //Let the plugin handle these
156 $wfFunc = $request->getQueryString('_wfsf');
157 if ($wfFunc == 'unlockEmail' || $wfFunc == 'unlockAccess') { // Can't check validity here, let it pass through to plugin level where it can
158 return false;
159 }
160
161 $logHuman = $request->getQueryString('wordfence_lh');
162 if ($logHuman !== null) {
163 return false;
164 }
165
166 //Start block checks
167 $ipNum = wfWAFUtils::inet_pton($ip);
168 $hostname = null;
169 $ua = $request->getHeaders('User-Agent'); if ($ua === null) { $ua = ''; }
170 $referer = $request->getHeaders('Referer'); if ($referer === null) { $referer = ''; }
171
172 $isPaid = false;
173 try {
174 $isPaid = wfWAF::getInstance()->getStorageEngine()->getConfig('isPaid', null, 'synced');
175 $pluginABSPATH = wfWAF::getInstance()->getStorageEngine()->getConfig('pluginABSPATH', null, 'synced');
176
177 $patternBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('patternBlocks', null, 'synced');
178 $countryBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('countryBlocks', null, 'synced');
179 $otherBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('otherBlocks', null, 'synced');
180 $lockoutsJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('lockouts', null, 'synced');
181 }
182 catch (Exception $e) {
183 // Do nothing
184 }
185
186 if (isset($_SERVER['SCRIPT_FILENAME']) && (strpos($_SERVER['SCRIPT_FILENAME'], $pluginABSPATH . "wp-admin/") === 0 || strpos($_SERVER['SCRIPT_FILENAME'], $pluginABSPATH . "wp-content/") === 0 || strpos($_SERVER['SCRIPT_FILENAME'], $pluginABSPATH . "wp-includes/") === 0)) {
187 return false; //Rely on WordPress's own access control and blocking at the plugin level
188 }
189
190 // Pattern Blocks from the Advanced Blocking page (IP Range, UA, Referer)
191 $patternBlocks = @wfWAFUtils::json_decode($patternBlocksJSON, true);
192 if (is_array($patternBlocks)) {
193 // Instead of a long block of if/else statements, using bitshifting to generate an expected value and a found value
194 $ipRangeOffset = 1;
195 $uaPatternOffset = 2;
196 $refPatternOffset = 3;
197
198 foreach ($patternBlocks as $b) {
199 $expectedBits = 0;
200 $foundBits = 0;
201
202 if (isset($b['expiration']) && $b['expiration'] < time() && $b['expiration'] != 0) {
203 continue;
204 }
205
206 if (!empty($b['ipRange'])) {
207 $expectedBits |= (1 << $ipRangeOffset);
208
209 $range = new wfWAFUserIPRange($b['ipRange']);
210 if ($range->isIPInRange($ip)) {
211 $foundBits |= (1 << $ipRangeOffset);
212 }
213 }
214
215 if (!empty($b['hostnamePattern'])) {
216 $expectedBits |= (1 << $ipRangeOffset);
217 if ($hostname === null) {
218 $hostname = wfWAFUtils::reverseLookup($ip);
219 }
220 if (preg_match(wfWAFUtils::patternToRegex($b['hostnamePattern']), $hostname)) {
221 $foundBits |= (1 << $ipRangeOffset);
222 }
223 }
224
225 if (!empty($b['uaPattern'])) {
226 $expectedBits |= (1 << $uaPatternOffset);
227 if (wfWAFUtils::isUABlocked($b['uaPattern'], $ua)) {
228 $foundBits |= (1 << $uaPatternOffset);
229 }
230 }
231
232 if (!empty($b['refPattern'])) {
233 $expectedBits |= (1 << $refPatternOffset);
234 if (wfWAFUtils::isRefererBlocked($b['refPattern'], $referer)) {
235 $foundBits |= (1 << $refPatternOffset);
236 }
237 }
238
239 if ($foundBits === $expectedBits && $expectedBits > 0) {
240 return array('action' => self::WFWAF_BLOCK_UAREFIPRANGE, 'id' => $b['id']);
241 }
242 }
243 }
244 // End Pattern Blocks
245
246 // Country Blocking
247 if ($isPaid) {
248 $countryBlocks = @wfWAFUtils::json_decode($countryBlocksJSON, true);
249 if (is_array($countryBlocks) && isset($countryBlocks['blocks'])) {
250 $blocks = $countryBlocks['blocks'];
251 foreach ($blocks as $b) {
252 $blockedCountries = $b['countries'];
253 $bareRequestURI = wfWAFUtils::extractBareURI($request->getURI());
254 $bareBypassRedirURI = wfWAFUtils::extractBareURI($countryBlocks['bypassRedirURL']);
255 $skipCountryBlocking = false;
256
257 if ($bareBypassRedirURI && $bareRequestURI == $bareBypassRedirURI) { // Run this before country blocking because even if the user isn't blocked we need to set the bypass cookie so they can bypass future blocks.
258 if ($countryBlocks['bypassRedirDest']) {
259 setcookie('wfCBLBypass', $countryBlocks['cookieVal'], time() + (86400 * 365), '/', null, $this->isFullSSL(), true);
260 return array('action' => self::WFWAF_BLOCK_COUNTRY_BYPASS_REDIR, 'id' => $b['id']);
261 }
262 }
263
264 $bareBypassViewURI = wfWAFUtils::extractBareURI($countryBlocks['bypassViewURL']);
265 if ($bareBypassViewURI && $bareBypassViewURI == $bareRequestURI) {
266 setcookie('wfCBLBypass', $countryBlocks['cookieVal'], time() + (86400 * 365), '/', null, $this->isFullSSL(), true);
267 $skipCountryBlocking = true;
268 }
269
270 $bypassCookieSet = false;
271 $bypassCookie = $request->getCookies('wfCBLBypass');
272 if (isset($bypassCookie) && $bypassCookie == $countryBlocks['cookieVal']) {
273 $bypassCookieSet = true;
274 }
275
276 if (!$skipCountryBlocking && $blockedCountries && !$bypassCookieSet) {
277 $isAuthRequest = (strpos($bareRequestURI, '/wp-login.php') !== false);
278 $isXMLRPC = (strpos($bareRequestURI, '/xmlrpc.php') !== false);
279 $isUserLoggedIn = wfWAF::getInstance()->parseAuthCookie() !== false;
280
281 // If everything is checked, make sure this always runs.
282 if ($countryBlocks['loggedInBlocked'] && $b['blockLogin'] && $b['blockSite']) {
283 if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { $blocked['id'] = $b['id']; return $blocked; }
284 }
285 // Block logged in users.
286 if ($countryBlocks['loggedInBlocked'] && $isUserLoggedIn) {
287 if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { $blocked['id'] = $b['id']; return $blocked; }
288 }
289 // Block the login form itself and any attempt to authenticate.
290 if ($b['blockLogin'] && $isAuthRequest) {
291 if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { $blocked['id'] = $b['id']; return $blocked; }
292 }
293 // Block requests that aren't to the login page, xmlrpc.php, or a user already logged in.
294 if ($b['blockSite'] && !$isAuthRequest && !$isXMLRPC && !$isUserLoggedIn) {
295 if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { $blocked['id'] = $b['id']; return $blocked; }
296 }
297 // XMLRPC is inaccesible when public portion of the site and auth is disabled.
298 if ($b['blockLogin'] && $b['blockSite'] && $isXMLRPC) {
299 if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { $blocked['id'] = $b['id']; return $blocked; }
300 }
301
302 // Any bypasses and other block possibilities will be checked at the plugin level once WordPress loads
303 }
304 }
305 }
306 }
307 // End Country Blocking
308
309 // Other Blocks
310 $otherBlocks = @wfWAFUtils::json_decode($otherBlocksJSON, true);
311 if (is_array($otherBlocks)) {
312 $blocks = $otherBlocks['blocks'];
313 $bareRequestURI = wfWAFUtils::extractBareURI($request->getURI());
314 $isAuthRequest = (stripos($bareRequestURI, '/wp-login.php') !== false);
315 foreach ($blocks as $b) {
316 if (isset($b['expiration']) && $b['expiration'] < time() && $b['expiration'] != 0) {
317 continue;
318 }
319
320 if (base64_decode($b['IP']) != $ipNum) {
321 continue;
322 }
323
324 if ($isAuthRequest && isset($b['wfsn']) && $b['wfsn']) {
325 return array('action' => self::WFWAF_BLOCK_WFSN, 'id' => $b['id']);
326 }
327
328 return array('action' => (empty($b['reason']) ? '' : $b['reason']), 'id' => $b['id'], 'block' => true);
329 }
330 }
331 // End Other Blocks
332
333 // Lockouts
334 $lockouts = @wfWAFUtils::json_decode($lockoutsJSON, true);
335 if (is_array($lockouts)) {
336 $lockouts = $lockouts['lockouts'];
337 $isAuthRequest = (stripos($bareRequestURI, '/wp-login.php') !== false) || (stripos($bareRequestURI, '/xmlrpc.php') !== false);
338 if ($isAuthRequest) {
339 foreach ($lockouts as $l) {
340 if (isset($l['expiration']) && $l['expiration'] < time()) {
341 continue;
342 }
343
344 if (base64_decode($l['IP']) != $ipNum) {
345 continue;
346 }
347
348 return array('action' => (empty($l['reason']) ? '' : $l['reason']), 'id' => $l['id'], 'lockout' => true);
349 }
350 }
351 }
352 // End Lockouts
353
354 return false;
355 }
356
357 public function countryRedirURL($countryBlocks = null) {
358 if (!isset($countryBlocks)) {
359 try {
360 $countryBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('countryBlocks', null, 'synced');
361 }
362 catch (Exception $e) {
363 return false;
364 }
365 }
366
367 $countryBlocks = @wfWAFUtils::json_decode($countryBlocksJSON, true);
368 if (is_array($countryBlocks)) {
369 if ($countryBlocks['action'] == 'redir') {
370 return $countryBlocks['redirURL'];
371 }
372 }
373 return false;
374 }
375
376 public function countryBypassRedirURL($countryBlocks = null) {
377 if (!isset($countryBlocks)) {
378 try {
379 $countryBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('countryBlocks', null, 'synced');
380 }
381 catch (Exception $e) {
382 return false;
383 }
384 }
385
386 $countryBlocks = @wfWAFUtils::json_decode($countryBlocksJSON, true);
387 if (is_array($countryBlocks)) {
388 return $countryBlocks['bypassRedirDest'];
389 }
390 return false;
391 }
392
393 protected function checkForBlockedCountry($countryBlock, $ip, $bareRequestURI) {
394 try {
395 $homeURL = wfWAF::getInstance()->getStorageEngine()->getConfig('homeURL', null, 'synced');
396 }
397 catch (Exception $e) {
398 //Do nothing
399 }
400
401 $bareRequestURI = rtrim($bareRequestURI, '/\\');
402 if ($country = $this->ip2Country($ip)) {
403 $blocks = $countryBlock['blocks'];
404 foreach ($blocks as $b) {
405 foreach ($b['countries'] as $blocked) {
406 if (strtoupper($blocked) == strtoupper($country)) {
407 if ($countryBlock['action'] == 'redir') {
408 $redirURL = $countryBlock['redirURL'];
409 $eRedirHost = wfWAFUtils::extractHostname($redirURL);
410 $isExternalRedir = false;
411 if ($eRedirHost && $homeURL && $eRedirHost != wfWAFUtils::extractHostname($homeURL)) {
412 $isExternalRedir = true;
413 }
414
415 if ((!$isExternalRedir) && rtrim(wfWAFUtils::extractBareURI($redirURL), '/\\') == $bareRequestURI){ //Is this the URI we want to redirect to, then don't block it
416 //Do nothing
417 }
418 else {
419 return array('action' => self::WFWAF_BLOCK_COUNTRY_REDIR);
420 }
421 }
422 else {
423 return array('action' => self::WFWAF_BLOCK_COUNTRY);
424 }
425 }
426 }
427 }
428 }
429
430 return false;
431 }
432
433 protected function checkForWhitelisted($ip) {
434 try {
435 $pluginABSPATH = wfWAF::getInstance()->getStorageEngine()->getConfig('pluginABSPATH', null, 'synced');
436 $serverIPsJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('serverIPs', null, 'synced');
437 $whitelistedServiceIPsJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('whitelistedServiceIPs', null, 'synced');
438 }
439 catch (Exception $e) {
440 // Do nothing
441 }
442
443 $serverIPs = @wfWAFUtils::json_decode($serverIPsJSON, true);
444 if (is_array($serverIPs)) {
445 if (
446 (isset($_SERVER['SCRIPT_FILENAME']) && $_SERVER['SCRIPT_FILENAME'] == realpath($pluginABSPATH . DIRECTORY_SEPARATOR . 'wp-cron.php')) || //Safe -- plugin will do a final check to make sure the cron constant is defined
447 (!empty($_GET['wordfence_syncAttackData'])) //Safe but plugin will do a final check to make sure it runs
448 ) {
449 foreach ($serverIPs as $testIP) {
450 if (wfWAFUtils::inet_pton($ip) == wfWAFUtils::inet_pton($testIP)) {
451 return true;
452 }
453 }
454 }
455 }
456
457 $whitelistedServiceIPs = @wfWAFUtils::json_decode($whitelistedServiceIPsJSON, true);
458 if (is_array($whitelistedServiceIPs)) {
459 $wfIPWhitelist = $whitelistedServiceIPs;
460 }
461 else {
462 $wordfenceLib = realpath(dirname(__FILE__) . '/../lib');
463 include($wordfenceLib . '/wfIPWhitelist.php'); /** @var array $wfIPWhitelist */
464 }
465
466 foreach ($wfIPWhitelist as $group) {
467 foreach ($group as $subnet) {
468 if ($subnet instanceof wfWAFUserIPRange) { //Not currently reached
469 if ($subnet->isIPInRange($ip)) {
470 return true;
471 }
472 } elseif (wfWAFUtils::subnetContainsIP($subnet, $ip)) {
473 return true;
474 }
475 }
476 }
477 return false;
478 }
479
480 protected function ip2Country($ip) {
481 if (version_compare(phpversion(), '5.4.0', '<')) {
482 return '';
483 }
484
485 require_once(dirname(__FILE__) . '/wfWAFGeoIP2.php');
486
487 try {
488 $geoip = @wfWAFGeoIP2::shared();
489 $code = @$geoip->countryCode($ip);
490 return is_string($code) ? $code : '';
491 }
492 catch (Exception $e) {
493 //Ignore
494 }
495
496 return '';
497 }
498
499 /**
500 * Returns whether or not the site should be treated as if it's full-time SSL.
501 *
502 * @return bool
503 */
504 protected function isFullSSL() {
505 try {
506 $is_ssl = false; //This is the same code from WP modified so we can use it here
507 if ( isset( $_SERVER['HTTPS'] ) ) {
508 if ( 'on' == strtolower( $_SERVER['HTTPS'] ) ) {
509 $is_ssl = true;
510 }
511
512 if ( '1' == $_SERVER['HTTPS'] ) {
513 $is_ssl = true;
514 }
515 } elseif ( isset($_SERVER['SERVER_PORT'] ) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
516 $is_ssl = true;
517 }
518
519 $homeURL = wfWAF::getInstance()->getStorageEngine()->getConfig('homeURL', null, 'synced');
520 return $is_ssl && parse_url($homeURL, PHP_URL_SCHEME) === 'https';
521 }
522 catch (Exception $e) {
523 //Do nothing
524 }
525
526 return false;
527 }
528 }
529 }
530