: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
require_once(dirname(__FILE__) . '/wordfenceConstants.php');
require_once(dirname(__FILE__) . '/wfScanEngine.php');
require_once(dirname(__FILE__) . '/wfScan.php');
require_once(dirname(__FILE__) . '/wfScanMonitor.php');
require_once(dirname(__FILE__) . '/wfCrawl.php');
require_once(dirname(__FILE__) . '/Diff.php');
require_once(dirname(__FILE__) . '/Diff/Renderer/Html/SideBySide.php');
require_once(dirname(__FILE__) . '/wfAPI.php');
require_once(dirname(__FILE__) . '/wfIssues.php');
require_once(dirname(__FILE__) . '/wfDB.php');
require_once(dirname(__FILE__) . '/wfUtils.php');
require_once(dirname(__FILE__) . '/wfLog.php');
require_once(dirname(__FILE__) . '/wfConfig.php');
require_once(dirname(__FILE__) . '/wfSchema.php');
require_once(dirname(__FILE__) . '/wfCache.php');
require_once(dirname(__FILE__) . '/wfCrypt.php');
require_once(dirname(__FILE__) . '/wfMD5BloomFilter.php');
require_once(dirname(__FILE__) . '/wfView.php');
require_once(dirname(__FILE__) . '/wfHelperString.php');
require_once(dirname(__FILE__) . '/wfDirectoryIterator.php');
require_once(dirname(__FILE__) . '/wfUpdateCheck.php');
require_once(dirname(__FILE__) . '/wfActivityReport.php');
require_once(dirname(__FILE__) . '/wfHelperBin.php');
require_once(dirname(__FILE__) . '/wfDiagnostic.php');
require_once(dirname(__FILE__) . '/wfStyle.php');
require_once(dirname(__FILE__) . '/wfDashboard.php');
require_once(dirname(__FILE__) . '/wfNotification.php');
require_once(dirname(__FILE__) . '/../models/page/wfPage.php');
require_once(dirname(__FILE__) . '/../models/common/wfTab.php');
require_once(dirname(__FILE__) . '/../models/block/wfBlock.php');
require_once(dirname(__FILE__) . '/../models/block/wfRateLimit.php');
require_once(dirname(__FILE__) . '/../models/firewall/wfFirewall.php');
require_once(dirname(__FILE__) . '/../models/scanner/wfScanner.php');
require_once(dirname(__FILE__) . '/wfPersistenceController.php');
require_once(dirname(__FILE__) . '/wfImportExportController.php');
require_once(dirname(__FILE__) . '/wfOnboardingController.php');
require_once(dirname(__FILE__) . '/wfSupportController.php');
require_once(dirname(__FILE__) . '/wfCredentialsController.php');
require_once(dirname(__FILE__) . '/wfVersionCheckController.php');
require_once(dirname(__FILE__) . '/wfDateLocalization.php');
require_once(dirname(__FILE__) . '/wfAdminNoticeQueue.php');
require_once(dirname(__FILE__) . '/wfModuleController.php');
require_once(dirname(__FILE__) . '/wfAlerts.php');
require_once(dirname(__FILE__) . '/wfDeactivationOption.php');
if (version_compare(phpversion(), '5.3', '>=')) {
require_once(dirname(__FILE__) . '/WFLSPHP52Compatability.php');
define('WORDFENCE_USE_LEGACY_2FA', wfCredentialsController::useLegacy2FA());
require(dirname(__FILE__) . '/../modules/login-security/wordfence-login-security.php');
require_once(dirname(__FILE__) . '/wfJWT.php');
require_once(dirname(__FILE__) . '/wfCentralAPI.php');
if (class_exists('WP_REST_Users_Controller')) { //WP 4.7+
require_once(dirname(__FILE__) . '/wfRESTAPI.php');
if (wfCentral::isSupported()) { //WP 4.4.0+
require_once(dirname(__FILE__) . '/rest-api/wfRESTAuthenticationController.php');
require_once(dirname(__FILE__) . '/rest-api/wfRESTConfigController.php');
require_once(dirname(__FILE__) . '/rest-api/wfRESTScanController.php');
public static $printStatus = false;
public static $wordfence_wp_version = false;
public static $authError;
private static $passwordCodePattern = '/\s+wf([a-z0-9 ]+)$/i';
protected static $lastURLError = false;
protected static $curlContent = "";
protected static $curlDataWritten = 0;
protected static $hasher = '';
protected static $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
protected static $ignoreList = false;
private static $wfLog = false;
private static $hitID = 0;
private static $debugOn = null;
private static $runInstallCalled = false;
private static $userDat = false;
const ATTACK_DATA_BODY_LIMIT=41943040; //40MB
public static function installPlugin(){
if (get_current_user_id() > 0) {
wfConfig::set('activatingIP', wfUtils::getIP());
update_option('wordfenceActivated', 1);
if (defined('WORDFENCE_LS_FROM_CORE') && WORDFENCE_LS_FROM_CORE) {
WFLSPHP52Compatability::install_plugin();
public static function uninstallPlugin(){
$currentUser = wp_get_current_user();
$username = $currentUser->user_login;
$alertCallback = array(new wfWordfenceDeactivatedAlert($username, wfUtils::getIP()), 'send');
do_action('wordfence_security_event', 'wordfenceDeactivated', array(
'ip' => wfUtils::getIP(),
//Check if caching is enabled and if it is, disable it and fix the .htaccess file.
wfCache::removeCaching();
update_option('wordfenceActivated', 0);
wp_clear_scheduled_hook('wordfence_daily_cron');
wp_clear_scheduled_hook('wordfence_hourly_cron');
wp_clear_scheduled_hook('wordfence_daily_autoUpdate');
//Remove old legacy cron job if it exists
wp_clear_scheduled_hook('wordfence_scheduled_scan');
//Remove all scheduled scans.
wfScanner::shared()->unscheduleAllScans();
wfScanMonitor::handleDeactivation();
// Remove cron for email summary
wfActivityReport::clearCronJobs();
// Remove the admin user list so it can be regenerated if Wordfence is reactivated.
wfConfig::set_ser('adminUserList', false);
if (!WFWAF_SUBDIRECTORY_INSTALL) {
wfWAFConfig::set('wafDisabled', true);
if(wfConfig::get('deleteTablesOnDeact')){
if (wfCentral::isSupported() && wfCentral::isConnected()) {
self::ajax_wfcentral_disconnect_callback();
wfConfig::updateTableExists(false);
$schema = new wfSchema();
foreach(array('wordfence_version', 'wordfenceActivated', wfSchema::TABLE_CASE_OPTION) as $opt) {
if (is_multisite() && function_exists('delete_network_option')) {
delete_network_option(null, $opt);
if (!WFWAF_SUBDIRECTORY_INSTALL) {
if (WFWAF_AUTO_PREPEND) {
$helper = new wfWAFAutoPrependHelper();
if ($helper->uninstall()) {
wfWAF::getInstance()->uninstall();
wfWAF::getInstance()->uninstall();
} catch (wfWAFStorageFileException $e) {
error_log($e->getMessage());
} catch (wfWAFStorageEngineMySQLiException $e) {
error_log($e->getMessage());
if (defined('WORDFENCE_LS_FROM_CORE') && WORDFENCE_LS_FROM_CORE) {
WFLSPHP52Compatability::uninstall_plugin();
public static function hourlyCron() {
wfCentral::checkForUnsentSecurityEvents();
wfCentral::populateCentralSiteUrl();
wfVersionCheckController::shared()->checkVersionsAndWarn();
if (wfScanner::shared()->shouldRunQuickScan()) {
wfScanner::shared()->recordLastQuickScanTime();
wfScanEngine::startScan(false, wfScanner::SCAN_TYPE_QUICK);
private static function keyAlert($msg){
self::alert($msg, $msg . " " . __("To ensure uninterrupted Premium Wordfence protection on your site,\nplease renew your license by visiting http://www.wordfence.com/ Sign in, go to your dashboard,\nselect the license about to expire and click the button to renew that license.", 'wordfence'), false);
private static function pingApiKey() {
$apiKey = wfConfig::get('apiKey');
$api = new wfAPI($apiKey, wfUtils::getWPVersion());
$keyType = wfLicense::KEY_TYPE_FREE;
$keyData = $api->call('ping_api_key', array(), array('supportHash' => wfConfig::get('supportHash', ''), 'whitelistHash' => wfConfig::get('whitelistHash', ''), 'tldlistHash' => wfConfig::get('tldlistHash', ''), 'ipResolutionListHash' => wfConfig::get('ipResolutionListHash', '')));
if (isset($keyData['_isPaidKey'])) {
$keyType = wfConfig::get('keyType');
if (isset($keyData['_feedbackBasis'])) {
wfConfig::setBool('satisfactionPromptOverride', $keyData['_feedbackBasis'] > WORDFENCE_FEEDBACK_EPOCH);
if(isset($keyData['_isPaidKey']) && $keyData['_isPaidKey']){
$keyExpDays = $keyData['_keyExpDays'];
$keyIsExpired = $keyData['_expired'];
if (!empty($keyData['_autoRenew'])) {
wfConfig::set('keyAutoRenew10Sent', '');
} else if ($keyExpDays <= 12 && $keyExpDays > 0 && !wfConfig::get('keyAutoRenew10Sent')) {
wfConfig::set('keyAutoRenew10Sent', 1);
$email = __("Your Premium Wordfence License is set to auto-renew in 10 days.", 'wordfence');
self::alert($email, $email . " " . __("To update your license settings please visit http://www.wordfence.com/zz9/dashboard", 'wordfence'), false);
wfConfig::set('keyExp15Sent', '');
wfConfig::set('keyExp7Sent', '');
wfConfig::set('keyExp2Sent', '');
wfConfig::set('keyExp1Sent', '');
wfConfig::set('keyExpFinalSent', '');
} else if($keyExpDays <= 15 && $keyExpDays > 0){
if($keyExpDays <= 15 && $keyExpDays >= 11 && (! wfConfig::get('keyExp15Sent'))){
wfConfig::set('keyExp15Sent', 1);
self::keyAlert(__("Your Premium Wordfence License expires in less than 2 weeks.", 'wordfence'));
} else if($keyExpDays <= 7 && $keyExpDays >= 4 && (! wfConfig::get('keyExp7Sent'))){
wfConfig::set('keyExp7Sent', 1);
self::keyAlert(__("Your Premium Wordfence License expires in less than a week.", 'wordfence'));
} else if($keyExpDays == 2 && (! wfConfig::get('keyExp2Sent'))){
wfConfig::set('keyExp2Sent', 1);
self::keyAlert(__("Your Premium Wordfence License expires in 2 days.", 'wordfence'));
} else if($keyExpDays == 1 && (! wfConfig::get('keyExp1Sent'))){
wfConfig::set('keyExp1Sent', 1);
self::keyAlert(__("Your Premium Wordfence License expires in 1 day.", 'wordfence'));
} else if($keyIsExpired && (! wfConfig::get('keyExpFinalSent')) ){
wfConfig::set('keyExpFinalSent', 1);
self::keyAlert(__("Your Wordfence Premium License has Expired!", 'wordfence'));
if (isset($keyData['dashboard'])) {
wfConfig::set('lastDashboardCheck', time());
wfDashboard::processDashboardResponse($keyData['dashboard']);
if (isset($keyData['support']) && isset($keyData['supportHash'])) {
wfConfig::set('supportContent', $keyData['support'], wfConfig::DONT_AUTOLOAD);
wfConfig::set('supportHash', $keyData['supportHash']);
if (isset($keyData['_whitelist']) && isset($keyData['_whitelistHash'])) {
wfConfig::setJSON('whitelistPresets', $keyData['_whitelist']);
wfConfig::set('whitelistHash', $keyData['_whitelistHash']);
if (isset($keyData['_tldlist']) && isset($keyData['_tldlistHash'])) {
wfConfig::set('tldlist', $keyData['_tldlist'], wfConfig::DONT_AUTOLOAD);
wfConfig::set('tldlistHash', $keyData['_tldlistHash']);
if (isset($keyData['_ipResolutionList']) && isset($keyData['_ipResolutionListHash'])) {
wfConfig::setJSON('ipResolutionList', $keyData['_ipResolutionList']);
wfConfig::set('ipResolutionListHash', $keyData['_ipResolutionListHash']);
if (isset($keyData['scanSchedule']) && is_array($keyData['scanSchedule'])) {
wfConfig::set_ser('noc1ScanSchedule', $keyData['scanSchedule']);
if (wfScanner::shared()->schedulingMode() == wfScanner::SCAN_SCHEDULING_MODE_AUTOMATIC) {
wfScanner::shared()->scheduleScans();
if (isset($keyData['showWfCentralUI'])) {
wfConfig::set('showWfCentralUI', (int) $keyData['showWfCentralUI']);
if (isset($keyData['_keyNoLongerValid']) && $keyData['_keyNoLongerValid'] == 1) {
if (wfConfig::get('keyDeletedNotice') !== $apiKey) {
$keyDeletedNoticeSent = self::alert(__("The Wordfence Premium License in use on this site has been removed from your account.", 'wordfence'), __("The license you were using has been removed from your account. Please reach out to billing@wordfence.com or create a Premium support case at https://support.wordfence.com/support/tickets for more information. Our staff is happy to help.", 'wordfence'), false);
if ($keyDeletedNoticeSent) {
wfConfig::set('keyDeletedNotice', $apiKey);
wfConfig::set('keyType', $keyType);
wordfence::status(4, 'error', sprintf(/* translators: Wordfence license key. */ __("Could not verify Wordfence License: %s", 'wordfence'), $e->getMessage()));
public static function dailyCron() {
$lastDailyCron = (int) wfConfig::get('lastDailyCron', 0);
if (($lastDailyCron + 43200) > time()) { //Run no more frequently than every 12 hours
wfConfig::set('lastDailyCron', time());
$version = $wpdb->get_var("SELECT VERSION()");
wfConfig::set('dbVersion', $version);
$allowMySQLi = wfConfig::testDB();
wfConfig::set('allowMySQLi', $allowMySQLi);
$table_wfLocs = wfDB::networkTable('wfLocs');
$wfdb->queryWrite("delete from {$table_wfLocs} where ctime < unix_timestamp() - %d", WORDFENCE_MAX_IPLOC_AGE);
$table_wfCrawlers = wfDB::networkTable('wfCrawlers');
$wfdb->queryWrite("delete from {$table_wfCrawlers} where lastUpdate < unix_timestamp() - (86400 * 7)");
$maxRows = absint(wfConfig::get('liveTraf_maxRows', 2000));; //affects stuff further down too
$table_wfLogins = wfDB::networkTable('wfLogins');
$count2 = $wfdb->querySingle("select count(*) as cnt from {$table_wfLogins}");
$wfdb->truncate($table_wfLogins); //in case of Dos
} else if($count2 > $maxRows){
$wfdb->queryWrite("delete from {$table_wfLogins} order by ctime asc limit %d", ($count2 - $maxRows));
wfCentral::trimSecurityEvents();
$table_wfReverseCache = wfDB::networkTable('wfReverseCache');
$wfdb->queryWrite("delete from {$table_wfReverseCache} where unix_timestamp() - lastUpdate > 86400");
$table_wfStatus = wfDB::networkTable('wfStatus');
$count4 = $wfdb->querySingle("select count(*) as cnt from {$table_wfStatus}");
$wfdb->truncate($table_wfStatus);
} else if($count4 > 1000){ //max status events we keep. This determines how much gets emailed to us when users sends us a debug report.
$wfdb->queryWrite("delete from {$table_wfStatus} where level != 10 order by ctime asc limit %d", ($count4 - 1000));
$count5 = $wfdb->querySingle("select count(*) as cnt from {$table_wfStatus} where level=10");
$wfdb->queryWrite("delete from {$table_wfStatus} where level = 10 order by ctime asc limit %d", ($count5 - 100) );
$report = new wfActivityReport();
self::_refreshUpdateNotification($report, true);
wfUpdateCheck::syncAllVersionInfo();
self::purgeWafFailures();
wfConfig::remove('lastPermissionsTemplateCheck');
public static function _scheduleRefreshUpdateNotification($upgrader = null, $options = null) {
if (is_array($options) && isset($options['type']) && $options['type'] == 'core') {
set_site_transient('wordfence_updating_notifications', true, 600);
wp_schedule_single_event(time(), 'wordfence_refreshUpdateNotification');
self::_refreshUpdateNotification();
public static function _refreshUpdateNotification($report = null, $useCachedValued = false) {
$report = new wfActivityReport();
$updatesNeeded = $report->getUpdatesNeeded($useCachedValued);
if ($updatesNeeded['core']) {
$items[] = sprintf(/* translators: WordPress version. */ __('WordPress (v%s)', 'wordfence'), esc_html($updatesNeeded['core']));
if ($updatesNeeded['plugins']) {
$entry = sprintf(/* translators: Number of plugins. */ _n('%d plugin', '%d plugins', count($updatesNeeded['plugins']), 'wordfence'), count($updatesNeeded['plugins']));
if ($updatesNeeded['themes']) {
$entry = sprintf(/* translators: Number of themes. */ _n('%d theme', '%d themes', count($updatesNeeded['themes']), 'wordfence'), count($updatesNeeded['themes']));
$message = _n('An update is available for ', 'Updates are available for ', count($items), 'wordfence');
for ($i = 0; $i < count($items); $i++) {
if ($i > 0 && count($items) > 2) { $message .= ', '; }
else if ($i > 0) { $message .= ' '; }
if ($i > 0 && $i == count($items) - 1) { $message .= __('and ', 'wordfence'); }
new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, '<a href="' . wfUtils::wpAdminURL('update-core.php') . '">' . $message . '</a>', 'wfplugin_updates');
$n = wfNotification::getNotificationForCategory('wfplugin_updates');
$i->reconcileUpgradeIssues($report, true);
wp_schedule_single_event(time(), 'wordfence_completeCoreUpdateNotification');
public static function _completeCoreUpdateNotification() {
//This approach is here because WP Core updates run in a different sequence than plugin/theme updates, so we have to defer the running of the notification update sequence by an extra page load
delete_site_transient('wordfence_updating_notifications');
wfVersionCheckController::shared()->checkVersionsAndWarn();
private static function scheduleCrons($delay = 0) {
wp_clear_scheduled_hook('wordfence_daily_cron');
wp_clear_scheduled_hook('wordfence_hourly_cron');
wfConfig::remove('lastDailyCron');
wp_schedule_event(time() + $delay, 'daily', 'wordfence_daily_cron'); //'daily'
wp_schedule_event(time() + $delay, 'hourly', 'wordfence_hourly_cron');
public static function runInstall(){
if(self::$runInstallCalled){ return; }
self::$runInstallCalled = true;
if (function_exists('ignore_user_abort')) {
@ignore_user_abort(true);
if (!defined('DONOTCACHEDB')) { define('DONOTCACHEDB', true); }
$previous_version = ((is_multisite() && function_exists('get_network_option')) ? get_network_option(null, 'wordfence_version', '0.0.0') : get_option('wordfence_version', '0.0.0'));
if (is_multisite() && function_exists('update_network_option')) {
update_network_option(null, 'wordfence_version', WORDFENCE_VERSION); //In case we have a fatal error we don't want to keep running install.
update_option('wordfence_version', WORDFENCE_VERSION); //In case we have a fatal error we don't want to keep running install.
wordfence::status(4, 'info', sprintf(/* translators: Wordfence version. */ __('`runInstall` called with previous version = %s', 'wordfence'), $previous_version));
//EVERYTHING HERE MUST BE IDEMPOTENT
//Remove old legacy cron job if exists
wp_clear_scheduled_hook('wordfence_scheduled_scan');
wfSchema::updateTableCase();
$schema = new wfSchema();
$schema->createAll(); //if not exists
wfConfig::updateTableExists(true);
$configTable = wfDB::networkTable('wfConfig');
$hasAutoload = $wpdb->get_col($wpdb->prepare(<<<SQL
SELECT * FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=DATABASE()
AND COLUMN_NAME='autoload'
$wpdb->query("ALTER TABLE {$configTable} ADD COLUMN autoload ENUM('no', 'yes') NOT NULL DEFAULT 'yes'");
$wpdb->query("UPDATE {$configTable} SET autoload = 'no' WHERE name = 'wfsd_engine' OR name LIKE 'wordfence_chunked_%'");
$wpdb->query("DELETE FROM $configTable WHERE `name` = 'emailedIssuesList' AND LENGTH(`val`) > 2 * 1024 * 1024");
wfConfig::setDefaults(); //If not set
$restOfSite = wfConfig::get('cbl_restOfSiteBlocked', 'notset');
if($restOfSite == 'notset'){
wfConfig::set('cbl_restOfSiteBlocked', '1');
if(wfConfig::get('autoUpdate') == '1'){
wfConfig::enableAutoUpdate(); //Sets up the cron
$freshAPIKey = !wfConfig::get('apiKey');
wfConfig::set('touppPromptNeeded', true);
// IPv6 schema changes for 6.0.1
$tables_with_ips = array(