Wordfence Security – Firewall & Malware Scan - Version 7.5.0

Version Description

  • March 24, 2021 =

  • Improvement: Translation-readiness: All user-facing strings are now run through WordPress's i18n functions.

  • Improvement: Remove legacy admin functions no longer used within the UI.

  • Improvement: Local GeoIP database update.

  • Improvement: Remove Lynwood IP range from allowlist, and add new AWS IP range.

  • Fix: Fixed bug with unlocking a locked out IP without correctly resetting its failure counters.

  • Fix: Sites using deleted premium licenses correctly revert to free license behavior.

  • Fix: When enabled, cookies are now set for the correct roles on previously used devices.

  • Fix: WAF cron jobs are now skipped when running on the CLI.

  • Fix: PHP 8.0 compatibility - prevent syntax error when linting files.

  • Fix: Fixed issue where PHP 8 notice sometimes cannot be dismissed.

Download this release

Release Info

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

Code changes from version 7.4.14 to 7.5.0

Files changed (107) hide show
  1. css/{activity-report-widget.1607007971.css → activity-report-widget.1616599470.css} +0 -0
  2. css/{diff.1607007971.css → diff.1616599470.css} +0 -0
  3. css/{dt_table.1607007971.css → dt_table.1616599470.css} +0 -0
  4. css/{fullLog.1607007971.css → fullLog.1616599470.css} +0 -0
  5. css/{iptraf.1607007971.css → iptraf.1616599470.css} +0 -0
  6. css/{jquery-ui-timepicker-addon.1607007971.css → jquery-ui-timepicker-addon.1616599470.css} +0 -0
  7. css/{jquery-ui.min.1607007971.css → jquery-ui.min.1616599470.css} +0 -0
  8. css/{jquery-ui.structure.min.1607007971.css → jquery-ui.structure.min.1616599470.css} +0 -0
  9. css/{jquery-ui.theme.min.1607007971.css → jquery-ui.theme.min.1616599470.css} +0 -0
  10. css/{main.1607007971.css → main.1616599470.css} +0 -0
  11. css/{phpinfo.1607007971.css → phpinfo.1616599470.css} +0 -0
  12. css/{wf-adminbar.1607007971.css → wf-adminbar.1616599470.css} +0 -0
  13. css/{wf-colorbox.1607007971.css → wf-colorbox.1616599470.css} +0 -0
  14. css/{wf-font-awesome.1607007971.css → wf-font-awesome.1616599470.css} +0 -0
  15. css/{wf-global.1607007971.css → wf-global.1616599470.css} +0 -0
  16. css/{wf-ionicons.1607007971.css → wf-ionicons.1616599470.css} +0 -0
  17. css/{wf-onboarding.1607007971.css → wf-onboarding.1616599470.css} +0 -0
  18. css/{wf-roboto-font.1607007971.css → wf-roboto-font.1616599470.css} +0 -0
  19. css/{wfselect2.min.1607007971.css → wfselect2.min.1616599470.css} +0 -0
  20. css/{wordfenceBox.1607007971.css → wordfenceBox.1616599470.css} +0 -0
  21. js/{Chart.bundle.min.1607007971.js → Chart.bundle.min.1616599470.js} +0 -0
  22. js/{admin.1607007971.js → admin.1616599470.js} +118 -105
  23. js/{admin.ajaxWatcher.1607007971.js → admin.ajaxWatcher.1616599470.js} +7 -4
  24. js/{admin.liveTraffic.1607007971.js → admin.liveTraffic.1616599470.js} +71 -69
  25. js/{date.1607007971.js → date.1616599470.js} +0 -0
  26. js/{jquery-ui-timepicker-addon.1607007971.js → jquery-ui-timepicker-addon.1616599470.js} +0 -0
  27. js/{jquery.colorbox-min.1607007971.js → jquery.colorbox-min.1616599470.js} +0 -0
  28. js/{jquery.colorbox.1607007971.js → jquery.colorbox.1616599470.js} +0 -0
  29. js/{jquery.dataTables.min.1607007971.js → jquery.dataTables.min.1616599470.js} +0 -0
  30. js/{jquery.qrcode.min.1607007971.js → jquery.qrcode.min.1616599470.js} +0 -0
  31. js/{jquery.tmpl.min.1607007971.js → jquery.tmpl.min.1616599470.js} +0 -0
  32. js/{jquery.tools.min.1607007971.js → jquery.tools.min.1616599470.js} +0 -0
  33. js/{knockout-3.3.0.1607007971.js → knockout-3.3.0.1616599470.js} +0 -0
  34. js/{wfdashboard.1607007971.js → wfdashboard.1616599470.js} +0 -0
  35. js/{wfdropdown.1607007971.js → wfdropdown.1616599470.js} +0 -0
  36. js/{wfglobal.1607007971.js → wfglobal.1616599470.js} +7 -12
  37. js/wfi18n.1616599470.js +225 -0
  38. js/{wfpopover.1607007971.js → wfpopover.1616599470.js} +0 -0
  39. js/{wfselect2.min.1607007971.js → wfselect2.min.1616599470.js} +0 -0
  40. languages/wordfence.mo +0 -0
  41. languages/wordfence.po +4554 -1541
  42. lib/GeoLite2-Country.mmdb +0 -0
  43. lib/IPTraf.php +8 -3
  44. lib/IPTrafList.php +22 -27
  45. lib/conntest.php +0 -86
  46. lib/cronview.php +0 -33
  47. lib/dashboard/widget_content_countries.php +2 -2
  48. lib/dashboard/widget_content_ips.php +3 -3
  49. lib/dashboard/widget_content_logins.php +3 -3
  50. lib/dashboard/widget_countries.php +5 -5
  51. lib/dashboard/widget_ips.php +15 -15
  52. lib/dashboard/widget_localattacks.php +9 -7
  53. lib/dashboard/widget_logins.php +11 -11
  54. lib/dashboard/widget_networkattacks.php +9 -6
  55. lib/dashboard/widget_notifications.php +15 -11
  56. lib/dashboard/widget_tdf.php +0 -53
  57. lib/dbview.php +0 -32
  58. lib/diffResult.php +17 -17
  59. lib/email_genericAlert.php +13 -6
  60. lib/email_newIssues.php +57 -29
  61. lib/email_unlockRequest.php +12 -8
  62. lib/email_unsubscribeRequest.php +10 -4
  63. lib/live_activity.php +2 -2
  64. lib/menu_dashboard.php +56 -42
  65. lib/menu_dashboard_options.php +21 -11
  66. lib/menu_firewall.php +3 -3
  67. lib/menu_firewall_blocking.php +26 -24
  68. lib/menu_firewall_blocking_options.php +6 -4
  69. lib/menu_firewall_waf.php +18 -18
  70. lib/menu_firewall_waf_options.php +2 -2
  71. lib/menu_options.php +6 -6
  72. lib/menu_scanner.php +26 -24
  73. lib/menu_scanner_credentials.php +4 -2
  74. lib/menu_scanner_options.php +3 -3
  75. lib/menu_support.php +24 -22
  76. lib/menu_tools_diagnostic.php +88 -74
  77. lib/menu_tools_importExport.php +6 -4
  78. lib/menu_tools_livetraffic.php +116 -91
  79. lib/menu_tools_twoFactor.php +25 -25
  80. lib/menu_tools_whois.php +13 -9
  81. lib/menu_wordfence_central.php +16 -14
  82. lib/rest-api/wfRESTConfigController.php +18 -6
  83. lib/rest-api/wfRESTScanController.php +1 -1
  84. lib/sysinfo.php +3 -3
  85. lib/unknownFiles.php +0 -158
  86. lib/viewFullActivityLog.php +2 -1
  87. lib/wf503.php +13 -13
  88. lib/wfAPI.php +18 -9
  89. lib/wfActivityReport.php +10 -10
  90. lib/wfAdminNoticeQueue.php +7 -2
  91. lib/wfAlerts.php +17 -13
  92. lib/wfCentralAPI.php +3 -1
  93. lib/wfConfig.php +46 -18
  94. lib/wfDiagnostic.php +9 -9
  95. lib/wfIPWhitelist.php +2 -2
  96. lib/wfImportExportController.php +3 -3
  97. lib/wfLockedOut.php +16 -16
  98. lib/wfLog.php +6 -6
  99. lib/wfScan.php +81 -40
  100. lib/wfScanEngine.php +1052 -700
  101. lib/wfSupportController.php +4 -2
  102. lib/wfUnlockMsg.php +1 -1
  103. lib/wfUtils.php +28 -27
  104. lib/wfVersionCheckController.php +44 -8
  105. lib/wfView.php +3 -3
  106. lib/wfViewResult.php +7 -7
  107. lib/wordfenceClass.php +564 -253
css/{activity-report-widget.1607007971.css → activity-report-widget.1616599470.css} RENAMED
File without changes
css/{diff.1607007971.css → diff.1616599470.css} RENAMED
File without changes
css/{dt_table.1607007971.css → dt_table.1616599470.css} RENAMED
File without changes
css/{fullLog.1607007971.css → fullLog.1616599470.css} RENAMED
File without changes
css/{iptraf.1607007971.css → iptraf.1616599470.css} RENAMED
File without changes
css/{jquery-ui-timepicker-addon.1607007971.css → jquery-ui-timepicker-addon.1616599470.css} RENAMED
File without changes
css/{jquery-ui.min.1607007971.css → jquery-ui.min.1616599470.css} RENAMED
File without changes
css/{jquery-ui.structure.min.1607007971.css → jquery-ui.structure.min.1616599470.css} RENAMED
File without changes
css/{jquery-ui.theme.min.1607007971.css → jquery-ui.theme.min.1616599470.css} RENAMED
File without changes
css/{main.1607007971.css → main.1616599470.css} RENAMED
File without changes
css/{phpinfo.1607007971.css → phpinfo.1616599470.css} RENAMED
File without changes
css/{wf-adminbar.1607007971.css → wf-adminbar.1616599470.css} RENAMED
File without changes
css/{wf-colorbox.1607007971.css → wf-colorbox.1616599470.css} RENAMED
File without changes
css/{wf-font-awesome.1607007971.css → wf-font-awesome.1616599470.css} RENAMED
File without changes
css/{wf-global.1607007971.css → wf-global.1616599470.css} RENAMED
File without changes
css/{wf-ionicons.1607007971.css → wf-ionicons.1616599470.css} RENAMED
File without changes
css/{wf-onboarding.1607007971.css → wf-onboarding.1616599470.css} RENAMED
File without changes
css/{wf-roboto-font.1607007971.css → wf-roboto-font.1616599470.css} RENAMED
File without changes
css/{wfselect2.min.1607007971.css → wfselect2.min.1616599470.css} RENAMED
File without changes
css/{wordfenceBox.1607007971.css → wordfenceBox.1616599470.css} RENAMED
File without changes
js/{Chart.bundle.min.1607007971.js → Chart.bundle.min.1616599470.js} RENAMED
File without changes
js/{admin.1607007971.js → admin.1616599470.js} RENAMED
@@ -1,4 +1,7 @@
1
  (function($) {
 
 
 
2
  if (!window['wordfenceAdmin']) { //To compile for checking: java -jar /usr/local/bin/closure.jar --js=admin.js --js_output_file=test.js
3
  window['wordfenceAdmin'] = {
4
  isSmallScreen: false,
@@ -84,14 +87,14 @@
84
  $('#doSendEmail').click(function() {
85
  var ticket = $('#_ticketnumber').val();
86
  if (ticket === null || typeof ticket === "undefined" || ticket.length == 0) {
87
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "Error", "Please include your support ticket number or forum username.");
88
  return;
89
  }
90
  WFAD.ajax('wordfence_sendDiagnostic', {email: $('#_email').val(), ticket: ticket}, function(res) {
91
  if (res.result) {
92
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "Email Diagnostic Report", "Diagnostic report has been sent successfully.");
93
  } else {
94
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "Error", "There was an error while sending the email.");
95
  }
96
  });
97
  });
@@ -761,8 +764,7 @@
761
  var self = this;
762
  this.ajax('wordfence_sendTestEmail', {email: email}, function(res) {
763
  if (res.result) {
764
- self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), "Test Email Sent", "Your test email was sent to the requested email address. The result we received from the WordPress wp_mail() function was: " +
765
- res.result + "<br /><br />A 'True' result means WordPress thinks the mail was sent without errors. A 'False' result means that WordPress encountered an error sending your mail. Note that it's possible to get a 'True' response with an error elsewhere in your mail system that may cause emails to not be delivered.");
766
  }
767
  });
768
  },
@@ -868,7 +870,7 @@
868
  showLoading: function() {
869
  this.loadingCount++;
870
  if (this.loadingCount == 1) {
871
- $('<div id="wordfenceWorking">Wordfence is working...</div>').appendTo('body');
872
  }
873
  },
874
  removeLoading: function() {
@@ -1030,7 +1032,7 @@
1030
  }
1031
 
1032
  var sigTimestampEl = $('#wf-scan-sigs-last-update');
1033
- var newText = 'Last Updated: ' + dateString;
1034
  if (sigTimestampEl.text() !== newText) {
1035
  sigTimestampEl.text(newText)
1036
  .css({
@@ -1146,21 +1148,21 @@
1146
  summaryUpdated = true;
1147
  } else if (item.msg.indexOf('SUM_DISABLED:') != -1) {
1148
  msg = item.msg.replace('SUM_DISABLED:', '');
1149
- jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult">Disabled</div><div class="wfClear"></div>');
1150
  summaryUpdated = true;
1151
  } else if (item.msg.indexOf('SUM_PAIDONLY:') != -1) {
1152
  msg = item.msg.replace('SUM_PAIDONLY:', '');
1153
- jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult"><a href="https://www.wordfence.com/wordfence-signup/" target="_blank" rel="noopener noreferrer">Paid Members Only</a></div><div class="wfClear"></div>');
1154
  summaryUpdated = true;
1155
  } else if (item.msg.indexOf('SUM_FINAL:') != -1) {
1156
  msg = item.msg.replace('SUM_FINAL:', '');
1157
- jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg wfSummaryFinal">' + msg + '</div><div class="wfSummaryResult wfSummaryOK">Scan Complete.</div><div class="wfClear"></div>');
1158
  } else if (item.msg.indexOf('SUM_PREP:') != -1) {
1159
  msg = item.msg.replace('SUM_PREP:', '');
1160
  jQuery('#consoleSummary').empty().html('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult" id="wfStartingScan"><div class="wfSummaryLoading"></div></div><div class="wfClear"></div>');
1161
  } else if (item.msg.indexOf('SUM_KILLED:') != -1) {
1162
  msg = item.msg.replace('SUM_KILLED:', '');
1163
- jQuery('#consoleSummary').empty().html('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult wfSummaryOK">Scan Complete.</div><div class="wfClear"></div>');
1164
  }
1165
  },
1166
  processActQueueItem: function() {
@@ -1586,7 +1588,7 @@
1586
  WFAD.updateIssueCounts(res.issueCounts);
1587
  WFAD.repositionSiteCleaningCallout();
1588
  WFAD.updateBulkButtons();
1589
- WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), "Success deleting file", "The file " + res.file + " was successfully deleted.");
1590
  }
1591
  else if (res.errorMsg) {
1592
  WFAD.colorboxError(res.errorMsg, res.tokenInvalid);
@@ -1625,7 +1627,7 @@
1625
  WFAD.updateIssueCounts(res.issueCounts);
1626
  WFAD.repositionSiteCleaningCallout();
1627
  WFAD.updateBulkButtons();
1628
- WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), "File hidden successfully", "The file " + res.file + " was successfully hidden from public view.");
1629
  }
1630
  else if (res.errorMsg) {
1631
  WFAD.colorboxError(res.errorMsg, res.tokenInvalid);
@@ -1756,7 +1758,7 @@
1756
  if (newCount == 0) {
1757
  var existing = $('.wf-issue[data-issue-id="no-issues-new"]');
1758
  if (existing.length == 0) {
1759
- var issue = $('#issueTmpl_noneFound').tmpl({shortMsg: 'No new issues have been found.', id: 'no-issues-new'});
1760
  $('#wf-scan-results-new').append(issue);
1761
  }
1762
  }
@@ -1767,7 +1769,7 @@
1767
  if (ignoredCount == 0) {
1768
  var existing = $('.wf-issue[data-issue-id="no-issues-ignored"]');
1769
  if (existing.length == 0) {
1770
- var issue = $('#issueTmpl_noneFound').tmpl({shortMsg: 'No issues have been ignored.', id: 'no-issues-ignored'});
1771
  $('#wf-scan-results-ignored').append(issue);
1772
  }
1773
  }
@@ -1916,7 +1918,7 @@
1916
  WFAD.tokenErrorShowing = true;
1917
  }
1918
 
1919
- var prompt = $.tmpl(WordfenceAdminVars.tokenInvalidTemplate, {title: 'An error occurred', message: errorMsg});
1920
  var promptHTML = $("<div />").append(prompt).html();
1921
  var settings = {};
1922
  settings.overlayClose = false;
@@ -2006,12 +2008,12 @@
2006
  return;
2007
  }
2008
  }
2009
- WFAD.colorboxModalHTML((WFAD.isSmallScreen ? '300px' : '400px'), "Download Backup File", 'Please make a backup of this file before proceeding. If you need to restore this backup file, you can copy it to the following path from your site\'s root:<p class="wf-padding-add-top-medium"><code>' + file + '</code></p>'
2010
- + '<a href="' + WFAD.makeDownloadFileLink(file) + '" onclick="jQuery(\'#wfRepairFileNextBtn\').prop(\'disabled\', false); return true;">Click here to download a backup copy of this file now</a><p class="wf-flex-horizontal">' +
2011
  '<input type="button" class="wf-btn wf-btn-primary" name="but1" id="wfRepairFileNextBtn" value="Repair File" disabled="disabled" onclick="WFAD.promptToRepairFileDone(' + parseInt(issueID, 10) + ', jQuery(\'#forceRepairFileCheckbox\').prop(\'checked\'));this.disabled=true;" />' +
2012
- '<label class="wf-padding-add-left"><input type="checkbox" id="forceRepairFileCheckbox" onclick="jQuery(\'#wfRepairFileNextBtn\').prop(\'disabled\', !this.checked); return true;"> Don\'t ask again</label>' +
2013
  '</p>' +
2014
- '<div class="wordfenceHelpLink"><a href="' + WordfenceAdminVars.supportURLs['scan-result-repair-modified-files'] + '" target="_blank" rel="noopener noreferrer" class="wfhelp"></a><a href="' + WordfenceAdminVars.supportURLs['scan-result-repair-modified-files'] + '" target="_blank" rel="noopener noreferrer">Learn more about repairing modified files.</a></div>'
2015
  );
2016
  },
2017
  promptToRepairFileDone: function(issueID, dontPromptAgain) {
@@ -2032,7 +2034,7 @@
2032
  self.updateIssueCounts(res.issueCounts);
2033
  self.repositionSiteCleaningCallout();
2034
  self.updateBulkButtons();
2035
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "Success restoring file", "The file " + res.file + " was successfully restored.");
2036
  }
2037
  else if (res.errorMsg) {
2038
  self.colorboxError(res.errorMsg, res.tokenInvalid);
@@ -2052,7 +2054,7 @@
2052
  var self = this;
2053
  if (res.ok) {
2054
  this.loadIssues(function() {
2055
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "Success removing option", "The option " + res.option_name + " was successfully removed.");
2056
  });
2057
  } else if (res.cerrorMsg) {
2058
  this.loadIssues(function() {
@@ -2070,7 +2072,7 @@
2070
  jQuery('#wordfenceMisconfiguredHowGetIPsNotice').fadeOut();
2071
 
2072
  self.loadIssues(function() {
2073
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "Success updating option", "The 'How does Wordfence get IPs' option was successfully updated to the recommended value.");
2074
  });
2075
  } else if (res.cerrorMsg) {
2076
  self.loadIssues(function() {
@@ -2081,18 +2083,18 @@
2081
  },
2082
  fixFPD: function(issueID) {
2083
  var self = this;
2084
- var title = "Full Path Disclosure";
2085
  issueID = parseInt(issueID);
2086
 
2087
  this.ajax('wordfence_checkHtaccess', {}, function(res) {
2088
  if (res.ok) {
2089
- self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), title, 'We are about to change your <em>.htaccess</em> file. Please make a backup of this file before proceeding.'
2090
  + '<br/>'
2091
- + '<a href="' + WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadHtaccess&nonce=' + self.nonce + '" onclick="jQuery(\'#wfFPDNextBut\').prop(\'disabled\', false); return true;">Click here to download a backup copy of your .htaccess file now</a><br /><br /><input type="button" class="wf-btn wf-btn-default" name="but1" id="wfFPDNextBut" value="Click to fix .htaccess" disabled="disabled" onclick="WFAD.fixFPD_WriteHtAccess(' + issueID + ');" />');
2092
  } else if (res.nginx) {
2093
- self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), title, 'You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. You will need to manually modify your php.ini to disable <em>display_error</em>');
2094
  } else if (res.err) {
2095
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "We encountered a problem", "We can't modify your .htaccess file for you because: " + res.err);
2096
  }
2097
  });
2098
  },
@@ -2104,7 +2106,7 @@
2104
  }, function(res) {
2105
  if (res.ok) {
2106
  self.loadIssues(function() {
2107
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "File restored OK", "The Full Path disclosure issue has been fixed");
2108
  });
2109
  } else {
2110
  self.loadIssues(function() {
@@ -2117,10 +2119,10 @@
2117
  hideFile: function(issueID, callback) {
2118
  WFAD.ajax('wordfence_checkHtaccess', {}, function(checkRes) {
2119
  if (checkRes.ok) {
2120
- WFAD.colorboxModalHTML((WFAD.isSmallScreen ? '300px' : '400px'), '.htaccess change', 'We are about to change your <em>.htaccess</em> file. Please make a backup of this file before proceeding.'
2121
  + '<br/>'
2122
- + '<a id="dlButton" href="' + WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadHtaccess&nonce=' + WFAD.nonce + '">Click here to download a backup copy of your .htaccess file now</a>'
2123
- + '<br /><br /><input type="button" class="wf-btn wf-btn-default" name="but1" id="wfFPDNextBut" value="Click to fix .htaccess" disabled="disabled" />'
2124
  );
2125
  $('#dlButton').on('click', function(e) {
2126
  $('#wfFPDNextBut').prop('disabled', false);
@@ -2138,10 +2140,10 @@
2138
  });
2139
  }
2140
  else if (checkRes.nginx) {
2141
- WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), 'Unable to automatically hide file', 'You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. You will need to manually delete or hide those files.');
2142
  }
2143
  else if (checkRes.err) {
2144
- WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), "We encountered a problem", "We can't modify your .htaccess file for you because: " + res.err);
2145
  }
2146
  });
2147
  },
@@ -2166,17 +2168,15 @@
2166
 
2167
  this.ajax('wordfence_checkHtaccess', {}, function(res) {
2168
  if (res.ok) {
2169
- self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), title, 'We are about to change your <em>.htaccess</em> file. Please make a backup of this file before proceeding.'
2170
  + '<br/>'
2171
- + '<a href="' + WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadHtaccess&nonce=' + self.nonce + '" onclick="jQuery(\'#wf-htaccess-confirm\').prop(\'disabled\', false); return true;">Click here to download a backup copy of your .htaccess file now</a>' +
2172
  '<br /><br />' +
2173
- '<button class="wf-btn wf-btn-default" type="button" id="wf-htaccess-confirm" disabled="disabled" onclick="WFAD.confirmDisableDirectoryListing(' + issueID + ');">Add code to .htaccess</button>');
2174
  } else if (res.nginx) {
2175
- self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), "You are using Nginx as your web server. " +
2176
- "You'll need to disable autoindexing in your nginx.conf. " +
2177
- "See the <a target='_blank' rel='noopener noreferrer' href='http://nginx.org/en/docs/http/ngx_http_autoindex_module.html'>Nginx docs for more info</a> on how to do this.");
2178
  } else if (res.err) {
2179
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "We encountered a problem", "We can't modify your .htaccess file for you because: " + res.err);
2180
  }
2181
  });
2182
  },
@@ -2188,7 +2188,7 @@
2188
  }, function(res) {
2189
  if (res.ok) {
2190
  self.loadIssues(function() {
2191
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "Directory Listing Disabled", "Directory listing has been disabled on your server.");
2192
  });
2193
  } else {
2194
  //self.loadIssues(function() {
@@ -2249,24 +2249,24 @@
2249
  }
2250
  jQuery('#wfActivity').html(html);
2251
  } else {
2252
- jQuery('#wfActivity').html("<p>&nbsp;&nbsp;No activity to report yet. Please complete your first scan.</p>");
2253
  }
2254
  });
2255
  },
2256
  emailActivityLog: function() {
2257
- this.colorboxModalHTML((this.isSmallScreen ? '300px' : '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='wftest@wordfence.com' size='20' id='wfALogRecip' /><input class='wf-btn wf-btn-default' type='button' value='Send' onclick=\"WFAD.completeEmailActivityLog();\" />");
2258
  },
2259
  completeEmailActivityLog: function() {
2260
  WFAD.colorboxClose();
2261
  var email = jQuery('#wfALogRecip').val();
2262
  if (!/^[^@]+@[^@]+$/.test(email)) {
2263
- alert("Please enter a valid email address.");
2264
  return;
2265
  }
2266
  var self = this;
2267
  this.ajax('wordfence_sendActivityLog', {email: jQuery('#wfALogRecip').val()}, function(res) {
2268
  if (res.ok) {
2269
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), 'Activity Log Sent', "Your Wordfence activity log was sent to " + email);
2270
  }
2271
  });
2272
  },
@@ -2581,17 +2581,17 @@
2581
  whois: function(val) {
2582
  val = val.replace(' ', '');
2583
  if (!/\w+/.test(val)) {
2584
- this.colorboxModal('300px', "Enter a valid IP or domain", "Please enter a valid IP address or domain name for your whois lookup.");
2585
  return;
2586
  }
2587
  var self = this;
2588
  jQuery('#whoisbutton').attr('disabled', 'disabled');
2589
- jQuery('#whoisbutton').attr('value', 'Loading...');
2590
  this.ajax('wordfence_whois', {
2591
  val: val
2592
  }, function(res) {
2593
  jQuery('#whoisbutton').removeAttr('disabled');
2594
- jQuery('#whoisbutton').attr('value', 'Look up IP or Domain');
2595
  if (res.ok) {
2596
  self.completeWhois(res);
2597
  }
@@ -2602,9 +2602,9 @@
2602
  var self = this;
2603
  var rawhtml = "";
2604
  var ipRangeTmpl = jQuery("<div><div class='wf-flex-row'>" +
2605
- "<a class=\"wf-btn wf-btn-default wf-flex-row-0\" href=\"${adminUrl}\">Block This Network</a>" +
2606
  "<span class='wf-flex-row-1 wf-padding-add-left'>{{html totalStr}}{{if totalStr.indexOf(ipRange) == -1}} (${ipRange}){{/if}}" +
2607
- '{{if (totalIPs)}}<br>[${totalIPs} addresses in this network]{{/if}}' +
2608
  "</span></div></div>");
2609
  if (res.ok && res.result && res.result.rawdata && res.result.rawdata.length > 0) {
2610
  for (var i = 0; i < res.result.rawdata.length; i++) {
@@ -2675,7 +2675,7 @@
2675
  }
2676
  jQuery('#wfrawhtml').html(rawhtml);
2677
  } else {
2678
- rawhtml = '<span style="color: #F00;">Sorry, but no data for that IP or domain was found.</span>';
2679
  if (ret) {
2680
  return rawhtml;
2681
  }
@@ -2684,7 +2684,7 @@
2684
  },
2685
  blockIPUARange: function(ipRange, hostname, uaRange, referer, reason) {
2686
  if (!/\w+/.test(reason)) {
2687
- this.colorboxModal('300px', "Please specify a reason", "You forgot to include a reason you're blocking this IP range. We ask you to include this for your own record keeping.");
2688
  return;
2689
  }
2690
  ipRange = ipRange.replace(/ /g, '').toLowerCase();
@@ -2700,16 +2700,16 @@
2700
  validRange = this.inet_aton(range[0]) !== false && this.inet_aton(range[1]) !== false;
2701
  }
2702
  if (!validRange) {
2703
- this.colorboxModal('300px', 'Specify a valid IP range', "Please specify a valid IP address range in the form of \"1.2.3.4 - 1.2.3.5\" without quotes. Make sure the dash between the IP addresses in a normal dash (a minus sign on your keyboard) and not another character that looks like a dash.");
2704
  return;
2705
  }
2706
  }
2707
  if (hostname && !/^[a-z0-9\.\*\-]+$/i.test(hostname)) {
2708
- this.colorboxModalHTML('300px', 'Specify a valid hostname', '<i>' + this.htmlEscape(hostname) + '</i> is not valid hostname');
2709
  return;
2710
  }
2711
  if (!(/\w+/.test(ipRange) || /\w+/.test(uaRange) || /\w+/.test(referer) || /\w+/.test(hostname))) {
2712
- this.colorboxModal('300px', 'Specify an IP range, Hostname or Browser pattern', "Please specify either an IP address range, Hostname or a web browser pattern to match.");
2713
  return;
2714
  }
2715
  var self = this;
@@ -2792,7 +2792,7 @@
2792
  });
2793
  },
2794
  twoFacStatus: function(msg) {
2795
- this.colorboxModal('300px', 'Two Factor Status', msg);
2796
  },
2797
  addTwoFactor: function(username, phone, mode) {
2798
  var self = this;
@@ -2804,12 +2804,12 @@
2804
  if (res.ok) {
2805
  if (mode == 'authenticator') {
2806
  var totpURL = "otpauth://totp/" + encodeURI(res.homeurl) + encodeURI(" (" + res.username + ")") + "?" + res.uriQueryString + "&issuer=Wordfence";
2807
- var message = "Scan the code below with your authenticator app to add this account. Some authenticator apps also allow you to type in the text version instead.<br><div id=\"wfTwoFactorQRCodeTable\"></div><br><strong>Key:</strong> <input type=\"text\"" + (self.isSmallScreen ? "" : " size=\"45\"") + " value=\"" + res.base32Secret + "\" onclick=\"this.select();\" readonly>";
2808
  if (res.recoveryCodes.length > 0) {
2809
- message = message + "<br><br><strong>Recovery Codes</strong><br><p>Use one of these " + res.recoveryCodes.length + " codes to log in if you lose access to your authenticator device. Codes are 16 characters long, plus optional spaces. Each one may be used only once.</p><ul id=\"wfTwoFactorRecoveryCodes\">";
2810
 
2811
- var recoveryCodeFileContents = "Cellphone Sign-In Recovery Codes - " + res.homeurl + " (" + res.username + ")\r\n";
2812
- recoveryCodeFileContents = recoveryCodeFileContents + "\r\nEach line of 16 letters and numbers is a single recovery code, with optional spaces for readability. When typing your password, enter \"wf\" followed by the entire code like \"mypassword wf1234 5678 90AB CDEF\". If your site shows a separate prompt for entering a code after entering only your username and password, enter only the code like \"1234 5678 90AB CDEF\". Your recovery codes are:\r\n\r\n";
2813
  var splitter = /.{4}/g;
2814
  for (var i = 0; i < res.recoveryCodes.length; i++) {
2815
  var code = res.recoveryCodes[i];
@@ -2820,12 +2820,12 @@
2820
 
2821
  message = message + "</ul>";
2822
 
2823
- message = message + "<p class=\"wf-center\"><a href=\"#\" class=\"wf-btn wf-btn-default\" id=\"wfTwoFactorDownload\" target=\"_blank\" rel=\"noopener noreferrer\"><i class=\"dashicons dashicons-download\"></i> Download</a></p>";
2824
  }
2825
 
2826
- message = message + "<p><em>This will be shown only once. Keep these codes somewhere safe.</em></p>";
2827
 
2828
- self.colorboxModalHTML((self.isSmallScreen ? '300px' : '440px'), "Authentication Code", message, {onComplete: function() {
2829
  jQuery('#wfTwoFactorQRCodeTable').qrcode({text: totpURL, width: (self.isSmallScreen ? 175 : 256), height: (self.isSmallScreen ? 175 : 256)});
2830
  jQuery('#wfTwoFactorDownload').on('click', function(e) {
2831
  e.preventDefault();
@@ -2836,10 +2836,10 @@
2836
  }
2837
  else {
2838
  if (res.recoveryCodes.length > 0) {
2839
- var message = "<p>Use one of these " + res.recoveryCodes.length + " codes to log in if you are unable to access your phone. Codes are 16 characters long, plus optional spaces. Each one may be used only once.</p><ul id=\"wfTwoFactorRecoveryCodes\">";
2840
 
2841
- var recoveryCodeFileContents = "Cellphone Sign-In Recovery Codes - " + res.homeurl + " (" + res.username + ")\r\n";
2842
- recoveryCodeFileContents = recoveryCodeFileContents + "\r\nEach line of 16 letters and numbers is a single recovery code, with optional spaces for readability. When typing your password, enter \"wf\" followed by the entire code like \"mypassword wf1234 5678 90AB CDEF\". If your site shows a separate prompt for entering a code after entering only your username and password, enter only the code like \"1234 5678 90AB CDEF\". Your recovery codes are:\r\n\r\n";
2843
  var splitter = /.{4}/g;
2844
  for (var i = 0; i < res.recoveryCodes.length; i++) {
2845
  var code = res.recoveryCodes[i];
@@ -2848,11 +2848,11 @@
2848
  recoveryCodeFileContents = recoveryCodeFileContents + chunks[0] + " " + chunks[1] + " " + chunks[2] + " " + chunks[3] + "\r\n";
2849
  }
2850
 
2851
- message = message + "<p class=\"wf-center\"><a href=\"#\" class=\"wf-btn wf-btn-default\" id=\"wfTwoFactorDownload\" target=\"_blank\" rel=\"noopener noreferrer\"><i class=\"dashicons dashicons-download\"></i> Download</a></p>";
2852
 
2853
- message = message + "</ul><p><em>This will be shown only once. Keep these codes somewhere safe.</em></p>";
2854
 
2855
- self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), "Recovery Codes", message, {onComplete: function() {
2856
  jQuery('#wfTwoFactorDownload').on('click', function(e) {
2857
  e.preventDefault();
2858
  e.stopPropagation();
@@ -2879,7 +2879,7 @@
2879
  updatedTwoFac.find('tbody > tr').each(function(index, element) {
2880
  jQuery('#' + jQuery(element).attr('id')).replaceWith(element);
2881
  });
2882
- self.twoFacStatus('Cellphone Sign-in activated for user.');
2883
  }
2884
  });
2885
  },
@@ -3020,7 +3020,7 @@
3020
  }, function(res) {
3021
  if (res.ok) {
3022
  self.loadIssues(function() {
3023
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "Successfully deleted admin", "The admin user " + res.user_login + " was successfully deleted.");
3024
  });
3025
  } else if (res.errorMsg) {
3026
  self.loadIssues(function() {
@@ -3037,7 +3037,7 @@
3037
  }, function(res) {
3038
  if (res.ok) {
3039
  self.loadIssues(function() {
3040
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), "Successfully revoked admin", "All capabilties of admin user " + res.user_login + " were successfully revoked.");
3041
  });
3042
  } else if (res.errorMsg) {
3043
  self.loadIssues(function() {
@@ -3222,7 +3222,7 @@
3222
  if (date.toLocaleString) {
3223
  dateString = date.toLocaleString();
3224
  }
3225
- $('#waf-rules-last-updated').text('Last Updated: ' + dateString)
3226
  .css({
3227
  'opacity': 0
3228
  })
@@ -3236,7 +3236,7 @@
3236
  if (date.toLocaleString) {
3237
  dateString = date.toLocaleString();
3238
  }
3239
- $('#waf-rules-next-update').text('Next Update Check: ' + dateString)
3240
  .css({
3241
  'opacity': 0
3242
  })
@@ -3254,24 +3254,20 @@
3254
  self.wafConfigPageRender();
3255
  if (self.wafData['updated']) {
3256
  if (!self.wafData['isPaid']) {
3257
- self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), 'Rules Updated', 'Your rules have been updated successfully. You are ' +
3258
- 'currently using the free version of Wordfence. ' +
3259
- 'Upgrade to Wordfence premium to have your rules updated automatically as new threats emerge. ' +
3260
- '<a href="https://www.wordfence.com/wafUpdateRules1/wordfence-signup/">Click here to purchase a premium license</a>. ' +
3261
- '<em>Note: Your rules will still update every 30 days as a free user.</em>');
3262
  } else {
3263
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), 'Rules Updated', 'Your rules have been updated successfully.');
3264
  }
3265
  }
3266
  else {
3267
  if (self.wafData['failure'] == 'ratelimit') {
3268
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), 'Rule Update Failed', 'No rules were updated. Your website has reached the maximum number of rule update requests. Please try again later.');
3269
  }
3270
  else if (self.wafData['failure'] == 'unreachable') {
3271
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), 'Rule Update Failed', 'No rules were updated. Please verify your website can reach the Wordfence servers.');
3272
  }
3273
  else {
3274
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), 'Rule Update Failed', 'No rules were updated. Please verify you have permissions to write to the /wp-content/wflogs directory.');
3275
  }
3276
  }
3277
  if (typeof onSuccess === 'function') {
@@ -3293,8 +3289,7 @@
3293
  confirmWAFConfigureAutoPrepend: function() {
3294
  var self = this;
3295
  this.ajax('wordfence_wafConfigureAutoPrepend', {}, function(res) {
3296
- self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), '.htaccess Updated', "Your .htaccess has been updated successfully. Please " +
3297
- "verify your site is functioning normally.");
3298
  });
3299
  },
3300
 
@@ -3312,7 +3307,7 @@
3312
  },
3313
 
3314
  _unsavedOptionsHandler: function(e) {
3315
- var message = "You have unsaved changes to your options. If you leave this page, those changes will be lost."; //Only shows on older browsers, newer browsers don't allow message customization
3316
  e = e || window.event;
3317
  if (e) {
3318
  e.returnValue = message; //IE and Firefox
@@ -3328,7 +3323,7 @@
3328
  typeof successCallback == 'function' && successCallback(res);
3329
  }
3330
  else {
3331
- WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), 'Error Saving Option', res.error);
3332
  typeof failureCallback == 'function' && failureCallback(res);
3333
  }
3334
  });
@@ -3345,7 +3340,7 @@
3345
  typeof successCallback == 'function' && successCallback(res);
3346
  }
3347
  else {
3348
- WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), 'Error Saving Options', res.error);
3349
  typeof failureCallback == 'function' && failureCallback
3350
  }
3351
  });
@@ -3357,7 +3352,7 @@
3357
  window.location.href = res.redirect;
3358
  }
3359
  else {
3360
- WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), 'Error Enabling All Options Page', res.error);
3361
  }
3362
  });
3363
  },
@@ -3424,6 +3419,10 @@
3424
  WFAD.updateTimeAgo();
3425
  }, 1000);
3426
  }
 
 
 
 
3427
  jQuery(function() {
3428
  wordfenceAdmin.init();
3429
  jQuery(window).on('focus', function() {
@@ -3440,9 +3439,9 @@
3440
 
3441
  $.wfMobileMenu({
3442
  menuItems: [
3443
- {title: 'Save Changes', primary: true, disabled: $('#wf-save-changes').hasClass('wf-disabled'), action: function() { $('#wf-save-changes').trigger('click'); }},
3444
- {title: 'Cancel Changes', primary: false, disabled: $('#wf-cancel-changes').hasClass('wf-disabled'), action: function() { $('#wf-cancel-changes').trigger('click'); }},
3445
- {title: 'Restore Defaults', primary: false, disabled: $('#wf-restore-defaults').hasClass('wf-disabled'), action: function() { $('#wf-restore-defaults').trigger('click'); }}
3446
  ]
3447
  });
3448
  });
@@ -3472,7 +3471,7 @@
3472
  }
3473
  else {
3474
  WFAD.colorboxClose();
3475
- WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), 'Error Restoring Defaults', res.error);
3476
  }
3477
  });
3478
  });
@@ -3683,6 +3682,9 @@
3683
 
3684
  //wfCircularProgress
3685
  jQuery.fn.wfCircularProgress = function(options) {
 
 
 
3686
  jQuery(this).each(function() {
3687
  var creationOptions;
3688
  try {
@@ -3781,19 +3783,27 @@ jQuery.fn.wfCircularProgress = function(options) {
3781
  });
3782
  };
3783
 
3784
- jQuery.fn.wfCircularProgress.defaults = {
3785
- startPercent: 0,
3786
- endPercent: 1,
3787
- color: '#16bc9b',
3788
- inactiveColor: '#ececec',
3789
- strokeWidth: 3,
3790
- diameter: 100,
3791
- pendingOverlay: false,
3792
- pendingMessage: 'Note: Status will update when changes are saved',
3793
- };
 
 
 
 
 
3794
 
3795
  //wfDrawer
3796
  (function ($, document, window) {
 
 
 
3797
  var defaults = {
3798
  width: '600px',
3799
  clickOverlayDismiss: false,
@@ -3859,6 +3869,9 @@ jQuery.fn.wfCircularProgress.defaults = {
3859
 
3860
  //wfMobileMenu
3861
  (function ($, document, window) {
 
 
 
3862
  var defaults = {
3863
  width: '280px',
3864
  clickOverlayDismiss: true,
@@ -3908,7 +3921,7 @@ jQuery.fn.wfCircularProgress.defaults = {
3908
  itemsWrapper.append(button);
3909
  }
3910
 
3911
- var button = $('<li class="wf-padding-add-top-small"><a href="#" class="wf-btn wf-btn-callout-subtle wf-btn-default">Close</a></li>');
3912
  button.find('a').css('width', opts.width).on('click', function(e) {
3913
  e.preventDefault();
3914
  e.stopPropagation();
1
  (function($) {
2
+ var sprintf,
3
+ __;
4
+
5
  if (!window['wordfenceAdmin']) { //To compile for checking: java -jar /usr/local/bin/closure.jar --js=admin.js --js_output_file=test.js
6
  window['wordfenceAdmin'] = {
7
  isSmallScreen: false,
87
  $('#doSendEmail').click(function() {
88
  var ticket = $('#_ticketnumber').val();
89
  if (ticket === null || typeof ticket === "undefined" || ticket.length == 0) {
90
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Error"), __("Please include your support ticket number or forum username."));
91
  return;
92
  }
93
  WFAD.ajax('wordfence_sendDiagnostic', {email: $('#_email').val(), ticket: ticket}, function(res) {
94
  if (res.result) {
95
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Email Diagnostic Report"), __("Diagnostic report has been sent successfully."));
96
  } else {
97
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Error"), __("There was an error while sending the email."));
98
  }
99
  });
100
  });
764
  var self = this;
765
  this.ajax('wordfence_sendTestEmail', {email: email}, function(res) {
766
  if (res.result) {
767
+ self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), __("Test Email Sent"), sprintf(__("Your test email was sent to the requested email address. The result we received from the WordPress wp_mail() function was: %s<br /><br />A 'True' result means WordPress thinks the mail was sent without errors. A 'False' result means that WordPress encountered an error sending your mail. Note that it's possible to get a 'True' response with an error elsewhere in your mail system that may cause emails to not be delivered."), res.result));
 
768
  }
769
  });
770
  },
870
  showLoading: function() {
871
  this.loadingCount++;
872
  if (this.loadingCount == 1) {
873
+ $('<div id="wordfenceWorking">' + __('Wordfence is working...') + '</div>').appendTo('body');
874
  }
875
  },
876
  removeLoading: function() {
1032
  }
1033
 
1034
  var sigTimestampEl = $('#wf-scan-sigs-last-update');
1035
+ var newText = sprintf(__('Last Updated: %s'), dateString);
1036
  if (sigTimestampEl.text() !== newText) {
1037
  sigTimestampEl.text(newText)
1038
  .css({
1148
  summaryUpdated = true;
1149
  } else if (item.msg.indexOf('SUM_DISABLED:') != -1) {
1150
  msg = item.msg.replace('SUM_DISABLED:', '');
1151
+ jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult">' + __('Disabled') + '</div><div class="wfClear"></div>');
1152
  summaryUpdated = true;
1153
  } else if (item.msg.indexOf('SUM_PAIDONLY:') != -1) {
1154
  msg = item.msg.replace('SUM_PAIDONLY:', '');
1155
+ jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult"><a href="https://www.wordfence.com/wordfence-signup/" target="_blank" rel="noopener noreferrer">' + __('Paid Members Only') + '</a></div><div class="wfClear"></div>');
1156
  summaryUpdated = true;
1157
  } else if (item.msg.indexOf('SUM_FINAL:') != -1) {
1158
  msg = item.msg.replace('SUM_FINAL:', '');
1159
+ jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg wfSummaryFinal">' + msg + '</div><div class="wfSummaryResult wfSummaryOK">' + __('Scan Complete.') + '</div><div class="wfClear"></div>');
1160
  } else if (item.msg.indexOf('SUM_PREP:') != -1) {
1161
  msg = item.msg.replace('SUM_PREP:', '');
1162
  jQuery('#consoleSummary').empty().html('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult" id="wfStartingScan"><div class="wfSummaryLoading"></div></div><div class="wfClear"></div>');
1163
  } else if (item.msg.indexOf('SUM_KILLED:') != -1) {
1164
  msg = item.msg.replace('SUM_KILLED:', '');
1165
+ jQuery('#consoleSummary').empty().html('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult wfSummaryOK">' + __('Scan Complete.') + '</div><div class="wfClear"></div>');
1166
  }
1167
  },
1168
  processActQueueItem: function() {
1588
  WFAD.updateIssueCounts(res.issueCounts);
1589
  WFAD.repositionSiteCleaningCallout();
1590
  WFAD.updateBulkButtons();
1591
+ WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), __("Success deleting file"), sprintf(__("The file %s was successfully deleted."), res.file));
1592
  }
1593
  else if (res.errorMsg) {
1594
  WFAD.colorboxError(res.errorMsg, res.tokenInvalid);
1627
  WFAD.updateIssueCounts(res.issueCounts);
1628
  WFAD.repositionSiteCleaningCallout();
1629
  WFAD.updateBulkButtons();
1630
+ WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), __("File hidden successfully"), sprintf(__("The file %s was successfully hidden from public view."), res.file));
1631
  }
1632
  else if (res.errorMsg) {
1633
  WFAD.colorboxError(res.errorMsg, res.tokenInvalid);
1758
  if (newCount == 0) {
1759
  var existing = $('.wf-issue[data-issue-id="no-issues-new"]');
1760
  if (existing.length == 0) {
1761
+ var issue = $('#issueTmpl_noneFound').tmpl({shortMsg: __('No new issues have been found.'), id: 'no-issues-new'});
1762
  $('#wf-scan-results-new').append(issue);
1763
  }
1764
  }
1769
  if (ignoredCount == 0) {
1770
  var existing = $('.wf-issue[data-issue-id="no-issues-ignored"]');
1771
  if (existing.length == 0) {
1772
+ var issue = $('#issueTmpl_noneFound').tmpl({shortMsg: __('No issues have been ignored.'), id: 'no-issues-ignored'});
1773
  $('#wf-scan-results-ignored').append(issue);
1774
  }
1775
  }
1918
  WFAD.tokenErrorShowing = true;
1919
  }
1920
 
1921
+ var prompt = $.tmpl(WordfenceAdminVars.tokenInvalidTemplate, {title: __('An error occurred'), message: errorMsg});
1922
  var promptHTML = $("<div />").append(prompt).html();
1923
  var settings = {};
1924
  settings.overlayClose = false;
2008
  return;
2009
  }
2010
  }
2011
+ WFAD.colorboxModalHTML((WFAD.isSmallScreen ? '300px' : '400px'), __("Download Backup File"), __('Please make a backup of this file before proceeding. If you need to restore this backup file, you can copy it to the following path from your site\'s root:') + '<p class="wf-padding-add-top-medium"><code>' + file + '</code></p>'
2012
+ + '<a href="' + WFAD.makeDownloadFileLink(file) + '" onclick="jQuery(\'#wfRepairFileNextBtn\').prop(\'disabled\', false); return true;">' + __('Click here to download a backup copy of this file now') + '</a><p class="wf-flex-horizontal">' +
2013
  '<input type="button" class="wf-btn wf-btn-primary" name="but1" id="wfRepairFileNextBtn" value="Repair File" disabled="disabled" onclick="WFAD.promptToRepairFileDone(' + parseInt(issueID, 10) + ', jQuery(\'#forceRepairFileCheckbox\').prop(\'checked\'));this.disabled=true;" />' +
2014
+ '<label class="wf-padding-add-left"><input type="checkbox" id="forceRepairFileCheckbox" onclick="jQuery(\'#wfRepairFileNextBtn\').prop(\'disabled\', !this.checked); return true;"> ' + __('Don\'t ask again') + '</label>' +
2015
  '</p>' +
2016
+ '<div class="wordfenceHelpLink"><a href="' + WordfenceAdminVars.supportURLs['scan-result-repair-modified-files'] + '" target="_blank" rel="noopener noreferrer" class="wfhelp"></a><a href="' + WordfenceAdminVars.supportURLs['scan-result-repair-modified-files'] + '" target="_blank" rel="noopener noreferrer">' + __('Learn more about repairing modified files.') + '</a></div>'
2017
  );
2018
  },
2019
  promptToRepairFileDone: function(issueID, dontPromptAgain) {
2034
  self.updateIssueCounts(res.issueCounts);
2035
  self.repositionSiteCleaningCallout();
2036
  self.updateBulkButtons();
2037
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Success restoring file"), sprintf(__("The file %s was successfully restored."), res.file));
2038
  }
2039
  else if (res.errorMsg) {
2040
  self.colorboxError(res.errorMsg, res.tokenInvalid);
2054
  var self = this;
2055
  if (res.ok) {
2056
  this.loadIssues(function() {
2057
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Success removing option"), sprintf(__("The option %s was successfully removed."), res.option_name));
2058
  });
2059
  } else if (res.cerrorMsg) {
2060
  this.loadIssues(function() {
2072
  jQuery('#wordfenceMisconfiguredHowGetIPsNotice').fadeOut();
2073
 
2074
  self.loadIssues(function() {
2075
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Success updating option"), __("The 'How does Wordfence get IPs' option was successfully updated to the recommended value."));
2076
  });
2077
  } else if (res.cerrorMsg) {
2078
  self.loadIssues(function() {
2083
  },
2084
  fixFPD: function(issueID) {
2085
  var self = this;
2086
+ var title = __("Full Path Disclosure");
2087
  issueID = parseInt(issueID);
2088
 
2089
  this.ajax('wordfence_checkHtaccess', {}, function(res) {
2090
  if (res.ok) {
2091
+ self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), title, __('We are about to change your <em>.htaccess</em> file. Please make a backup of this file before proceeding.')
2092
  + '<br/>'
2093
+ + '<a href="' + WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadHtaccess&nonce=' + self.nonce + '" onclick="jQuery(\'#wfFPDNextBut\').prop(\'disabled\', false); return true;">' + __('Click here to download a backup copy of your .htaccess file now') + '</a><br /><br /><input type="button" class="wf-btn wf-btn-default" name="but1" id="wfFPDNextBut" value="Click to fix .htaccess" disabled="disabled" onclick="WFAD.fixFPD_WriteHtAccess(' + issueID + ');" />');
2094
  } else if (res.nginx) {
2095
+ self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), title, __('You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. You will need to manually modify your php.ini to disable <em>display_error</em>'));
2096
  } else if (res.err) {
2097
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("We encountered a problem"), sprintf(__("We can't modify your .htaccess file for you because: %s"), res.err));
2098
  }
2099
  });
2100
  },
2106
  }, function(res) {
2107
  if (res.ok) {
2108
  self.loadIssues(function() {
2109
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("File restored OK"), __("The Full Path disclosure issue has been fixed"));
2110
  });
2111
  } else {
2112
  self.loadIssues(function() {
2119
  hideFile: function(issueID, callback) {
2120
  WFAD.ajax('wordfence_checkHtaccess', {}, function(checkRes) {
2121
  if (checkRes.ok) {
2122
+ WFAD.colorboxModalHTML((WFAD.isSmallScreen ? '300px' : '400px'), __('.htaccess change'), __('We are about to change your <em>.htaccess</em> file. Please make a backup of this file before proceeding.')
2123
  + '<br/>'
2124
+ + '<a id="dlButton" href="' + WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadHtaccess&nonce=' + WFAD.nonce + '">' + __('Click here to download a backup copy of your .htaccess file now') + '</a>'
2125
+ + '<br /><br /><input type="button" class="wf-btn wf-btn-default" name="but1" id="wfFPDNextBut" value="' + __('Click to fix .htaccess') + '" disabled="disabled" />'
2126
  );
2127
  $('#dlButton').on('click', function(e) {
2128
  $('#wfFPDNextBut').prop('disabled', false);
2140
  });
2141
  }
2142
  else if (checkRes.nginx) {
2143
+ WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), __('Unable to automatically hide file'), __('You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. You will need to manually delete or hide those files.'));
2144
  }
2145
  else if (checkRes.err) {
2146
+ WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), __("We encountered a problem"), sprintf(__("We can't modify your .htaccess file for you because: %s"), res.err));
2147
  }
2148
  });
2149
  },
2168
 
2169
  this.ajax('wordfence_checkHtaccess', {}, function(res) {
2170
  if (res.ok) {
2171
+ self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), title, __('We are about to change your <em>.htaccess</em> file. Please make a backup of this file before proceeding.')
2172
  + '<br/>'
2173
+ + '<a href="' + WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadHtaccess&nonce=' + self.nonce + '" onclick="jQuery(\'#wf-htaccess-confirm\').prop(\'disabled\', false); return true;">' + __('Click here to download a backup copy of your .htaccess file now') + '</a>' +
2174
  '<br /><br />' +
2175
+ '<button class="wf-btn wf-btn-default" type="button" id="wf-htaccess-confirm" disabled="disabled" onclick="WFAD.confirmDisableDirectoryListing(' + issueID + ');">' + __('Add code to .htaccess') + '</button>');
2176
  } else if (res.nginx) {
2177
+ self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), __("You are using Nginx as your web server. You'll need to disable autoindexing in your nginx.conf. See the <a target='_blank' rel='noopener noreferrer' href='http://nginx.org/en/docs/http/ngx_http_autoindex_module.html'>Nginx docs for more info</a> on how to do this."));
 
 
2178
  } else if (res.err) {
2179
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("We encountered a problem"), sprintf(__("We can't modify your .htaccess file for you because: %s"), res.err));
2180
  }
2181
  });
2182
  },
2188
  }, function(res) {
2189
  if (res.ok) {
2190
  self.loadIssues(function() {
2191
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Directory Listing Disabled"), __("Directory listing has been disabled on your server."));
2192
  });
2193
  } else {
2194
  //self.loadIssues(function() {
2249
  }
2250
  jQuery('#wfActivity').html(html);
2251
  } else {
2252
+ jQuery('#wfActivity').html("<p>&nbsp;&nbsp;" + __('No activity to report yet. Please complete your first scan.') + "</p>");
2253
  }
2254
  });
2255
  },
2256
  emailActivityLog: function() {
2257
+ this.colorboxModalHTML((this.isSmallScreen ? '300px' : '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='wftest@wordfence.com' size='20' id='wfALogRecip' /><input class='wf-btn wf-btn-default' type='button' value='" + __('Send') + "' onclick=\"WFAD.completeEmailActivityLog();\" />");
2258
  },
2259
  completeEmailActivityLog: function() {
2260
  WFAD.colorboxClose();
2261
  var email = jQuery('#wfALogRecip').val();
2262
  if (!/^[^@]+@[^@]+$/.test(email)) {
2263
+ alert(__("Please enter a valid email address."));
2264
  return;
2265
  }
2266
  var self = this;
2267
  this.ajax('wordfence_sendActivityLog', {email: jQuery('#wfALogRecip').val()}, function(res) {
2268
  if (res.ok) {
2269
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Activity Log Sent'), sprintf(__("Your Wordfence activity log was sent to %s"), email));
2270
  }
2271
  });
2272
  },
2581
  whois: function(val) {
2582
  val = val.replace(' ', '');
2583
  if (!/\w+/.test(val)) {
2584
+ this.colorboxModal('300px', __("Enter a valid IP or domain"), __("Please enter a valid IP address or domain name for your whois lookup."));
2585
  return;
2586
  }
2587
  var self = this;
2588
  jQuery('#whoisbutton').attr('disabled', 'disabled');
2589
+ jQuery('#whoisbutton').attr('value', __('Loading...'));
2590
  this.ajax('wordfence_whois', {
2591
  val: val
2592
  }, function(res) {
2593
  jQuery('#whoisbutton').removeAttr('disabled');
2594
+ jQuery('#whoisbutton').attr('value', __('Look up IP or Domain'));
2595
  if (res.ok) {
2596
  self.completeWhois(res);
2597
  }
2602
  var self = this;
2603
  var rawhtml = "";
2604
  var ipRangeTmpl = jQuery("<div><div class='wf-flex-row'>" +
2605
+ "<a class=\"wf-btn wf-btn-default wf-flex-row-0\" href=\"${adminUrl}\">" + __('Block This Network') + "</a>" +
2606
  "<span class='wf-flex-row-1 wf-padding-add-left'>{{html totalStr}}{{if totalStr.indexOf(ipRange) == -1}} (${ipRange}){{/if}}" +
2607
+ '{{if (totalIPs)}}<br>[' + __('${totalIPs} addresses in this network') + ']{{/if}}' +
2608
  "</span></div></div>");
2609
  if (res.ok && res.result && res.result.rawdata && res.result.rawdata.length > 0) {
2610
  for (var i = 0; i < res.result.rawdata.length; i++) {
2675
  }
2676
  jQuery('#wfrawhtml').html(rawhtml);
2677
  } else {
2678
+ rawhtml = '<span style="color: #F00;">' + __('Sorry, but no data for that IP or domain was found.') + '</span>';
2679
  if (ret) {
2680
  return rawhtml;
2681
  }
2684
  },
2685
  blockIPUARange: function(ipRange, hostname, uaRange, referer, reason) {
2686
  if (!/\w+/.test(reason)) {
2687
+ this.colorboxModal('300px', __("Please specify a reason"), __("You forgot to include a reason you're blocking this IP range. We ask you to include this for your own record keeping."));
2688
  return;
2689
  }
2690
  ipRange = ipRange.replace(/ /g, '').toLowerCase();
2700
  validRange = this.inet_aton(range[0]) !== false && this.inet_aton(range[1]) !== false;
2701
  }
2702
  if (!validRange) {
2703
+ this.colorboxModal('300px', __('Specify a valid IP range'), __("Please specify a valid IP address range in the form of \"1.2.3.4 - 1.2.3.5\" without quotes. Make sure the dash between the IP addresses in a normal dash (a minus sign on your keyboard) and not another character that looks like a dash."));
2704
  return;
2705
  }
2706
  }
2707
  if (hostname && !/^[a-z0-9\.\*\-]+$/i.test(hostname)) {
2708
+ this.colorboxModalHTML('300px', __('Specify a valid hostname'), sprintf(__('%s is not valid hostname'), '<i>' + this.htmlEscape(hostname) + '</i>'));
2709
  return;
2710
  }
2711
  if (!(/\w+/.test(ipRange) || /\w+/.test(uaRange) || /\w+/.test(referer) || /\w+/.test(hostname))) {
2712
+ this.colorboxModal('300px', __('Specify an IP range, Hostname or Browser pattern'), __("Please specify either an IP address range, Hostname or a web browser pattern to match."));
2713
  return;
2714
  }
2715
  var self = this;
2792
  });
2793
  },
2794
  twoFacStatus: function(msg) {
2795
+ this.colorboxModal('300px', __('Two Factor Status'), msg);
2796
  },
2797
  addTwoFactor: function(username, phone, mode) {
2798
  var self = this;
2804
  if (res.ok) {
2805
  if (mode == 'authenticator') {
2806
  var totpURL = "otpauth://totp/" + encodeURI(res.homeurl) + encodeURI(" (" + res.username + ")") + "?" + res.uriQueryString + "&issuer=Wordfence";
2807
+ var message = __('Scan the code below with your authenticator app to add this account. Some authenticator apps also allow you to type in the text version instead.') + "<br><div id=\"wfTwoFactorQRCodeTable\"></div><br><strong>" + __('Key:') + "</strong> <input type=\"text\"" + (self.isSmallScreen ? "" : " size=\"45\"") + " value=\"" + res.base32Secret + "\" onclick=\"this.select();\" readonly>";
2808
  if (res.recoveryCodes.length > 0) {
2809
+ message = message + "<br><br><strong>" + __('Recovery Codes') + "</strong><br><p>" + sprintf(__("Use one of these %s codes to log in if you lose access to your authenticator device. Codes are 16 characters long, plus optional spaces. Each one may be used only once."), res.recoveryCodes.length) + "</p><ul id=\"wfTwoFactorRecoveryCodes\">";
2810
 
2811
+ var recoveryCodeFileContents = __('Cellphone Sign-In Recovery Codes') + " - " + res.homeurl + " (" + res.username + ")\r\n";
2812
+ recoveryCodeFileContents = recoveryCodeFileContents + "\r\n" + __("Each line of 16 letters and numbers is a single recovery code, with optional spaces for readability. When typing your password, enter \"wf\" followed by the entire code like \"mypassword wf1234 5678 90AB CDEF\". If your site shows a separate prompt for entering a code after entering only your username and password, enter only the code like \"1234 5678 90AB CDEF\". Your recovery codes are:") + "\r\n\r\n";
2813
  var splitter = /.{4}/g;
2814
  for (var i = 0; i < res.recoveryCodes.length; i++) {
2815
  var code = res.recoveryCodes[i];
2820
 
2821
  message = message + "</ul>";
2822
 
2823
+ message = message + "<p class=\"wf-center\"><a href=\"#\" class=\"wf-btn wf-btn-default\" id=\"wfTwoFactorDownload\" target=\"_blank\" rel=\"noopener noreferrer\"><i class=\"dashicons dashicons-download\"></i> " + __('Download') + "</a></p>";
2824
  }
2825
 
2826
+ message = message + "<p><em>" + __("This will be shown only once. Keep these codes somewhere safe.") + "</em></p>";
2827
 
2828
+ self.colorboxModalHTML((self.isSmallScreen ? '300px' : '440px'), __("Authentication Code"), message, {onComplete: function() {
2829
  jQuery('#wfTwoFactorQRCodeTable').qrcode({text: totpURL, width: (self.isSmallScreen ? 175 : 256), height: (self.isSmallScreen ? 175 : 256)});
2830
  jQuery('#wfTwoFactorDownload').on('click', function(e) {
2831
  e.preventDefault();
2836
  }
2837
  else {
2838
  if (res.recoveryCodes.length > 0) {
2839
+ var message = "<p>" + sprintf(__("Use one of these %s codes to log in if you are unable to access your phone. Codes are 16 characters long, plus optional spaces. Each one may be used only once."), res.recoveryCodes.length) + "</p><ul id=\"wfTwoFactorRecoveryCodes\">";
2840
 
2841
+ var recoveryCodeFileContents = __('Cellphone Sign-In Recovery Codes') + " - " + res.homeurl + " (" + res.username + ")\r\n";
2842
+ recoveryCodeFileContents = recoveryCodeFileContents + "\r\n" + __("Each line of 16 letters and numbers is a single recovery code, with optional spaces for readability. When typing your password, enter \"wf\" followed by the entire code like \"mypassword wf1234 5678 90AB CDEF\". If your site shows a separate prompt for entering a code after entering only your username and password, enter only the code like \"1234 5678 90AB CDEF\". Your recovery codes are:") + "\r\n\r\n";
2843
  var splitter = /.{4}/g;
2844
  for (var i = 0; i < res.recoveryCodes.length; i++) {
2845
  var code = res.recoveryCodes[i];
2848
  recoveryCodeFileContents = recoveryCodeFileContents + chunks[0] + " " + chunks[1] + " " + chunks[2] + " " + chunks[3] + "\r\n";
2849
  }
2850
 
2851
+ message = message + "<p class=\"wf-center\"><a href=\"#\" class=\"wf-btn wf-btn-default\" id=\"wfTwoFactorDownload\" target=\"_blank\" rel=\"noopener noreferrer\"><i class=\"dashicons dashicons-download\"></i> " + __('Download') + "</a></p>";
2852
 
2853
+ message = message + "</ul><p><em>" + __("This will be shown only once. Keep these codes somewhere safe.") + "</em></p>";
2854
 
2855
+ self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), __("Recovery Codes"), message, {onComplete: function() {
2856
  jQuery('#wfTwoFactorDownload').on('click', function(e) {
2857
  e.preventDefault();
2858
  e.stopPropagation();
2879
  updatedTwoFac.find('tbody > tr').each(function(index, element) {
2880
  jQuery('#' + jQuery(element).attr('id')).replaceWith(element);
2881
  });
2882
+ self.twoFacStatus(__('Cellphone Sign-in activated for user.'));
2883
  }
2884
  });
2885
  },
3020
  }, function(res) {
3021
  if (res.ok) {
3022
  self.loadIssues(function() {
3023
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Successfully deleted admin"), sprintf(__("The admin user %s was successfully deleted."), res.user_login));
3024
  });
3025
  } else if (res.errorMsg) {
3026
  self.loadIssues(function() {
3037
  }, function(res) {
3038
  if (res.ok) {
3039
  self.loadIssues(function() {
3040
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Successfully revoked admin"), sprintf(__("All capabilties of admin user %s were successfully revoked."), res.user_login));
3041
  });
3042
  } else if (res.errorMsg) {
3043
  self.loadIssues(function() {
3222
  if (date.toLocaleString) {
3223
  dateString = date.toLocaleString();
3224
  }
3225
+ $('#waf-rules-last-updated').text(sprintf(__('Last Updated: %s'), dateString))
3226
  .css({
3227
  'opacity': 0
3228
  })
3236
  if (date.toLocaleString) {
3237
  dateString = date.toLocaleString();
3238
  }
3239
+ $('#waf-rules-next-update').text(sprintf(__('Next Update Check: %s'), dateString))
3240
  .css({
3241
  'opacity': 0
3242
  })
3254
  self.wafConfigPageRender();
3255
  if (self.wafData['updated']) {
3256
  if (!self.wafData['isPaid']) {
3257
+ self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), __('Rules Updated'), __('Your rules have been updated successfully. You are currently using the free version of Wordfence. Upgrade to Wordfence premium to have your rules updated automatically as new threats emerge. <a href="https://www.wordfence.com/wafUpdateRules1/wordfence-signup/">Click here to purchase a premium license</a>. <em>Note: Your rules will still update every 30 days as a free user.</em>'));
 
 
 
 
3258
  } else {
3259
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Rules Updated'), __('Your rules have been updated successfully.'));
3260
  }
3261
  }
3262
  else {
3263
  if (self.wafData['failure'] == 'ratelimit') {
3264
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Rule Update Failed'), __('No rules were updated. Your website has reached the maximum number of rule update requests. Please try again later.'));
3265
  }
3266
  else if (self.wafData['failure'] == 'unreachable') {
3267
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Rule Update Failed'), __('No rules were updated. Please verify your website can reach the Wordfence servers.'));
3268
  }
3269
  else {
3270
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Rule Update Failed'), __('No rules were updated. Please verify you have permissions to write to the /wp-content/wflogs directory.'));
3271
  }
3272
  }
3273
  if (typeof onSuccess === 'function') {
3289
  confirmWAFConfigureAutoPrepend: function() {
3290
  var self = this;
3291
  this.ajax('wordfence_wafConfigureAutoPrepend', {}, function(res) {
3292
+ self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('.htaccess Updated'), __("Your .htaccess has been updated successfully. Please verify your site is functioning normally."));
 
3293
  });
3294
  },
3295
 
3307
  },
3308
 
3309
  _unsavedOptionsHandler: function(e) {
3310
+ var message = __("You have unsaved changes to your options. If you leave this page, those changes will be lost."); //Only shows on older browsers, newer browsers don't allow message customization
3311
  e = e || window.event;
3312
  if (e) {
3313
  e.returnValue = message; //IE and Firefox
3323
  typeof successCallback == 'function' && successCallback(res);
3324
  }
3325
  else {
3326
+ WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Error Saving Option'), res.error);
3327
  typeof failureCallback == 'function' && failureCallback(res);
3328
  }
3329
  });
3340
  typeof successCallback == 'function' && successCallback(res);
3341
  }
3342
  else {
3343
+ WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Error Saving Options'), res.error);
3344
  typeof failureCallback == 'function' && failureCallback
3345
  }
3346
  });
3352
  window.location.href = res.redirect;
3353
  }
3354
  else {
3355
+ WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Error Enabling All Options Page'), res.error);
3356
  }
3357
  });
3358
  },
3419
  WFAD.updateTimeAgo();
3420
  }, 1000);
3421
  }
3422
+
3423
+ __ = window.wfi18n.__;
3424
+ sprintf = window.wfi18n.sprintf;
3425
+
3426
  jQuery(function() {
3427
  wordfenceAdmin.init();
3428
  jQuery(window).on('focus', function() {
3439
 
3440
  $.wfMobileMenu({
3441
  menuItems: [
3442
+ {title: __('Save Changes'), primary: true, disabled: $('#wf-save-changes').hasClass('wf-disabled'), action: function() { $('#wf-save-changes').trigger('click'); }},
3443
+ {title: __('Cancel Changes'), primary: false, disabled: $('#wf-cancel-changes').hasClass('wf-disabled'), action: function() { $('#wf-cancel-changes').trigger('click'); }},
3444
+ {title: __('Restore Defaults'), primary: false, disabled: $('#wf-restore-defaults').hasClass('wf-disabled'), action: function() { $('#wf-restore-defaults').trigger('click'); }}
3445
  ]
3446
  });
3447
  });
3471
  }
3472
  else {
3473
  WFAD.colorboxClose();
3474
+ WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), __('Error Restoring Defaults'), res.error);
3475
  }
3476
  });
3477
  });
3682
 
3683
  //wfCircularProgress
3684
  jQuery.fn.wfCircularProgress = function(options) {
3685
+ var __ = window.wfi18n.__;
3686
+ var sprintf = window.wfi18n.sprintf;
3687
+
3688
  jQuery(this).each(function() {
3689
  var creationOptions;
3690
  try {
3783
  });
3784
  };
3785
 
3786
+ (function() {
3787
+ var __ = window.wfi18n.__;
3788
+ var sprintf = window.wfi18n.sprintf;
3789
+
3790
+ jQuery.fn.wfCircularProgress.defaults = {
3791
+ startPercent: 0,
3792
+ endPercent: 1,
3793
+ color: '#16bc9b',
3794
+ inactiveColor: '#ececec',
3795
+ strokeWidth: 3,
3796
+ diameter: 100,
3797
+ pendingOverlay: false,
3798
+ pendingMessage: __('Note: Status will update when changes are saved'),
3799
+ };
3800
+ })();
3801
 
3802
  //wfDrawer
3803
  (function ($, document, window) {
3804
+ var __ = window.wfi18n.__;
3805
+ var sprintf = window.wfi18n.sprintf;
3806
+
3807
  var defaults = {
3808
  width: '600px',
3809
  clickOverlayDismiss: false,
3869
 
3870
  //wfMobileMenu
3871
  (function ($, document, window) {
3872
+ var __ = window.wfi18n.__;
3873
+ var sprintf = window.wfi18n.sprintf;
3874
+
3875
  var defaults = {
3876
  width: '280px',
3877
  clickOverlayDismiss: true,
3921
  itemsWrapper.append(button);
3922
  }
3923
 
3924
+ var button = $('<li class="wf-padding-add-top-small"><a href="#" class="wf-btn wf-btn-callout-subtle wf-btn-default">' + __('Close') + '</a></li>');
3925
  button.find('a').css('width', opts.width).on('click', function(e) {
3926
  e.preventDefault();
3927
  e.stopPropagation();
js/{admin.ajaxWatcher.1607007971.js → admin.ajaxWatcher.1616599470.js} RENAMED
@@ -1,4 +1,7 @@
1
  (function($, document, window) {
 
 
 
2
  if (!window['wordfenceAJAXWatcher']) {
3
  window['wordfenceAJAXWatcher'] = {
4
  blockWarningOpen: false,
@@ -39,7 +42,7 @@
39
  $.wordfenceBox({
40
  closeButton: false,
41
  width: '400px',
42
- html: "<h3>Background Request Blocked</h3><p>Wordfence Firewall blocked a background request to WordPress for the URL <code>" + requestURLEscaped + "</code>. If this occurred as a result of an intentional action, you may consider allowlisting the request to allow it in the future.</p><p class=\"wf-right\"><a href=\"https://www.wordfence.com/help/?query=ajax-blocked\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wfboxhelp\"></a><a href=\"#\" class=\"button\" id=\"background-block-whitelist\">Add action to allowlist</a> <a href=\"#\" class=\"button\" id=\"background-block-dismiss\">Dismiss</a></p>",
43
  onComplete: function() {
44
  $('#background-block-dismiss').click(function(event) {
45
  event.preventDefault();
@@ -51,18 +54,18 @@
51
  event.preventDefault();
52
  event.stopPropagation();
53
 
54
- if (confirm('Are you sure you want to allowlist this action?')) {
55
  $.ajax({
56
  method: 'POST',
57
  url: formAction,
58
  data: queryParams,
59
  global: false,
60
  success: function() {
61
- alert('The request has been allowlisted. Please try it again.');
62
  $.wordfenceBox.close();
63
  },
64
  error: function() {
65
- alert('An error occurred when adding the request to the allowlist.');
66
  $.wordfenceBox.close();
67
  }
68
  });
1
  (function($, document, window) {
2
+ var __ = window.wfi18n.__;
3
+ var sprintf = window.wfi18n.sprintf;
4
+
5
  if (!window['wordfenceAJAXWatcher']) {
6
  window['wordfenceAJAXWatcher'] = {
7
  blockWarningOpen: false,
42
  $.wordfenceBox({
43
  closeButton: false,
44
  width: '400px',
45
+ html: "<h3>" + __('Background Request Blocked') + "</h3><p>" + sprintf(__("Wordfence Firewall blocked a background request to WordPress for the URL %s. If this occurred as a result of an intentional action, you may consider allowlisting the request to allow it in the future."), "<code>" + requestURLEscaped + "</code>") + "</p><p class=\"wf-right\"><a href=\"https://www.wordfence.com/help/?query=ajax-blocked\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wfboxhelp\"></a><a href=\"#\" class=\"button\" id=\"background-block-whitelist\">" + __("Add action to allowlist") + "</a> <a href=\"#\" class=\"button\" id=\"background-block-dismiss\">" + __("Dismiss") + "</a></p>",
46
  onComplete: function() {
47
  $('#background-block-dismiss').click(function(event) {
48
  event.preventDefault();
54
  event.preventDefault();
55
  event.stopPropagation();
56
 
57
+ if (confirm(__('Are you sure you want to allowlist this action?'))) {
58
  $.ajax({
59
  method: 'POST',
60
  url: formAction,
61
  data: queryParams,
62
  global: false,
63
  success: function() {
64
+ alert(__('The request has been allowlisted. Please try it again.'));
65
  $.wordfenceBox.close();
66
  },
67
  error: function() {
68
+ alert(__('An error occurred when adding the request to the allowlist.'));
69
  $.wordfenceBox.close();
70
  }
71
  });
js/{admin.liveTraffic.1607007971.js → admin.liveTraffic.1616599470.js} RENAMED
@@ -1,4 +1,6 @@
1
  (function($) {
 
 
2
 
3
  var LISTING_LIMIT = 50;
4
 
@@ -18,32 +20,32 @@
18
  };
19
  self.filters = ko.observableArray(filters);
20
 
21
- var urlGroupBy = new GroupByModel('url', 'URL');
22
  var groupBys = [
23
- new GroupByModel('type', 'Type'),
24
- new GroupByModel('user_login', 'Username'),
25
- new GroupByModel('statusCode', 'HTTP Response Code'),
26
- new GroupByModel('action', 'Firewall Response', 'enum', ['ok', 'throttled', 'lockedOut', 'blocked', 'blocked:waf']),
27
- new GroupByModel('ip', 'IP'),
28
  urlGroupBy
29
  ];
30
 
31
  self.presetFiltersOptions = ko.observableArray([
32
- new PresetFilterModel('All Hits', "all", []),
33
- new PresetFilterModel('Humans', "humans", [new ListingsFilterModel(self, 'type', 'human')]),
34
- new PresetFilterModel('Registered Users', "users", [new ListingsFilterModel(self, 'userID', '0', '!=')]),
35
- new PresetFilterModel('Crawlers', "crawlers", [new ListingsFilterModel(self, 'type', 'bot')]),
36
- new PresetFilterModel('Google Crawlers', "google", [new ListingsFilterModel(self, 'isGoogle', '1')]),
37
- new PresetFilterModel('Pages Not Found', "404s", [new ListingsFilterModel(self, 'statusCode', '404')]),
38
- new PresetFilterModel('Logins and Logouts', "logins", [
39
  new ListingsFilterModel(self, 'action', 'login', 'contains'),
40
  new ListingsFilterModel(self, 'action', 'logout', 'contains')
41
  ]),
42
  //new PresetFilterModel('Top Consumers', "top_consumers", [new ListingsFilterModel(self, 'statusCode', '200')], urlGroupBy),
43
  //new PresetFilterModel('Top 404s', "top_404s", [new ListingsFilterModel(self, 'statusCode', '404')], urlGroupBy),
44
- new PresetFilterModel('Locked Out', "lockedOut", [new ListingsFilterModel(self, 'action', 'lockedOut')]),
45
- new PresetFilterModel('Blocked', "blocked", [new ListingsFilterModel(self, 'action', 'blocked', 'contains')]),
46
- new PresetFilterModel('Blocked By Firewall', "blocked:waf", [new ListingsFilterModel(self, 'action', 'blocked:waf')])
47
  ]);
48
 
49
  self.showAdvancedFilters = ko.observable(false);
@@ -388,20 +390,20 @@
388
  if (groupBy == 'action') {
389
  switch (self.action()) {
390
  case 'lockedOut':
391
- return 'Locked out from logging in';
392
  case 'blocked:waf-always':
393
- return 'Blocked by the Wordfence Application Firewall and plugin settings';
394
  case 'blocked:wordfence':
395
- return 'Blocked by Wordfence plugin settings';
396
  case 'blocked:wfsnrepeat':
397
  case 'blocked:wfsn':
398
- return 'Blocked by the Wordfence Security Network';
399
  case 'blocked:waf':
400
- return 'Blocked by the Wordfence Web Application Firewall';
401
  case 'cbl:redirect':
402
- return 'Redirected by Country Blocking bypass URL';
403
  default:
404
- return 'Blocked by Wordfence';
405
  }
406
  }
407
 
@@ -409,7 +411,7 @@
409
  var desc = '';
410
  switch (self.action()) {
411
  case 'lockedOut':
412
- return 'locked out from logging in';
413
 
414
  case 'blocked:waf-always':
415
  case 'blocked:wordfence':
@@ -418,10 +420,10 @@
418
  if (desc && desc.toLowerCase().indexOf('block') === 0) {
419
  return 'b' + desc.substring(1);
420
  }
421
- return 'blocked for ' + desc;
422
 
423
  case 'blocked:wfsn':
424
- return 'blocked by the Wordfence Security Network';
425
 
426
  case 'blocked:waf':
427
  var data = self.actionData();
@@ -435,28 +437,28 @@
435
  if (matches) {
436
  switch (matches[1]) {
437
  case 'request.queryString':
438
- desc = self.actionDescription() + ' in query string: ' + matches[2] + '=' + LiveTrafficViewModel.truncateText(encodeURIComponent(paramValue));
439
  break;
440
  case 'request.body':
441
- desc = self.actionDescription() + ' in POST body: ' + matches[2] + '=' + LiveTrafficViewModel.truncateText(encodeURIComponent(paramValue));
442
  break;
443
  case 'request.cookie':
444
- desc = self.actionDescription() + ' in cookie: ' + matches[2] + '=' + LiveTrafficViewModel.truncateText(encodeURIComponent(paramValue));
445
  break;
446
  case 'request.fileNames':
447
- desc = 'a ' + self.actionDescription() + ' in file: ' + matches[2] + '=' + LiveTrafficViewModel.truncateText(encodeURIComponent(paramValue));
448
  break;
449
  }
450
  }
451
  if (desc) {
452
- return 'blocked by firewall for ' + desc;
453
  }
454
  if (data.failedRules == 'blocked') {
455
- return 'blocked by real-time IP blocklist';
456
  }
457
- return 'blocked by firewall';
458
  }
459
- return 'blocked by firewall for ' + self.actionDescription();
460
  case 'cbl:redirect':
461
  desc = self.actionDescription();
462
  return desc;
@@ -503,21 +505,21 @@
503
  });
504
 
505
  self.typeText = ko.pureComputed(function() {
506
- var type = 'Type: ';
507
  if (self.action() == 'loginFailValidUsername' || self.action() == 'loginFailInvalidUsername') {
508
- type += 'Failed Login';
509
  } else if (self.statusCode() == 403 || self.statusCode() == 503) {
510
- type += 'Blocked';
511
  } else if (self.statusCode() == 404) {
512
- type += '404 Not Found';
513
  } else if (self.statusCode() == 302) {
514
- type += 'Redirected';
515
  } else if (self.jsRun() == 1) {
516
- type += 'Human';
517
  } else {
518
- type += 'Bot';
519
  }
520
- return type;
521
  });
522
 
523
  function slideInDrawer() {
@@ -544,7 +546,7 @@
544
  .animate({
545
  opacity: 1
546
  }, 200)
547
- .html('<h4 style=\'margin-top:0;\'>WHOIS LOOKUP</h4>' + whoisHTML);
548
  $(window).trigger('wf-live-traffic-overlay-bind', self);
549
  });
550
  };
@@ -561,7 +563,7 @@
561
  .animate({
562
  opacity: 1
563
  }, 200)
564
- .html('<h3 style=\'margin-top:0;\'>Recent Activity</h3>' + result.result);
565
  $(window).trigger('wf-live-traffic-overlay-bind', self);
566
  WFAD.avatarLookup();
567
  });
@@ -579,7 +581,7 @@
579
  WFAD.unblockNetwork(self.ipRangeID());
580
  };
581
  self.blockIP = function() {
582
- WFAD.blockIP(self.IP(), 'Manual block by administrator', function() {
583
  $(window).trigger('wf-live-traffic-ip-blocked', self.IP());
584
  });
585
  };
@@ -620,32 +622,32 @@
620
  ]);
621
 
622
  self.filterParamOptions = ko.observableArray([
623
- new FilterParamModel('type', 'Type', 'enum', [
624
- new FilterParamEnumOptionModel('human', 'Human'),
625
- new FilterParamEnumOptionModel('bot', 'Bot')
626
  ]),
627
- new FilterParamModel('user_login', 'Username'),
628
- new FilterParamModel('userID', 'UserID'),
629
- new FilterParamModel('isGoogle', 'Google Bot', 'bool'),
630
- new FilterParamModel('ip', 'IP'),
631
- new FilterParamModel('ua', 'User Agent'),
632
- new FilterParamModel('referer', 'Referer'),
633
- new FilterParamModel('url', 'URL'),
634
- new FilterParamModel('statusCode', 'HTTP Response Code'),
635
- new FilterParamModel('action', 'Firewall Response', 'enum', [
636
- new FilterParamEnumOptionModel('', 'OK'),
637
- new FilterParamEnumOptionModel('throttled', 'Throttled'),
638
- new FilterParamEnumOptionModel('lockedOut', 'Locked Out'),
639
- new FilterParamEnumOptionModel('blocked', 'Blocked', containsOperator),
640
- new FilterParamEnumOptionModel('blocked:waf', 'Blocked WAF')
641
  ]),
642
- new FilterParamModel('action', 'Logins', 'enum', [
643
- new FilterParamEnumOptionModel('loginOK', 'Logged In'),
644
- new FilterParamEnumOptionModel('loginFail', 'Failed Login'),
645
- new FilterParamEnumOptionModel('loginFailInvalidUsername', 'Failed Login: Invalid Username'),
646
- new FilterParamEnumOptionModel('loginFailValidUsername', 'Failed Login: Valid Username')
647
  ]),
648
- new FilterParamModel('action', 'Security Event')
649
  ]);
650
 
651
  self.filterParamOptionsText = function(item) {
@@ -811,7 +813,7 @@
811
  var liveTrafficWrapper = $('#wf-live-traffic');
812
  $('#wf-lt-preset-filters').wfselect2({
813
  templateSelection: function(value) {
814
- return $('<span><em>Filter Traffic</em>: ' + value.text + '</span>');
815
  }
816
  });
817
 
1
  (function($) {
2
+ var __ = window.wfi18n.__;
3
+ var sprintf = window.wfi18n.sprintf;
4
 
5
  var LISTING_LIMIT = 50;
6
 
20
  };
21
  self.filters = ko.observableArray(filters);
22
 
23
+ var urlGroupBy = new GroupByModel('url', __('URL'));
24
  var groupBys = [
25
+ new GroupByModel('type', __('Type')),
26
+ new GroupByModel('user_login', __('Username')),
27
+ new GroupByModel('statusCode', __('HTTP Response Code')),
28
+ new GroupByModel('action', __('Firewall Response'), 'enum', ['ok', 'throttled', 'lockedOut', 'blocked', 'blocked:waf']),
29
+ new GroupByModel('ip', __('IP')),
30
  urlGroupBy
31
  ];
32
 
33
  self.presetFiltersOptions = ko.observableArray([
34
+ new PresetFilterModel(__('All Hits'), "all", []),
35
+ new PresetFilterModel(__('Humans'), "humans", [new ListingsFilterModel(self, 'type', 'human')]),
36
+ new PresetFilterModel(__('Registered Users'), "users", [new ListingsFilterModel(self, 'userID', '0', '!=')]),
37
+ new PresetFilterModel(__('Crawlers'), "crawlers", [new ListingsFilterModel(self, 'type', 'bot')]),
38
+ new PresetFilterModel(__('Google Crawlers'), "google", [new ListingsFilterModel(self, 'isGoogle', '1')]),
39
+ new PresetFilterModel(__('Pages Not Found'), "404s", [new ListingsFilterModel(self, 'statusCode', '404')]),
40
+ new PresetFilterModel(__('Logins and Logouts'), "logins", [
41
  new ListingsFilterModel(self, 'action', 'login', 'contains'),
42
  new ListingsFilterModel(self, 'action', 'logout', 'contains')
43
  ]),
44
  //new PresetFilterModel('Top Consumers', "top_consumers", [new ListingsFilterModel(self, 'statusCode', '200')], urlGroupBy),
45
  //new PresetFilterModel('Top 404s', "top_404s", [new ListingsFilterModel(self, 'statusCode', '404')], urlGroupBy),
46
+ new PresetFilterModel(__('Locked Out'), "lockedOut", [new ListingsFilterModel(self, 'action', 'lockedOut')]),
47
+ new PresetFilterModel(__('Blocked'), "blocked", [new ListingsFilterModel(self, 'action', 'blocked', 'contains')]),
48
+ new PresetFilterModel(__('Blocked By Firewall'), "blocked:waf", [new ListingsFilterModel(self, 'action', 'blocked:waf')])
49
  ]);
50
 
51
  self.showAdvancedFilters = ko.observable(false);
390
  if (groupBy == 'action') {
391
  switch (self.action()) {
392
  case 'lockedOut':
393
+ return __('Locked out from logging in');
394
  case 'blocked:waf-always':
395
+ return __('Blocked by the Wordfence Application Firewall and plugin settings');
396
  case 'blocked:wordfence':
397
+ return __('Blocked by Wordfence plugin settings');
398
  case 'blocked:wfsnrepeat':
399
  case 'blocked:wfsn':
400
+ return __('Blocked by the Wordfence Security Network');
401
  case 'blocked:waf':
402
+ return __('Blocked by the Wordfence Web Application Firewall');
403
  case 'cbl:redirect':
404
+ return __('Redirected by Country Blocking bypass URL');
405
  default:
406
+ return __('Blocked by Wordfence');
407
  }
408
  }
409
 
411
  var desc = '';
412
  switch (self.action()) {
413
  case 'lockedOut':
414
+ return __('locked out from logging in');
415
 
416
  case 'blocked:waf-always':
417
  case 'blocked:wordfence':
420
  if (desc && desc.toLowerCase().indexOf('block') === 0) {
421
  return 'b' + desc.substring(1);
422
  }
423
+ return sprintf(__('blocked for %s'), desc);
424
 
425
  case 'blocked:wfsn':
426
+ return __('blocked by the Wordfence Security Network');
427
 
428
  case 'blocked:waf':
429
  var data = self.actionData();
437
  if (matches) {
438
  switch (matches[1]) {
439
  case 'request.queryString':
440
+ desc = sprintf(__('%s in query string: %s'), self.actionDescription(), matches[2] + '=' + LiveTrafficViewModel.truncateText(encodeURIComponent(paramValue)));
441
  break;
442
  case 'request.body':
443
+ desc = sprintf(__('%s in POST body: %s'), self.actionDescription(), matches[2] + '=' + LiveTrafficViewModel.truncateText(encodeURIComponent(paramValue)));
444
  break;
445
  case 'request.cookie':
446
+ desc = sprintf(__('%s in cookie: %s'), self.actionDescription(), matches[2] + '=' + LiveTrafficViewModel.truncateText(encodeURIComponent(paramValue)));
447
  break;
448
  case 'request.fileNames':
449
+ desc = sprintf(__('%s in file: %s'), self.actionDescription(), matches[2] + '=' + LiveTrafficViewModel.truncateText(encodeURIComponent(paramValue)));
450
  break;
451
  }
452
  }
453
  if (desc) {
454
+ return sprintf(__('blocked by firewall for %s'), desc);
455
  }
456
  if (data.failedRules == 'blocked') {
457
+ return __('blocked by real-time IP blocklist');
458
  }
459
+ return __('blocked by firewall');
460
  }
461
+ return sprintf(__('blocked by firewall for %s'), self.actionDescription());
462
  case 'cbl:redirect':
463
  desc = self.actionDescription();
464
  return desc;
505
  });
506
 
507
  self.typeText = ko.pureComputed(function() {
508
+ var type = '';
509
  if (self.action() == 'loginFailValidUsername' || self.action() == 'loginFailInvalidUsername') {
510
+ type = __('Failed Login');
511
  } else if (self.statusCode() == 403 || self.statusCode() == 503) {
512
+ type = __('Blocked');
513
  } else if (self.statusCode() == 404) {
514
+ type = __('404 Not Found');
515
  } else if (self.statusCode() == 302) {
516
+ type = __('Redirected');
517
  } else if (self.jsRun() == 1) {
518
+ type = __('Human');
519
  } else {
520
+ type = __('Bot');
521
  }
522
+ return sprintf(__('Type: %s'), type);
523
  });
524
 
525
  function slideInDrawer() {
546
  .animate({
547
  opacity: 1
548
  }, 200)
549
+ .html('<h4 style=\'margin-top:0;\'>' + __('WHOIS LOOKUP') + '</h4>' + whoisHTML);
550
  $(window).trigger('wf-live-traffic-overlay-bind', self);
551
  });
552
  };
563
  .animate({
564
  opacity: 1
565
  }, 200)
566
+ .html('<h3 style=\'margin-top:0;\'>' + __('Recent Activity') + '</h3>' + result.result);
567
  $(window).trigger('wf-live-traffic-overlay-bind', self);
568
  WFAD.avatarLookup();
569
  });
581
  WFAD.unblockNetwork(self.ipRangeID());
582
  };
583
  self.blockIP = function() {
584
+ WFAD.blockIP(self.IP(), __('Manual block by administrator'), function() {
585
  $(window).trigger('wf-live-traffic-ip-blocked', self.IP());
586
  });
587
  };
622
  ]);
623
 
624
  self.filterParamOptions = ko.observableArray([
625
+ new FilterParamModel('type', __('Type'), 'enum', [
626
+ new FilterParamEnumOptionModel('human', __('Human')),
627
+ new FilterParamEnumOptionModel('bot', __('Bot'))
628
  ]),
629
+ new FilterParamModel('user_login', __('Username')),
630
+ new FilterParamModel('userID', __('User ID')),
631
+ new FilterParamModel('isGoogle', __('Google Bot'), 'bool'),
632
+ new FilterParamModel('ip', __('IP')),
633
+ new FilterParamModel('ua', __('User Agent')),
634
+ new FilterParamModel('referer', __('Referer')),
635
+ new FilterParamModel('url', __('URL')),
636
+ new FilterParamModel('statusCode', __('HTTP Response Code')),
637
+ new FilterParamModel('action', __('Firewall Response'), 'enum', [
638
+ new FilterParamEnumOptionModel('', __('OK')),
639
+ new FilterParamEnumOptionModel('throttled', __('Throttled')),
640
+ new FilterParamEnumOptionModel('lockedOut', __('Locked Out')),
641
+ new FilterParamEnumOptionModel('blocked', __('Blocked'), containsOperator),
642
+ new FilterParamEnumOptionModel('blocked:waf', __('Blocked WAF'))
643
  ]),
644
+ new FilterParamModel('action', __('Logins'), 'enum', [
645
+ new FilterParamEnumOptionModel('loginOK', __('Logged In')),
646
+ new FilterParamEnumOptionModel('loginFail', __('Failed Login')),
647
+ new FilterParamEnumOptionModel('loginFailInvalidUsername', __('Failed Login: Invalid Username')),
648
+ new FilterParamEnumOptionModel('loginFailValidUsername', __('Failed Login: Valid Username'))
649
  ]),
650
+ new FilterParamModel('action', __('Security Event'))
651
  ]);
652
 
653
  self.filterParamOptionsText = function(item) {
813
  var liveTrafficWrapper = $('#wf-live-traffic');
814
  $('#wf-lt-preset-filters').wfselect2({
815
  templateSelection: function(value) {
816
+ return $('<span><em>' + __('Filter Traffic') + '</em>: ' + value.text + '</span>');
817
  }
818
  });
819
 
js/{date.1607007971.js → date.1616599470.js} RENAMED
File without changes
js/{jquery-ui-timepicker-addon.1607007971.js → jquery-ui-timepicker-addon.1616599470.js} RENAMED
File without changes
js/{jquery.colorbox-min.1607007971.js → jquery.colorbox-min.1616599470.js} RENAMED
File without changes
js/{jquery.colorbox.1607007971.js → jquery.colorbox.1616599470.js} RENAMED
File without changes
js/{jquery.dataTables.min.1607007971.js → jquery.dataTables.min.1616599470.js} RENAMED
File without changes
js/{jquery.qrcode.min.1607007971.js → jquery.qrcode.min.1616599470.js} RENAMED
File without changes
js/{jquery.tmpl.min.1607007971.js → jquery.tmpl.min.1616599470.js} RENAMED
File without changes
js/{jquery.tools.min.1607007971.js → jquery.tools.min.1616599470.js} RENAMED
File without changes
js/{knockout-3.3.0.1607007971.js → knockout-3.3.0.1616599470.js} RENAMED
File without changes
js/{wfdashboard.1607007971.js → wfdashboard.1616599470.js} RENAMED
File without changes
js/{wfdropdown.1607007971.js → wfdropdown.1616599470.js} RENAMED
File without changes
js/{wfglobal.1607007971.js → wfglobal.1616599470.js} RENAMED
@@ -1,4 +1,6 @@
1
  (function($) {
 
 
2
  if (!window['wordfenceExt']) {
3
  window['wordfenceExt'] = {
4
  nonce: false,
@@ -11,7 +13,7 @@
11
  showLoading: function(){
12
  this.loadingCount++;
13
  if (this.loadingCount == 1) {
14
- jQuery('<div id="wordfenceWorking">Wordfence is working...</div>').appendTo('body');
15
  }
16
  },
17
  removeLoading: function(){
@@ -156,19 +158,12 @@
156
  }
157
  };
158
  }
159
-
 
 
 
160
  $(function() {
161
  wordfenceExt.init();
162
-
163
- $('.wf-dismiss-link').on('click', function() {
164
- $('#wf-extended-protection-notice').css({
165
- opacity: .75
166
- });
167
- $.get(this.href, function() {
168
- $('#wf-extended-protection-notice').fadeOut(1000);
169
- });
170
- return false;
171
- });
172
  });
173
  })(jQuery);
174
 
1
  (function($) {
2
+ var __, sprintf;
3
+
4
  if (!window['wordfenceExt']) {
5
  window['wordfenceExt'] = {
6
  nonce: false,
13
  showLoading: function(){
14
  this.loadingCount++;
15
  if (this.loadingCount == 1) {
16
+ jQuery('<div id="wordfenceWorking">' + __('Wordfence is working...') + '</div>').appendTo('body');
17
  }
18
  },
19
  removeLoading: function(){
158
  }
159
  };
160
  }
161
+
162
+ __ = window.wfi18n.__;
163
+ sprintf = window.wfi18n.sprintf;
164
+
165
  $(function() {
166
  wordfenceExt.init();
 
 
 
 
 
 
 
 
 
 
167
  });
168
  })(jQuery);
169
 
js/wfi18n.1616599470.js ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function () {
2
+
3
+ window.wfi18n = {
4
+ __: function(text) {
5
+ if (window.WordfenceI18nStrings && text in window.WordfenceI18nStrings) {
6
+ return window.WordfenceI18nStrings[text];
7
+ }
8
+ return text;
9
+ }
10
+ };
11
+
12
+ if (typeof wp === 'object' && wp.i18n) {
13
+ window.wfi18n.sprintf = wp.i18n.sprintf;
14
+ return;
15
+ }
16
+
17
+ /**
18
+ * Code has been adapted from WordPress' i18n.js functions and is being used as a polyfill for WordPress
19
+ * versions before 5.0.
20
+ */
21
+ var re = {
22
+ not_string: /[^s]/,
23
+ not_bool: /[^t]/,
24
+ not_type: /[^T]/,
25
+ not_primitive: /[^v]/,
26
+ number: /[diefg]/,
27
+ numeric_arg: /[bcdiefguxX]/,
28
+ json: /[j]/,
29
+ not_json: /[^j]/,
30
+ text: /^[^\x25]+/,
31
+ modulo: /^\x25{2}/,
32
+ placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
33
+ key: /^([a-z_][a-z_\d]*)/i,
34
+ key_access: /^\.([a-z_][a-z_\d]*)/i,
35
+ index_access: /^\[(\d+)\]/,
36
+ sign: /^[+-]/
37
+ };
38
+
39
+ function sprintf(key) {
40
+ // `arguments` is not an array, but should be fine for this call
41
+ return sprintf_format(sprintf_parse(key), arguments)
42
+ }
43
+
44
+ function vsprintf(fmt, argv) {
45
+ return sprintf.apply(null, [fmt].concat(argv || []))
46
+ }
47
+
48
+ function sprintf_format(parse_tree, argv) {
49
+ var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
50
+ for (i = 0; i < tree_length; i++) {
51
+ if (typeof parse_tree[i] === 'string') {
52
+ output += parse_tree[i]
53
+ }
54
+ else if (typeof parse_tree[i] === 'object') {
55
+ ph = parse_tree[i] // convenience purposes only
56
+ if (ph.keys) { // keyword argument
57
+ arg = argv[cursor]
58
+ for (k = 0; k < ph.keys.length; k++) {
59
+ if (arg == undefined) {
60
+ throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
61
+ }
62
+ arg = arg[ph.keys[k]]
63
+ }
64
+ }
65
+ else if (ph.param_no) { // positional argument (explicit)
66
+ arg = argv[ph.param_no]
67
+ }
68
+ else { // positional argument (implicit)
69
+ arg = argv[cursor++]
70
+ }
71
+
72
+ if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
73
+ arg = arg()
74
+ }
75
+
76
+ if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
77
+ throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
78
+ }
79
+
80
+ if (re.number.test(ph.type)) {
81
+ is_positive = arg >= 0
82
+ }
83
+
84
+ switch (ph.type) {
85
+ case 'b':
86
+ arg = parseInt(arg, 10).toString(2)
87
+ break
88
+ case 'c':
89
+ arg = String.fromCharCode(parseInt(arg, 10))
90
+ break
91
+ case 'd':
92
+ case 'i':
93
+ arg = parseInt(arg, 10)
94
+ break
95
+ case 'j':
96
+ arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
97
+ break
98
+ case 'e':
99
+ arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
100
+ break
101
+ case 'f':
102
+ arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
103
+ break
104
+ case 'g':
105
+ arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
106
+ break
107
+ case 'o':
108
+ arg = (parseInt(arg, 10) >>> 0).toString(8)
109
+ break
110
+ case 's':
111
+ arg = String(arg)
112
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
113
+ break
114
+ case 't':
115
+ arg = String(!!arg)
116
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
117
+ break
118
+ case 'T':
119
+ arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
120
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
121
+ break
122
+ case 'u':
123
+ arg = parseInt(arg, 10) >>> 0
124
+ break
125
+ case 'v':
126
+ arg = arg.valueOf()
127
+ arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
128
+ break
129
+ case 'x':
130
+ arg = (parseInt(arg, 10) >>> 0).toString(16)
131
+ break
132
+ case 'X':
133
+ arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
134
+ break
135
+ }
136
+ if (re.json.test(ph.type)) {
137
+ output += arg
138
+ }
139
+ else {
140
+ if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
141
+ sign = is_positive ? '+' : '-'
142
+ arg = arg.toString().replace(re.sign, '')
143
+ }
144
+ else {
145
+ sign = ''
146
+ }
147
+ pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
148
+ pad_length = ph.width - (sign + arg).length
149
+ pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
150
+ output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
151
+ }
152
+ }
153
+ }
154
+ return output
155
+ }
156
+
157
+ var sprintf_cache = Object.create(null)
158
+
159
+ function sprintf_parse(fmt) {
160
+ if (sprintf_cache[fmt]) {
161
+ return sprintf_cache[fmt]
162
+ }
163
+
164
+ var _fmt = fmt, match, parse_tree = [], arg_names = 0
165
+ while (_fmt) {
166
+ if ((match = re.text.exec(_fmt)) !== null) {
167
+ parse_tree.push(match[0])
168
+ }
169
+ else if ((match = re.modulo.exec(_fmt)) !== null) {
170
+ parse_tree.push('%')
171
+ }
172
+ else if ((match = re.placeholder.exec(_fmt)) !== null) {
173
+ if (match[2]) {
174
+ arg_names |= 1
175
+ var field_list = [], replacement_field = match[2], field_match = []
176
+ if ((field_match = re.key.exec(replacement_field)) !== null) {
177
+ field_list.push(field_match[1])
178
+ while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
179
+ if ((field_match = re.key_access.exec(replacement_field)) !== null) {
180
+ field_list.push(field_match[1])
181
+ }
182
+ else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
183
+ field_list.push(field_match[1])
184
+ }
185
+ else {
186
+ throw new SyntaxError('[sprintf] failed to parse named argument key')
187
+ }
188
+ }
189
+ }
190
+ else {
191
+ throw new SyntaxError('[sprintf] failed to parse named argument key')
192
+ }
193
+ match[2] = field_list
194
+ }
195
+ else {
196
+ arg_names |= 2
197
+ }
198
+ if (arg_names === 3) {
199
+ throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
200
+ }
201
+
202
+ parse_tree.push(
203
+ {
204
+ placeholder: match[0],
205
+ param_no: match[1],
206
+ keys: match[2],
207
+ sign: match[3],
208
+ pad_char: match[4],
209
+ align: match[5],
210
+ width: match[6],
211
+ precision: match[7],
212
+ type: match[8]
213
+ }
214
+ )
215
+ }
216
+ else {
217
+ throw new SyntaxError('[sprintf] unexpected placeholder')
218
+ }
219
+ _fmt = _fmt.substring(match[0].length)
220
+ }
221
+ return sprintf_cache[fmt] = parse_tree
222
+ }
223
+
224
+ window.wfi18n.sprintf = sprintf;
225
+ })();
js/{wfpopover.1607007971.js → wfpopover.1616599470.js} RENAMED
File without changes
js/{wfselect2.min.1607007971.js → wfselect2.min.1616599470.js} RENAMED
File without changes
languages/wordfence.mo CHANGED
Binary file
languages/wordfence.po CHANGED
@@ -1,260 +1,178 @@
1
- # Copyright (C) 2020 Wordfence
2
  # This file is distributed under the same license as the Wordfence Security plugin.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Wordfence Security 7.4.11\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/src\n"
7
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
  "Language-Team: LANGUAGE <LL@li.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2020-10-01T16:37:39+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
 
15
 
16
- #: 403-blacklist.php:79
17
- #: 403-blacklist.php:181
18
- #: 403-roadblock.php:40
19
- #: 403.php:7
20
- msgid "403 Forbidden"
21
- msgstr ""
22
-
23
- #: 403-blacklist.php:183
24
- msgid "WHAT? Why am I seeing this?"
25
- msgstr ""
26
-
27
- #: 403-blacklist.php:185
28
- msgid "Your access to this site was blocked by Wordfence, a security provider, who protects sites from malicious activity."
29
- msgstr ""
30
-
31
- #: 403-blacklist.php:187
32
- msgid "If you believe Wordfence should be allowing you access to this site, please let them know using the steps below so they can investigate why this is happening."
33
- msgstr ""
34
-
35
- #: 403-blacklist.php:191
36
- msgid "Reporting a Problem"
37
- msgstr ""
38
-
39
- #: 403-blacklist.php:193
40
- msgid "1. Please copy this text. You need to paste it into a form later."
41
- msgstr ""
42
-
43
- #: 403-blacklist.php:212
44
- msgid "2. Click this button and you will be prompted to paste the text above."
45
- msgstr ""
46
-
47
- #: 403-blacklist.php:214
48
- msgid "Report Problem"
49
- msgstr ""
50
-
51
- #: 403-blacklist.php:216
52
- #: 403-roadblock.php:447
53
- #: 403.php:362
54
- #: 503-lockout.php:389
55
- #: 503.php:383
56
- msgid "Generated by Wordfence at %s.<br>Your computer's time: "
57
- msgstr ""
58
-
59
- #: 403-roadblock.php:357
60
- #: 403-roadblock.php:421
61
- #: 403.php:324
62
- #: 403.php:336
63
- msgid "A potentially unsafe operation has been detected in your request to this site"
64
- msgstr ""
65
-
66
- #: 403-roadblock.php:358
67
- #: 403.php:325
68
- msgid "Your access to this service has been limited. (HTTP response code 403)"
69
- msgstr ""
70
-
71
- #: 403-roadblock.php:359
72
- #: 403.php:326
73
- #: 503-lockout.php:327
74
- #: 503.php:327
75
- #: lib/wf503.php:323
76
- #: lib/wfLockedOut.php:328
77
- msgid "If you think you have been blocked in error, contact the owner of this site for assistance."
78
- msgstr ""
79
-
80
- #: 403-roadblock.php:366
81
- msgid "If you are an administrator and you are certain this is a false positive, you can automatically allowlist this request and repeat the same action."
82
- msgstr ""
83
-
84
- #: 403-roadblock.php:373
85
- msgid "I am certain this is a false positive."
86
- msgstr ""
87
-
88
- #: 403-roadblock.php:375
89
- msgid "Allowlist This Action"
90
- msgstr ""
91
-
92
- #: 403-roadblock.php:378
93
- msgid "All set! You can refresh the page to try this action again."
94
- msgstr ""
95
-
96
- #: 403-roadblock.php:379
97
- msgid "Something went wrong allowlisting this request. You can try setting the Firewall Status to Learning Mode under Web App Firewall in the Wordfence menu, and retry this same action."
98
- msgstr ""
99
-
100
- #: 403-roadblock.php:417
101
- #: 403.php:332
102
- #: 503-lockout.php:359
103
- #: 503.php:353
104
- #: lib/wf503.php:331
105
- #: lib/wfLockedOut.php:340
106
- msgid "Block Technical Data"
107
  msgstr ""
108
 
109
- #: 403-roadblock.php:420
110
- #: 403.php:335
111
- #: 503-lockout.php:362
112
- #: 503.php:356
113
- #: lib/wfLockedOut.php:343
114
- msgid "Block Reason:"
115
  msgstr ""
116
 
117
- #: 403-roadblock.php:424
118
- #: 403.php:339
119
- #: 503-lockout.php:366
120
- #: 503.php:360
121
- #: lib/wfLockedOut.php:347
122
- msgid "Time:"
123
  msgstr ""
124
 
125
- #: 403-roadblock.php:440
126
- #: 403.php:355
127
- #: 503-lockout.php:382
128
- #: 503.php:376
129
- #: lib/wf503.php:354
130
- #: lib/wfLockedOut.php:363
131
- msgid "About Wordfence"
132
  msgstr ""
133
 
134
- #: 403-roadblock.php:441
135
- #: 403.php:356
136
- #: 503-lockout.php:383
137
- #: 503.php:377
138
- #: lib/wf503.php:355
139
- #: lib/wfLockedOut.php:364
140
- msgid "Wordfence is a security plugin installed on over 3 million WordPress sites. The owner of this site is using Wordfence to manage access to their site."
 
 
141
  msgstr ""
142
 
143
- #: 403-roadblock.php:442
144
- #: 403.php:357
145
- #: 503-lockout.php:384
146
- #: 503.php:378
147
- #: lib/wf503.php:356
148
- #: lib/wfLockedOut.php:365
149
- msgid "You can also read the documentation to learn about Wordfence's blocking tools, or visit wordfence.com to learn more about Wordfence."
 
 
150
  msgstr ""
151
 
152
- #: 403-roadblock.php:446
153
- #: 403.php:361
154
- #: 503-lockout.php:388
155
- #: 503.php:382
156
- msgid "Click here to learn more: <a href=\"https://www.wordfence.com/help/?query=locked-out\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation</a>"
 
 
 
 
 
 
157
  msgstr ""
158
 
159
- #: 503-lockout.php:8
160
- #: 503.php:8
161
- #: 503.php:325
162
- #: lib/wf503.php:321
163
- msgid "Your access to this site has been limited by the site owner"
 
164
  msgstr ""
165
 
166
- #: 503-lockout.php:325
167
- #: lib/wfLockedOut.php:326
168
- msgid "Your access to this site has been temporarily limited by the site owner"
169
  msgstr ""
170
 
171
- #: 503-lockout.php:326
172
- #: lib/wfLockedOut.php:327
173
- msgid "Your access to this service has been temporarily limited. Please try again in a few minutes. (HTTP response code 503)"
174
  msgstr ""
175
 
176
- #: 503-lockout.php:335
177
- #: lib/wfLockedOut.php:335
178
- msgid "Return to the site home page"
 
179
  msgstr ""
180
 
181
- #: 503-lockout.php:342
182
- #: 503.php:336
183
- msgid "If you are a WordPress user with administrative privileges on this site, please enter your email address in the box below and click \"Send\". You will then receive an email that helps you regain access."
 
184
  msgstr ""
185
 
186
- #: 503-lockout.php:346
187
- #: lib/wfUnlockMsg.php:6
188
- msgid "Send Unlock Email"
 
 
 
 
189
  msgstr ""
190
 
191
- #: 503-lockout.php:363
192
- #: lib/wfLockedOut.php:344
193
- msgid "You have been temporarily locked out of this system. This means that you will not be able to log in for a while."
194
  msgstr ""
195
 
196
- #: 503.php:326
197
- #: lib/wf503.php:322
198
- msgid "Your access to this service has been limited. (HTTP response code 503)"
199
  msgstr ""
200
 
201
- #. Plugin Name of the plugin
202
- msgid "Wordfence Security"
203
  msgstr ""
204
 
205
- #. Plugin URI of the plugin
206
- #. Author URI of the plugin
207
- msgid "http://www.wordfence.com/"
208
  msgstr ""
209
 
210
- #. Description of the plugin
211
- msgid "Wordfence Security - Anti-virus, Firewall and Malware Scan"
 
 
 
 
212
  msgstr ""
213
 
214
- #. Author of the plugin
215
- msgid "Wordfence"
 
 
 
216
  msgstr ""
217
 
218
- #: lib/dashboard/widget_countries.php:16
219
- #: lib/dashboard/widget_ips.php:21
220
- #: lib/dashboard/widget_localattacks.php:15
221
- msgid "No Data Available During Learning Mode"
222
  msgstr ""
223
 
224
  #: lib/dashboard/widget_localattacks.php:8
225
  msgid "Firewall Summary:"
226
  msgstr ""
227
 
228
- #: lib/dashboard/widget_localattacks.php:8
 
229
  msgid "Attacks Blocked for %s"
230
  msgstr ""
231
 
232
- #: lib/dashboard/widget_localattacks.php:30
233
- msgid "No blocks have been recorded."
234
- msgstr ""
235
-
236
- #: lib/dashboard/widget_localattacks.php:35
237
  #: views/blocking/blocking-create.php:10
238
  msgid "<span class=\"wf-hidden-xs\">Block </span>Type"
239
  msgstr ""
240
 
241
- #: lib/dashboard/widget_localattacks.php:42
242
  msgid "Total"
243
  msgstr ""
244
 
245
- #: lib/dashboard/widget_localattacks.php:47
246
  msgid "Today"
247
  msgstr ""
248
 
249
- #: lib/dashboard/widget_localattacks.php:47
250
  msgid "Week"
251
  msgstr ""
252
 
253
- #: lib/dashboard/widget_localattacks.php:47
254
  msgid "Month"
255
  msgstr ""
256
 
257
- #: lib/dashboard/widget_localattacks.php:62
258
  #: lib/menu_firewall_waf.php:52
259
  #: lib/menu_firewall_waf_options.php:158
260
  #: lib/menu_scanner.php:77
@@ -262,33 +180,56 @@ msgstr ""
262
  msgid "Premium"
263
  msgstr ""
264
 
265
- #: lib/dashboard/widget_localattacks.php:68
266
  msgid "How are these categorized?"
267
  msgstr ""
268
 
269
- #: lib/dashboard/widget_networkattacks.php:8
270
- msgid "Total Attacks Blocked:"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  msgstr ""
272
 
273
  #: lib/dashboard/widget_networkattacks.php:8
274
- #: lib/wfDiagnostic.php:779
275
- msgid "Wordfence Network"
276
  msgstr ""
277
 
278
  #: lib/dashboard/widget_networkattacks.php:17
279
  msgid "Blocked attack counts not available yet."
280
  msgstr ""
281
 
282
- #: lib/dashboard/widget_networkattacks.php:22
283
- msgid "24 Hours"
284
  msgstr ""
285
 
286
- #: lib/dashboard/widget_networkattacks.php:24
287
- msgid "30 Days"
 
288
  msgstr ""
289
 
290
- #: lib/dashboard/widget_networkattacks.php:206
291
- msgid "Last Updated: %s ago"
 
 
 
 
 
292
  msgstr ""
293
 
294
  #: lib/dashboard/widget_notifications.php:37
@@ -296,62 +237,73 @@ msgstr ""
296
  msgid "Wordfence Central Status"
297
  msgstr ""
298
 
299
- #: lib/dashboard/widget_notifications.php:40
300
- msgid "Connected by %s on %s"
 
301
  msgstr ""
302
 
303
- #: lib/dashboard/widget_notifications.php:42
304
- msgid "Disconnected by %s on %s"
 
305
  msgstr ""
306
 
307
- #: lib/dashboard/widget_notifications.php:44
308
- #: lib/menu_wordfence_central.php:105
309
  msgid "It looks like you've tried to connect this site to Wordfence Central, but the installation did not finish."
310
  msgstr ""
311
 
312
- #: lib/dashboard/widget_notifications.php:46
313
  #: lib/menu_wordfence_central.php:58
314
- #: lib/menu_wordfence_central.php:115
315
  msgid "Wordfence Central allows you to manage Wordfence on multiple sites from one location. It makes security monitoring and configuring Wordfence easier."
316
  msgstr ""
317
 
318
- #: lib/dashboard/widget_notifications.php:54
319
- #: lib/menu_wordfence_central.php:109
320
  #: views/onboarding/banner.php:9
321
  #: views/onboarding/disabled-overlay.php:8
322
  msgid "Resume Installation"
323
  msgstr ""
324
 
325
- #: lib/dashboard/widget_notifications.php:55
326
- #: lib/dashboard/widget_notifications.php:60
327
- #: lib/menu_wordfence_central.php:66
328
  msgid "Disconnect This Site"
329
  msgstr ""
330
 
331
- #: lib/dashboard/widget_notifications.php:65
 
 
 
 
 
 
 
 
332
  #: lib/menu_wordfence_central.php:59
333
  msgid "Visit Wordfence Central"
334
  msgstr ""
335
 
336
- #: lib/dashboard/widget_notifications.php:128
337
  msgid "Confirm Disconnect"
338
  msgstr ""
339
 
340
- #: lib/dashboard/widget_notifications.php:129
341
  msgid "Are you sure you want to disconnect your site from Wordfence Central?"
342
  msgstr ""
343
 
344
- #: lib/dashboard/widget_notifications.php:130
345
- #: lib/menu_scanner.php:215
346
- #: lib/menu_scanner.php:226
347
- #: lib/menu_tools_diagnostic.php:955
 
348
  #: lib/menu_tools_twoFactor.php:235
349
  #: lib/menu_tools_twoFactor.php:273
350
- #: lib/wordfenceClass.php:7596
351
- #: lib/wordfenceClass.php:7640
352
- #: lib/wordfenceClass.php:7704
353
- #: lib/wordfenceClass.php:7764
354
- #: lib/wordfenceClass.php:7810
355
  #: views/blocking/block-list.php:501
356
  #: views/blocking/blocking-create.php:212
357
  #: views/dashboard/options-group-license.php:150
@@ -360,19 +312,78 @@ msgstr ""
360
  msgid "Cancel"
361
  msgstr ""
362
 
363
- #: lib/dashboard/widget_notifications.php:131
364
  msgid "Disconnect"
365
  msgstr ""
366
 
367
- #: lib/email_genericAlert.php:2
368
- msgid "This email was sent from your website \"%s\" by the Wordfence plugin at %s"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
369
  msgstr ""
370
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  #: lib/email_genericAlert.php:4
 
 
 
 
 
372
  msgid "The Wordfence administrative URL for this site is: %s"
373
  msgstr ""
374
 
375
- #: lib/email_genericAlert.php:10
376
  msgid ""
377
  "NOTE: You are using the free version of Wordfence. Upgrade today:\n"
378
  " - Receive real-time Firewall and Scan engine rule updates for protection as threats emerge\n"
@@ -387,85 +398,87 @@ msgid ""
387
  "https://www.wordfence.com/zz1/wordfence-signup/"
388
  msgstr ""
389
 
390
- #: lib/email_genericAlert.php:24
 
391
  msgid ""
392
  "To change your alert options for Wordfence, visit:\n"
393
  "%s"
394
  msgstr ""
395
 
396
- #: lib/email_genericAlert.php:26
 
397
  msgid ""
398
  "To see current Wordfence alerts, visit:\n"
399
  "%s"
400
  msgstr ""
401
 
402
- #: lib/email_newIssues.php:3
403
- msgid "This email was sent from your website \"%s\" by the Wordfence plugin."
404
- msgstr ""
405
-
406
- #: lib/email_newIssues.php:5
407
- msgid "Wordfence found the following new issues on \"%s\"%s."
408
- msgstr ""
409
-
410
  #: lib/email_newIssues.php:5
411
- msgid " (%d existing %s also found again)"
412
  msgstr ""
413
 
414
- #: lib/email_newIssues.php:5
415
- msgid "issue was"
416
- msgstr ""
 
 
 
417
 
418
- #: lib/email_newIssues.php:5
419
- msgid "issues were"
 
420
  msgstr ""
421
 
422
- #: lib/email_newIssues.php:7
 
423
  msgid "Alert generated at %s"
424
  msgstr ""
425
 
426
- #: lib/email_newIssues.php:11
 
427
  msgid "See the details of these scan results on your site at: %s"
428
  msgstr ""
429
 
430
- #: lib/email_newIssues.php:15
431
  msgid "HIGH SENSITIVITY scanning is enabled, it may produce false positives"
432
  msgstr ""
433
 
434
- #: lib/email_newIssues.php:21
435
  #: lib/menu_scanner.php:119
436
  msgid "Beta scan signatures are currently enabled. These signatures have not been fully tested yet and may cause false positives or scan stability issues on some sites."
437
  msgstr ""
438
 
439
- #: lib/email_newIssues.php:21
440
  msgid "The Beta option can be turned off at the bottom of the Diagnostics page."
441
  msgstr ""
442
 
443
- #: lib/email_newIssues.php:27
444
- msgid "The scan was terminated early because it reached the time limit for scans. If you would like to allow your scans to run longer, you can customize the limit on the options page: <a href=\"%s\">%s</a> or read more about scan options to improve scan speed here: <a href=\"%s\">%s</a>"
 
445
  msgstr ""
446
 
447
- #: lib/email_newIssues.php:33
448
  msgid "Critical Problems:"
449
  msgstr ""
450
 
451
- #: lib/email_newIssues.php:34
452
  msgid "High Severity Problems:"
453
  msgstr ""
454
 
455
- #: lib/email_newIssues.php:35
456
  msgid "Medium Severity Problems:"
457
  msgstr ""
458
 
459
- #: lib/email_newIssues.php:36
460
  msgid "Low Severity Problems:"
461
  msgstr ""
462
 
463
- #: lib/email_newIssues.php:55
464
  msgid "Plugin contains an unpatched security vulnerability."
465
  msgstr ""
466
 
467
- #: lib/email_newIssues.php:57
468
- #: lib/email_newIssues.php:79
469
  #: views/scanner/issue-wfPluginAbandoned.php:20
470
  #: views/scanner/issue-wfPluginAbandoned.php:37
471
  #: views/scanner/issue-wfPluginRemoved.php:18
@@ -481,31 +494,32 @@ msgstr ""
481
  msgid "Vulnerability Information"
482
  msgstr ""
483
 
484
- #: lib/email_newIssues.php:63
485
  msgid "The core files scan has not run because this version is not currently indexed by Wordfence. New WordPress versions may take up to a day to be indexed."
486
  msgstr ""
487
 
488
- #: lib/email_newIssues.php:66
489
  msgid "Firewall issues may be caused by file permission changes or other technical problems."
490
  msgstr ""
491
 
492
- #: lib/email_newIssues.php:66
493
  msgid "More Details and Instructions"
494
  msgstr ""
495
 
496
- #: lib/email_newIssues.php:69
497
  msgid "Scanning additional paths is optional and is not always necessary."
498
  msgstr ""
499
 
500
- #: lib/email_newIssues.php:69
501
- #: lib/email_unlockRequest.php:10
502
- #: lib/menu_dashboard.php:108
503
- #: lib/menu_dashboard.php:464
504
- #: lib/menu_dashboard_options.php:152
505
- #: lib/wfVersionCheckController.php:56
506
- #: lib/wfVersionCheckController.php:69
507
- #: lib/wfVersionCheckController.php:135
508
- #: lib/wfVersionCheckController.php:150
 
509
  #: views/blocking/blocking-status.php:27
510
  #: views/dashboard/options-group-dashboard.php:107
511
  #: views/gdpr/banner.php:55
@@ -521,7 +535,7 @@ msgstr ""
521
  msgid "Learn More"
522
  msgstr ""
523
 
524
- #: lib/email_newIssues.php:77
525
  #: views/scanner/issue-wfPluginUpgrade.php:16
526
  #: views/scanner/issue-wfPluginUpgrade.php:33
527
  #: views/scanner/issue-wfThemeUpgrade.php:16
@@ -531,116 +545,179 @@ msgstr ""
531
  msgid "Update includes security-related fixes."
532
  msgstr ""
533
 
534
- #: lib/email_newIssues.php:104
535
- msgid "%d existing issue was found again and is not shown."
536
  msgstr ""
537
 
538
- #: lib/email_newIssues.php:104
539
- msgid "%d existing issues were found again and are not shown."
540
- msgstr ""
 
 
 
541
 
542
- #: lib/email_newIssues.php:107
 
543
  msgid "%d issue was omitted from this email due to length limits."
544
- msgstr ""
545
-
546
- #: lib/email_newIssues.php:107
547
- msgid "%d issues were omitted from this email due to length limits."
548
- msgstr ""
549
 
550
- #: lib/email_newIssues.php:108
 
551
  msgid "View every issue:"
552
  msgstr ""
553
 
554
- #: lib/email_newIssues.php:117
555
  msgid "NOTE: You are using the free version of Wordfence. Upgrade today:"
556
  msgstr ""
557
 
558
- #: lib/email_newIssues.php:120
559
  msgid "Receive real-time Firewall and Scan engine rule updates for protection as threats emerge"
560
  msgstr ""
561
 
562
- #: lib/email_newIssues.php:121
563
  msgid "Real-time IP Blocklist blocks the most malicious IPs from accessing your site"
564
  msgstr ""
565
 
566
- #: lib/email_newIssues.php:122
567
  msgid "Country blocking"
568
  msgstr ""
569
 
570
- #: lib/email_newIssues.php:123
571
  msgid "IP reputation monitoring"
572
  msgstr ""
573
 
574
- #: lib/email_newIssues.php:124
575
  msgid "Schedule scans to run more frequently and at optimal times"
576
  msgstr ""
577
 
578
- #: lib/email_newIssues.php:125
579
  msgid "Access to Premium Support"
580
  msgstr ""
581
 
582
- #: lib/email_newIssues.php:126
583
  msgid "Discounts for multi-year and multi-license purchases"
584
  msgstr ""
585
 
586
- #: lib/email_newIssues.php:129
587
  msgid "Click here to upgrade to Wordfence Premium:"
588
  msgstr ""
589
 
590
- #: lib/email_unlockRequest.php:2
591
- msgid "Either you or someone else at IP address <b>%s</b> requested instructions to regain access to the website <a href=\"%s\"><b>%s</b></a>."
 
592
  msgstr ""
593
 
594
- #: lib/email_unlockRequest.php:4
595
- #: lib/email_unsubscribeRequest.php:4
 
596
  msgid "Request was generated at: %s"
597
  msgstr ""
598
 
599
- #: lib/email_unlockRequest.php:6
600
  msgid "If you did not request these instructions then you can safely ignore them."
601
  msgstr ""
602
 
603
- #: lib/email_unlockRequest.php:7
604
  msgid "These instructions <b>will be valid for 30 minutes</b> from the time they were sent."
605
  msgstr ""
606
 
607
- #: lib/email_unlockRequest.php:10
608
  msgid "Click here to unlock your ability to sign-in and to access to the site."
609
  msgstr ""
610
 
611
- #: lib/email_unlockRequest.php:10
612
  msgid "Do this if you simply need to regain access because you were accidentally locked out. If you received an \"Insecure Password\" message before getting locked out, you may also need to reset your password."
613
  msgstr ""
614
 
615
- #: lib/email_unlockRequest.php:13
616
  msgid "Click here to unblock all IP addresses."
617
  msgstr ""
618
 
619
- #: lib/email_unlockRequest.php:13
620
  msgid "Do this if you still can't regain access using the link above. It causes everyone who is blocked or locked out to be able to access your site again."
621
  msgstr ""
622
 
623
- #: lib/email_unlockRequest.php:16
624
  msgid "Click here to unlock all IP addresses and disable the Wordfence Firewall and Wordfence login security for all users"
625
  msgstr ""
626
 
627
- #: lib/email_unlockRequest.php:16
628
  msgid "Do this if you keep getting locked out or blocked and can't access your site. You can re-enable login security and the firewall once you sign-in to the site by visiting the Wordfence Firewall menu, clicking and then turning on the firewall and login security options. If you use country blocking, you will also need to choose which countries to block."
629
  msgstr ""
630
 
631
- #: lib/email_unsubscribeRequest.php:2
632
- msgid "Either you or someone at IP address <b>%s</b> requested an alert unsubscribe link for the website <a href=\"%s\"><b>%s</b></a>."
 
633
  msgstr ""
634
 
635
- #: lib/email_unsubscribeRequest.php:6
636
  msgid "If you did not request this, you can safely ignore it."
637
  msgstr ""
638
 
639
- #: lib/email_unsubscribeRequest.php:8
 
640
  msgid "<a href=\"%s\" target=\"_blank\">Click here</a> to stop receiving security alerts."
641
  msgstr ""
642
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
643
  #: lib/menu_dashboard.php:24
 
644
  msgid "Wordfence Dashboard"
645
  msgstr ""
646
 
@@ -652,6 +729,7 @@ msgstr ""
652
  #: lib/menu_dashboard_options.php:98
653
  #: lib/menu_firewall.php:20
654
  #: lib/menu_firewall.php:30
 
655
  #: models/page/wfPage.php:105
656
  msgid "Firewall"
657
  msgstr ""
@@ -687,7 +765,8 @@ msgstr ""
687
  #: lib/menu_dashboard.php:71
688
  #: lib/menu_dashboard_options.php:115
689
  #: lib/menu_scanner.php:31
690
- #: lib/menu_scanner.php:303
 
691
  #: models/page/wfPage.php:113
692
  msgid "Scan"
693
  msgstr ""
@@ -728,9 +807,11 @@ msgid "Reset License"
728
  msgstr ""
729
 
730
  #: lib/menu_dashboard.php:97
731
- #: lib/menu_dashboard.php:106
 
732
  #: lib/menu_dashboard_options.php:141
733
- #: lib/menu_dashboard_options.php:150
 
734
  #: views/scanner/scanner-status.php:53
735
  #: views/waf/firewall-status.php:66
736
  msgid "Premium Protection Disabled"
@@ -742,26 +823,32 @@ msgid "License is expired"
742
  msgstr ""
743
 
744
  #: lib/menu_dashboard.php:100
745
- #: lib/menu_dashboard.php:117
746
  #: lib/menu_dashboard_options.php:144
747
- #: lib/menu_dashboard_options.php:161
748
  msgid "Renew License"
749
  msgstr ""
750
 
751
- #: lib/menu_dashboard.php:107
752
- #: lib/menu_dashboard_options.php:151
 
 
 
 
 
753
  #: views/waf/firewall-status.php:67
754
- msgid "As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by an additional %d firewall rules and malware signatures. Upgrade to Premium today to improve your protection."
755
  msgstr ""
756
 
757
- #: lib/menu_dashboard.php:108
758
- #: lib/menu_dashboard_options.php:152
759
  #: lib/menu_firewall_waf.php:55
760
  #: lib/menu_firewall_waf.php:72
761
  #: lib/menu_scanner.php:80
762
  #: lib/menu_support.php:43
763
  #: lib/menu_tools_twoFactor.php:51
764
  #: views/blocking/blocking-create.php:179
 
765
  #: views/blocking/blocking-status.php:27
766
  #: views/blocking/options-group-advanced-country.php:85
767
  #: views/dashboard/options-group-dashboard.php:107
@@ -776,239 +863,230 @@ msgstr ""
776
  msgid "Upgrade to Premium"
777
  msgstr ""
778
 
779
- #: lib/menu_dashboard.php:114
780
- #: lib/menu_dashboard.php:171
781
- #: lib/menu_dashboard_options.php:158
782
- #: lib/menu_dashboard_options.php:215
783
  msgid "Premium License Expiring"
784
  msgstr ""
785
 
786
- #: lib/menu_dashboard.php:115
787
- #: lib/menu_dashboard_options.php:159
788
  msgid "Auto-renew is disabled"
789
  msgstr ""
790
 
791
- #: lib/menu_dashboard.php:124
792
- #: lib/menu_dashboard_options.php:168
793
  msgid "Payment Method Expiring"
794
  msgstr ""
795
 
796
- #: lib/menu_dashboard.php:127
797
- #: lib/menu_dashboard_options.php:171
798
  msgid "Payment Method Expired"
799
  msgstr ""
800
 
801
- #: lib/menu_dashboard.php:130
802
- #: lib/menu_dashboard_options.php:174
803
  msgid "Payment Method Missing"
804
  msgstr ""
805
 
806
- #: lib/menu_dashboard.php:133
807
- #: lib/menu_dashboard_options.php:177
808
  msgid "Payment Method Invalid"
809
  msgstr ""
810
 
811
- #: lib/menu_dashboard.php:139
812
- #: lib/menu_dashboard.php:160
813
- #: lib/menu_dashboard_options.php:183
814
- #: lib/menu_dashboard_options.php:204
815
- msgid "today"
816
- msgstr ""
817
-
818
- #: lib/menu_dashboard.php:142
819
- #: lib/menu_dashboard_options.php:186
820
- msgid "tomorrow"
821
  msgstr ""
822
 
823
- #: lib/menu_dashboard.php:145
824
- #: lib/menu_dashboard.php:166
825
- #: lib/menu_dashboard_options.php:189
826
- #: lib/menu_dashboard_options.php:210
827
- msgid "in %d days"
828
  msgstr ""
829
 
830
- #: lib/menu_dashboard.php:151
831
- #: lib/menu_dashboard.php:172
832
- #: lib/menu_dashboard_options.php:195
833
- #: lib/menu_dashboard_options.php:216
834
- msgid "License renews %s"
835
  msgstr ""
836
 
837
- #: lib/menu_dashboard.php:153
838
- #: lib/menu_dashboard_options.php:197
839
  msgid "Update Payment Method"
840
  msgstr ""
841
 
842
- #: lib/menu_dashboard.php:163
843
- #: lib/menu_dashboard_options.php:207
844
- msgid "in 1 day"
845
  msgstr ""
846
 
847
- #: lib/menu_dashboard.php:174
848
- #: lib/menu_dashboard_options.php:218
849
  msgid "Review Payment Method"
850
  msgstr ""
851
 
852
- #: lib/menu_dashboard.php:182
853
- #: lib/menu_dashboard_options.php:226
854
  msgid "Wordfence Premium Enabled"
855
  msgstr ""
856
 
857
- #: lib/menu_dashboard.php:208
 
858
  msgid "Tools"
859
  msgstr ""
860
 
861
- #: lib/menu_dashboard.php:209
862
  msgid "Live Traffic, Whois Lookup, Import/Export, and Diagnostics"
863
  msgstr ""
864
 
865
- #: lib/menu_dashboard.php:219
866
  #: lib/menu_firewall_waf.php:157
867
  #: lib/menu_scanner.php:139
868
  #: lib/menu_support.php:19
 
869
  msgid "Help"
870
  msgstr ""
871
 
872
- #: lib/menu_dashboard.php:220
873
  #: lib/menu_firewall_waf.php:158
874
  #: lib/menu_scanner.php:140
875
  msgid "Find the documentation and help you need"
876
  msgstr ""
877
 
878
- #: lib/menu_dashboard.php:230
879
  #: models/page/wfPage.php:103
880
  msgid "Global Options"
881
  msgstr ""
882
 
883
- #: lib/menu_dashboard.php:231
884
  msgid "Manage global options for Wordfence such as alerts, premium status, and more"
885
  msgstr ""
886
 
887
- #: lib/menu_dashboard.php:282
888
  msgid "This is your Dashboard"
889
  msgstr ""
890
 
891
- #: lib/menu_dashboard.php:283
892
  msgid "The Wordfence Dashboard provides valuable insights into the current state of your site's security. You'll find useful data summarized here as well as important status updates and notifications."
893
  msgstr ""
894
 
895
- #: lib/menu_dashboard.php:290
896
- #: lib/menu_dashboard.php:306
897
- #: lib/menu_dashboard.php:367
898
- #: lib/menu_dashboard.php:384
899
- #: lib/menu_dashboard.php:402
900
- #: lib/menu_firewall_blocking.php:125
901
- #: lib/menu_firewall_blocking.php:141
902
- #: lib/menu_firewall_blocking.php:209
903
  #: lib/menu_firewall_waf.php:255
904
  #: lib/menu_firewall_waf.php:272
905
  #: lib/menu_firewall_waf.php:289
906
- #: lib/menu_scanner.php:311
907
- #: lib/menu_scanner.php:328
908
- #: lib/menu_scanner.php:380
909
  #: views/tours/login-security.php:37
910
  #: views/tours/login-security.php:53
911
  msgid "Next"
912
  msgstr ""
913
 
914
- #: lib/menu_dashboard.php:297
915
  msgid "Easily Monitor Your Wordfence Protection"
916
  msgstr ""
917
 
918
- #: lib/menu_dashboard.php:298
919
  msgid "Each feature contains a status that reminds you what's enabled, disabled or needs attention. The Notifications section will highlight actions you need to take."
920
  msgstr ""
921
 
922
- #: lib/menu_dashboard.php:305
923
- #: lib/menu_dashboard.php:322
924
- #: lib/menu_dashboard.php:383
925
- #: lib/menu_dashboard.php:401
926
- #: lib/menu_dashboard.php:418
927
- #: lib/menu_firewall_blocking.php:140
928
- #: lib/menu_firewall_blocking.php:156
929
- #: lib/menu_firewall_blocking.php:223
930
  #: lib/menu_firewall_waf.php:271
931
  #: lib/menu_firewall_waf.php:288
932
  #: lib/menu_firewall_waf.php:306
933
- #: lib/menu_scanner.php:327
934
- #: lib/menu_scanner.php:343
935
- #: lib/menu_scanner.php:394
936
  #: views/tours/login-security.php:52
937
  #: views/tours/login-security.php:69
938
  msgid "Previous"
939
  msgstr ""
940
 
941
- #: lib/menu_dashboard.php:313
942
- #: lib/menu_dashboard.php:391
943
  msgid "Global Wordfence Options"
944
  msgstr ""
945
 
946
- #: lib/menu_dashboard.php:315
947
  msgid "You'll find this icon throughout the plugin. Clicking it will show you the options and features for each section of Wordfence. From the dashboard, you can find the <strong>Global Options</strong> for Wordfence such as alerts, automatic updates, and managing your site's Premium License."
948
  msgstr ""
949
 
950
- #: lib/menu_dashboard.php:323
951
- #: lib/menu_dashboard.php:419
952
- #: lib/menu_firewall_blocking.php:157
953
- #: lib/menu_firewall_blocking.php:224
954
  #: lib/menu_firewall_waf.php:307
955
  #: lib/menu_firewall_waf.php:354
956
- #: lib/menu_scanner.php:344
957
- #: lib/menu_scanner.php:395
958
- #: lib/menu_tools_livetraffic.php:552
959
- #: lib/menu_tools_livetraffic.php:583
960
  msgid "Got it"
961
  msgstr ""
962
 
963
- #: lib/menu_dashboard.php:357
 
964
  msgid "You have successfully updated to Wordfence %s"
965
  msgstr ""
966
 
967
- #: lib/menu_dashboard.php:358
968
  msgid "This update includes a number of significant interface changes. We'd like to walk you through some of them, but you can bypass the tour for a section at any time by closing the dialogs."
969
  msgstr ""
970
 
971
- #: lib/menu_dashboard.php:359
972
  msgid "We welcome your feedback and comments at <a href=\"mailto:feedback@wordfence.com\">feedback@wordfence.com</a>. For a deeper dive on all of the changes, <a href=\"https://www.wordfence.com/blog/2018/01/introducing-wordfence-7/\" target=\"_blank\" rel=\"noopener noreferrer\">click here</a>."
973
  msgstr ""
974
 
975
- #: lib/menu_dashboard.php:374
976
  msgid "Monitor Your Wordfence Protection"
977
  msgstr ""
978
 
979
- #: lib/menu_dashboard.php:375
980
  msgid "Each feature contains a status percentage reminding you at a high level of what's enabled, disabled, or needing your attention. The Notifications section highlights actions you need to take."
981
  msgstr ""
982
 
983
- #: lib/menu_dashboard.php:393
984
  msgid "Manage your Wordfence license, see alerts and automatic plugin updates, and import/export your settings."
985
  msgstr ""
986
 
987
- #: lib/menu_dashboard.php:409
988
  msgid "Updated Navigation"
989
  msgstr ""
990
 
991
- #: lib/menu_dashboard.php:410
992
  msgid "The main navigation no longer includes an <strong>Options</strong> link. Options are now accessed via the <strong>Options</strong> link on each feature's main page. Live Traffic is now located in the Tools section, and blocking is found under the Firewall. Shortcuts to add a <strong>Blocking</strong> link back to the main navigation are available under Blocking options."
993
  msgstr ""
994
 
995
- #: lib/menu_dashboard.php:459
996
  msgid "Recommended Settings Change"
997
  msgstr ""
998
 
999
- #: lib/menu_dashboard.php:460
1000
  msgid "Greetings! The default configuration for Wordfence Live Traffic has changed. The new default saves only logins and blocked requests, while this site is currently recording all traffic. Would you like to change to the new default?"
1001
  msgstr ""
1002
 
1003
- #: lib/menu_dashboard.php:460
1004
  msgid "Rate limiting based on type of request (human vs crawler) may be less accurate because this prevents loading the extra JavaScript used for that identification."
1005
  msgstr ""
1006
 
1007
- #: lib/menu_dashboard.php:461
1008
  msgid "Yes Please"
1009
  msgstr ""
1010
 
1011
- #: lib/menu_dashboard.php:463
1012
  #: views/onboarding/fresh-install.php:45
1013
  #: views/onboarding/modal-final-attempt.php:43
1014
  #: views/onboarding/plugin-header.php:67
@@ -1017,7 +1095,7 @@ msgstr ""
1017
 
1018
  #: lib/menu_dashboard_options.php:11
1019
  #: lib/menu_dashboard_options.php:79
1020
- #: lib/menu_options.php:271
1021
  msgid "Wordfence Global Options"
1022
  msgstr ""
1023
 
@@ -1033,11 +1111,34 @@ msgstr ""
1033
  msgid "Learn more<span class=\"wf-hidden-xs\"> about Global Options</span>"
1034
  msgstr ""
1035
 
1036
- #: lib/menu_dashboard_options.php:268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1037
  #: lib/menu_dashboard_options.php:278
1038
- #: lib/menu_options.php:404
1039
- #: lib/menu_options.php:414
1040
- #: lib/menu_tools.php:26
1041
  #: lib/menu_tools_importExport.php:7
1042
  #: lib/menu_tools_importExport.php:13
1043
  #: models/page/wfPage.php:121
@@ -1045,7 +1146,7 @@ msgstr ""
1045
  msgid "Import/Export Options"
1046
  msgstr ""
1047
 
1048
- #: lib/menu_dashboard_options.php:276
1049
  msgid "Importing and exporting of options has moved to the Tools page"
1050
  msgstr ""
1051
 
@@ -1057,8 +1158,9 @@ msgstr ""
1057
 
1058
  #: lib/menu_firewall.php:21
1059
  #: lib/menu_firewall.php:41
1060
- #: lib/menu_firewall_blocking.php:117
1061
  #: lib/menu_firewall_waf.php:142
 
1062
  #: models/page/wfPage.php:109
1063
  msgid "Blocking"
1064
  msgstr ""
@@ -1069,7 +1171,7 @@ msgid "Learn more<span class=\"wf-hidden-xs\"> about the Firewall</span>"
1069
  msgstr ""
1070
 
1071
  #: lib/menu_firewall.php:44
1072
- #: lib/menu_firewall_blocking_options.php:92
1073
  msgid "Learn more<span class=\"wf-hidden-xs\"> about Blocking</span>"
1074
  msgstr ""
1075
 
@@ -1082,75 +1184,77 @@ msgstr ""
1082
  msgid "Turn On"
1083
  msgstr ""
1084
 
1085
- #: lib/menu_firewall_blocking.php:31
 
1086
  msgid "<strong>Note:</strong> The GeoIP database that is required for country blocking has been updated to a new format. This new format requires sites to run PHP 5.4 or newer, and this site is on PHP %s. To ensure country blocking continues functioning, please update PHP."
1087
  msgstr ""
1088
 
1089
- #: lib/menu_firewall_blocking.php:32
1090
  msgid "More Information"
1091
  msgstr ""
1092
 
1093
- #: lib/menu_firewall_blocking.php:38
1094
  msgid "Create a Blocking Rule"
1095
  msgstr ""
1096
 
1097
- #: lib/menu_firewall_blocking.php:38
1098
  msgid "Edit Blocking Rule"
1099
  msgstr ""
1100
 
1101
- #: lib/menu_firewall_blocking.php:118
1102
  msgid "Wordfence lets you take control of protecting your site with powerful blocking features. Block traffic based on IP, IP range, hostname, browser, or referrer. Country blocking is available for Premium customers."
1103
  msgstr ""
1104
 
1105
- #: lib/menu_firewall_blocking.php:132
1106
- #: lib/menu_firewall_blocking.php:202
1107
  msgid "Blocking Builder"
1108
  msgstr ""
1109
 
1110
- #: lib/menu_firewall_blocking.php:133
1111
  msgid "All of your blocking rules are in one central location. Choose the Block Type, then enter the details for the rule. Once it has been added, you'll see it saved as a rule for your site."
1112
  msgstr ""
1113
 
1114
- #: lib/menu_firewall_blocking.php:148
1115
- #: lib/menu_firewall_blocking.php:216
1116
  msgid "Manage Blocking Rules"
1117
  msgstr ""
1118
 
1119
- #: lib/menu_firewall_blocking.php:149
1120
  msgid "Here's where you'll see all the blocking rules you've created. You can also manage them as well as remove or modify them from this table."
1121
  msgstr ""
1122
 
1123
- #: lib/menu_firewall_blocking.php:203
1124
  msgid "All of the blocking rules you create are now in one central location. Simply choose the block type and enter the details for the rule you want to create. Premium users have access to advanced country blocking options, found via the <strong>Options</strong> link."
1125
  msgstr ""
1126
 
1127
- #: lib/menu_firewall_blocking.php:217
1128
  msgid "All blocking rules you create will show here. You can manage them as well as remove or modify them from the same location."
1129
  msgstr ""
1130
 
1131
  #: lib/menu_firewall_blocking_options.php:12
1132
- #: lib/menu_firewall_blocking_options.php:90
1133
- #: lib/menu_options.php:339
1134
  #: models/page/wfPage.php:111
1135
  #: views/blocking/blocking-status.php:14
1136
  msgid "Blocking Options"
1137
  msgstr ""
1138
 
1139
- #: lib/menu_firewall_blocking_options.php:49
 
1140
  #: lib/menu_firewall_waf_options.php:78
1141
  #: lib/menu_scanner_options.php:66
1142
  msgid "<span class=\"wf-hidden-xs\">Back to </span>%s"
1143
  msgstr ""
1144
 
1145
- #: lib/menu_firewall_blocking_options.php:51
1146
  msgid "Are you sure you want to restore the default Blocking settings? This will undo any custom changes you have made to the options on this page. Any existing blocks will be preserved."
1147
  msgstr ""
1148
 
1149
- #: lib/menu_firewall_blocking_options.php:102
1150
  msgid "General"
1151
  msgstr ""
1152
 
1153
- #: lib/menu_firewall_blocking_options.php:116
1154
  msgid "Display Blocking menu option"
1155
  msgstr ""
1156
 
@@ -1244,6 +1348,7 @@ msgstr ""
1244
  #: lib/menu_tools_diagnostic.php:300
1245
  #: lib/menu_tools_diagnostic.php:301
1246
  #: lib/menu_tools_diagnostic.php:304
 
1247
  #: models/firewall/wfFirewall.php:41
1248
  #: views/diagnostics/text.php:154
1249
  #: views/diagnostics/text.php:159
@@ -1345,7 +1450,7 @@ msgstr ""
1345
  #: lib/menu_firewall_waf.php:347
1346
  #: lib/menu_firewall_waf_options.php:23
1347
  #: lib/menu_firewall_waf_options.php:122
1348
- #: lib/menu_options.php:302
1349
  #: models/page/wfPage.php:107
1350
  msgid "Firewall Options"
1351
  msgstr ""
@@ -1363,7 +1468,8 @@ msgid "Are you sure you want to restore the default Firewall settings? This will
1363
  msgstr ""
1364
 
1365
  #: lib/menu_options.php:24
1366
- #: lib/menu_options.php:261
 
1367
  msgid "All Options"
1368
  msgstr ""
1369
 
@@ -1502,7 +1608,7 @@ msgstr ""
1502
 
1503
  #: lib/menu_options.php:96
1504
  #: views/dashboard/options-group-alert.php:140
1505
- msgid "Only alert me when that administrator signs in from a new device or location"
1506
  msgstr ""
1507
 
1508
  #: lib/menu_options.php:97
@@ -1512,7 +1618,7 @@ msgstr ""
1512
 
1513
  #: lib/menu_options.php:98
1514
  #: views/dashboard/options-group-alert.php:157
1515
- msgid "Only alert me when that user signs in from a new device or location"
1516
  msgstr ""
1517
 
1518
  #: lib/menu_options.php:99
@@ -1638,329 +1744,339 @@ msgstr ""
1638
 
1639
  #: lib/menu_options.php:125
1640
  #: views/waf/options-group-brute-force.php:226
1641
- msgid "Block IPs who send POST requests with blank User-Agent and Referer"
1642
  msgstr ""
1643
 
1644
  #: lib/menu_options.php:126
1645
- #: views/waf/options-group-brute-force.php:236
1646
- msgid "Custom text shown on block pages"
1647
  msgstr ""
1648
 
1649
  #: lib/menu_options.php:127
1650
- #: views/waf/options-group-brute-force.php:251
1651
- msgid "Check password strength on profile update"
1652
  msgstr ""
1653
 
1654
  #: lib/menu_options.php:128
1655
  #: views/waf/options-group-brute-force.php:263
1656
- msgid "Participate in the Real-Time Wordfence Security Network"
1657
  msgstr ""
1658
 
1659
  #: lib/menu_options.php:129
 
 
 
 
 
1660
  #: views/waf/options-group-rate-limiting.php:38
1661
  msgid "Enable Rate Limiting and Advanced Blocking"
1662
  msgstr ""
1663
 
1664
- #: lib/menu_options.php:130
1665
  #: views/waf/options-group-rate-limiting.php:60
1666
  msgid "How should we treat Google's crawlers"
1667
  msgstr ""
1668
 
1669
- #: lib/menu_options.php:131
1670
  #: views/waf/options-group-rate-limiting.php:100
1671
  msgid "If anyone's requests exceed"
1672
  msgstr ""
1673
 
1674
- #: lib/menu_options.php:132
1675
  #: views/waf/options-group-rate-limiting.php:117
1676
  msgid "If a crawler's page views exceed"
1677
  msgstr ""
1678
 
1679
- #: lib/menu_options.php:133
1680
  #: views/waf/options-group-rate-limiting.php:134
1681
  msgid "If a crawler's pages not found (404s) exceed"
1682
  msgstr ""
1683
 
1684
- #: lib/menu_options.php:134
1685
  #: views/waf/options-group-rate-limiting.php:151
1686
  msgid "If a human's page views exceed"
1687
  msgstr ""
1688
 
1689
- #: lib/menu_options.php:135
1690
  #: views/waf/options-group-rate-limiting.php:168
1691
  msgid "If a human's pages not found (404s) exceed"
1692
  msgstr ""
1693
 
1694
- #: lib/menu_options.php:136
1695
  #: views/waf/options-group-rate-limiting.php:184
1696
  msgid "How long is an IP address blocked when it breaks a rule"
1697
  msgstr ""
1698
 
1699
- #: lib/menu_options.php:137
1700
  #: views/waf/options-group-rate-limiting.php:194
1701
  msgid "Allowlisted 404 URLs"
1702
  msgstr ""
1703
 
1704
- #: lib/menu_options.php:138
1705
  msgid "Web Application Firewall Allowlisted URLs"
1706
  msgstr ""
1707
 
1708
- #: lib/menu_options.php:139
1709
  msgid "Monitor background requests from an administrator's web browser for false positives (Front-end Website)"
1710
  msgstr ""
1711
 
1712
- #: lib/menu_options.php:140
1713
  msgid "Monitor background requests from an administrator's web browser for false positives (Admin Panel)"
1714
  msgstr ""
1715
 
1716
- #: lib/menu_options.php:141
1717
  msgid "What to do when we block someone visiting from a blocked country"
1718
  msgstr ""
1719
 
1720
- #: lib/menu_options.php:142
1721
  msgid "URL to redirect blocked countries to"
1722
  msgstr ""
1723
 
1724
- #: lib/menu_options.php:143
1725
  #: views/blocking/options-group-advanced-country.php:62
1726
  msgid "Block countries even if they are logged in"
1727
  msgstr ""
1728
 
1729
- #: lib/menu_options.php:144
1730
  msgid "If user from a blocked country hits the relative URL ____ then redirect that user to ____ and set a cookie that will bypass all country blocking"
1731
  msgstr ""
1732
 
1733
- #: lib/menu_options.php:145
1734
  msgid "If user who is allowed to access the site views the relative URL ____ then set a cookie that will bypass country blocking in future in case that user hits the site from a blocked country"
1735
  msgstr ""
1736
 
1737
- #: lib/menu_options.php:146
1738
  #: views/scanner/scan-scheduling.php:12
1739
  msgid "Schedule Wordfence Scans"
1740
  msgstr ""
1741
 
1742
- #: lib/menu_options.php:147
1743
  msgid "Scan Type"
1744
  msgstr ""
1745
 
1746
- #: lib/menu_options.php:148
1747
  #: views/scanner/options-group-general.php:32
1748
  msgid "Check if this website is on a domain blocklist"
1749
  msgstr ""
1750
 
1751
- #: lib/menu_options.php:149
1752
  msgid "Check if this website is being &quot;Spamvertised&quot;"
1753
  msgstr ""
1754
 
1755
- #: lib/menu_options.php:150
1756
  #: views/scanner/options-group-general.php:34
1757
  msgid "Check if this website IP is generating spam"
1758
  msgstr ""
1759
 
1760
- #: lib/menu_options.php:151
1761
  #: views/scanner/options-group-general.php:35
1762
  msgid "Scan for misconfigured How does Wordfence get IPs"
1763
  msgstr ""
1764
 
1765
- #: lib/menu_options.php:152
1766
  #: views/scanner/options-group-general.php:36
1767
  msgid "Scan for publicly accessible configuration, backup, or log files"
1768
  msgstr ""
1769
 
1770
- #: lib/menu_options.php:153
1771
  #: views/scanner/options-group-general.php:37
1772
  msgid "Scan for publicly accessible quarantined files"
1773
  msgstr ""
1774
 
1775
- #: lib/menu_options.php:154
1776
  #: views/scanner/options-group-general.php:38
1777
  msgid "Scan core files against repository versions for changes"
1778
  msgstr ""
1779
 
1780
- #: lib/menu_options.php:155
1781
  #: views/scanner/options-group-general.php:39
1782
  msgid "Scan theme files against repository versions for changes"
1783
  msgstr ""
1784
 
1785
- #: lib/menu_options.php:156
1786
  #: views/scanner/options-group-general.php:40
1787
  msgid "Scan plugin files against repository versions for changes"
1788
  msgstr ""
1789
 
1790
- #: lib/menu_options.php:157
1791
  #: views/scanner/options-group-general.php:41
1792
  msgid "Scan wp-admin and wp-includes for files not bundled with WordPress"
1793
  msgstr ""
1794
 
1795
- #: lib/menu_options.php:158
1796
  #: views/scanner/options-group-general.php:42
1797
  msgid "Scan for signatures of known malicious files"
1798
  msgstr ""
1799
 
1800
- #: lib/menu_options.php:159
1801
  #: views/scanner/options-group-general.php:43
1802
  msgid "Scan file contents for backdoors, trojans and suspicious code"
1803
  msgstr ""
1804
 
1805
- #: lib/menu_options.php:160
1806
  #: views/scanner/options-group-general.php:44
1807
  msgid "Scan file contents for malicious URLs"
1808
  msgstr ""
1809
 
1810
- #: lib/menu_options.php:161
1811
  #: views/scanner/options-group-general.php:45
1812
  msgid "Scan posts for known dangerous URLs and suspicious content"
1813
  msgstr ""
1814
 
1815
- #: lib/menu_options.php:162
1816
  #: views/scanner/options-group-general.php:46
1817
  msgid "Scan comments for known dangerous URLs and suspicious content"
1818
  msgstr ""
1819
 
1820
- #: lib/menu_options.php:163
1821
  #: views/scanner/options-group-general.php:47
1822
  msgid "Scan WordPress core, plugin, and theme options for known dangerous URLs and suspicious content"
1823
  msgstr ""
1824
 
1825
- #: lib/menu_options.php:164
1826
  #: views/scanner/options-group-general.php:48
1827
  msgid "Scan for out of date, abandoned, and vulnerable plugins, themes, and WordPress versions"
1828
  msgstr ""
1829
 
1830
- #: lib/menu_options.php:165
1831
  #: views/scanner/options-group-general.php:49
1832
  msgid "Scan for suspicious admin users created outside of WordPress"
1833
  msgstr ""
1834
 
1835
- #: lib/menu_options.php:166
1836
  #: views/scanner/options-group-general.php:50
1837
  msgid "Check the strength of passwords"
1838
  msgstr ""
1839
 
1840
- #: lib/menu_options.php:167
1841
  #: views/scanner/options-group-general.php:51
1842
  msgid "Monitor disk space"
1843
  msgstr ""
1844
 
1845
- #: lib/menu_options.php:168
1846
  #: views/scanner/options-group-general.php:52
1847
  msgid "Monitor Web Application Firewall status"
1848
  msgstr ""
1849
 
1850
- #: lib/menu_options.php:169
1851
  #: views/scanner/options-group-general.php:53
1852
  msgid "Scan files outside your WordPress installation"
1853
  msgstr ""
1854
 
1855
- #: lib/menu_options.php:170
1856
  #: views/scanner/options-group-general.php:54
1857
  msgid "Scan images, binary, and other files as if they were executable"
1858
  msgstr ""
1859
 
1860
- #: lib/menu_options.php:171
1861
  #: views/scanner/options-group-performance.php:32
1862
  msgid "Use low resource scanning (reduces server load by lengthening the scan duration)"
1863
  msgstr ""
1864
 
1865
- #: lib/menu_options.php:172
1866
  #: views/scanner/options-group-performance.php:33
1867
  msgid "Limit the number of issues sent in the scan results email"
1868
  msgstr ""
1869
 
1870
- #: lib/menu_options.php:173
1871
  #: views/scanner/options-group-performance.php:34
1872
  msgid "Time limit that a scan can run in seconds"
1873
  msgstr ""
1874
 
1875
- #: lib/menu_options.php:174
 
1876
  #: views/scanner/options-group-performance.php:35
1877
  msgid "How much memory should Wordfence request when scanning"
1878
  msgstr ""
1879
 
1880
- #: lib/menu_options.php:175
1881
  msgid "Maximum execution time for each scan stage"
1882
  msgstr ""
1883
 
1884
- #: lib/menu_options.php:176
1885
  msgid "Exclude files from scan that match these wildcard patterns"
1886
  msgstr ""
1887
 
1888
- #: lib/menu_options.php:177
1889
  msgid "Additional scan signatures"
1890
  msgstr ""
1891
 
1892
- #: lib/menu_options.php:178
1893
  msgid "Traffic logging mode (Live Traffic)"
1894
  msgstr ""
1895
 
1896
- #: lib/menu_options.php:179
1897
  #: views/tools/options-group-live-traffic.php:78
1898
  msgid "Don't log signed-in users with publishing access"
1899
  msgstr ""
1900
 
1901
- #: lib/menu_options.php:180
1902
  #: views/tools/options-group-live-traffic.php:87
1903
  msgid "List of comma separated usernames to ignore"
1904
  msgstr ""
1905
 
1906
- #: lib/menu_options.php:181
1907
  #: views/tools/options-group-live-traffic.php:96
1908
  msgid "List of comma separated IP addresses to ignore"
1909
  msgstr ""
1910
 
1911
- #: lib/menu_options.php:182
1912
  #: views/tools/options-group-live-traffic.php:105
1913
  msgid "Browser user-agent to ignore"
1914
  msgstr ""
1915
 
1916
- #: lib/menu_options.php:183
1917
  #: views/tools/options-group-live-traffic.php:114
1918
  msgid "Amount of Live Traffic data to store (number of rows)"
1919
  msgstr ""
1920
 
1921
- #: lib/menu_options.php:184
1922
  msgid "Maximum days to keep Live Traffic data"
1923
  msgstr ""
1924
 
1925
- #: lib/menu_options.php:185
1926
  #: views/dashboard/options-group-import.php:31
1927
  msgid "Export this site's Wordfence options for import on another site"
1928
  msgstr ""
1929
 
1930
- #: lib/menu_options.php:186
1931
  #: views/dashboard/options-group-import.php:44
1932
  msgid "Import Wordfence options from another site using a token"
1933
  msgstr ""
1934
 
1935
- #: lib/menu_options.php:190
1936
  msgid "Require Cellphone Sign-in for all Administrators"
1937
  msgstr ""
1938
 
1939
- #: lib/menu_options.php:191
1940
  msgid "Enable Separate Prompt for Two Factor Code"
1941
  msgstr ""
1942
 
1943
- #: lib/menu_options.php:200
1944
  msgid "Are you sure you want to restore the default settings? This will undo any custom changes you have made to the options on this page. If you have manually disabled any rules or added any custom allowlisted URLs, those changes will not be overwritten."
1945
  msgstr ""
1946
 
1947
- #: lib/menu_options.php:267
1948
  msgid "These options are also available throughout the plugin pages, in the relevant sections. This page is provided for easier setup for experienced Wordfence users."
1949
  msgstr ""
1950
 
1951
- #: lib/menu_options.php:350
1952
  #: models/page/wfPage.php:115
1953
  msgid "Scan Options"
1954
  msgstr ""
1955
 
1956
- #: lib/menu_options.php:382
1957
  msgid "Tool Options"
1958
  msgstr ""
1959
 
1960
- #: lib/menu_options.php:412
1961
  msgid "Importing and exporting of options is available on the Tools page"
1962
  msgstr ""
1963
 
 
 
 
 
1964
  #: lib/menu_scanner.php:34
1965
  msgid "Learn more<span class=\"wf-hidden-xs\"> about the Scanner</span>"
1966
  msgstr ""
@@ -1992,6 +2108,7 @@ msgid "Signature updates delayed by 30 days"
1992
  msgstr ""
1993
 
1994
  #: lib/menu_scanner.php:80
 
1995
  msgid "Protect More Sites"
1996
  msgstr ""
1997
 
@@ -2046,44 +2163,48 @@ msgstr ""
2046
  msgid "<strong>WARNING:</strong> If you delete the wrong file, it could cause your WordPress website to stop functioning, and you will probably have to restore from a backup."
2047
  msgstr ""
2048
 
2049
- #: lib/menu_scanner.php:214
 
2050
  msgid "Do not delete files on your system unless you're ABSOLUTELY sure you know what you're doing. If you delete the wrong file it could cause your WordPress website to stop functioning and you will probably have to restore from backups. If you're unsure, Cancel and work with your hosting provider to clean your system of infected files. If you'd like to learn more, <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">click here for our help article</a>."
2051
  msgstr ""
2052
 
2053
- #: lib/menu_scanner.php:216
2054
  msgid "Delete Files"
2055
  msgstr ""
2056
 
2057
- #: lib/menu_scanner.php:224
2058
  msgid "Are you sure you want to repair?"
2059
  msgstr ""
2060
 
2061
- #: lib/menu_scanner.php:225
2062
  msgid "Do not repair files on your system unless you're ABSOLUTELY sure you know what you're doing. If you repair the wrong file it could cause your WordPress website to stop functioning and you will probably have to restore from backups. If you're unsure, Cancel and work with your hosting provider to clean your system of infected files."
2063
  msgstr ""
2064
 
2065
- #: lib/menu_scanner.php:227
2066
  msgid "Repair Files"
2067
  msgstr ""
2068
 
2069
- #: lib/menu_scanner.php:237
 
 
2070
  #: lib/menu_tools_twoFactor.php:246
2071
  #: lib/menu_tools_twoFactor.php:255
2072
  #: lib/menu_tools_twoFactor.php:264
2073
  #: lib/menu_tools_twoFactor.php:284
2074
- #: lib/wordfenceClass.php:4846
2075
- #: lib/wordfenceClass.php:4852
2076
- #: lib/wordfenceClass.php:4858
2077
- #: lib/wordfenceClass.php:4865
2078
- #: lib/wordfenceClass.php:4871
2079
- #: lib/wordfenceClass.php:4878
2080
- #: lib/wordfenceClass.php:4886
2081
- #: lib/wordfenceClass.php:5919
2082
- #: lib/wordfenceClass.php:5921
2083
- #: lib/wordfenceClass.php:7621
2084
- #: lib/wordfenceClass.php:7628
2085
- #: lib/wordfenceClass.php:7735
2086
- #: lib/wordfenceClass.php:7799
 
2087
  #: views/dashboard/options-group-import.php:147
2088
  #: views/dashboard/options-group-import.php:157
2089
  #: views/dashboard/options-group-import.php:177
@@ -2098,39 +2219,39 @@ msgstr ""
2098
  msgid "Close"
2099
  msgstr ""
2100
 
2101
- #: lib/menu_scanner.php:304
2102
  msgid "A Wordfence scan looks for malware, malicious URLs, and patterns of infections by examining all of the files, posts, and comments on your WordPress website. It also checks your server and monitors your site's online reputation."
2103
  msgstr ""
2104
 
2105
- #: lib/menu_scanner.php:318
2106
  msgid "Manage Scan Settings"
2107
  msgstr ""
2108
 
2109
- #: lib/menu_scanner.php:320
2110
  msgid "Set up the way you want the scan to monitor your site security including custom scan configurations and scheduling."
2111
  msgstr ""
2112
 
2113
- #: lib/menu_scanner.php:335
2114
  msgid "Start Your First Scan"
2115
  msgstr ""
2116
 
2117
- #: lib/menu_scanner.php:336
2118
  msgid "By default, Wordfence will scan your site daily. Start your first scan now to see if your site has any security issues that need to be addressed. From here you can run manual scans any time you like."
2119
  msgstr ""
2120
 
2121
- #: lib/menu_scanner.php:372
2122
  msgid "Scan Options &amp; Settings"
2123
  msgstr ""
2124
 
2125
- #: lib/menu_scanner.php:374
2126
  msgid "All of your scan options, including scheduling, are now located here."
2127
  msgstr ""
2128
 
2129
- #: lib/menu_scanner.php:387
2130
  msgid "Scan Progress and Activity"
2131
  msgstr ""
2132
 
2133
- #: lib/menu_scanner.php:388
2134
  msgid "Track each scan stage as Wordfence scans your entire site. Along the way you can see the activity log one line at a time or expand the activity log for a more detailed view. Clicking on scan results will reveal detailed scan findings."
2135
  msgstr ""
2136
 
@@ -2142,7 +2263,8 @@ msgstr ""
2142
  msgid "File System Credentials Required"
2143
  msgstr ""
2144
 
2145
- #: lib/menu_scanner_credentials.php:66
 
2146
  msgid "Security token has expired. Click <a href=\"%s\">here</a> to return to the scan page."
2147
  msgstr ""
2148
 
@@ -2203,85 +2325,61 @@ msgstr ""
2203
  msgid "Data Processing Agreement"
2204
  msgstr ""
2205
 
2206
- #: lib/menu_support.php:81
 
2207
  msgid "If you qualify as a data controller under the GDPR and need a data processing agreement, it can be <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">found here</a>."
2208
  msgstr ""
2209
 
2210
- #: lib/menu_support.php:90
2211
  msgid "Agreement to New Terms and Privacy Policies"
2212
  msgstr ""
2213
 
2214
- #: lib/menu_support.php:91
2215
  msgid "To continue using Defiant products and services including the Wordfence plugin, all customers must review and agree to the updated terms and privacy policies. These changes reflect our commitment to follow data protection best practices and regulations. The Wordfence interface will remain disabled until these terms are agreed to."
2216
  msgstr ""
2217
 
2218
- #: lib/menu_support.php:104
2219
  msgid "All Documentation"
2220
  msgstr ""
2221
 
2222
- #: lib/menu_support.php:112
2223
  msgid "Top Topics and Questions"
2224
  msgstr ""
2225
 
2226
- #: lib/menu_support.php:160
2227
  msgid "Documentation"
2228
  msgstr ""
2229
 
2230
- #: lib/menu_support.php:161
2231
  msgid "Documentation about Wordfence may be found on our website by clicking the button below or by clicking the <i class=\"wf-fa wf-fa-question-circle-o\" aria-hidden=\"true\"></i> links on any of the plugin's pages."
2232
  msgstr ""
2233
 
2234
- #: lib/menu_support.php:162
2235
  msgid "View Documentation"
2236
  msgstr ""
2237
 
2238
- #: lib/menu_support.php:267
2239
  #: views/onboarding/fresh-install.php:131
2240
  #: views/onboarding/plugin-header.php:167
2241
  msgid "Premium License Installed"
2242
  msgstr ""
2243
 
2244
- #: lib/menu_support.php:267
2245
  #: views/onboarding/fresh-install.php:131
2246
  #: views/onboarding/plugin-header.php:167
2247
  msgid "Congratulations! Wordfence Premium is now active on your website. Please note that some Premium features are not enabled by default."
2248
  msgstr ""
2249
 
2250
- #: lib/menu_support.php:267
2251
  #: views/onboarding/fresh-install.php:30
2252
  #: views/onboarding/modal-final-attempt.php:59
2253
  #: views/onboarding/plugin-header.php:61
2254
- #: views/waf/waf-install.php:105
2255
  #: views/waf/waf-modal-wrapper.php:17
2256
- #: views/waf/waf-uninstall.php:106
2257
  msgid "Continue"
2258
  msgstr ""
2259
 
2260
- #: lib/menu_tools.php:22
2261
- #: lib/menu_tools_twoFactor.php:14
2262
- #: lib/menu_tools_twoFactor.php:23
2263
- #: models/page/wfPage.php:117
2264
- msgid "Two-Factor Authentication"
2265
- msgstr ""
2266
-
2267
- #: lib/menu_tools.php:24
2268
- #: lib/menu_tools_livetraffic.php:8
2269
- #: lib/menu_tools_livetraffic.php:41
2270
- #: lib/menu_tools_livetraffic.php:546
2271
- #: lib/menu_tools_livetraffic.php:577
2272
- #: models/page/wfPage.php:119
2273
- msgid "Live Traffic"
2274
- msgstr ""
2275
-
2276
- #: lib/menu_tools.php:25
2277
- #: lib/menu_tools_whois.php:7
2278
- #: lib/menu_tools_whois.php:16
2279
- #: lib/menu_tools_whois.php:71
2280
- #: models/page/wfPage.php:123
2281
- msgid "Whois Lookup"
2282
- msgstr ""
2283
-
2284
- #: lib/menu_tools.php:27
2285
  #: lib/menu_tools_diagnostic.php:24
2286
  #: models/page/wfPage.php:125
2287
  msgid "Diagnostics"
@@ -2342,6 +2440,10 @@ msgstr ""
2342
  msgid "Used"
2343
  msgstr ""
2344
 
 
 
 
 
2345
  #: lib/menu_tools_diagnostic.php:217
2346
  #: lib/menu_tools_diagnostic.php:268
2347
  #: lib/menu_tools_diagnostic.php:269
@@ -2403,6 +2505,7 @@ msgstr ""
2403
  msgid "Return value of is_multisite()"
2404
  msgstr ""
2405
 
 
2406
  #: lib/menu_tools_diagnostic.php:265
2407
  #: lib/menu_tools_diagnostic.php:276
2408
  #: lib/menu_tools_diagnostic.php:278
@@ -2420,6 +2523,7 @@ msgstr ""
2420
  #: lib/menu_tools_diagnostic.php:318
2421
  #: lib/menu_tools_diagnostic.php:319
2422
  #: lib/menu_tools_diagnostic.php:323
 
2423
  #: lib/wfDiagnostic.php:357
2424
  #: lib/wfDiagnostic.php:375
2425
  #: views/diagnostics/text.php:124
@@ -2442,7 +2546,7 @@ msgstr ""
2442
  #: views/onboarding/fresh-install.php:18
2443
  #: views/onboarding/modal-final-attempt.php:25
2444
  #: views/onboarding/plugin-header.php:39
2445
- #: views/reports/activity-report-email-inline.php:262
2446
  #: views/reports/activity-report.php:117
2447
  msgid "Yes"
2448
  msgstr ""
@@ -2460,6 +2564,7 @@ msgstr ""
2460
  #: lib/menu_tools_diagnostic.php:318
2461
  #: lib/menu_tools_diagnostic.php:319
2462
  #: lib/menu_tools_diagnostic.php:323
 
2463
  #: lib/wfDiagnostic.php:357
2464
  #: lib/wfDiagnostic.php:375
2465
  #: views/diagnostics/text.php:124
@@ -2478,7 +2583,7 @@ msgstr ""
2478
  #: views/onboarding/fresh-install.php:19
2479
  #: views/onboarding/modal-final-attempt.php:26
2480
  #: views/onboarding/plugin-header.php:40
2481
- #: views/reports/activity-report-email-inline.php:262
2482
  #: views/reports/activity-report.php:117
2483
  msgid "No"
2484
  msgstr ""
@@ -2562,6 +2667,9 @@ msgstr ""
2562
  msgid "\"wp-content\" folder is in default location"
2563
  msgstr ""
2564
 
 
 
 
2565
  #: lib/menu_tools_diagnostic.php:276
2566
  #: lib/menu_tools_diagnostic.php:278
2567
  #: lib/menu_tools_diagnostic.php:279
@@ -2571,6 +2679,7 @@ msgstr ""
2571
  msgid "No: %s"
2572
  msgstr ""
2573
 
 
2574
  #: lib/menu_tools_diagnostic.php:277
2575
  #: views/diagnostics/text.php:136
2576
  msgid "URL to the \"wp-content\" folder"
@@ -2581,11 +2690,13 @@ msgstr ""
2581
  msgid "\"plugins\" folder is in default location"
2582
  msgstr ""
2583
 
 
2584
  #: lib/menu_tools_diagnostic.php:279
2585
  #: views/diagnostics/text.php:138
2586
  msgid "\"languages\" folder is in default location"
2587
  msgstr ""
2588
 
 
2589
  #: lib/menu_tools_diagnostic.php:280
2590
  #: views/diagnostics/text.php:139
2591
  msgid "Language choice"
@@ -2601,6 +2712,8 @@ msgstr ""
2601
  msgid "Theme template folder override"
2602
  msgstr ""
2603
 
 
 
2604
  #: lib/menu_tools_diagnostic.php:282
2605
  #: lib/menu_tools_diagnostic.php:283
2606
  #: views/diagnostics/text.php:141
@@ -2608,11 +2721,13 @@ msgstr ""
2608
  msgid "Overridden: %s"
2609
  msgstr ""
2610
 
 
2611
  #: lib/menu_tools_diagnostic.php:283
2612
  #: views/diagnostics/text.php:142
2613
  msgid "Theme stylesheet folder override"
2614
  msgstr ""
2615
 
 
2616
  #: lib/menu_tools_diagnostic.php:284
2617
  #: views/diagnostics/text.php:143
2618
  msgid "Post editing automatic saving interval"
@@ -2635,7 +2750,7 @@ msgstr ""
2635
  #: lib/wfDiagnostic.php:411
2636
  #: views/diagnostics/text.php:144
2637
  #: views/diagnostics/text.php:171
2638
- #: views/scanner/issue-base.php:101
2639
  msgid "None"
2640
  msgstr ""
2641
 
@@ -2694,6 +2809,8 @@ msgstr ""
2694
  msgid "Custom \"users\" table"
2695
  msgstr ""
2696
 
 
 
2697
  #: lib/menu_tools_diagnostic.php:296
2698
  #: lib/menu_tools_diagnostic.php:297
2699
  #: views/diagnostics/text.php:155
@@ -2701,11 +2818,13 @@ msgstr ""
2701
  msgid "Set: %s"
2702
  msgstr ""
2703
 
 
2704
  #: lib/menu_tools_diagnostic.php:297
2705
  #: views/diagnostics/text.php:156
2706
  msgid "Custom \"usermeta\" table"
2707
  msgstr ""
2708
 
 
2709
  #: lib/menu_tools_diagnostic.php:298
2710
  #: views/diagnostics/text.php:157
2711
  msgid "Overridden permissions for a new folder"
@@ -2737,7 +2856,7 @@ msgid "Interval the trash is automatically emptied at in days"
2737
  msgstr ""
2738
 
2739
  #: lib/menu_tools_diagnostic.php:303
2740
- #: lib/wordfenceClass.php:4172
2741
  #: views/diagnostics/text.php:162
2742
  msgid "Never"
2743
  msgstr ""
@@ -2862,6 +2981,8 @@ msgstr ""
2862
  msgid "Status of installed plugins."
2863
  msgstr ""
2864
 
 
 
2865
  #: lib/menu_tools_diagnostic.php:382
2866
  #: lib/menu_tools_diagnostic.php:428
2867
  #: lib/menu_tools_diagnostic.php:527
@@ -2921,69 +3042,9 @@ msgstr ""
2921
  msgid "WordPress \"drop-in\" plugins that are active."
2922
  msgstr ""
2923
 
2924
- #: lib/menu_tools_diagnostic.php:464
2925
- #: views/diagnostics/text.php:302
2926
- msgid "Advanced caching plugin"
2927
- msgstr ""
2928
-
2929
- #: lib/menu_tools_diagnostic.php:465
2930
- #: views/diagnostics/text.php:303
2931
- msgid "Custom database class"
2932
- msgstr ""
2933
-
2934
- #: lib/menu_tools_diagnostic.php:466
2935
- #: views/diagnostics/text.php:304
2936
- msgid "Custom database error message"
2937
- msgstr ""
2938
-
2939
- #: lib/menu_tools_diagnostic.php:467
2940
- #: views/diagnostics/text.php:305
2941
- msgid "Custom installation script"
2942
- msgstr ""
2943
-
2944
- #: lib/menu_tools_diagnostic.php:468
2945
- #: views/diagnostics/text.php:306
2946
- msgid "Custom maintenance message"
2947
- msgstr ""
2948
-
2949
- #: lib/menu_tools_diagnostic.php:469
2950
- #: views/diagnostics/text.php:307
2951
- msgid "External object cache"
2952
- msgstr ""
2953
-
2954
- #: lib/menu_tools_diagnostic.php:470
2955
- #: views/diagnostics/text.php:308
2956
- msgid "Custom PHP error message"
2957
- msgstr ""
2958
-
2959
- #: lib/menu_tools_diagnostic.php:471
2960
- #: views/diagnostics/text.php:309
2961
- msgid "Custom PHP fatal error handler"
2962
- msgstr ""
2963
-
2964
- #: lib/menu_tools_diagnostic.php:473
2965
- #: views/diagnostics/text.php:311
2966
- msgid "Executed before Multisite is loaded"
2967
- msgstr ""
2968
-
2969
- #: lib/menu_tools_diagnostic.php:474
2970
- #: views/diagnostics/text.php:312
2971
- msgid "Custom site deleted message"
2972
- msgstr ""
2973
-
2974
- #: lib/menu_tools_diagnostic.php:475
2975
- #: views/diagnostics/text.php:313
2976
- msgid "Custom site inactive message"
2977
- msgstr ""
2978
-
2979
- #: lib/menu_tools_diagnostic.php:476
2980
- #: views/diagnostics/text.php:314
2981
- msgid "Custom site suspended message"
2982
- msgstr ""
2983
-
2984
  #: lib/menu_tools_diagnostic.php:501
2985
  #: views/diagnostics/text.php:332
2986
- #: views/reports/activity-report-email-inline.php:384
2987
  #: views/reports/activity-report.php:191
2988
  msgid "Themes"
2989
  msgstr ""
@@ -3032,271 +3093,536 @@ msgstr ""
3032
  msgid "Unable to verify - table count too high"
3033
  msgstr ""
3034
 
3035
- #: lib/menu_tools_diagnostic.php:636
3036
- #: views/diagnostics/text.php:441
3037
  msgid "All Tables Exist"
3038
  msgstr ""
3039
 
3040
- #: lib/menu_tools_diagnostic.php:638
3041
- #: views/diagnostics/text.php:443
3042
- msgid "Tables missing (prefix %s, %s): %s"
3043
  msgstr ""
3044
 
3045
- #: lib/menu_tools_diagnostic.php:638
3046
- #: views/diagnostics/text.php:443
 
 
3047
  msgid "lowercase"
3048
  msgstr ""
3049
 
3050
- #: lib/menu_tools_diagnostic.php:638
3051
- #: views/diagnostics/text.php:443
 
 
3052
  msgid "regular case"
3053
  msgstr ""
3054
 
3055
- #: lib/menu_tools_diagnostic.php:684
3056
- #: views/diagnostics/text.php:477
 
3057
  msgid "and %d more"
3058
  msgstr ""
3059
 
3060
- #: lib/menu_tools_diagnostic.php:703
3061
- #: views/diagnostics/text.php:488
3062
  msgid "Log Files"
3063
  msgstr ""
3064
 
3065
- #: lib/menu_tools_diagnostic.php:704
3066
- #: views/diagnostics/text.php:488
3067
  msgid "PHP error logs generated by your site, if enabled by your host."
3068
  msgstr ""
3069
 
3070
- #: lib/menu_tools_diagnostic.php:716
3071
- #: views/diagnostics/text.php:494
3072
- #: views/reports/activity-report-email-inline.php:333
3073
  #: views/scanner/issue-file.php:8
3074
  #: views/scanner/issue-knownfile.php:8
3075
  msgid "File"
3076
  msgstr ""
3077
 
3078
- #: lib/menu_tools_diagnostic.php:717
3079
- #: lib/menu_tools_diagnostic.php:756
 
3080
  msgid "Download"
3081
  msgstr ""
3082
 
3083
- #: lib/menu_tools_diagnostic.php:725
3084
- #: views/diagnostics/text.php:501
3085
  msgid "No log files found."
3086
  msgstr ""
3087
 
3088
- #: lib/menu_tools_diagnostic.php:745
3089
- #: views/diagnostics/text.php:520
3090
  msgid "UTC"
3091
  msgstr ""
3092
 
3093
- #: lib/menu_tools_diagnostic.php:756
3094
  msgid "Requires downloading from the server directly"
3095
  msgstr ""
3096
 
3097
- #: lib/menu_tools_diagnostic.php:770
3098
- #: views/diagnostics/text.php:541
3099
  msgid "Scan Issues"
3100
  msgstr ""
3101
 
3102
- #: lib/menu_tools_diagnostic.php:775
3103
- #: views/diagnostics/text.php:549
 
3104
  msgid "New Issues (%d total)"
3105
  msgstr ""
3106
 
3107
- #: lib/menu_tools_diagnostic.php:796
3108
- #: lib/wordfenceClass.php:3877
3109
- #: views/diagnostics/text.php:572
3110
  msgid "No New Issues"
3111
  msgstr ""
3112
 
3113
- #: lib/menu_tools_diagnostic.php:811
3114
  msgid "Other Tests"
3115
  msgstr ""
3116
 
3117
- #: lib/menu_tools_diagnostic.php:812
3118
  msgid "System configuration, memory test, send test email from this server."
3119
  msgstr ""
3120
 
3121
- #: lib/menu_tools_diagnostic.php:823
3122
  msgid "Click to view your system's configuration in a new window"
3123
  msgstr ""
3124
 
3125
- #: lib/menu_tools_diagnostic.php:829
3126
  msgid "Test your WordPress host's available memory"
3127
  msgstr ""
3128
 
3129
- #: lib/menu_tools_diagnostic.php:835
3130
  msgid "Send a test email from this WordPress server to an email address:"
3131
  msgstr ""
3132
 
3133
- #: lib/menu_tools_diagnostic.php:837
3134
  msgid "Send Test Email"
3135
  msgstr ""
3136
 
3137
- #: lib/menu_tools_diagnostic.php:842
3138
  msgid "Send a test activity report email:"
3139
  msgstr ""
3140
 
3141
- #: lib/menu_tools_diagnostic.php:844
3142
  msgid "Send Test Activity Report"
3143
  msgstr ""
3144
 
3145
- #: lib/menu_tools_diagnostic.php:849
3146
  msgid "Clear all Wordfence Central connection data"
3147
  msgstr ""
3148
 
3149
- #: lib/menu_tools_diagnostic.php:850
3150
  msgid "Clear Connection Data"
3151
  msgstr ""
3152
 
3153
- #: lib/menu_tools_diagnostic.php:862
3154
  msgid "Debugging Options"
3155
  msgstr ""
3156
 
3157
- #: lib/menu_tools_diagnostic.php:879
3158
  msgid "Enable debugging mode (increases database load)"
3159
  msgstr ""
3160
 
3161
- #: lib/menu_tools_diagnostic.php:891
3162
  msgid "Start all scans remotely (Try this if your scans aren't starting and your site is publicly accessible)"
3163
  msgstr ""
3164
 
3165
- #: lib/menu_tools_diagnostic.php:903
3166
  msgid "Enable SSL Verification (Disable this if you are consistently unable to connect to the Wordfence servers.)"
3167
  msgstr ""
3168
 
3169
- #: lib/menu_tools_diagnostic.php:915
3170
  msgid "Disable reading of php://input"
3171
  msgstr ""
3172
 
3173
- #: lib/menu_tools_diagnostic.php:927
3174
  msgid "Enable beta threat defense feed"
3175
  msgstr ""
3176
 
3177
- #: lib/menu_tools_diagnostic.php:934
 
3178
  msgid "Restore Defaults"
3179
  msgstr ""
3180
 
3181
- #: lib/menu_tools_diagnostic.php:935
 
3182
  msgid "Cancel Changes"
3183
  msgstr ""
3184
 
3185
- #: lib/menu_tools_diagnostic.php:936
 
3186
  msgid "Save Changes"
3187
  msgstr ""
3188
 
3189
- #: lib/menu_tools_diagnostic.php:953
3190
  #: views/options/block-all-options-controls.php:162
3191
  #: views/options/block-controls.php:77
3192
  msgid "Confirm Restore Defaults"
3193
  msgstr ""
3194
 
3195
- #: lib/menu_tools_diagnostic.php:954
3196
  msgid "Are you sure you want to restore the default Diagnostics settings? This will undo any custom changes you have made to the options on this page."
3197
  msgstr ""
3198
 
3199
- #: lib/menu_tools_diagnostic.php:956
3200
  #: views/options/block-all-options-controls.php:165
3201
  #: views/options/block-controls.php:80
3202
  msgid "Restore<span class=\"wf-hidden-xs\"> Defaults</span>"
3203
  msgstr ""
3204
 
3205
- #: lib/menu_tools_importExport.php:14
 
3206
  msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wf-help-link\">Learn more<span class=\"wf-hidden-xs\"> about importing and exporting options</span></a>"
3207
  msgstr ""
3208
 
3209
- #: lib/menu_tools_importExport.php:18
3210
  msgid "To clone one site's configuration to another, use the import/export tools below."
3211
  msgstr ""
3212
 
3213
- #: lib/menu_tools_livetraffic.php:42
 
 
 
 
 
 
 
 
 
 
3214
  msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wf-help-link\">Learn more<span class=\"wf-hidden-xs\"> about Live Traffic</span></a>"
3215
  msgstr ""
3216
 
3217
- #: lib/menu_tools_livetraffic.php:49
3218
  msgid "Live Updates Paused"
3219
  msgstr ""
3220
 
3221
- #: lib/menu_tools_livetraffic.php:50
3222
  msgid "Click inside window to resume"
3223
  msgstr ""
3224
 
3225
- #: lib/menu_tools_livetraffic.php:55
3226
  msgid "Wordfence Live Traffic shows you what is happening on your site in real-time, including user logins, hack attempts, and requests that were blocked by the Wordfence Firewall. You can choose to log security-related traffic only or all traffic. Traffic is logged directly on the server, which means it includes visits that don't execute JavaScript. Google and other JavaScript-based analytics packages typically only show visits from browsers that are operated by a human, while Live Traffic can show visits from crawlers like Google and Bing."
3227
  msgstr ""
3228
 
3229
- #: lib/menu_tools_livetraffic.php:71
3230
  msgid "Traffic logging mode: Security-related traffic only"
3231
  msgstr ""
3232
 
3233
- #: lib/menu_tools_livetraffic.php:73
3234
- #: lib/menu_tools_livetraffic.php:80
 
3235
  msgid " (host setting <a href=\"%s\" class=\"wfhelp\" target=\"_blank\" rel=\"noopener noreferrer\"></a>)"
3236
  msgstr ""
3237
 
3238
- #: lib/menu_tools_livetraffic.php:74
3239
  msgid "Login and firewall activity will appear below."
3240
  msgstr ""
3241
 
3242
- #: lib/menu_tools_livetraffic.php:78
3243
  msgid "Traffic logging mode: All traffic"
3244
  msgstr ""
3245
 
3246
- #: lib/menu_tools_livetraffic.php:81
3247
  msgid "Regular traffic and security-related traffic will appear below."
3248
  msgstr ""
3249
 
3250
- #: lib/menu_tools_livetraffic.php:94
 
 
 
3251
  msgid "Human"
3252
  msgstr ""
3253
 
3254
- #: lib/menu_tools_livetraffic.php:95
 
 
 
3255
  msgid "Bot"
3256
  msgstr ""
3257
 
3258
- #: lib/menu_tools_livetraffic.php:96
3259
  msgid "Warning"
3260
  msgstr ""
3261
 
3262
- #: lib/menu_tools_livetraffic.php:97
3263
  #: lib/wfDiagnostic.php:746
 
3264
  msgid "Blocked"
3265
  msgstr ""
3266
 
3267
- #: lib/menu_tools_livetraffic.php:111
3268
  msgid "Show Advanced Filters"
3269
  msgstr ""
3270
 
3271
- #: lib/menu_tools_livetraffic.php:118
3272
  msgid "Expand All Results"
3273
  msgstr ""
3274
 
3275
- #: lib/menu_tools_livetraffic.php:459
3276
- msgid "See recent traffic"
3277
  msgstr ""
3278
 
3279
- #: lib/menu_tools_livetraffic.php:459
3280
- msgid "Recent"
3281
  msgstr ""
3282
 
3283
- #: lib/menu_tools_livetraffic.php:547
3284
- msgid "Live traffic defaults to a summary view of all security-related traffic. Details are viewable by clicking anywhere within the summary record. To switch to the expanded view, click the <strong>Expand All Records</strong> switch."
 
3285
  msgstr ""
3286
 
3287
- #: lib/menu_tools_livetraffic.php:578
3288
- msgid "Live traffic now defaults to a summary view. Details are viewable by clicking anywhere within the summary record. To switch to the expanded view, click the <strong>Expand All Records</strong> switch. New installations will only log security-related traffic by default, though your previous setting has been preserved."
3289
  msgstr ""
3290
 
3291
- #: lib/menu_tools_twoFactor.php:16
3292
- msgid "Learn more<span class=\"wf-hidden-xs\"> about Two-Factor Authentication</span>"
3293
  msgstr ""
3294
 
3295
- #: lib/menu_tools_twoFactor.php:35
3296
- msgid "2FA Mode: Legacy"
3297
  msgstr ""
3298
 
3299
- #: lib/menu_tools_twoFactor.php:35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3300
  msgid "Two-factor authentication is using legacy support, which enables SMS-based codes but is less compatible. An improved interface and use by non-administrators is available by activating the new login security module."
3301
  msgstr ""
3302
 
@@ -3350,6 +3676,34 @@ msgstr ""
3350
  msgid "Two-Factor Authentication Users"
3351
  msgstr ""
3352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3353
  #: lib/menu_tools_twoFactor.php:186
3354
  msgid "Phone (%s)"
3355
  msgstr ""
@@ -3458,20 +3812,44 @@ msgstr ""
3458
  msgid "Your site is now using the legacy two-factor authentication system."
3459
  msgstr ""
3460
 
3461
- #: lib/menu_tools_whois.php:17
 
 
 
 
 
 
 
 
3462
  msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wf-help-link\">Learn more<span class=\"wf-hidden-xs\"> about Whois Lookup</span></a>"
3463
  msgstr ""
3464
 
3465
- #: lib/menu_tools_whois.php:21
3466
  msgid "The whois service gives you a way to look up who owns an IP address or domain name that is visiting your website or is engaging in malicious activity on your website."
3467
  msgstr ""
3468
 
3469
- #: lib/menu_tools_whois.php:34
3470
  msgid "How to block a network"
3471
  msgstr ""
3472
 
3473
- #: lib/menu_tools_whois.php:36
3474
- msgid "You've chosen to block the network that <span style=\"color: #F00;\">%s</span> is part of. We've marked the networks we found that this IP address belongs to in red below. Make sure you read all the WHOIS information so that you see all networks this IP belongs to. We recommend blocking the network with the lowest number of addresses. You may find this is listed at the end as part of the 'rWHOIS' query which contacts the local WHOIS server that is run by the network administrator."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3475
  msgstr ""
3476
 
3477
  #: lib/menu_wordfence_central.php:10
@@ -3500,26 +3878,28 @@ msgstr ""
3500
 
3501
  #: lib/menu_wordfence_central.php:44
3502
  #: lib/menu_wordfence_central.php:57
 
3503
  msgid "Wordfence Central"
3504
  msgstr ""
3505
 
3506
- #: lib/menu_wordfence_central.php:65
3507
- msgid "Activated - connected by %s on %s"
 
3508
  msgstr ""
3509
 
3510
- #: lib/menu_wordfence_central.php:75
3511
  msgid "Wordfence Central Installation Process"
3512
  msgstr ""
3513
 
3514
- #: lib/menu_wordfence_central.php:110
3515
  msgid "Disconnect Site"
3516
  msgstr ""
3517
 
3518
- #: lib/menu_wordfence_central.php:116
3519
  msgid "To connect your site your site to Wordfence Central, use the link below:"
3520
  msgstr ""
3521
 
3522
- #: lib/menu_wordfence_central.php:118
3523
  msgid "Connect Site"
3524
  msgstr ""
3525
 
@@ -3578,30 +3958,33 @@ msgstr ""
3578
  msgid "Specific config options to set."
3579
  msgstr ""
3580
 
3581
- #: lib/rest-api/wfRESTConfigController.php:213
3582
- #: lib/rest-api/wfRESTConfigController.php:250
3583
- #: lib/wordfenceClass.php:4433
 
3584
  msgid "An error occurred while saving the configuration: %s"
3585
  msgstr ""
3586
 
3587
- #: lib/rest-api/wfRESTConfigController.php:222
3588
- #: lib/rest-api/wfRESTConfigController.php:259
3589
- #: lib/wordfenceClass.php:4442
 
3590
  msgid "Errors occurred while saving the configuration: %s"
3591
  msgstr ""
3592
 
3593
- #: lib/rest-api/wfRESTConfigController.php:227
3594
- #: lib/rest-api/wfRESTConfigController.php:264
3595
- #: lib/wordfenceClass.php:4447
3596
  msgid "Errors occurred while saving the configuration."
3597
  msgstr ""
3598
 
3599
- #: lib/rest-api/wfRESTConfigController.php:241
3600
- #: lib/rest-api/wfRESTConfigController.php:276
 
3601
  msgid "A server error occurred while saving the configuration: %s"
3602
  msgstr ""
3603
 
3604
- #: lib/rest-api/wfRESTConfigController.php:281
3605
  msgid "Validation error: 'fields' parameter is empty or not an array."
3606
  msgstr ""
3607
 
@@ -3617,6 +4000,7 @@ msgstr ""
3617
  msgid "Number of scan results to return."
3618
  msgstr ""
3619
 
 
3620
  #: lib/rest-api/wfRESTScanController.php:84
3621
  msgid "Wordfence scan starting at %s from Wordfence Central"
3622
  msgstr ""
@@ -3629,63 +4013,158 @@ msgstr ""
3629
  msgid "SUM_KILLED:A request was received to stop the previous scan from Wordfence Central."
3630
  msgstr ""
3631
 
 
 
 
 
 
 
 
 
3632
  #: lib/wf503.php:5
3633
  msgid "Your access to this site has been limited"
3634
  msgstr ""
3635
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3636
  #: lib/wf503.php:334
3637
  msgid "Block Reason"
3638
  msgstr ""
3639
 
3640
- #: lib/wf503.php:338
3641
- #: views/reports/activity-report-email-inline.php:286
3642
- msgid "Time"
 
 
 
 
 
 
 
 
 
 
3643
  msgstr ""
3644
 
 
3645
  #: lib/wf503.php:360
3646
  #: lib/wfLockedOut.php:369
3647
  msgid "Click here to learn more: <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation</a>"
3648
  msgstr ""
3649
 
 
3650
  #: lib/wf503.php:361
3651
  #: lib/wfLockedOut.php:370
3652
  msgid "Generated by Wordfence at %s"
3653
  msgstr ""
3654
 
 
3655
  #: lib/wf503.php:361
3656
  #: lib/wfLockedOut.php:370
3657
  msgid "Your computer's time:"
3658
  msgstr ""
3659
 
3660
- #: lib/wfActivityReport.php:506
 
3661
  #: lib/wfIssues.php:487
3662
  msgid "No longer an administrator for this site? <a href=\"%s\" target=\"_blank\">Click here</a> to stop receiving security alerts."
3663
  msgstr ""
3664
 
3665
- #: lib/wfAdminNoticeQueue.php:175
3666
- msgid "<a class=\"wf-btn wf-btn-default wf-btn-sm wf-dismiss-link\" href=\"#\" onclick=\"wordfenceExt.dismissAdminNotice('%s'); return false;\">Dismiss</a>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3667
  msgstr ""
3668
 
 
3669
  #: lib/wfAlerts.php:29
3670
  msgid "Wordfence has blocked IP address %s."
3671
  msgstr ""
3672
 
 
3673
  #: lib/wfAlerts.php:30
3674
  msgid "The reason is: \"%s\"."
3675
  msgstr ""
3676
 
 
3677
  #: lib/wfAlerts.php:32
3678
  msgid "The duration of the block is %s."
3679
  msgstr ""
3680
 
 
3681
  #: lib/wfAlerts.php:34
3682
  msgid "Blocking IP %s"
3683
  msgstr ""
3684
 
 
3685
  #: lib/wfAlerts.php:53
3686
  msgid "Wordfence Upgraded to version %s"
3687
  msgstr ""
3688
 
 
3689
  #: lib/wfAlerts.php:53
3690
  msgid "Your Wordfence installation has been upgraded to version %s"
3691
  msgstr ""
@@ -3694,6 +4173,7 @@ msgstr ""
3694
  msgid "Wordfence WAF Deactivated"
3695
  msgstr ""
3696
 
 
3697
  #: lib/wfAlerts.php:75
3698
  msgid "A user with username \"%s\" deactivated the Wordfence Web Application Firewall on your WordPress site."
3699
  msgstr ""
@@ -3702,6 +4182,7 @@ msgstr ""
3702
  msgid "Wordfence Deactivated"
3703
  msgstr ""
3704
 
 
3705
  #: lib/wfAlerts.php:96
3706
  msgid "A user with username \"%s\" deactivated Wordfence on your WordPress site."
3707
  msgstr ""
@@ -3710,50 +4191,88 @@ msgstr ""
3710
  msgid "Password recovery attempted"
3711
  msgstr ""
3712
 
 
3713
  #: lib/wfAlerts.php:118
3714
  msgid "Someone tried to recover the password for user with email address: %s"
3715
  msgstr ""
3716
 
3717
- #: lib/wfAlerts.php:140
3718
- msgid "A user with IP addr %s has been locked out from signing in or using the password recovery form for the following reason: %s."
 
3719
  msgstr ""
3720
 
3721
- #: lib/wfAlerts.php:142
 
3722
  msgid "The duration of the lockout is %s."
3723
  msgstr ""
3724
 
3725
- #: lib/wfAlerts.php:144
3726
  msgid "User locked out from signing in"
3727
  msgstr ""
3728
 
3729
- #: lib/wfAlerts.php:177
3730
  msgid "Admin Login"
3731
  msgstr ""
3732
 
3733
- #: lib/wfAlerts.php:177
 
3734
  msgid "A user with username \"%s\" who has administrator access signed in to your WordPress site."
3735
  msgstr ""
3736
 
3737
- #: lib/wfAlerts.php:211
3738
  msgid "User login"
3739
  msgstr ""
3740
 
3741
- #: lib/wfAlerts.php:211
 
3742
  msgid "A non-admin user with username \"%s\" signed in to your WordPress site."
3743
  msgstr ""
3744
 
3745
- #: lib/wfAlerts.php:239
3746
  msgid "User login blocked for insecure password"
3747
  msgstr ""
3748
 
3749
- #: lib/wfAlerts.php:239
3750
- msgid "A user with username \"%s\" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%s) to reactivate this account. Learn More: %s"
 
3751
  msgstr ""
3752
 
3753
- #: lib/wfAlerts.php:256
3754
  msgid "Increased Attack Rate"
3755
  msgstr ""
3756
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3757
  #: lib/wfBulkCountries.php:5
3758
  msgid "Andorra"
3759
  msgstr ""
@@ -4754,36 +5273,75 @@ msgstr ""
4754
  msgid "Zimbabwe"
4755
  msgstr ""
4756
 
4757
- #: lib/wfCentralAPI.php:199
4758
- msgid "HTTP %d received from Wordfence Central: %s"
 
4759
  msgstr ""
4760
 
4761
- #: lib/wfCentralAPI.php:261
4762
- #: lib/wfCentralAPI.php:317
4763
  msgid "Unable to authenticate with Wordfence Central."
4764
  msgstr ""
4765
 
4766
- #: lib/wfCentralAPI.php:280
4767
  msgid "Wordfence Central site ID has not been created yet."
4768
  msgstr ""
4769
 
4770
- #: lib/wfCentralAPI.php:284
4771
  msgid "Wordfence Central secret key has not been created yet."
4772
  msgstr ""
4773
 
4774
- #: lib/wfCentralAPI.php:296
4775
  msgid "Invalid response received from Wordfence Central when fetching nonce."
4776
  msgstr ""
4777
 
4778
- #: lib/wfCentralAPI.php:314
4779
  msgid "Invalid response received from Wordfence Central when fetching token."
4780
  msgstr ""
4781
 
4782
- #: lib/wfConfig.php:951
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4783
  msgid "Wordfence Upgrade not run. Please modify your .htaccess"
4784
  msgstr ""
4785
 
4786
- #: lib/wfConfig.php:951
 
4787
  msgid ""
4788
  "To preserve the integrity of your website we are not running Wordfence auto-update.\n"
4789
  "You are running the LiteSpeed web server which has been known to cause a problem with Wordfence auto-update.\n"
@@ -4795,56 +5353,75 @@ msgid ""
4795
  ""
4796
  msgstr ""
4797
 
4798
- #: lib/wfConfig.php:1146
4799
- msgid "The grace period end time must be in the future."
4800
  msgstr ""
4801
 
4802
- #: lib/wfConfig.php:1155
4803
- msgid "Unknown firewall mode."
4804
  msgstr ""
4805
 
4806
  #: lib/wfConfig.php:1174
 
 
 
 
 
 
 
 
 
4807
  msgid "The following emails are invalid: "
4808
  msgstr ""
4809
 
4810
- #: lib/wfConfig.php:1185
 
4811
  msgid "\"%s\" is not a valid regular expression."
4812
  msgstr ""
4813
 
4814
- #: lib/wfConfig.php:1204
4815
  msgid "Please make sure you separate your IP addresses with commas. The following allowlisted IP addresses are invalid: "
4816
  msgstr ""
4817
 
4818
- #: lib/wfConfig.php:1223
4819
  msgid "The following users you selected to ignore in live traffic reports are not valid on this system: "
4820
  msgstr ""
4821
 
4822
- #: lib/wfConfig.php:1240
4823
  msgid "The following IPs you selected to ignore in live traffic reports are not valid: "
4824
  msgstr ""
4825
 
4826
- #: lib/wfConfig.php:1257
4827
  msgid "The following IPs/ranges you selected to trust as proxies are not valid: "
4828
  msgstr ""
4829
 
4830
- #: lib/wfConfig.php:1267
4831
  msgid "An empty license key was entered."
4832
  msgstr ""
4833
 
4834
- #: lib/wfConfig.php:1270
4835
- #: lib/wordfenceClass.php:4318
4836
  msgid "The license key entered is not in a valid format. It must contain only numbers and the letters A-F."
4837
  msgstr ""
4838
 
4839
- #: lib/wfConfig.php:1741
 
 
 
 
 
 
 
 
 
4840
  msgid "Your options have been saved, but you left your license key blank, so we tried to get you a free license key from the Wordfence servers. There was a problem fetching the free key: "
4841
  msgstr ""
4842
 
4843
- #: lib/wfConfig.php:1763
4844
  msgid "Your options have been saved. However we noticed you changed your license key, and we tried to verify it with the Wordfence servers but received an error: "
4845
  msgstr ""
4846
 
4847
- #: lib/wfConfig.php:1807
4848
  msgid "Your options have been saved. However we tried to verify your license key with the Wordfence servers and received an error: "
4849
  msgstr ""
4850
 
@@ -4984,10 +5561,12 @@ msgstr ""
4984
  msgid "PHP version, important PHP extensions."
4985
  msgstr ""
4986
 
 
4987
  #: lib/wfDiagnostic.php:110
4988
  msgid "PHP version >= PHP 5.6.20<br><em> (<a href=\"https://wordpress.org/about/requirements/\" target=\"_blank\" rel=\"noopener noreferrer\">Minimum version required by WordPress</a>)</em> <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wfhelp\"></a>"
4989
  msgstr ""
4990
 
 
4991
  #: lib/wfDiagnostic.php:111
4992
  msgid "Process Owner"
4993
  msgstr ""
@@ -5077,14 +5656,14 @@ msgstr ""
5077
  msgid "WordPress Time Zone"
5078
  msgstr ""
5079
 
 
5080
  #: lib/wfDiagnostic.php:197
5081
- msgid "1 Job Overdue"
5082
- msgstr ""
5083
-
5084
- #: lib/wfDiagnostic.php:197
5085
- msgid "%d Jobs Overdue"
5086
- msgstr ""
5087
 
 
5088
  #: lib/wfDiagnostic.php:197
5089
  msgid "Normal"
5090
  msgstr ""
@@ -5094,11 +5673,13 @@ msgstr ""
5094
  msgid "No files readable"
5095
  msgstr ""
5096
 
 
5097
  #: lib/wfDiagnostic.php:231
5098
  #: lib/wfDiagnostic.php:267
5099
  msgid "File \"%s\" does not exist"
5100
  msgstr ""
5101
 
 
5102
  #: lib/wfDiagnostic.php:234
5103
  msgid "File \"%s\" is unreadable"
5104
  msgstr ""
@@ -5108,6 +5689,7 @@ msgstr ""
5108
  msgid "No files writable"
5109
  msgstr ""
5110
 
 
5111
  #: lib/wfDiagnostic.php:270
5112
  msgid "File \"%s\" is unwritable"
5113
  msgstr ""
@@ -5124,10 +5706,12 @@ msgstr ""
5124
  msgid "(default)"
5125
  msgstr ""
5126
 
 
5127
  #: lib/wfDiagnostic.php:388
5128
  msgid "%s - using constant"
5129
  msgstr ""
5130
 
 
5131
  #: lib/wfDiagnostic.php:401
5132
  msgid "%s - using template"
5133
  msgstr ""
@@ -5140,11 +5724,6 @@ msgstr ""
5140
  msgid "Unavailable"
5141
  msgstr ""
5142
 
5143
- #: lib/wfDiagnostic.php:478
5144
- #: models/block/wfBlock.php:95
5145
- msgid "Unknown"
5146
- msgstr ""
5147
-
5148
  #: lib/wfDiagnostic.php:607
5149
  #: lib/wfDiagnostic.php:610
5150
  msgid "wp_remote_post() test to noc1.wordfence.com failed! Response was: "
@@ -5154,10 +5733,6 @@ msgstr ""
5154
  msgid "This likely means that your hosting provider is blocking requests to noc1.wordfence.com or has set up a proxy that is not behaving itself."
5155
  msgstr ""
5156
 
5157
- #: lib/wfDiagnostic.php:637
5158
- msgid "OK - %s"
5159
- msgstr ""
5160
-
5161
  #: lib/wfDiagnostic.php:644
5162
  #: lib/wfDiagnostic.php:647
5163
  msgid "wp_remote_post() test back to this server failed! Response was: "
@@ -5167,6 +5742,7 @@ msgstr ""
5167
  msgid "This additional info may help you diagnose the issue. The response headers we received were:"
5168
  msgstr ""
5169
 
 
5170
  #: lib/wfDiagnostic.php:677
5171
  msgid "We cannot read $_SERVER[%s]"
5172
  msgstr ""
@@ -5192,14 +5768,45 @@ msgstr ""
5192
  msgid "An error occurred: Invalid options format received."
5193
  msgstr ""
5194
 
 
 
 
 
 
 
 
 
 
 
 
5195
  #: lib/wfLockedOut.php:10
5196
  msgid "You are temporarily locked out"
5197
  msgstr ""
5198
 
 
 
 
 
 
 
 
 
 
 
 
 
5199
  #: lib/wfLockedOut.php:336
5200
  msgid "Attempt to return to the admin login page (you may still be locked out)"
5201
  msgstr ""
5202
 
 
 
 
 
 
 
 
 
5203
  #: lib/wfLog.php:217
5204
  msgid "Exceeded the maximum global requests per minute for crawlers or humans."
5205
  msgstr ""
@@ -5220,6 +5827,20 @@ msgstr ""
5220
  msgid "Exceeded the maximum number of page not found errors per minute for humans."
5221
  msgstr ""
5222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5223
  #: lib/wfLog.php:556
5224
  msgid "Advanced blocking in effect."
5225
  msgstr ""
@@ -5228,38 +5849,67 @@ msgstr ""
5228
  msgid "redirected to bypass URL"
5229
  msgstr ""
5230
 
 
5231
  #: lib/wfLog.php:582
5232
  msgid "blocked access via country blocking and redirected to URL (%s)"
5233
  msgstr ""
5234
 
5235
  #: lib/wfLog.php:597
5236
- #: models/block/wfBlock.php:1427
5237
  msgid "blocked access via country blocking"
5238
  msgstr ""
5239
 
5240
  #: lib/wfLog.php:600
5241
- #: models/block/wfBlock.php:1430
5242
  #: waf/wfWAFIPBlocksController.php:71
5243
  msgid "Access from your area has been temporarily limited for security reasons"
5244
  msgstr ""
5245
 
5246
  #: lib/wfLog.php:615
 
5247
  #: waf/wfWAFIPBlocksController.php:97
5248
  msgid "Manual block by administrator"
5249
  msgstr ""
5250
 
 
5251
  #: lib/wfLog.php:643
5252
- msgid "Blocking IP %s. %s"
5253
  msgstr ""
5254
 
 
5255
  #: lib/wfLog.php:655
5256
- msgid "Throttling IP %s. %s"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5257
  msgstr ""
5258
 
5259
  #: lib/wfScan.php:58
5260
  msgid "The signature on the request to start a scan is invalid. Please try again."
5261
  msgstr ""
5262
 
 
 
 
 
5263
  #: lib/wfScan.php:65
5264
  msgid "[invalid]"
5265
  msgstr ""
@@ -5269,888 +5919,3270 @@ msgstr ""
5269
  msgid "[none]"
5270
  msgstr ""
5271
 
 
5272
  #: lib/wfScan.php:67
5273
- msgid "Checking cronkey: %s (expecting %s)"
5274
  msgstr ""
5275
 
5276
- #: lib/wfScan.php:135
5277
- #: lib/wfScan.php:138
5278
- msgid "Scan can't continue - stored data not found after a fork."
5279
  msgstr ""
5280
 
5281
- #: lib/wfScan.php:261
5282
- msgid "Wordfence scan failed because of license site URL conflict"
5283
  msgstr ""
5284
 
5285
- #: lib/wfScanEngine.php:850
5286
- msgid ", and %d more."
5287
  msgstr ""
5288
 
5289
- #: lib/wfScanEngine.php:876
5290
- msgid "%d path was skipped for the malware scan due to scan settings"
 
5291
  msgstr ""
5292
 
5293
- #: lib/wfScanEngine.php:876
5294
- msgid "%d paths were skipped for the malware scan due to scan settings"
5295
  msgstr ""
5296
 
5297
- #: lib/wfScanEngine.php:877
5298
- msgid "The option \"Scan files outside your WordPress installation\" is off by default, which means %d path and its file(s) will not be scanned for malware or unauthorized changes. To continue skipping this path, you may ignore this issue. Or to start scanning it, enable the option and subsequent scans will include it. Some paths may not be necessary to scan, so this is optional. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a><br><br>The path skipped is %s"
5299
  msgstr ""
5300
 
5301
- #: lib/wfScanEngine.php:877
5302
- msgid "The option \"Scan files outside your WordPress installation\" is off by default, which means %d paths and their file(s) will not be scanned for malware or unauthorized changes. To continue skipping these paths, you may ignore this issue. Or to start scanning them, enable the option and subsequent scans will include them. Some paths may not be necessary to scan, so this is optional. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a><br><br>The paths skipped are %s"
5303
  msgstr ""
5304
 
5305
- #: lib/wfScanEngine.php:1486
5306
- msgid "Scanning to check available disk space"
5307
  msgstr ""
5308
 
5309
- #: lib/wfScanEngine.php:1493
5310
- msgid "Unable to access available disk space information"
5311
  msgstr ""
5312
 
5313
- #: lib/wfScanEngine.php:1500
5314
- msgid "Total disk space: %s -- Free disk space: %s"
5315
  msgstr ""
5316
 
5317
- #: lib/wfScanEngine.php:1502
5318
- msgid "The disk has %s MB available"
 
5319
  msgstr ""
5320
 
5321
- #: lib/wfScanEngine.php:1519
5322
- msgid "You have %s disk space remaining"
 
5323
  msgstr ""
5324
 
5325
- #: lib/wfScanEngine.php:1520
5326
- msgid "You only have %s of your disk space remaining. Please free up disk space or your website may stop serving requests."
 
5327
  msgstr ""
5328
 
5329
- #: lib/wfScanEngine.php:1529
5330
- msgid "Checking Web Application Firewall status"
 
 
5331
  msgstr ""
5332
 
5333
- #: lib/wfScanEngine.php:1540
5334
- msgid "Web Application Firewall is disabled"
5335
  msgstr ""
5336
 
5337
- #: lib/wfScanEngine.php:1541
5338
- msgid "Wordfence's Web Application Firewall has been unexpectedly disabled. If you see a notice at the top of the Wordfence admin pages that says \"The Wordfence Web Application Firewall cannot run,\" click the link in that message to rebuild the configuration. If this does not work, you may need to fix file permissions. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">More Details</a>"
5339
  msgstr ""
5340
 
5341
- #: lib/wfScanEngine.php:1821
5342
- msgid "An admin user with the username %s was created outside of WordPress."
 
 
 
 
 
 
 
 
5343
  msgstr ""
5344
 
5345
- #: lib/wfScanEngine.php:1822
5346
- msgid "An admin user with the username %s was created outside of WordPress. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it."
 
 
 
 
 
 
 
5347
  msgstr ""
5348
 
5349
- #: lib/wfScanEngine.php:1845
5350
- msgid "An admin user with a suspicious username %s was found."
5351
  msgstr ""
5352
 
5353
- #: lib/wfScanEngine.php:1846
5354
- msgid "An admin user with a suspicious username %s was found. Administrators accounts with usernames similar to this are commonly seen created by hackers. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it."
 
5355
  msgstr ""
5356
 
5357
- #: lib/wfScanEngine.php:1976
5358
- msgid "PHP Update Needed for Country Blocking"
 
 
 
 
 
 
 
 
5359
  msgstr ""
5360
 
5361
- #: lib/wfScanEngine.php:1977
5362
- msgid "The GeoIP database that is required for country blocking has been updated to a new format. This new format requires sites to run PHP 5.4 or newer, and this site is on PHP %s. To ensure country blocking continues functioning, please update PHP."
5363
  msgstr ""
5364
 
5365
- #: lib/wfUnlockMsg.php:2
5366
- msgid "If you are a WordPress user with administrative privileges on this site please enter your email in the box below and click &quot;Send&quot;. You will then receive an email that helps you regain access."
 
5367
  msgstr ""
5368
 
5369
- #: lib/wfVersionCheckController.php:49
5370
- #: lib/wfVersionCheckController.php:62
5371
- msgid "PHP version too old"
 
 
 
 
 
 
5372
  msgstr ""
5373
 
5374
- #: lib/wfVersionCheckController.php:50
5375
- msgid "Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
 
5376
  msgstr ""
5377
 
5378
- #: lib/wfVersionCheckController.php:50
5379
- #: lib/wfVersionCheckController.php:63
5380
- #: lib/wfVersionCheckController.php:129
5381
- #: lib/wfVersionCheckController.php:144
5382
- msgid "Learn More: %s"
5383
  msgstr ""
5384
 
5385
- #: lib/wfVersionCheckController.php:56
5386
- msgid "<strong>WARNING: </strong> Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
5387
  msgstr ""
5388
 
5389
- #: lib/wfVersionCheckController.php:63
5390
- msgid "Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
5391
  msgstr ""
5392
 
5393
- #: lib/wfVersionCheckController.php:69
5394
- msgid "<strong>WARNING: </strong> Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
 
5395
  msgstr ""
5396
 
5397
- #: lib/wfVersionCheckController.php:128
5398
- #: lib/wfVersionCheckController.php:143
5399
- msgid "WordPress version too old"
5400
  msgstr ""
5401
 
5402
- #: lib/wfVersionCheckController.php:129
5403
- msgid "Your site is using a WordPress version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5404
  msgstr ""
5405
 
5406
- #: lib/wfVersionCheckController.php:135
5407
- msgid "<strong>WARNING: </strong> Your site is using a WordPress version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
5408
  msgstr ""
5409
 
5410
- #: lib/wfVersionCheckController.php:144
5411
- msgid "Your site is using a WordPress version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
5412
  msgstr ""
5413
 
5414
- #: lib/wfVersionCheckController.php:150
5415
- msgid "<strong>WARNING: </strong> Your site is using a WordPress version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
5416
  msgstr ""
5417
 
5418
- #: lib/wordfenceClass.php:833
5419
- msgid "Automatically generated from previous country blocking settings"
5420
  msgstr ""
5421
 
5422
- #: lib/wordfenceClass.php:1625
5423
- msgid "Please choose a stronger password. Try including numbers, symbols, and a mix of upper and lowercase letters and remove common words."
5424
  msgstr ""
5425
 
5426
- #: lib/wordfenceClass.php:1631
5427
- msgid "Passwords containing a space followed by \"wf\" without quotes are not allowed."
 
5428
  msgstr ""
5429
 
5430
- #: lib/wordfenceClass.php:1646
5431
- msgid "Please choose a different password. The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. <a href=\"%s\">Learn More</a>"
 
5432
  msgstr ""
5433
 
5434
- #: lib/wordfenceClass.php:1800
5435
- msgid "Your request was received"
5436
  msgstr ""
5437
 
5438
- #: lib/wordfenceClass.php:1801
5439
- msgid "We received a request to email \"%s\" instructions to unlock their access. If that is the email address of a site administrator or someone on the Wordfence alert list, they have been emailed instructions on how to regain access to this system. The instructions we sent will expire 30 minutes from now."
 
5440
  msgstr ""
5441
 
5442
- #: lib/wordfenceClass.php:1807
5443
- msgid "Invalid key provided for authentication."
 
5444
  msgstr ""
5445
 
5446
- #: lib/wordfenceClass.php:1818
5447
- msgid "Request received via unlock email link to unblock all IPs."
5448
  msgstr ""
5449
 
5450
- #: lib/wordfenceClass.php:1827
5451
- msgid "Request received via unlock email link to unblock all IPs via disabling firewall rules."
 
5452
  msgstr ""
5453
 
5454
- #: lib/wordfenceClass.php:1835
5455
- msgid "Invalid function specified. Please check the link we emailed you and make sure it was not cut-off by your email reader."
 
5456
  msgstr ""
5457
 
5458
- #: lib/wordfenceClass.php:1880
5459
- msgid "Unsubscribe Requested"
5460
  msgstr ""
5461
 
5462
- #: lib/wordfenceClass.php:1936
5463
- msgid "Sorry but your browser sent an invalid security token when trying to use this form."
 
5464
  msgstr ""
5465
 
5466
- #: lib/wordfenceClass.php:1942
5467
- msgid "An error occurred while saving the license."
 
5468
  msgstr ""
5469
 
5470
- #: lib/wordfenceClass.php:1944
5471
- #: lib/wordfenceClass.php:1964
5472
- msgid "An error occurred while saving the license: %s"
5473
  msgstr ""
5474
 
5475
- #: lib/wordfenceClass.php:2339
5476
- #: lib/wordfenceClass.php:2343
5477
- msgid "Accessed a banned URL"
5478
  msgstr ""
5479
 
5480
- #: lib/wordfenceClass.php:2350
5481
- #: lib/wordfenceClass.php:2354
5482
- msgid "POST received with blank user-agent and referer"
5483
  msgstr ""
5484
 
5485
- #: lib/wordfenceClass.php:2484
5486
- msgid "<strong>ERROR</strong>: You can't register using that username"
5487
  msgstr ""
5488
 
5489
- #: lib/wordfenceClass.php:2524
5490
- msgid "Sorry, you are not allowed to list users."
 
5491
  msgstr ""
5492
 
5493
- #: lib/wordfenceClass.php:2531
5494
- msgid "Invalid user ID."
 
5495
  msgstr ""
5496
 
5497
- #: lib/wordfenceClass.php:2675
5498
- msgid "<strong>VERIFICATION FAILED</strong>: Two-factor authentication verification failed. Please try again."
 
5499
  msgstr ""
5500
 
5501
- #: lib/wordfenceClass.php:2682
5502
- #: lib/wordfenceClass.php:3112
5503
- msgid "<strong>ERROR</strong>: The username or password you entered is incorrect. <a href=\"%2$s\" title=\"Password Lost and Found\">Lost your password</a>?"
5504
  msgstr ""
5505
 
5506
- #: lib/wordfenceClass.php:2690
5507
- #: lib/wordfenceClass.php:2821
5508
- msgid "<strong>WARNING: </strong>The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href=\"%s\">change your password</a>. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
5509
  msgstr ""
5510
 
5511
- #: lib/wordfenceClass.php:2711
5512
- msgid "<strong>INVALID CODE</strong>: Please sign in again and add a space, the letters <code>wf</code>, and the code from your authenticator app to the end of your password (e.g., <code>wf123456</code>)."
5513
  msgstr ""
5514
 
5515
- #: lib/wordfenceClass.php:2715
5516
- msgid "<strong>INVALID CODE</strong>: Please sign in again and add a space, the letters <code>wf</code>, and the code sent to your phone to the end of your password (e.g., <code>wf123456</code>)."
 
5517
  msgstr ""
5518
 
5519
- #: lib/wordfenceClass.php:2722
5520
- #: lib/wordfenceClass.php:2773
5521
- #: lib/wordfenceClass.php:2796
5522
- msgid "<strong>AUTHENTICATION FAILURE</strong>: A temporary failure was encountered while trying to log in. Please try again."
5523
  msgstr ""
5524
 
5525
- #: lib/wordfenceClass.php:2732
5526
- msgid "<strong>INVALID CODE</strong>: You need to enter the code generated by your authenticator app. The code should be a six digit number (e.g., 123456)."
 
5527
  msgstr ""
5528
 
5529
- #: lib/wordfenceClass.php:2736
5530
- msgid "<strong>INVALID CODE</strong>: You need to enter the code generated sent to your phone. The code should be a six digit number (e.g., 123456)."
 
5531
  msgstr ""
5532
 
5533
- #: lib/wordfenceClass.php:2782
5534
- msgid "<strong>CODE EXPIRED. CHECK YOUR PHONE:</strong> The code you entered has expired. Codes are only valid for 30 minutes for security reasons. We have sent you a new code. Please sign in using your username, password, and the new code we sent you."
5535
  msgstr ""
5536
 
5537
- #: lib/wordfenceClass.php:2805
5538
- msgid "<strong>INVALID CODE</strong>: You need to enter your password and the code we sent to your phone. The code should start with 'wf' and should be four characters (e.g., wfAB12)."
5539
  msgstr ""
5540
 
5541
- #: lib/wordfenceClass.php:2854
5542
- msgid "<strong>CODE REQUIRED</strong>: Please check your authenticator app for the current code. Enter it below to sign in."
5543
  msgstr ""
5544
 
5545
- #: lib/wordfenceClass.php:2859
5546
- msgid "<strong>CODE REQUIRED</strong>: Please check your authenticator app for the current code. Please sign in again and add a space, the letters <code>wf</code>, and the code to the end of your password (e.g., <code>wf123456</code>)."
5547
  msgstr ""
5548
 
5549
- #: lib/wordfenceClass.php:2893
5550
- #: lib/wordfenceClass.php:2950
5551
- msgid "<strong>CHECK YOUR PHONE</strong>: A code has been sent to your phone and will arrive within 30 seconds. Enter it below to sign in."
5552
  msgstr ""
5553
 
5554
- #: lib/wordfenceClass.php:2898
5555
- msgid "<strong>CHECK YOUR PHONE</strong>: A code has been sent to your phone and will arrive within 30 seconds. Please sign in again and add a space, the letters <code>wf</code>, and the code to the end of your password (e.g., <code>wf123456</code>)."
5556
  msgstr ""
5557
 
5558
- #: lib/wordfenceClass.php:2955
5559
- msgid "<strong>CHECK YOUR PHONE</strong>: A code has been sent to your phone and will arrive within 30 seconds. Please sign in again and add a space and the code to the end of your password (e.g., <code>wfABCD</code>)."
5560
  msgstr ""
5561
 
5562
- #: lib/wordfenceClass.php:2976
5563
- #: lib/wordfenceClass.php:3010
5564
- msgid "<strong>WARNING: </strong>Your login has been allowed because you have previously logged in from the same IP, but you will be blocked if your IP changes. The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href=\"%s\">change your password</a>. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
5565
  msgstr ""
5566
 
5567
- #: lib/wordfenceClass.php:2991
5568
- #: lib/wordfenceClass.php:3025
5569
- msgid "<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href=\"%s\">reset your password</a> to reactivate your account. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
5570
  msgstr ""
5571
 
5572
- #: lib/wordfenceClass.php:3000
5573
- msgid "<strong>Cellphone Sign-in Required</strong>: Cellphone Sign-in is required for all administrator accounts. Please contact the site administrator to enable it for your account."
 
5574
  msgstr ""
5575
 
5576
- #: lib/wordfenceClass.php:3038
5577
- msgid "Blocked by Wordfence Security Network"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5578
  msgstr ""
5579
 
5580
- #: lib/wordfenceClass.php:3068
5581
- msgid "Blocked by login security setting"
5582
  msgstr ""
5583
 
5584
- #: lib/wordfenceClass.php:3446
5585
- msgid "An invalid type was specified to get file."
 
 
 
 
 
 
 
5586
  msgstr ""
5587
 
5588
- #: lib/wordfenceClass.php:3462
5589
- msgid "We could not fetch a core WordPress file from the Wordfence API."
 
 
 
 
 
 
 
5590
  msgstr ""
5591
 
5592
- #: lib/wordfenceClass.php:3521
5593
- msgid "Wordfence Test Email"
5594
  msgstr ""
5595
 
5596
- #: lib/wordfenceClass.php:3521
5597
- msgid ""
5598
- "This is a test email from %s.\n"
5599
- "The IP address that requested this was: %s"
5600
  msgstr ""
5601
 
5602
- #: lib/wordfenceClass.php:3528
5603
- msgid "Cellphone Sign-in is only available to paid members. <a href=\"https://www.wordfence.com/gnl1twoFac3/wordfence-signup/\" target=\"_blank\" rel=\"noopener noreferrer\">Click here to upgrade now.</a>"
5604
  msgstr ""
5605
 
5606
- #: lib/wordfenceClass.php:3535
5607
- msgid "The username you specified does not exist."
5608
  msgstr ""
5609
 
5610
- #: lib/wordfenceClass.php:3544
5611
- msgid "The username you specified is already enabled."
5612
  msgstr ""
5613
 
5614
- #: lib/wordfenceClass.php:3549
5615
- msgid "Unknown authentication mode."
 
 
 
5616
  msgstr ""
5617
 
5618
- #: lib/wordfenceClass.php:3554
5619
- msgid "The phone number you entered must start with a '+', then country code and then area code and number. For example, a number in the United States with country code '1' would look like this: +1-123-555-1234"
5620
  msgstr ""
5621
 
5622
- #: lib/wordfenceClass.php:3561
5623
- #: lib/wordfenceClass.php:3593
5624
- msgid "Could not contact Wordfence servers to generate a verification code: %s"
5625
  msgstr ""
5626
 
5627
- #: lib/wordfenceClass.php:3573
5628
- #: lib/wordfenceClass.php:3617
5629
- msgid "Could not gen verification code: %s"
5630
  msgstr ""
5631
 
5632
- #: lib/wordfenceClass.php:3574
5633
- #: lib/wordfenceClass.php:3618
5634
- msgid "We could not generate a verification code."
5635
  msgstr ""
5636
 
5637
- #: lib/wordfenceClass.php:3634
5638
- msgid "Unknown two-factor authentication mode."
5639
  msgstr ""
5640
 
5641
- #: lib/wordfenceClass.php:3851
5642
- msgid "# Scan Issues"
 
5643
  msgstr ""
5644
 
5645
- #: lib/wordfenceClass.php:3856
5646
- msgid "## New Issues (%d total)"
5647
  msgstr ""
5648
 
5649
- #: lib/wordfenceClass.php:3883
5650
- msgid "## Ignored Issues (%d total)"
5651
  msgstr ""
5652
 
5653
- #: lib/wordfenceClass.php:3904
5654
- msgid "No Ignored Issues"
5655
  msgstr ""
5656
 
5657
- #: lib/wordfenceClass.php:3926
5658
- msgid "Wordfence Activity Log"
 
5659
  msgstr ""
5660
 
5661
- #: lib/wordfenceClass.php:4127
5662
- msgid "All Countries"
 
 
5663
  msgstr ""
5664
 
5665
- #: lib/wordfenceClass.php:4130
5666
- msgid "1 Country"
 
5667
  msgstr ""
5668
 
5669
- #: lib/wordfenceClass.php:4133
5670
- msgid "%d Countries"
 
5671
  msgstr ""
5672
 
5673
- #: lib/wordfenceClass.php:4137
5674
- msgid "Entire Site"
 
 
 
5675
  msgstr ""
5676
 
5677
- #: lib/wordfenceClass.php:4140
5678
- msgid "Login Only"
 
 
 
5679
  msgstr ""
5680
 
5681
- #: lib/wordfenceClass.php:4143
5682
- msgid "Site Except Login"
 
5683
  msgstr ""
5684
 
5685
- #: lib/wordfenceClass.php:4151
5686
- msgid "IP Range"
5687
  msgstr ""
5688
 
5689
- #: lib/wordfenceClass.php:4152
5690
- msgid "User Agent"
 
5691
  msgstr ""
5692
 
5693
- #: lib/wordfenceClass.php:4153
5694
- #: views/blocking/blocking-create.php:201
5695
- msgid "Referrer"
5696
  msgstr ""
5697
 
5698
- #: lib/wordfenceClass.php:4154
5699
- #: views/blocking/blocking-create.php:193
5700
- msgid "Hostname"
5701
  msgstr ""
5702
 
5703
- #: lib/wordfenceClass.php:4168
5704
- msgid "Permanent"
 
5705
  msgstr ""
5706
 
5707
- #: lib/wordfenceClass.php:4240
5708
- msgid "An error occurred while creating the block."
 
5709
  msgstr ""
5710
 
5711
- #: lib/wordfenceClass.php:4246
5712
- msgid "No block parameters were provided."
 
5713
  msgstr ""
5714
 
5715
- #: lib/wordfenceClass.php:4278
5716
- #: lib/wordfenceClass.php:4310
5717
- msgid "No blocks were provided."
5718
  msgstr ""
5719
 
5720
- #: lib/wordfenceClass.php:4342
5721
- msgid "The license provided is already in use on another site."
 
5722
  msgstr ""
5723
 
5724
- #: lib/wordfenceClass.php:4347
5725
- msgid "The Wordfence activation server returned an unexpected response. Please try again."
 
5726
  msgstr ""
5727
 
5728
- #: lib/wordfenceClass.php:4353
5729
- msgid "We received an error while trying to activate the license with the Wordfence servers: "
 
 
5730
  msgstr ""
5731
 
5732
- #: lib/wordfenceClass.php:4366
5733
- msgid "No license was provided to install."
 
5734
  msgstr ""
5735
 
5736
- #: lib/wordfenceClass.php:4417
5737
- msgid "An unknown configuration section was provided."
 
5738
  msgstr ""
5739
 
5740
- #: lib/wordfenceClass.php:4423
5741
- msgid "No configuration section was provided."
5742
  msgstr ""
5743
 
5744
- #: lib/wordfenceClass.php:4469
5745
- #: lib/wordfenceClass.php:4474
5746
- msgid "An error occurred while saving the configuration."
5747
  msgstr ""
5748
 
5749
- #: lib/wordfenceClass.php:4485
5750
- msgid "No configuration changes were provided to save."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5751
  msgstr ""
5752
 
5753
- #: lib/wordfenceClass.php:4588
5754
- msgid "Manual permanent block by admin"
 
5755
  msgstr ""
5756
 
5757
- #: lib/wordfenceClass.php:4754
5758
- msgid "Idle"
 
5759
  msgstr ""
5760
 
5761
- #: lib/wordfenceClass.php:4763
5762
- msgid "Scan completed on %s"
 
5763
  msgstr ""
5764
 
5765
- #: lib/wordfenceClass.php:4770
5766
- msgid "Last scan failed"
 
5767
  msgstr ""
5768
 
5769
- #: lib/wordfenceClass.php:4837
5770
- msgid "The current scan looks like it has failed. Its last status update was <span id=\"wf-scan-failed-time-ago\">%s</span> ago. You may continue to wait in case it resumes or stop and restart the scan. Some sites may need adjustments to run scans reliably."
5771
  msgstr ""
5772
 
5773
- #: lib/wordfenceClass.php:4837
5774
- #: lib/wordfenceClass.php:4845
5775
- #: lib/wordfenceClass.php:4864
5776
- #: lib/wordfenceClass.php:4876
5777
- #: lib/wordfenceClass.php:4884
5778
- msgid "Click here for steps you can try."
5779
  msgstr ""
5780
 
5781
- #: lib/wordfenceClass.php:4838
5782
- msgid "Cancel Scan"
 
5783
  msgstr ""
5784
 
5785
- #: lib/wordfenceClass.php:4845
5786
- msgid "The previous scan has failed. Some sites may need adjustments to run scans reliably."
5787
  msgstr ""
5788
 
5789
- #: lib/wordfenceClass.php:4851
5790
- msgid "The previous scan has terminated because the time limit of %s was reached. This limit can be customized on the options page."
5791
  msgstr ""
5792
 
5793
- #: lib/wordfenceClass.php:4857
5794
- msgid "The previous scan has terminated because we detected an update occurring during the scan."
 
5795
  msgstr ""
5796
 
5797
- #: lib/wordfenceClass.php:4864
5798
- msgid "The scan has failed to start. This is often because the site either cannot make outbound requests or is blocked from connecting to itself."
 
5799
  msgstr ""
5800
 
5801
- #: lib/wordfenceClass.php:4870
5802
- msgid "Scans are not functional because SSL is unavailable."
 
5803
  msgstr ""
5804
 
5805
- #: lib/wordfenceClass.php:4876
5806
- msgid "The scan has failed because we were unable to contact the Wordfence servers. Some sites may need adjustments to run scans reliably."
 
5807
  msgstr ""
5808
 
5809
- #: lib/wordfenceClass.php:4884
5810
- msgid "The scan has failed because we received an unexpected response from the Wordfence servers. This may be a temporary error, though some sites may need adjustments to run scans reliably."
5811
  msgstr ""
5812
 
5813
- #: lib/wordfenceClass.php:4936
5814
- #: lib/wordfenceClass.php:5052
5815
- msgid "Deleting an infected wp-config.php file must be done outside of Wordfence. The wp-config.php file contains your database credentials, which you will need to restore normal site operations. Your site will NOT function once the wp-config.php file has been deleted."
5816
  msgstr ""
5817
 
5818
- #: lib/wordfenceClass.php:4945
5819
- msgid "Could not delete file %s. Error was: %s"
 
5820
  msgstr ""
5821
 
5822
- #: lib/wordfenceClass.php:4969
5823
- msgid "We could not retrieve the original file of %s to do a repair."
5824
  msgstr ""
5825
 
5826
- #: lib/wordfenceClass.php:4974
5827
- msgid "An invalid file %s was specified for repair."
5828
  msgstr ""
5829
 
5830
- #: lib/wordfenceClass.php:4982
5831
- msgid "You don't have permission to repair %s. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file."
 
5832
  msgstr ""
5833
 
5834
- #: lib/wordfenceClass.php:4985
5835
- msgid "We could not write to %s. The error was: %s"
 
5836
  msgstr ""
5837
 
5838
- #: lib/wordfenceClass.php:4996
5839
- msgid "We could not write to %s. (%d bytes written) You may not have permission to modify files on your WordPress server."
 
 
5840
  msgstr ""
5841
 
5842
- #: lib/wordfenceClass.php:5008
5843
- msgid "Deleted some files with errors"
 
5844
  msgstr ""
5845
 
5846
- #: lib/wordfenceClass.php:5008
5847
- msgid "Repaired some files with errors"
 
5848
  msgstr ""
5849
 
5850
- #: lib/wordfenceClass.php:5009
5851
- msgid "Deleted %d files but we encountered the following errors with other files: %s"
 
5852
  msgstr ""
5853
 
5854
- #: lib/wordfenceClass.php:5009
5855
- msgid "Repaired %d files but we encountered the following errors with other files: %s"
 
5856
  msgstr ""
5857
 
5858
- #: lib/wordfenceClass.php:5012
5859
- msgid "Deleted %d files successfully"
 
5860
  msgstr ""
5861
 
5862
- #: lib/wordfenceClass.php:5012
5863
- msgid "Repaired %d files successfully"
 
5864
  msgstr ""
5865
 
5866
- #: lib/wordfenceClass.php:5013
5867
- msgid "Deleted %d files successfully. No errors were encountered."
 
5868
  msgstr ""
5869
 
5870
- #: lib/wordfenceClass.php:5013
5871
- msgid "Repaired %d files successfully. No errors were encountered."
 
 
 
 
5872
  msgstr ""
5873
 
5874
- #: lib/wordfenceClass.php:5016
5875
- msgid "Could not delete files"
 
5876
  msgstr ""
5877
 
5878
- #: lib/wordfenceClass.php:5016
5879
- msgid "Could not repair files"
5880
  msgstr ""
5881
 
5882
- #: lib/wordfenceClass.php:5017
5883
- msgid "We could not delete any of the files you selected. We encountered the following errors: %s"
 
5884
  msgstr ""
5885
 
5886
- #: lib/wordfenceClass.php:5017
5887
- msgid "We could not repair any of the files you selected. We encountered the following errors: %s"
 
5888
  msgstr ""
5889
 
5890
- #: lib/wordfenceClass.php:5020
5891
- msgid "Nothing done"
 
5892
  msgstr ""
5893
 
5894
- #: lib/wordfenceClass.php:5021
5895
- msgid "We didn't delete anything and no errors were found."
 
5896
  msgstr ""
5897
 
5898
- #: lib/wordfenceClass.php:5021
5899
- msgid "We didn't repair anything and no errors were found."
5900
  msgstr ""
5901
 
5902
- #: lib/wordfenceClass.php:5029
5903
- msgid "Invalid bulk operation selected"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5904
  msgstr ""
5905
 
5906
- #: lib/wordfenceClass.php:5039
5907
- msgid "Could not delete file because we could not find that issue."
5908
  msgstr ""
5909
 
5910
- #: lib/wordfenceClass.php:5042
5911
- msgid "Could not delete file because that issue does not appear to be a file related issue."
5912
  msgstr ""
5913
 
5914
- #: lib/wordfenceClass.php:5048
5915
- msgid "An invalid file was requested for deletion."
5916
  msgstr ""
5917
 
5918
- #: lib/wordfenceClass.php:5920
5919
- #: views/dashboard/options-group-import.php:167
5920
- msgid "Reload"
5921
  msgstr ""
5922
 
5923
- #: lib/wordfenceClass.php:5955
5924
- msgid "The Wordfence Web Application Firewall cannot run."
5925
  msgstr ""
5926
 
5927
- #: lib/wordfenceClass.php:5968
5928
- #: lib/wordfenceClass.php:5981
5929
- msgid "The Wordfence Web Application Firewall needs a configuration update."
5930
  msgstr ""
5931
 
5932
- #: lib/wordfenceClass.php:5984
5933
- msgid "The Wordfence Web Application Firewall is in read-only mode."
5934
  msgstr ""
5935
 
5936
- #: lib/wordfenceClass.php:6102
5937
- msgid "The last rules update for the Wordfence Web Application Firewall was unsuccessful. The last successful update check was %s, so this site may be missing new rules added since then."
5938
  msgstr ""
5939
 
5940
- #: lib/wordfenceClass.php:6106
5941
- msgid "You may wait for the next automatic attempt at %s or try to <a href=\"%s\">Manually Update</a> by clicking the \"Manually Refresh Rules\" button below the Rules list."
5942
  msgstr ""
5943
 
5944
- #: lib/wordfenceClass.php:6109
5945
- msgid "You may wait for the next automatic attempt or try to <a href=\"%s\">Manually Update</a> by clicking the \"Manually Refresh Rules\" button below the Rules list."
5946
  msgstr ""
5947
 
5948
- #: lib/wordfenceClass.php:6114
5949
- msgid "You may wait for the next automatic attempt at %s or log into the parent site to manually update by clicking the \"Manually Refresh Rules\" button below the Rules list."
5950
  msgstr ""
5951
 
5952
- #: lib/wordfenceClass.php:6117
5953
- msgid "You may wait for the next automatic attempt or log into the parent site to manually update by clicking the \"Manually Refresh Rules\" button below the Rules list."
5954
  msgstr ""
5955
 
5956
- #: lib/wordfenceClass.php:6700
5957
- msgid ""
5958
- "User IP: %s\n"
5959
- ""
5960
  msgstr ""
5961
 
5962
- #: lib/wordfenceClass.php:6703
5963
- msgid ""
5964
- "User hostname: %s\n"
5965
- ""
5966
  msgstr ""
5967
 
5968
- #: lib/wordfenceClass.php:6707
5969
- msgid "User location: "
5970
  msgstr ""
5971
 
5972
- #: lib/wordfenceClass.php:6762
5973
- msgid "No longer an administrator for this site? Click here to stop receiving security alerts: %s"
5974
  msgstr ""
5975
 
5976
- #: lib/wordfenceClass.php:6821
5977
- msgid "Invalid email address provided."
5978
  msgstr ""
5979
 
5980
- #: lib/wordfenceClass.php:6865
5981
- msgid "<strong>ERROR</strong>: Incorrect username or password."
5982
  msgstr ""
5983
 
5984
- #: lib/wordfenceClass.php:7558
5985
- #: lib/wordfenceClass.php:7655
5986
- msgid "A valid server configuration was not provided."
5987
  msgstr ""
5988
 
5989
- #: lib/wordfenceClass.php:7569
5990
- #: lib/wordfenceClass.php:7676
5991
- msgid "Filesystem Credentials Required"
5992
  msgstr ""
5993
 
5994
- #: lib/wordfenceClass.php:7571
5995
- #: lib/wordfenceClass.php:7595
5996
- #: lib/wordfenceClass.php:7639
5997
- #: views/waf/waf-install.php:13
5998
- msgid "If you cannot complete the setup process, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">click here for help</a>"
5999
  msgstr ""
6000
 
6001
- #: lib/wordfenceClass.php:7572
6002
- msgid "Once you have entered credentials, click Continue to complete the setup."
6003
  msgstr ""
6004
 
6005
- #: lib/wordfenceClass.php:7593
6006
- #: lib/wordfenceClass.php:7701
6007
- msgid "Filesystem Permission Error"
6008
  msgstr ""
6009
 
6010
- #: lib/wordfenceClass.php:7619
6011
- msgid "Manual Installation Instructions"
 
6012
  msgstr ""
6013
 
6014
- #: lib/wordfenceClass.php:7626
6015
- msgid "Installation Successful"
 
6016
  msgstr ""
6017
 
6018
- #: lib/wordfenceClass.php:7637
6019
- msgid "Installation Failed"
 
6020
  msgstr ""
6021
 
6022
- #: lib/wordfenceClass.php:7678
6023
- #: lib/wordfenceClass.php:7703
6024
- #: lib/wordfenceClass.php:7734
6025
- #: lib/wordfenceClass.php:7763
6026
- #: lib/wordfenceClass.php:7809
6027
- #: views/waf/waf-uninstall.php:13
6028
- msgid "If you cannot complete the uninstall process, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">click here for help</a>"
6029
  msgstr ""
6030
 
6031
- #: lib/wordfenceClass.php:7679
6032
- msgid "Once you have entered credentials, click Continue to complete uninstallation."
 
6033
  msgstr ""
6034
 
6035
- #: lib/wordfenceClass.php:7723
6036
- msgid "The <code>auto_prepend_file</code> setting has been successfully removed from <code>.htaccess</code> and <code>.user.ini</code>. Once this change takes effect, Extended Protection Mode will be disabled."
6037
  msgstr ""
6038
 
6039
- #: lib/wordfenceClass.php:7725
6040
- msgid "Any previous value for <code>auto_prepend_file</code> will need to be re-enabled manually if still needed."
6041
  msgstr ""
6042
 
6043
- #: lib/wordfenceClass.php:7729
6044
- msgid "Waiting for it to take effect. This may take up to %s."
 
6045
  msgstr ""
6046
 
6047
- #: lib/wordfenceClass.php:7732
6048
- msgid "Waiting for Changes"
6049
  msgstr ""
6050
 
6051
- #: lib/wordfenceClass.php:7754
6052
- msgid "Extended Protection Mode has not been disabled. This may be because <code>auto_prepend_file</code> is configured somewhere else or the value is still cached by PHP."
 
6053
  msgstr ""
6054
 
6055
- #: lib/wordfenceClass.php:7756
6056
- msgid "Retrying Failed."
 
6057
  msgstr ""
6058
 
6059
- #: lib/wordfenceClass.php:7758
6060
- msgid "Try Again"
 
 
6061
  msgstr ""
6062
 
6063
- #: lib/wordfenceClass.php:7761
6064
- msgid "Unable to Uninstall"
 
 
6065
  msgstr ""
6066
 
6067
- #: lib/wordfenceClass.php:7797
6068
- msgid "Uninstallation Complete"
 
6069
  msgstr ""
6070
 
6071
- #: lib/wordfenceClass.php:7807
6072
- msgid "Uninstallation Failed"
 
6073
  msgstr ""
6074
 
6075
- #: lib/wordfenceClass.php:8472
6076
- msgid ""
6077
- "To make your site as secure as possible, take a moment to optimize the Wordfence Web\n"
6078
- "\t\tApplication Firewall:"
6079
  msgstr ""
6080
 
6081
- #: lib/wordfenceClass.php:8473
6082
- msgid "Click here to configure"
 
6083
  msgstr ""
6084
 
6085
- #: lib/wordfenceClass.php:8474
6086
- msgid "Dismiss"
 
6087
  msgstr ""
6088
 
6089
- #: lib/wordfenceClass.php:8476
6090
- msgid "If you cannot complete the setup process, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">click here for help</a>."
 
6091
  msgstr ""
6092
 
6093
- #: lib/wordfenceClass.php:8643
6094
- msgid "Auth grant is invalid."
 
6095
  msgstr ""
6096
 
6097
- #: lib/wordfenceClass.php:8658
6098
- msgid "Invalid response from Wordfence Central: %s"
 
6099
  msgstr ""
6100
 
6101
- #: lib/wordfenceClass.php:8664
6102
- #: lib/wordfenceClass.php:8677
6103
- msgid "Invalid response from Wordfence Central. Parameter %s not found in response."
6104
  msgstr ""
6105
 
6106
- #: lib/wordfenceClass.php:8706
6107
- #: lib/wordfenceClass.php:8843
6108
- msgid "Access token not found."
6109
  msgstr ""
6110
 
6111
- #: lib/wordfenceClass.php:8751
6112
- #: lib/wordfenceClass.php:8818
6113
- msgid "Invalid response from Wordfence Central."
6114
  msgstr ""
6115
 
6116
- #: lib/wordfenceClass.php:8794
6117
- msgid "Auth grant not found."
 
6118
  msgstr ""
6119
 
6120
- #: lib/wordfenceHash.php:600
 
6121
  msgid "Old WordPress core file not removed during update: %s"
6122
  msgstr ""
6123
 
6124
- #: lib/wordfenceHash.php:601
 
6125
  msgid "This file is in a WordPress core location but is from an older version of WordPress and not used with your current version. Hosting or permissions issues can cause these files to get left behind when WordPress is updated and they should be removed if possible."
6126
  msgstr ""
6127
 
6128
- #: lib/wordfenceHash.php:617
6129
- #: lib/wordfenceHash.php:637
 
6130
  msgid "Unknown file in WordPress core: %s"
6131
  msgstr ""
6132
 
6133
- #: lib/wordfenceHash.php:618
 
6134
  msgid "This file is in a WordPress core location but is not distributed with this version of WordPress. This scan often includes files left over from a previous WordPress version, but it may also find files added by another plugin, files added by your host, or malicious files added by an attacker."
6135
  msgstr ""
6136
 
6137
- #: lib/wordfenceHash.php:638
 
6138
  msgid "This file is in a WordPress core location but is not distributed with this version of WordPress. This scan often includes files left over from a previous WordPress version, but it may also find files added by another plugin, files added by your host, or malicious files added by an attacker. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
6139
  msgstr ""
6140
 
6141
- #: lib/wordfenceHash.php:745
 
 
 
 
 
 
6142
  msgid "(+ %d more)"
6143
  msgstr ""
6144
 
6145
- #: lib/wordfenceHash.php:746
 
6146
  msgid "%d more similar files were found."
6147
  msgstr ""
6148
 
6149
- #: lib/wordfenceHash.php:746
 
6150
  msgid "1 more similar file was found."
6151
  msgstr ""
6152
 
6153
- #: lib/wordfenceHash.php:746
 
6154
  msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
6155
  msgstr ""
6156
 
@@ -6158,121 +9190,163 @@ msgstr ""
6158
  msgid "Wordfence could not get the attack signature patterns from the scanning server."
6159
  msgstr ""
6160
 
6161
- #: lib/wordfenceScanner.php:106
6162
  msgid "Wordfence received malformed attack signature patterns from the scanning server."
6163
  msgstr ""
6164
 
6165
- #: lib/wordfenceScanner.php:112
6166
  msgid "A regex Wordfence received from its servers is invalid. The pattern is: "
6167
  msgstr ""
6168
 
6169
- #: lib/wordfenceScanner.php:214
 
6170
  msgid "Backtrack limit is %d, reducing to 1000000"
6171
  msgstr ""
6172
 
6173
- #: lib/wordfenceScanner.php:227
6174
  msgid "Detected loop in malware scan, aborting."
6175
  msgstr ""
6176
 
6177
- #: lib/wordfenceScanner.php:234
6178
  msgid "No files remaining for malware scan."
6179
  msgstr ""
6180
 
6181
- #: lib/wordfenceScanner.php:298
 
6182
  msgid "Encountered file that is too large: %s - Skipping."
6183
  msgstr ""
6184
 
6185
- #: lib/wordfenceScanner.php:307
6186
- msgid "Scanning contents: %s (Size: %s Mem: %s)"
 
6187
  msgstr ""
6188
 
6189
- #: lib/wordfenceScanner.php:309
6190
- msgid "Scanning contents: %s (Size: %s)"
 
6191
  msgstr ""
6192
 
6193
- #: lib/wordfenceScanner.php:339
6194
  msgid "This file was detected because you have enabled \"Scan images, binary, and other files as if they were executable\", which treats non-PHP files as if they were PHP code. This option is more aggressive than the usual scans, and may cause false positives."
6195
  msgstr ""
6196
 
6197
- #: lib/wordfenceScanner.php:342
6198
  msgid "This file was detected because you have enabled HIGH SENSITIVITY scanning. This option is more aggressive than the usual scans, and may cause false positives."
6199
  msgstr ""
6200
 
6201
- #: lib/wordfenceScanner.php:353
6202
  msgid "File is an old version of TimThumb which is vulnerable."
6203
  msgstr ""
6204
 
6205
- #: lib/wordfenceScanner.php:354
6206
  msgid "This file appears to be an old version of the TimThumb script which makes your system vulnerable to attackers. Please upgrade the theme or plugin that uses this or remove it."
6207
  msgstr ""
6208
 
6209
- #: lib/wordfenceScanner.php:375
 
6210
  msgid "Resuming malware scan at rule %s."
6211
  msgstr ""
6212
 
6213
- #: lib/wordfenceScanner.php:383
6214
  msgid "This file appears to be installed or modified by a hacker to perform malicious activity. If you know about this file you can choose to ignore it to exclude it from future scans."
6215
  msgstr ""
6216
 
6217
- #: lib/wordfenceScanner.php:420
6218
- msgid "File appears to be malicious or unsafe: "
6219
  msgstr ""
6220
 
6221
- #: lib/wordfenceScanner.php:421
6222
- msgid "The matched text in this file is:"
6223
  msgstr ""
6224
 
6225
- #: lib/wordfenceScanner.php:421
6226
- msgid "The issue type is: <strong>%s</strong>"
 
6227
  msgstr ""
6228
 
6229
- #: lib/wordfenceScanner.php:421
6230
- msgid "Description: <strong>%s</strong>"
 
6231
  msgstr ""
6232
 
6233
- #: lib/wordfenceScanner.php:439
 
6234
  msgid "Forking during malware scan (%s) to ensure continuity."
6235
  msgstr ""
6236
 
6237
- #: lib/wordfenceScanner.php:461
6238
  msgid "This file may contain malicious executable code: "
6239
  msgstr ""
6240
 
6241
- #: lib/wordfenceScanner.php:462
6242
- msgid "This file is a PHP executable file and contains the word \"eval\" (without quotes) and the word \"<span class=\"wf-split-word\">%s</span>\" (without quotes). The eval() function along with an encoding function like the one mentioned are commonly used by hackers to hide their code. If you know about this file you can choose to ignore it to exclude it from future scans. This file was detected because you have enabled HIGH SENSITIVITY scanning. This option is more aggressive than the usual scans, and may cause false positives."
 
6243
  msgstr ""
6244
 
6245
- #: lib/wordfenceScanner.php:499
6246
  msgid "Asking Wordfence to check URLs against malware list."
6247
  msgstr ""
6248
 
6249
- #: lib/wordfenceScanner.php:527
6250
- #: lib/wordfenceScanner.php:563
6251
  msgid "File contains suspected malware URL: "
6252
  msgstr ""
6253
 
6254
- #: lib/wordfenceScanner.php:528
6255
- msgid "This file contains a suspected malware URL listed on Google's list of malware sites. Wordfence decodes %s when scanning files so the URL may not be visible if you view this file. The URL is: %s - More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>."
 
6256
  msgstr ""
6257
 
6258
- #: lib/wordfenceScanner.php:545
6259
  msgid "File contains suspected phishing URL: "
6260
  msgstr ""
6261
 
6262
- #: lib/wordfenceScanner.php:546
6263
  msgid "This file contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. The URL is: "
6264
  msgstr ""
6265
 
6266
- #: lib/wordfenceScanner.php:564
6267
  msgid "This file contains a URL that is currently listed on Wordfence's domain blocklist. The URL is: "
6268
  msgstr ""
6269
 
6270
- #: lib/wordfenceScanner.php:580
6271
  msgid "Finalizing malware scan results"
6272
  msgstr ""
6273
 
6274
- #: lib/wordfenceScanner.php:600
6275
- msgid "Scanned contents of %d additional files at %.2f per second"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6276
  msgstr ""
6277
 
6278
  #: models/block/wfBlock.php:84
@@ -6311,6 +9385,7 @@ msgstr ""
6311
  msgid "Invalid IP address."
6312
  msgstr ""
6313
 
 
6314
  #: models/block/wfBlock.php:180
6315
  msgid "This IP address is in a range of addresses that Wordfence does not block. The IP range may be internal or belong to a service that is always allowed. Allowlisting of external services can be disabled. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
6316
  msgstr ""
@@ -6379,13 +9454,6 @@ msgstr ""
6379
  msgid "Repair the Wordfence Firewall configuration."
6380
  msgstr ""
6381
 
6382
- #: models/firewall/wfFirewall.php:395
6383
- msgctxt "wordfence"
6384
- msgid "Re-enable %d firewall rule."
6385
- msgid_plural "Re-enable %d firewall rules."
6386
- msgstr[0] ""
6387
- msgstr[1] ""
6388
-
6389
  #: models/firewall/wfFirewall.php:452
6390
  msgid "Enable Firewall."
6391
  msgstr ""
@@ -6419,10 +9487,6 @@ msgstr ""
6419
  msgid "Enable Brute Force Protection."
6420
  msgstr ""
6421
 
6422
- #: models/page/wfPage.php:101
6423
- msgid "Dashboard"
6424
- msgstr ""
6425
-
6426
  #: models/page/wfPage.php:127
6427
  msgid "Support"
6428
  msgstr ""
@@ -6469,13 +9533,6 @@ msgstr ""
6469
  msgid "Enable Premium Reputation Checks."
6470
  msgstr ""
6471
 
6472
- #: models/scanner/wfScanner.php:778
6473
- msgctxt "wordfence"
6474
- msgid "Enable %d scan option."
6475
- msgid_plural "Enable %d scan options."
6476
- msgstr[0] ""
6477
- msgstr[1] ""
6478
-
6479
  #: models/scanner/wfScanner.php:820
6480
  msgid "Enable scan option to check if this website is being \"Spamvertised\"."
6481
  msgstr ""
@@ -6492,6 +9549,12 @@ msgstr ""
6492
  msgid "User defined scan pattern"
6493
  msgstr ""
6494
 
 
 
 
 
 
 
6495
  #: views/blocking/block-list.php:11
6496
  msgid "Current blocks<span class=\"wf-hidden-xs\"> for %s</span>"
6497
  msgstr ""
@@ -6543,14 +9606,6 @@ msgstr ""
6543
  msgid "Expiration"
6544
  msgstr ""
6545
 
6546
- #: views/blocking/block-list.php:73
6547
- #: views/reports/activity-report-email-inline.php:140
6548
- #: views/reports/activity-report-email-inline.php:195
6549
- #: views/reports/activity-report.php:18
6550
- #: views/reports/activity-report.php:63
6551
- msgid "Block Count"
6552
- msgstr ""
6553
-
6554
  #: views/blocking/block-list.php:74
6555
  msgid "Last Attempt"
6556
  msgstr ""
@@ -6575,14 +9630,6 @@ msgstr ""
6575
  msgid "Unblocking"
6576
  msgstr ""
6577
 
6578
- #: views/blocking/block-list.php:500
6579
- msgid "Are you sure you want to stop blocking the selected IP, range, or country?"
6580
- msgstr ""
6581
-
6582
- #: views/blocking/block-list.php:500
6583
- msgid "Are you sure you want to stop blocking the ${count} selected IPs, ranges, and countries?"
6584
- msgstr ""
6585
-
6586
  #: views/blocking/blocking-create.php:13
6587
  msgid "Block<span class=\"wf-hidden-xs\"> this IP Address</span>"
6588
  msgstr ""
@@ -6599,14 +9646,6 @@ msgstr ""
6599
  msgid "Update<span class=\"wf-hidden-xs\"> Block</span>"
6600
  msgstr ""
6601
 
6602
- #: views/blocking/blocking-create.php:14
6603
- #: views/reports/activity-report-email-inline.php:139
6604
- #: views/reports/activity-report-email-inline.php:193
6605
- #: views/reports/activity-report.php:17
6606
- #: views/reports/activity-report.php:61
6607
- msgid "Country"
6608
- msgstr ""
6609
-
6610
  #: views/blocking/blocking-create.php:15
6611
  msgid "Block<span class=\"wf-hidden-xs\"> Visitors Matching this Pattern</span>"
6612
  msgstr ""
@@ -6639,8 +9678,9 @@ msgstr ""
6639
  msgid "<span class=\"wf-hidden-xs\">Block access to the rest of the site</span><span class=\"wf-visible-xs\">Rest of site</span>"
6640
  msgstr ""
6641
 
 
6642
  #: views/blocking/blocking-create.php:149
6643
- msgid "If you use Google Adwords, blocking countries from accessing the entire site is not recommended. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
6644
  msgstr ""
6645
 
6646
  #: views/blocking/blocking-create.php:153
@@ -6709,6 +9749,10 @@ msgstr ""
6709
  msgid "Manage global blocking options."
6710
  msgstr ""
6711
 
 
 
 
 
6712
  #: views/blocking/country-modal.php:24
6713
  msgid "Select Countries to Block from List"
6714
  msgstr ""
@@ -6801,6 +9845,7 @@ msgstr ""
6801
  msgid "The Wordfence license provided has been installed."
6802
  msgstr ""
6803
 
 
6804
  #: views/common/license.php:106
6805
  msgid "Return to the <a href=\"%s\">Wordfence Admin Page</a>"
6806
  msgstr ""
@@ -6823,8 +9868,12 @@ msgstr ""
6823
  msgid "Your computer's time: "
6824
  msgstr ""
6825
 
6826
- #: views/common/status-tooltip.php:18
6827
- msgid "<strong>Congratulations!</strong> You've optimized configurations for this feature! If you want to learn more about how this score is determined, click the link below."
 
 
 
 
6828
  msgstr ""
6829
 
6830
  #: views/common/status-tooltip.php:19
@@ -6864,6 +9913,7 @@ msgstr ""
6864
  msgid "Please enter an email address to unsubscribe from alerts. If this email address exists on the alert email list, it will receive a confirmation link to unsubscribe."
6865
  msgstr ""
6866
 
 
6867
  #: views/common/unsubscribe.php:120
6868
  msgid "Please confirm the unsubscribe request for %s."
6869
  msgstr ""
@@ -6896,6 +9946,14 @@ msgstr ""
6896
  msgid "Use the Cloudflare \"CF-Connecting-IP\" HTTP header to get a visitor IP. Only use if you're using Cloudflare."
6897
  msgstr ""
6898
 
 
 
 
 
 
 
 
 
6899
  #: views/dashboard/option-howgetips.php:51
6900
  msgid "These IPs (or CIDR ranges) will be ignored when determining the requesting IP via the X-Forwarded-For HTTP header. Enter one IP or CIDR range per line."
6901
  msgstr ""
@@ -6911,28 +9969,28 @@ msgstr ""
6911
  #: views/dashboard/options-group-alert.php:73
6912
  #: views/scanner/issue-base.php:32
6913
  #: views/scanner/issue-base.php:41
6914
- #: views/scanner/issue-base.php:89
6915
  msgid "Critical"
6916
  msgstr ""
6917
 
6918
  #: views/dashboard/options-group-alert.php:74
6919
  #: views/scanner/issue-base.php:33
6920
  #: views/scanner/issue-base.php:42
6921
- #: views/scanner/issue-base.php:92
6922
  msgid "High"
6923
  msgstr ""
6924
 
6925
  #: views/dashboard/options-group-alert.php:75
6926
  #: views/scanner/issue-base.php:34
6927
  #: views/scanner/issue-base.php:43
6928
- #: views/scanner/issue-base.php:95
6929
  msgid "Medium"
6930
  msgstr ""
6931
 
6932
  #: views/dashboard/options-group-alert.php:76
6933
  #: views/scanner/issue-base.php:35
6934
  #: views/scanner/issue-base.php:44
6935
- #: views/scanner/issue-base.php:98
6936
  msgid "Low"
6937
  msgstr ""
6938
 
@@ -7125,16 +10183,6 @@ msgstr ""
7125
  msgid "Name"
7126
  msgstr ""
7127
 
7128
- #: views/diagnostics/text.php:225
7129
- #: views/diagnostics/text.php:263
7130
- #: views/diagnostics/text.php:317
7131
- #: views/diagnostics/text.php:337
7132
- #: views/scanner/issue-base.php:52
7133
- #: views/scanner/issue-wafStatus.php:12
7134
- #: views/scanner/issue-wafStatus.php:21
7135
- msgid "Status"
7136
- msgstr ""
7137
-
7138
  #: views/diagnostics/text.php:381
7139
  msgid "Run Time"
7140
  msgstr ""
@@ -7143,6 +10191,11 @@ msgstr ""
7143
  msgid "Job"
7144
  msgstr ""
7145
 
 
 
 
 
 
7146
  #: views/gdpr/banner.php:8
7147
  msgid "Wordfence's terms of use and privacy policy have changed"
7148
  msgstr ""
@@ -7181,10 +10234,12 @@ msgstr ""
7181
  msgid "Wordfence - Securing your WordPress Website"
7182
  msgstr ""
7183
 
 
7184
  #: views/onboarding/fresh-install.php:10
7185
  msgid "You have successfully installed Wordfence %s"
7186
  msgstr ""
7187
 
 
7188
  #: views/onboarding/fresh-install.php:11
7189
  #: views/onboarding/modal-final-attempt.php:18
7190
  #: views/onboarding/plugin-header.php:32
@@ -7215,6 +10270,7 @@ msgstr ""
7215
  msgid "By checking this box, I agree to the Wordfence <a href=\"https://www.wordfence.com/terms-of-use/\" target=\"_blank\" rel=\"noopener noreferrer\">terms</a> and <a href=\"https://www.wordfence.com/privacy-policy/\" target=\"_blank\" rel=\"noopener noreferrer\">privacy policy</a>"
7216
  msgstr ""
7217
 
 
7218
  #: views/onboarding/fresh-install.php:28
7219
  #: views/onboarding/modal-final-attempt.php:57
7220
  #: views/onboarding/plugin-header.php:59
@@ -7333,171 +10389,164 @@ msgstr ""
7333
  msgid "Collapse All"
7334
  msgstr ""
7335
 
7336
- #: views/reports/activity-report-email-inline.php:11
7337
- msgid "Wordfence activity from <br><strong>%s</strong> to <strong>%s</strong>"
 
7338
  msgstr ""
7339
 
7340
- #: views/reports/activity-report-email-inline.php:126
7341
- msgid "This email was sent from your website <a href=\"%s\">%s</a> and is a summary of security related activity that Wordfence monitors for the period %s to %s."
 
7342
  msgstr ""
7343
 
7344
- #: views/reports/activity-report-email-inline.php:126
7345
  msgid "NOTE: You are using the free version of Wordfence and are missing out on features like cellphone sign-in, country blocking and detecting if your site IP is sending spam. <a href=\"http://www.wordfence.com/zz6/\">Click here to upgrade to Wordfence Premium now</a>."
7346
  msgstr ""
7347
 
7348
- #: views/reports/activity-report-email-inline.php:130
7349
- msgid "Top 10 IPs Blocked"
7350
- msgstr ""
7351
-
7352
  #: views/reports/activity-report-email-inline.php:138
7353
- #: views/reports/activity-report.php:16
7354
- #: views/waf/option-whitelist.php:110
7355
- #: views/waf/options-group-whitelisted.php:87
7356
- #: views/waf/options-group-whitelisted.php:100
7357
- msgid "IP"
7358
  msgstr ""
7359
 
7360
- #: views/reports/activity-report-email-inline.php:166
7361
- #: views/reports/activity-report-email-inline.php:220
7362
  #: views/reports/activity-report.php:34
7363
  #: views/reports/activity-report.php:78
7364
  msgid "(Unknown)"
7365
  msgstr ""
7366
 
7367
- #: views/reports/activity-report-email-inline.php:175
7368
- #: views/reports/activity-report-email-inline.php:230
7369
  msgid "No data currently."
7370
  msgstr ""
7371
 
7372
- #: views/reports/activity-report-email-inline.php:183
7373
  #: views/reports/activity-report.php:51
7374
  msgid "Update Blocked IPs"
7375
  msgstr ""
7376
 
7377
- #: views/reports/activity-report-email-inline.php:188
7378
  msgid "Top 10 Countries Blocked"
7379
  msgstr ""
7380
 
7381
- #: views/reports/activity-report-email-inline.php:194
7382
  #: views/reports/activity-report.php:62
7383
  msgid "Total IPs Blocked"
7384
  msgstr ""
7385
 
7386
- #: views/reports/activity-report-email-inline.php:238
7387
  #: views/reports/activity-report.php:96
7388
  msgid "Update Blocked Countries"
7389
  msgstr ""
7390
 
7391
- #: views/reports/activity-report-email-inline.php:243
7392
  msgid "Top 10 Failed Logins"
7393
  msgstr ""
7394
 
7395
- #: views/reports/activity-report-email-inline.php:248
7396
- #: views/reports/activity-report.php:106
7397
- msgid "Username"
7398
- msgstr ""
7399
-
7400
- #: views/reports/activity-report-email-inline.php:249
7401
- #: views/reports/activity-report.php:107
7402
- msgid "Login Attempts"
7403
- msgstr ""
7404
-
7405
- #: views/reports/activity-report-email-inline.php:250
7406
  #: views/reports/activity-report.php:108
7407
  msgid "Existing User"
7408
  msgstr ""
7409
 
7410
- #: views/reports/activity-report-email-inline.php:268
7411
  #: views/reports/activity-report.php:123
7412
  msgid "No failed logins yet."
7413
  msgstr ""
7414
 
7415
- #: views/reports/activity-report-email-inline.php:276
7416
  #: views/reports/activity-report.php:131
7417
  msgid "Update Login Security Options"
7418
  msgstr ""
7419
 
7420
- #: views/reports/activity-report-email-inline.php:281
7421
  msgid "Recently Blocked Attacks"
7422
  msgstr ""
7423
 
7424
- #: views/reports/activity-report-email-inline.php:287
7425
  msgid "IP / Action"
7426
  msgstr ""
7427
 
7428
- #: views/reports/activity-report-email-inline.php:308
7429
  msgid "No blocked attacks yet."
7430
  msgstr ""
7431
 
7432
- #: views/reports/activity-report-email-inline.php:318
7433
  msgid "and %d additional attacks"
7434
  msgstr ""
7435
 
7436
- #: views/reports/activity-report-email-inline.php:322
7437
  msgid "View Recent Traffic"
7438
  msgstr ""
7439
 
7440
- #: views/reports/activity-report-email-inline.php:327
7441
  msgid "Recently Modified Files"
7442
  msgstr ""
7443
 
7444
- #: views/reports/activity-report-email-inline.php:332
7445
  msgid "Modified"
7446
  msgstr ""
7447
 
7448
- #: views/reports/activity-report-email-inline.php:353
7449
  msgid "This list may include WordPress core/plugin/theme updates, error logs, cache files, and other normal changes."
7450
  msgstr ""
7451
 
7452
- #: views/reports/activity-report-email-inline.php:357
7453
  #: views/reports/activity-report.php:164
7454
  msgid "Updates Needed"
7455
  msgstr ""
7456
 
7457
- #: views/reports/activity-report-email-inline.php:365
7458
  #: views/reports/activity-report.php:172
7459
  msgid "Core"
7460
  msgstr ""
7461
 
7462
- #: views/reports/activity-report-email-inline.php:367
 
7463
  #: views/reports/activity-report.php:174
7464
  msgid "A new version of WordPress (v%s) is available."
7465
  msgstr ""
7466
 
7467
- #: views/reports/activity-report-email-inline.php:371
7468
  #: views/reports/activity-report.php:178
7469
  msgid "Plugins"
7470
  msgstr ""
7471
 
7472
- #: views/reports/activity-report-email-inline.php:378
 
 
7473
  #: views/reports/activity-report.php:185
7474
  msgid "A new version of the plugin \"%s\" is available."
7475
  msgstr ""
7476
 
7477
- #: views/reports/activity-report-email-inline.php:378
7478
- #: views/reports/activity-report-email-inline.php:391
 
 
7479
  msgid "<strong>This update includes security-related fixes.</strong>"
7480
  msgstr ""
7481
 
7482
- #: views/reports/activity-report-email-inline.php:391
 
 
7483
  #: views/reports/activity-report.php:198
7484
  msgid "A new version of the theme \"%s\" is available."
7485
  msgstr ""
7486
 
7487
- #: views/reports/activity-report-email-inline.php:399
7488
  #: views/reports/activity-report.php:205
7489
  msgid "Update Now"
7490
  msgstr ""
7491
 
7492
- #: views/reports/activity-report-email-inline.php:403
7493
  #: views/reports/activity-report.php:207
7494
  msgid "No updates are available at this time."
7495
  msgstr ""
7496
 
7497
- #: views/reports/activity-report-email-inline.php:408
7498
- msgid "If you would like to sign-in to <a href=\"%s\">%s</a> please <a href=\"%s\">click here</a> now. You can change the frequency of this email or turn it on and off by visiting your <a href=\"%s\">Wordfence options page</a>."
 
7499
  msgstr ""
7500
 
 
7501
  #: views/reports/activity-report.php:9
7502
  msgid "Top %d IPs Blocked"
7503
  msgstr ""
@@ -7506,6 +10555,7 @@ msgstr ""
7506
  msgid "No IPs blocked yet."
7507
  msgstr ""
7508
 
 
7509
  #: views/reports/activity-report.php:56
7510
  msgid "Top %d Countries Blocked"
7511
  msgstr ""
@@ -7514,19 +10564,16 @@ msgstr ""
7514
  msgid "No requests blocked yet."
7515
  msgstr ""
7516
 
 
7517
  #: views/reports/activity-report.php:101
7518
  msgid "Top %d Failed Logins"
7519
  msgstr ""
7520
 
 
7521
  #: views/reports/activity-report.php:210
7522
  msgid "Generated in %.4f seconds"
7523
  msgstr ""
7524
 
7525
- #: views/scanner/issue-base.php:29
7526
- #: views/scanner/issue-base.php:39
7527
- msgid "Type:"
7528
- msgstr ""
7529
-
7530
  #: views/scanner/issue-base.php:31
7531
  msgid "Issue Found "
7532
  msgstr ""
@@ -7540,7 +10587,7 @@ msgid "New"
7540
  msgstr ""
7541
 
7542
  #: views/scanner/issue-base.php:52
7543
- #: views/scanner/issue-base.php:83
7544
  msgid "Ignored"
7545
  msgstr ""
7546
 
@@ -7552,33 +10599,16 @@ msgstr ""
7552
  msgid "ago"
7553
  msgstr ""
7554
 
7555
- #: views/scanner/issue-base.php:85
 
7556
  msgid "Issue Found: %s"
7557
  msgstr ""
7558
 
7559
- #: views/scanner/issue-base.php:105
 
7560
  msgid "Severity: %s"
7561
  msgstr ""
7562
 
7563
- #: views/scanner/issue-checkGSB.php:8
7564
- #: views/scanner/issue-commentBadURL.php:8
7565
- #: views/scanner/issue-configReadable.php:12
7566
- #: views/scanner/issue-configReadable.php:23
7567
- #: views/scanner/issue-optionBadURL.php:8
7568
- #: views/scanner/issue-postBadURL.php:8
7569
- #: views/scanner/issue-publiclyAccessible.php:12
7570
- #: views/scanner/issue-publiclyAccessible.php:23
7571
- #: views/scanner/issue-wpscan_directoryList.php:12
7572
- #: views/scanner/issue-wpscan_directoryList.php:23
7573
- #: views/scanner/issue-wpscan_fullPathDiscl.php:12
7574
- #: views/scanner/issue-wpscan_fullPathDiscl.php:23
7575
- #: views/waf/option-whitelist.php:9
7576
- #: views/waf/option-whitelist.php:106
7577
- #: views/waf/options-group-whitelisted.php:82
7578
- #: views/waf/options-group-whitelisted.php:95
7579
- msgid "URL"
7580
- msgstr ""
7581
-
7582
  #: views/scanner/issue-checkGSB.php:10
7583
  #: views/scanner/issue-checkHowGetIPs.php:10
7584
  #: views/scanner/issue-checkSpamIP.php:10
@@ -8037,23 +11067,6 @@ msgstr ""
8037
  msgid "Plugin URL"
8038
  msgstr ""
8039
 
8040
- #: views/scanner/issue-wfPluginAbandoned.php:18
8041
- #: views/scanner/issue-wfPluginAbandoned.php:19
8042
- #: views/scanner/issue-wfPluginAbandoned.php:20
8043
- #: views/scanner/issue-wfPluginRemoved.php:17
8044
- #: views/scanner/issue-wfPluginRemoved.php:18
8045
- #: views/scanner/issue-wfPluginUpgrade.php:18
8046
- #: views/scanner/issue-wfPluginUpgrade.php:19
8047
- #: views/scanner/issue-wfPluginUpgrade.php:20
8048
- #: views/scanner/issue-wfPluginVulnerable.php:17
8049
- #: views/scanner/issue-wfPluginVulnerable.php:18
8050
- #: views/scanner/issue-wfPluginVulnerable.php:19
8051
- #: views/scanner/issue-wfThemeUpgrade.php:18
8052
- #: views/scanner/issue-wfThemeUpgrade.php:19
8053
- #: views/scanner/issue-wfUpgrade.php:17
8054
- msgid "View"
8055
- msgstr ""
8056
-
8057
  #: views/scanner/issue-wfPluginAbandoned.php:19
8058
  #: views/scanner/issue-wfPluginAbandoned.php:36
8059
  #: views/scanner/issue-wfPluginUpgrade.php:36
@@ -8158,8 +11171,8 @@ msgstr ""
8158
  msgid "Directory Listing Enabled"
8159
  msgstr ""
8160
 
8161
- #: views/scanner/issue-wpscan_fullPathDiscl.php:8
8162
- msgid "Full Path Disclosure"
8163
  msgstr ""
8164
 
8165
  #: views/scanner/options-group-advanced.php:23
@@ -8200,10 +11213,12 @@ msgstr ""
8200
  msgid "0 or empty means unlimited issues will be sent"
8201
  msgstr ""
8202
 
 
8203
  #: views/scanner/options-group-performance.php:34
8204
  msgid "0 or empty means the default of %s will be used"
8205
  msgstr ""
8206
 
 
8207
  #: views/scanner/options-group-performance.php:35
8208
  msgid "Memory size in megabytes"
8209
  msgstr ""
@@ -8212,6 +11227,7 @@ msgstr ""
8212
  msgid "Maximum execution time for each scan stage "
8213
  msgstr ""
8214
 
 
8215
  #: views/scanner/options-group-performance.php:36
8216
  msgid "0 for default. Must be %d or greater and 10-20 or higher is recommended for most servers"
8217
  msgstr ""
@@ -8484,7 +11500,7 @@ msgid "Wordfence Scan Enabled"
8484
  msgstr ""
8485
 
8486
  #: views/scanner/scanner-status.php:54
8487
- msgid "As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by an additional %d firewall rules and malware signatures as well as the Wordfence real-time IP blocklist. Upgrade to Premium today to improve your protection."
8488
  msgstr ""
8489
 
8490
  #: views/scanner/scanner-status.php:60
@@ -8508,11 +11524,11 @@ msgid "Get Help"
8508
  msgstr ""
8509
 
8510
  #: views/scanner/site-cleaning-bottom.php:12
8511
- msgid "Need help from a web security expert?"
8512
  msgstr ""
8513
 
8514
  #: views/scanner/site-cleaning-bottom.php:13
8515
- msgid "Whether you want to proactively lock your site down or it has already been hacked, we're here to help. All services include a detailed report and a 90-day guarantee for an affordable price. <strong class=\"wf-blue\">Includes a 1-year Premium license.</strong>"
8516
  msgstr ""
8517
 
8518
  #: views/scanner/site-cleaning-bottom.php:15
@@ -8543,14 +11559,17 @@ msgstr ""
8543
  msgid "Two-Factor Authentication Options"
8544
  msgstr ""
8545
 
 
8546
  #: views/tools/options-group-2fa.php:51
8547
  msgid "<strong>Require Cellphone Sign-in for all Administrators<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wfhelp wf-inline-help\"></a></strong><br><em>Note:</em> This setting requires at least one administrator to have Cellphone Sign-in enabled. On multisite, this option applies only to super admins."
8548
  msgstr ""
8549
 
 
8550
  #: views/tools/options-group-2fa.php:63
8551
  msgid "<strong>Enable Separate Prompt for Two-Factor Code<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wfhelp wf-inline-help\"></a></strong><br><em>Note:</em> This setting changes the behavior for obtaining the two-factor authentication code from using the password field to showing a separate prompt. If your theme overrides the default login page, you may not be able to use this option."
8552
  msgstr ""
8553
 
 
8554
  #: views/tools/options-group-2fa.php:64
8555
  msgid "<br><strong>This setting will be ignored because the PHP configuration option <code>output_buffering</code> is off.</strong>"
8556
  msgstr ""
@@ -8615,6 +11634,11 @@ msgstr ""
8615
  msgid "Done"
8616
  msgstr ""
8617
 
 
 
 
 
 
8618
  #: views/waf/firewall-status.php:16
8619
  msgid "Wordfence Firewall &amp; Premium Enabled"
8620
  msgstr ""
@@ -8639,10 +11663,12 @@ msgstr ""
8639
  msgid "Learning Mode Enabled"
8640
  msgstr ""
8641
 
 
8642
  #: views/waf/firewall-status.php:56
8643
  msgid "Learning Mode Until %s"
8644
  msgstr ""
8645
 
 
8646
  #: views/waf/firewall-status.php:57
8647
  msgid "<i class=\"wf-fa wf-fa-lightbulb-o wf-tip\" aria-hidden=\"true\"></i> When you first install the Wordfence Web Application Firewall, it will be in learning mode. This allows Wordfence to learn about your site so that we can understand how to protect it and how to allow normal visitors through the firewall. We recommend you let Wordfence learn for a week before you enable the firewall."
8648
  msgstr ""
@@ -8704,15 +11730,7 @@ msgid "Allowlist Entry Exists"
8704
  msgstr ""
8705
 
8706
  #: views/waf/option-whitelist.php:53
8707
- msgid "A allowlist entry for this URL and parameter already exists."
8708
- msgstr ""
8709
-
8710
- #: views/waf/option-whitelist.php:60
8711
- msgid "Allowlisted via Firewall Options page"
8712
- msgstr ""
8713
-
8714
- #: views/waf/option-whitelist.php:102
8715
- msgid "Delete"
8716
  msgstr ""
8717
 
8718
  #: views/waf/option-whitelist.php:102
@@ -8731,12 +11749,6 @@ msgstr ""
8731
  msgid "Source"
8732
  msgstr ""
8733
 
8734
- #: views/waf/option-whitelist.php:109
8735
- #: views/waf/options-group-whitelisted.php:86
8736
- #: views/waf/options-group-whitelisted.php:99
8737
- msgid "User"
8738
- msgstr ""
8739
-
8740
  #: views/waf/option-whitelist.php:112
8741
  msgid "Filter Value"
8742
  msgstr ""
@@ -8750,7 +11762,7 @@ msgid "You are currently running the WAF from another WordPress installation. Th
8750
  msgstr ""
8751
 
8752
  #: views/waf/options-group-advanced-firewall.php:54
8753
- msgid "Allowlisted IPs must be separated by commas or placed on separate lines. You can specify ranges using the following formats: 127.0.0.1/24, 127.0.0.[1-100], or 127.0.0.1-127.0.1.100<br/>Wordfence automatically whitelists <a href=\"http://en.wikipedia.org/wiki/Private_network\" target=\"_blank\" rel=\"noopener noreferrer\">private networks</a> because these are not routable on the public Internet."
8754
  msgstr ""
8755
 
8756
  #: views/waf/options-group-advanced-firewall.php:101
@@ -8781,6 +11793,7 @@ msgstr ""
8781
  msgid "Basic Firewall Options"
8782
  msgstr ""
8783
 
 
8784
  #: views/waf/options-group-basic-firewall.php:36
8785
  #: views/waf/options-group-basic-firewall.php:469
8786
  #: views/waf/options-group-whitelisted.php:35
@@ -8799,14 +11812,17 @@ msgstr ""
8799
  msgid "Learning Mode:"
8800
  msgstr ""
8801
 
 
8802
  #: views/waf/options-group-basic-firewall.php:41
8803
  msgid "When you first install the Wordfence Web Application Firewall, it will be in learning mode. This allows Wordfence to learn about your site so that we can understand how to protect it and how to allow normal visitors through the firewall. We recommend you let Wordfence learn for a week before you enable the firewall. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
8804
  msgstr ""
8805
 
 
8806
  #: views/waf/options-group-basic-firewall.php:42
8807
  msgid "Disabled:"
8808
  msgstr ""
8809
 
 
8810
  #: views/waf/options-group-basic-firewall.php:42
8811
  msgid "In this mode, the Wordfence Web Application Firewall is functionally turned off and does not run any of its rules or analyze the request in any way."
8812
  msgstr ""
@@ -8831,10 +11847,12 @@ msgstr ""
8831
  msgid "All PHP requests will be processed by the firewall prior to running."
8832
  msgstr ""
8833
 
 
8834
  #: views/waf/options-group-basic-firewall.php:168
8835
  msgid "If you're moving to a new host or a new installation location, you may need to temporarily disable extended protection to avoid any file not found errors. Use this action to remove the configuration changes that enable extended protection mode or you can <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">remove them manually</a>."
8836
  msgstr ""
8837
 
 
8838
  #: views/waf/options-group-basic-firewall.php:169
8839
  msgid "Remove Extended Protection"
8840
  msgstr ""
@@ -8860,6 +11878,10 @@ msgstr ""
8860
  msgid "The plugin will load as a regular plugin after WordPress has been loaded, and while it can block many malicious requests, some vulnerable plugins or WordPress itself may run vulnerable code before all plugins are loaded."
8861
  msgstr ""
8862
 
 
 
 
 
8863
  #: views/waf/options-group-basic-firewall.php:466
8864
  msgid "Premium Feature:"
8865
  msgstr ""
@@ -8905,7 +11927,7 @@ msgstr ""
8905
  msgid "Prevent discovery of usernames through '/?author=N' scans, the oEmbed API, the WordPress REST API, and WordPress XML Sitemaps"
8906
  msgstr ""
8907
 
8908
- #: views/waf/options-group-brute-force.php:238
8909
  msgid "HTML tags will be stripped prior to output and line breaks will be converted into the appropriate tags."
8910
  msgstr ""
8911
 
@@ -8925,6 +11947,7 @@ msgstr ""
8925
  msgid "Treat Google like any other Crawler"
8926
  msgstr ""
8927
 
 
8928
  #: views/waf/options-group-rate-limiting.php:68
8929
  #: views/waf/options-group-rate-limiting.php:69
8930
  #: views/waf/options-group-rate-limiting.php:70
@@ -8992,6 +12015,7 @@ msgstr ""
8992
  msgid "No allowlisted URLs currently set."
8993
  msgstr ""
8994
 
 
8995
  #: views/waf/status-tooltip-learning-mode.php:6
8996
  msgid "The Web Application Firewall is currently in Learning Mode. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
8997
  msgstr ""
@@ -9000,21 +12024,21 @@ msgstr ""
9000
  msgid "The required file has been created. You'll need to insert the following code into your <code>php.ini</code> to finish installation:"
9001
  msgstr ""
9002
 
 
9003
  #: views/waf/waf-install-manual.php:12
9004
  msgid "You can find more details on alternative setup steps, including installation on SiteGround or for multiple sites sharing a single php.ini, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">in our documentation</a>."
9005
  msgstr ""
9006
 
9007
- #: views/waf/waf-install-success.php:14
9008
- msgid "Nice work! The firewall is now optimized."
9009
  msgstr ""
9010
 
9011
- #: views/waf/waf-install-success.php:16
9012
- #: views/waf/waf-uninstall-success.php:19
9013
- msgid "The changes have not yet taken effect. If you are using LiteSpeed or IIS as your web server or CGI/FastCGI interface, you may need to wait a few minutes for the changes to take effect since the configuration files are sometimes cached. You also may need to select a different server configuration in order to complete this step, but wait for a few minutes before trying. You can try refreshing this page."
9014
  msgstr ""
9015
 
9016
- #: views/waf/waf-install.php:9
9017
- msgid "Optimize Wordfence Firewall"
9018
  msgstr ""
9019
 
9020
  #: views/waf/waf-install.php:22
@@ -9026,108 +12050,96 @@ msgid "To make your site as secure as possible, the Wordfence Web Application Fi
9026
  msgstr ""
9027
 
9028
  #: views/waf/waf-install.php:26
9029
- msgid ""
9030
- "If you don't recognize this file, please <a href=\"https://wordpress.org/support/plugin/wordfence\" target=\"_blank\" rel=\"noopener noreferrer\">contact us on the\n"
9031
- "\t\t\t\t\tWordPress support forums</a> before proceeding."
9032
  msgstr ""
9033
 
9034
- #: views/waf/waf-install.php:28
9035
  msgid "You can proceed with the installation and we will include this from within our <code>wordfence-waf.php</code> file which should maintain compatibility with your site, or you can opt to override the existing PHP setting."
9036
  msgstr ""
9037
 
9038
- #: views/waf/waf-install.php:29
9039
  msgid "Include"
9040
  msgstr ""
9041
 
9042
- #: views/waf/waf-install.php:29
9043
  msgid "Override"
9044
  msgstr ""
9045
 
9046
- #: views/waf/waf-install.php:31
9047
  msgid "NOTE:"
9048
  msgstr ""
9049
 
9050
- #: views/waf/waf-install.php:31
9051
  msgid "If you have separate WordPress installations with Wordfence installed within a subdirectory of this site, it is recommended that you perform the Firewall installation procedure on those sites before this one."
9052
  msgstr ""
9053
 
9054
- #: views/waf/waf-install.php:35
9055
  #: views/waf/waf-uninstall.php:40
9056
  msgid "Apache + mod_php"
9057
  msgstr ""
9058
 
9059
- #: views/waf/waf-install.php:36
9060
  #: views/waf/waf-uninstall.php:41
9061
  msgid "Apache + suPHP"
9062
  msgstr ""
9063
 
9064
- #: views/waf/waf-install.php:37
9065
  #: views/waf/waf-uninstall.php:42
9066
  msgid "Apache + CGI/FastCGI"
9067
  msgstr ""
9068
 
9069
- #: views/waf/waf-install.php:38
9070
  #: views/waf/waf-uninstall.php:43
9071
  msgid "LiteSpeed/lsapi"
9072
  msgstr ""
9073
 
9074
- #: views/waf/waf-install.php:39
9075
  #: views/waf/waf-uninstall.php:44
9076
  msgid "NGINX"
9077
  msgstr ""
9078
 
9079
- #: views/waf/waf-install.php:40
9080
  #: views/waf/waf-uninstall.php:45
9081
  msgid "Windows (IIS)"
9082
  msgstr ""
9083
 
9084
- #: views/waf/waf-install.php:41
9085
  msgid "Manual Configuration"
9086
  msgstr ""
9087
 
9088
- #: views/waf/waf-install.php:55
9089
- #: views/waf/waf-uninstall.php:59
9090
  msgid "If you know your web server's configuration, please select it from the list below."
9091
  msgstr ""
9092
 
9093
- #: views/waf/waf-install.php:57
9094
  msgid "We've preselected your server configuration based on our tests, but if you know your web server's configuration, please select it now. You can also choose \"Manual Configuration\" for alternate installation details."
9095
  msgstr ""
9096
 
9097
- #: views/waf/waf-install.php:62
9098
- msgid "Part of the Firewall configuration procedure for NGINX depends on creating a <code>%s</code> file in the root of your WordPress installation. This file can contain sensitive information and public access to it should be restricted. We have <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">instructions on our documentation site</a> on what directives to put in your nginx.conf to fix this."
 
9099
  msgstr ""
9100
 
9101
- #: views/waf/waf-install.php:62
9102
- msgid "(.user.ini)"
9103
- msgstr ""
9104
-
9105
- #: views/waf/waf-install.php:64
9106
  msgid "If you are using a web server not listed in the dropdown or if file permissions prevent the installer from completing successfully, you will need to perform the change manually. Click Continue below to create the required file and view manual installation instructions."
9107
  msgstr ""
9108
 
9109
- #: views/waf/waf-install.php:85
9110
- #: views/waf/waf-uninstall.php:85
9111
  msgid "Please download a backup of the following files before we make the necessary changes:"
9112
  msgstr ""
9113
 
9114
- #: views/waf/waf-install.php:95
9115
- #: views/waf/waf-uninstall.php:95
 
9116
  msgid "Download %s"
9117
  msgstr ""
9118
 
9119
- #: views/waf/waf-install.php:104
9120
  msgid "Once you have downloaded the files, click Continue to complete the setup."
9121
  msgstr ""
9122
 
9123
- #: views/waf/waf-uninstall-success.php:15
9124
- msgid "Uninstallation was successful!"
9125
- msgstr ""
9126
-
9127
- #: views/waf/waf-uninstall-success.php:17
9128
- msgid "Uninstallation from this site was successful! The Wordfence Firewall is still active because it is installed in another WordPress installation."
9129
- msgstr ""
9130
-
9131
  #: views/waf/waf-uninstall.php:9
9132
  msgid "Uninstall Wordfence Firewall"
9133
  msgstr ""
@@ -9136,6 +12148,7 @@ msgstr ""
9136
  msgid "Extended Protection Mode of the Wordfence Web Application Firewall uses the PHP ini setting called <code>auto_prepend_file</code> in order to ensure it runs before any potentially vulnerable code runs. This PHP setting currently refers to the Wordfence file at:"
9137
  msgstr ""
9138
 
 
9139
  #: views/waf/waf-uninstall.php:34
9140
  msgid "Automatic uninstallation cannot be completed, but you may still be able to <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">manually uninstall extended protection</a>."
9141
  msgstr ""
@@ -9144,10 +12157,10 @@ msgstr ""
9144
  msgid "Before this file can be deleted, the configuration for the <code>auto_prepend_file</code> setting needs to be removed."
9145
  msgstr ""
9146
 
9147
- #: views/waf/waf-uninstall.php:61
9148
  msgid "We've preselected your server configuration based on our tests, but if you know your web server's configuration, please select it now."
9149
  msgstr ""
9150
 
9151
- #: views/waf/waf-uninstall.php:105
9152
  msgid "Once you have downloaded the files, click Continue to complete uninstallation."
9153
  msgstr ""
1
+ # Copyright (C) 2021 Wordfence
2
  # This file is distributed under the same license as the Wordfence Security plugin.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Wordfence Security 7.5.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/src\n"
7
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
  "Language-Team: LANGUAGE <LL@li.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2021-03-19T15:54:58+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
+ "X-Domain: wordfence\n"
16
 
17
+ #. Plugin Name of the plugin
18
+ msgid "Wordfence Security"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  msgstr ""
20
 
21
+ #. Plugin URI of the plugin
22
+ #. Author URI of the plugin
23
+ msgid "http://www.wordfence.com/"
 
 
 
24
  msgstr ""
25
 
26
+ #. Description of the plugin
27
+ msgid "Wordfence Security - Anti-virus, Firewall and Malware Scan"
 
 
 
 
28
  msgstr ""
29
 
30
+ #. Author of the plugin
31
+ msgid "Wordfence"
 
 
 
 
 
32
  msgstr ""
33
 
34
+ #: lib/dashboard/widget_content_countries.php:6
35
+ #: lib/dashboard/widget_content_ips.php:7
36
+ #: lib/dashboard/widget_ips.php:116
37
+ #: views/blocking/blocking-create.php:14
38
+ #: views/reports/activity-report-email-inline.php:147
39
+ #: views/reports/activity-report-email-inline.php:201
40
+ #: views/reports/activity-report.php:17
41
+ #: views/reports/activity-report.php:61
42
+ msgid "Country"
43
  msgstr ""
44
 
45
+ #: lib/dashboard/widget_content_countries.php:7
46
+ #: lib/dashboard/widget_content_ips.php:8
47
+ #: lib/dashboard/widget_ips.php:117
48
+ #: views/blocking/block-list.php:73
49
+ #: views/reports/activity-report-email-inline.php:148
50
+ #: views/reports/activity-report-email-inline.php:203
51
+ #: views/reports/activity-report.php:18
52
+ #: views/reports/activity-report.php:63
53
+ msgid "Block Count"
54
  msgstr ""
55
 
56
+ #: lib/dashboard/widget_content_ips.php:6
57
+ #: lib/dashboard/widget_content_logins.php:7
58
+ #: lib/dashboard/widget_ips.php:115
59
+ #: lib/dashboard/widget_logins.php:96
60
+ #: lib/wordfenceClass.php:6101
61
+ #: views/reports/activity-report-email-inline.php:146
62
+ #: views/reports/activity-report.php:16
63
+ #: views/waf/option-whitelist.php:110
64
+ #: views/waf/options-group-whitelisted.php:87
65
+ #: views/waf/options-group-whitelisted.php:100
66
+ msgid "IP"
67
  msgstr ""
68
 
69
+ #: lib/dashboard/widget_content_logins.php:6
70
+ #: lib/dashboard/widget_logins.php:95
71
+ #: lib/wordfenceClass.php:6176
72
+ #: views/reports/activity-report-email-inline.php:256
73
+ #: views/reports/activity-report.php:106
74
+ msgid "Username"
75
  msgstr ""
76
 
77
+ #: lib/dashboard/widget_content_logins.php:8
78
+ #: lib/dashboard/widget_logins.php:97
79
+ msgid "Date"
80
  msgstr ""
81
 
82
+ #: lib/dashboard/widget_countries.php:9
83
+ msgid "Top Countries by Number of Attacks - Last 7 Days"
 
84
  msgstr ""
85
 
86
+ #: lib/dashboard/widget_countries.php:16
87
+ #: lib/dashboard/widget_ips.php:21
88
+ #: lib/dashboard/widget_localattacks.php:17
89
+ msgid "No Data Available During Learning Mode"
90
  msgstr ""
91
 
92
+ #: lib/dashboard/widget_countries.php:25
93
+ #: lib/dashboard/widget_networkattacks.php:8
94
+ #: lib/wfDiagnostic.php:779
95
+ msgid "Wordfence Network"
96
  msgstr ""
97
 
98
+ #: lib/dashboard/widget_countries.php:31
99
+ #: lib/dashboard/widget_countries.php:38
100
+ #: lib/dashboard/widget_ips.php:35
101
+ #: lib/dashboard/widget_ips.php:45
102
+ #: lib/dashboard/widget_ips.php:55
103
+ #: lib/dashboard/widget_localattacks.php:32
104
+ msgid "No blocks have been recorded."
105
  msgstr ""
106
 
107
+ #: lib/dashboard/widget_ips.php:14
108
+ msgid "Top IPs Blocked"
 
109
  msgstr ""
110
 
111
+ #: lib/dashboard/widget_ips.php:28
112
+ #: lib/dashboard/widget_networkattacks.php:22
113
+ msgid "24 Hours"
114
  msgstr ""
115
 
116
+ #: lib/dashboard/widget_ips.php:29
117
+ msgid "7 Days"
118
  msgstr ""
119
 
120
+ #: lib/dashboard/widget_ips.php:30
121
+ #: lib/dashboard/widget_networkattacks.php:24
122
+ msgid "30 Days"
123
  msgstr ""
124
 
125
+ #: lib/dashboard/widget_ips.php:39
126
+ #: lib/dashboard/widget_ips.php:49
127
+ #: lib/dashboard/widget_ips.php:59
128
+ #: lib/dashboard/widget_logins.php:30
129
+ #: lib/dashboard/widget_logins.php:40
130
+ msgid "Show more"
131
  msgstr ""
132
 
133
+ #. translators: WordPress username.
134
+ #: lib/dashboard/widget_ips.php:96
135
+ #: lib/dashboard/widget_logins.php:77
136
+ #: lib/wordfenceClass.php:6047
137
+ msgid "An error occurred"
138
  msgstr ""
139
 
140
+ #: lib/dashboard/widget_ips.php:96
141
+ #: lib/dashboard/widget_logins.php:77
142
+ msgid "We encountered an error trying load more data."
 
143
  msgstr ""
144
 
145
  #: lib/dashboard/widget_localattacks.php:8
146
  msgid "Firewall Summary:"
147
  msgstr ""
148
 
149
+ #. translators: The site's domain name.
150
+ #: lib/dashboard/widget_localattacks.php:10
151
  msgid "Attacks Blocked for %s"
152
  msgstr ""
153
 
154
+ #: lib/dashboard/widget_localattacks.php:37
 
 
 
 
155
  #: views/blocking/blocking-create.php:10
156
  msgid "<span class=\"wf-hidden-xs\">Block </span>Type"
157
  msgstr ""
158
 
159
+ #: lib/dashboard/widget_localattacks.php:44
160
  msgid "Total"
161
  msgstr ""
162
 
163
+ #: lib/dashboard/widget_localattacks.php:49
164
  msgid "Today"
165
  msgstr ""
166
 
167
+ #: lib/dashboard/widget_localattacks.php:49
168
  msgid "Week"
169
  msgstr ""
170
 
171
+ #: lib/dashboard/widget_localattacks.php:49
172
  msgid "Month"
173
  msgstr ""
174
 
175
+ #: lib/dashboard/widget_localattacks.php:64
176
  #: lib/menu_firewall_waf.php:52
177
  #: lib/menu_firewall_waf_options.php:158
178
  #: lib/menu_scanner.php:77
180
  msgid "Premium"
181
  msgstr ""
182
 
183
+ #: lib/dashboard/widget_localattacks.php:70
184
  msgid "How are these categorized?"
185
  msgstr ""
186
 
187
+ #: lib/dashboard/widget_logins.php:9
188
+ #: views/reports/activity-report-email-inline.php:257
189
+ #: views/reports/activity-report.php:107
190
+ msgid "Login Attempts"
191
+ msgstr ""
192
+
193
+ #: lib/dashboard/widget_logins.php:20
194
+ msgid "Successful"
195
+ msgstr ""
196
+
197
+ #: lib/dashboard/widget_logins.php:21
198
+ msgid "Failed"
199
+ msgstr ""
200
+
201
+ #: lib/dashboard/widget_logins.php:26
202
+ msgid "No successful logins have been recorded."
203
+ msgstr ""
204
+
205
+ #: lib/dashboard/widget_logins.php:36
206
+ msgid "No failed logins have been recorded."
207
  msgstr ""
208
 
209
  #: lib/dashboard/widget_networkattacks.php:8
210
+ msgid "Total Attacks Blocked:"
 
211
  msgstr ""
212
 
213
  #: lib/dashboard/widget_networkattacks.php:17
214
  msgid "Blocked attack counts not available yet."
215
  msgstr ""
216
 
217
+ #: lib/dashboard/widget_networkattacks.php:33
218
+ msgid "Total Attacks"
219
  msgstr ""
220
 
221
+ #. translators: Time since. Example: 1 minute, 2 seconds
222
+ #: lib/dashboard/widget_networkattacks.php:209
223
+ msgid "Last Updated: %s ago"
224
  msgstr ""
225
 
226
+ #: lib/dashboard/widget_notifications.php:8
227
+ #: lib/wordfenceClass.php:6641
228
+ msgid "Notifications"
229
+ msgstr ""
230
+
231
+ #: lib/dashboard/widget_notifications.php:25
232
+ msgid "No notifications received"
233
  msgstr ""
234
 
235
  #: lib/dashboard/widget_notifications.php:37
237
  msgid "Wordfence Central Status"
238
  msgstr ""
239
 
240
+ #. translators: 1. Email address. 2. Localized date.
241
+ #: lib/dashboard/widget_notifications.php:42
242
+ msgid "Connected by %1$s on %2$s"
243
  msgstr ""
244
 
245
+ #. translators: 1. Email address. 2. Localized date.
246
+ #: lib/dashboard/widget_notifications.php:46
247
+ msgid "Disconnected by %1$s on %2$s"
248
  msgstr ""
249
 
250
+ #: lib/dashboard/widget_notifications.php:48
251
+ #: lib/menu_wordfence_central.php:107
252
  msgid "It looks like you've tried to connect this site to Wordfence Central, but the installation did not finish."
253
  msgstr ""
254
 
255
+ #: lib/dashboard/widget_notifications.php:50
256
  #: lib/menu_wordfence_central.php:58
257
+ #: lib/menu_wordfence_central.php:117
258
  msgid "Wordfence Central allows you to manage Wordfence on multiple sites from one location. It makes security monitoring and configuring Wordfence easier."
259
  msgstr ""
260
 
261
+ #: lib/dashboard/widget_notifications.php:58
262
+ #: lib/menu_wordfence_central.php:111
263
  #: views/onboarding/banner.php:9
264
  #: views/onboarding/disabled-overlay.php:8
265
  msgid "Resume Installation"
266
  msgstr ""
267
 
268
+ #: lib/dashboard/widget_notifications.php:59
269
+ #: lib/dashboard/widget_notifications.php:64
270
+ #: lib/menu_wordfence_central.php:68
271
  msgid "Disconnect This Site"
272
  msgstr ""
273
 
274
+ #: lib/dashboard/widget_notifications.php:66
275
+ msgid "Reconnect This Site"
276
+ msgstr ""
277
+
278
+ #: lib/dashboard/widget_notifications.php:66
279
+ msgid "Connect This Site"
280
+ msgstr ""
281
+
282
+ #: lib/dashboard/widget_notifications.php:69
283
  #: lib/menu_wordfence_central.php:59
284
  msgid "Visit Wordfence Central"
285
  msgstr ""
286
 
287
+ #: lib/dashboard/widget_notifications.php:132
288
  msgid "Confirm Disconnect"
289
  msgstr ""
290
 
291
+ #: lib/dashboard/widget_notifications.php:133
292
  msgid "Are you sure you want to disconnect your site from Wordfence Central?"
293
  msgstr ""
294
 
295
+ #. translators: Support URL.
296
+ #: lib/dashboard/widget_notifications.php:134
297
+ #: lib/menu_scanner.php:217
298
+ #: lib/menu_scanner.php:228
299
+ #: lib/menu_tools_diagnostic.php:981
300
  #: lib/menu_tools_twoFactor.php:235
301
  #: lib/menu_tools_twoFactor.php:273
302
+ #: lib/wordfenceClass.php:7931
303
+ #: lib/wordfenceClass.php:7975
304
+ #: lib/wordfenceClass.php:8039
305
+ #: lib/wordfenceClass.php:8099
306
+ #: lib/wordfenceClass.php:8145
307
  #: views/blocking/block-list.php:501
308
  #: views/blocking/blocking-create.php:212
309
  #: views/dashboard/options-group-license.php:150
312
  msgid "Cancel"
313
  msgstr ""
314
 
315
+ #: lib/dashboard/widget_notifications.php:135
316
  msgid "Disconnect"
317
  msgstr ""
318
 
319
+ #: lib/diffResult.php:9
320
+ msgid "Wordfence: Viewing File Differences"
321
+ msgstr ""
322
+
323
+ #: lib/diffResult.php:11
324
+ msgid "The two panels below show a before and after view of a file on your system that has been modified. The left panel shows the original file before modification. The right panel shows your version of the file that has been modified. Use this view to determine if a file has been modified by an attacker or if this is a change that you or another trusted person made. If you are happy with the modifications you see here, then you should choose to ignore this file the next time Wordfence scans your system."
325
+ msgstr ""
326
+
327
+ #: lib/diffResult.php:14
328
+ #: lib/wfViewResult.php:10
329
+ msgid "Filename:"
330
+ msgstr ""
331
+
332
+ #: lib/diffResult.php:15
333
+ msgid "File type:"
334
+ msgstr ""
335
+
336
+ #: lib/diffResult.php:18
337
+ msgid "WordPress Core File"
338
+ msgstr ""
339
+
340
+ #: lib/diffResult.php:20
341
+ msgid "Theme File"
342
  msgstr ""
343
 
344
+ #: lib/diffResult.php:21
345
+ msgid "Theme Name:"
346
+ msgstr ""
347
+
348
+ #: lib/diffResult.php:23
349
+ msgid "Theme Version:"
350
+ msgstr ""
351
+
352
+ #: lib/diffResult.php:25
353
+ msgid "Plugin File"
354
+ msgstr ""
355
+
356
+ #: lib/diffResult.php:26
357
+ msgid "Plugin Name:"
358
+ msgstr ""
359
+
360
+ #: lib/diffResult.php:27
361
+ msgid "Plugin Version:"
362
+ msgstr ""
363
+
364
+ #: lib/diffResult.php:29
365
+ msgid "Unknown Type"
366
+ msgstr ""
367
+
368
+ #: lib/diffResult.php:38
369
+ msgid "There are no differences between the original file and the file in the repository."
370
+ msgstr ""
371
+
372
+ #: lib/diffResult.php:44
373
+ msgid "&copy;&nbsp;%1$d to %2$d Wordfence &mdash; Visit <a href=\"http://wordfence.com/\">Wordfence.com</a> for help, security updates and more."
374
+ msgstr ""
375
+
376
+ #. translators: 1. Blog name/title. 2. Date.
377
  #: lib/email_genericAlert.php:4
378
+ msgid "This email was sent from your website \"%1$s\" by the Wordfence plugin at %2$s"
379
+ msgstr ""
380
+
381
+ #. translators: URL to the WordPress admin panel.
382
+ #: lib/email_genericAlert.php:8
383
  msgid "The Wordfence administrative URL for this site is: %s"
384
  msgstr ""
385
 
386
+ #: lib/email_genericAlert.php:14
387
  msgid ""
388
  "NOTE: You are using the free version of Wordfence. Upgrade today:\n"
389
  " - Receive real-time Firewall and Scan engine rule updates for protection as threats emerge\n"
398
  "https://www.wordfence.com/zz1/wordfence-signup/"
399
  msgstr ""
400
 
401
+ #. translators: URL to the WordPress admin panel.
402
+ #: lib/email_genericAlert.php:30
403
  msgid ""
404
  "To change your alert options for Wordfence, visit:\n"
405
  "%s"
406
  msgstr ""
407
 
408
+ #. translators: URL to the WordPress admin panel.
409
+ #: lib/email_genericAlert.php:34
410
  msgid ""
411
  "To see current Wordfence alerts, visit:\n"
412
  "%s"
413
  msgstr ""
414
 
415
+ #. translators: URL to the site's homepage.
 
 
 
 
 
 
 
416
  #: lib/email_newIssues.php:5
417
+ msgid "This email was sent from your website \"%s\" by the Wordfence plugin."
418
  msgstr ""
419
 
420
+ #. translators: 1. URL to the site's homepage. 2. Number of scan results.
421
+ #: lib/email_newIssues.php:12
422
+ msgid "Wordfence found the following new issues on \"%1$s\" (%2$d existing issue was also found again)."
423
+ msgid_plural "Wordfence found the following new issues on \"%1$s\" (%2$d existing issues were also found again)."
424
+ msgstr[0] ""
425
+ msgstr[1] ""
426
 
427
+ #. translators: 1. URL to the site's homepage.
428
+ #: lib/email_newIssues.php:22
429
+ msgid "Wordfence found the following new issues on \"%1$s\"."
430
  msgstr ""
431
 
432
+ #. translators: Localized date.
433
+ #: lib/email_newIssues.php:32
434
  msgid "Alert generated at %s"
435
  msgstr ""
436
 
437
+ #. translators: URL to WordPress admin panel.
438
+ #: lib/email_newIssues.php:38
439
  msgid "See the details of these scan results on your site at: %s"
440
  msgstr ""
441
 
442
+ #: lib/email_newIssues.php:42
443
  msgid "HIGH SENSITIVITY scanning is enabled, it may produce false positives"
444
  msgstr ""
445
 
446
+ #: lib/email_newIssues.php:48
447
  #: lib/menu_scanner.php:119
448
  msgid "Beta scan signatures are currently enabled. These signatures have not been fully tested yet and may cause false positives or scan stability issues on some sites."
449
  msgstr ""
450
 
451
+ #: lib/email_newIssues.php:48
452
  msgid "The Beta option can be turned off at the bottom of the Diagnostics page."
453
  msgstr ""
454
 
455
+ #. translators: 1. URL to WordPress admin panel. 2. URL to WordPress admin panel. 3. URL to Wordfence support page. 4. URL to Wordfence support page.
456
+ #: lib/email_newIssues.php:56
457
+ msgid "The scan was terminated early because it reached the time limit for scans. If you would like to allow your scans to run longer, you can customize the limit on the options page: <a href=\"%1$s\">%2$s</a> or read more about scan options to improve scan speed here: <a href=\"%3$s\">%4$s</a>"
458
  msgstr ""
459
 
460
+ #: lib/email_newIssues.php:62
461
  msgid "Critical Problems:"
462
  msgstr ""
463
 
464
+ #: lib/email_newIssues.php:63
465
  msgid "High Severity Problems:"
466
  msgstr ""
467
 
468
+ #: lib/email_newIssues.php:64
469
  msgid "Medium Severity Problems:"
470
  msgstr ""
471
 
472
+ #: lib/email_newIssues.php:65
473
  msgid "Low Severity Problems:"
474
  msgstr ""
475
 
476
+ #: lib/email_newIssues.php:84
477
  msgid "Plugin contains an unpatched security vulnerability."
478
  msgstr ""
479
 
480
+ #: lib/email_newIssues.php:86
481
+ #: lib/email_newIssues.php:108
482
  #: views/scanner/issue-wfPluginAbandoned.php:20
483
  #: views/scanner/issue-wfPluginAbandoned.php:37
484
  #: views/scanner/issue-wfPluginRemoved.php:18
494
  msgid "Vulnerability Information"
495
  msgstr ""
496
 
497
+ #: lib/email_newIssues.php:92
498
  msgid "The core files scan has not run because this version is not currently indexed by Wordfence. New WordPress versions may take up to a day to be indexed."
499
  msgstr ""
500
 
501
+ #: lib/email_newIssues.php:95
502
  msgid "Firewall issues may be caused by file permission changes or other technical problems."
503
  msgstr ""
504
 
505
+ #: lib/email_newIssues.php:95
506
  msgid "More Details and Instructions"
507
  msgstr ""
508
 
509
+ #: lib/email_newIssues.php:98
510
  msgid "Scanning additional paths is optional and is not always necessary."
511
  msgstr ""
512
 
513
+ #. translators: 1. WordPress version. 2. WordPress version.
514
+ #: lib/email_newIssues.php:98
515
+ #: lib/email_unlockRequest.php:14
516
+ #: lib/menu_dashboard.php:118
517
+ #: lib/menu_dashboard.php:478
518
+ #: lib/menu_dashboard_options.php:162
519
+ #: lib/wfVersionCheckController.php:68
520
+ #: lib/wfVersionCheckController.php:91
521
+ #: lib/wfVersionCheckController.php:167
522
+ #: lib/wfVersionCheckController.php:186
523
  #: views/blocking/blocking-status.php:27
524
  #: views/dashboard/options-group-dashboard.php:107
525
  #: views/gdpr/banner.php:55
535
  msgid "Learn More"
536
  msgstr ""
537
 
538
+ #: lib/email_newIssues.php:106
539
  #: views/scanner/issue-wfPluginUpgrade.php:16
540
  #: views/scanner/issue-wfPluginUpgrade.php:33
541
  #: views/scanner/issue-wfThemeUpgrade.php:16
545
  msgid "Update includes security-related fixes."
546
  msgstr ""
547
 
548
+ #: lib/email_newIssues.php:124
549
+ msgid "The malicious URL matched"
550
  msgstr ""
551
 
552
+ #. translators: Number of scan results
553
+ #: lib/email_newIssues.php:133
554
+ msgid "%d existing issue was found again and is not shown."
555
+ msgid_plural "%d existing issues were found again and are not shown."
556
+ msgstr[0] ""
557
+ msgstr[1] ""
558
 
559
+ #. translators: Number of scan results
560
+ #: lib/email_newIssues.php:136
561
  msgid "%d issue was omitted from this email due to length limits."
562
+ msgid_plural "%d issues were omitted from this email due to length limits."
563
+ msgstr[0] ""
564
+ msgstr[1] ""
 
 
565
 
566
+ #. translators: Number of scan results
567
+ #: lib/email_newIssues.php:137
568
  msgid "View every issue:"
569
  msgstr ""
570
 
571
+ #: lib/email_newIssues.php:146
572
  msgid "NOTE: You are using the free version of Wordfence. Upgrade today:"
573
  msgstr ""
574
 
575
+ #: lib/email_newIssues.php:149
576
  msgid "Receive real-time Firewall and Scan engine rule updates for protection as threats emerge"
577
  msgstr ""
578
 
579
+ #: lib/email_newIssues.php:150
580
  msgid "Real-time IP Blocklist blocks the most malicious IPs from accessing your site"
581
  msgstr ""
582
 
583
+ #: lib/email_newIssues.php:151
584
  msgid "Country blocking"
585
  msgstr ""
586
 
587
+ #: lib/email_newIssues.php:152
588
  msgid "IP reputation monitoring"
589
  msgstr ""
590
 
591
+ #: lib/email_newIssues.php:153
592
  msgid "Schedule scans to run more frequently and at optimal times"
593
  msgstr ""
594
 
595
+ #: lib/email_newIssues.php:154
596
  msgid "Access to Premium Support"
597
  msgstr ""
598
 
599
+ #: lib/email_newIssues.php:155
600
  msgid "Discounts for multi-year and multi-license purchases"
601
  msgstr ""
602
 
603
+ #: lib/email_newIssues.php:158
604
  msgid "Click here to upgrade to Wordfence Premium:"
605
  msgstr ""
606
 
607
+ #. translators: 1. IP address. 2. Site URL. 3. Site name.
608
+ #: lib/email_unlockRequest.php:4
609
+ msgid "Either you or someone else at IP address <b>%1$s</b> requested instructions to regain access to the website <a href=\"%2$s\"><b>%3$s</b></a>."
610
  msgstr ""
611
 
612
+ #. translators: Localized date.
613
+ #: lib/email_unlockRequest.php:8
614
+ #: lib/email_unsubscribeRequest.php:8
615
  msgid "Request was generated at: %s"
616
  msgstr ""
617
 
618
+ #: lib/email_unlockRequest.php:10
619
  msgid "If you did not request these instructions then you can safely ignore them."
620
  msgstr ""
621
 
622
+ #: lib/email_unlockRequest.php:11
623
  msgid "These instructions <b>will be valid for 30 minutes</b> from the time they were sent."
624
  msgstr ""
625
 
626
+ #: lib/email_unlockRequest.php:14
627
  msgid "Click here to unlock your ability to sign-in and to access to the site."
628
  msgstr ""
629
 
630
+ #: lib/email_unlockRequest.php:14
631
  msgid "Do this if you simply need to regain access because you were accidentally locked out. If you received an \"Insecure Password\" message before getting locked out, you may also need to reset your password."
632
  msgstr ""
633
 
634
+ #: lib/email_unlockRequest.php:17
635
  msgid "Click here to unblock all IP addresses."
636
  msgstr ""
637
 
638
+ #: lib/email_unlockRequest.php:17
639
  msgid "Do this if you still can't regain access using the link above. It causes everyone who is blocked or locked out to be able to access your site again."
640
  msgstr ""
641
 
642
+ #: lib/email_unlockRequest.php:20
643
  msgid "Click here to unlock all IP addresses and disable the Wordfence Firewall and Wordfence login security for all users"
644
  msgstr ""
645
 
646
+ #: lib/email_unlockRequest.php:20
647
  msgid "Do this if you keep getting locked out or blocked and can't access your site. You can re-enable login security and the firewall once you sign-in to the site by visiting the Wordfence Firewall menu, clicking and then turning on the firewall and login security options. If you use country blocking, you will also need to choose which countries to block."
648
  msgstr ""
649
 
650
+ #. translators: 1. IP address. 2. Site URL. 3. Site name.
651
+ #: lib/email_unsubscribeRequest.php:4
652
+ msgid "Either you or someone at IP address <b>%1$s</b> requested an alert unsubscribe link for the website <a href=\"%2$s\"><b>%3$s</b></a>."
653
  msgstr ""
654
 
655
+ #: lib/email_unsubscribeRequest.php:10
656
  msgid "If you did not request this, you can safely ignore it."
657
  msgstr ""
658
 
659
+ #. translators: URL to WordPress admin panel.
660
+ #: lib/email_unsubscribeRequest.php:14
661
  msgid "<a href=\"%s\" target=\"_blank\">Click here</a> to stop receiving security alerts."
662
  msgstr ""
663
 
664
+ #. translators: IP address.
665
+ #: lib/IPTraf.php:11
666
+ msgid "Wordfence: All recent hits for IP address %s"
667
+ msgstr ""
668
+
669
+ #. translators: 1. year (2011). 2. year (2020)
670
+ #: lib/IPTraf.php:14
671
+ #: lib/sysinfo.php:20
672
+ #: lib/wfViewResult.php:25
673
+ msgid "&copy;&nbsp;%d to %d Wordfence &mdash; Visit <a href=\"http://wordfence.com/\">Wordfence.com</a> for help, security updates and more."
674
+ msgstr ""
675
+
676
+ #: lib/IPTrafList.php:13
677
+ #: lib/wfLockedOut.php:347
678
+ msgid "Time:"
679
+ msgstr ""
680
+
681
+ #. translators: 1. Time ago, example: 2 hours, 40 seconds. 2. Localized date. 3. Unix timestamp.
682
+ #: lib/IPTrafList.php:16
683
+ msgid "%1$s ago -- %2$s -- %3$s in Unixtime"
684
+ msgstr ""
685
+
686
+ #: lib/IPTrafList.php:19
687
+ msgid "Seconds since last hit:"
688
+ msgstr ""
689
+
690
+ #: lib/IPTrafList.php:22
691
+ #: lib/menu_tools_livetraffic.php:251
692
+ msgid "URL:"
693
+ msgstr ""
694
+
695
+ #: lib/IPTrafList.php:34
696
+ msgid "Normal request"
697
+ msgstr ""
698
+
699
+ #: lib/IPTrafList.php:39
700
+ msgid "Referrer:"
701
+ msgstr ""
702
+
703
+ #: lib/IPTrafList.php:44
704
+ msgid "Full Browser ID:"
705
+ msgstr ""
706
+
707
+ #: lib/IPTrafList.php:49
708
+ msgid "User:"
709
+ msgstr ""
710
+
711
+ #: lib/IPTrafList.php:57
712
+ msgid "Location:"
713
+ msgstr ""
714
+
715
+ #: lib/live_activity.php:5
716
+ msgid "Wordfence Live Activity:"
717
+ msgstr ""
718
+
719
  #: lib/menu_dashboard.php:24
720
+ #: lib/wordfenceClass.php:6543
721
  msgid "Wordfence Dashboard"
722
  msgstr ""
723
 
729
  #: lib/menu_dashboard_options.php:98
730
  #: lib/menu_firewall.php:20
731
  #: lib/menu_firewall.php:30
732
+ #: lib/wordfenceClass.php:6547
733
  #: models/page/wfPage.php:105
734
  msgid "Firewall"
735
  msgstr ""
765
  #: lib/menu_dashboard.php:71
766
  #: lib/menu_dashboard_options.php:115
767
  #: lib/menu_scanner.php:31
768
+ #: lib/menu_scanner.php:305
769
+ #: lib/wordfenceClass.php:6554
770
  #: models/page/wfPage.php:113
771
  msgid "Scan"
772
  msgstr ""
807
  msgstr ""
808
 
809
  #: lib/menu_dashboard.php:97
810
+ #: lib/menu_dashboard.php:108
811
+ #: lib/menu_dashboard.php:116
812
  #: lib/menu_dashboard_options.php:141
813
+ #: lib/menu_dashboard_options.php:152
814
+ #: lib/menu_dashboard_options.php:160
815
  #: views/scanner/scanner-status.php:53
816
  #: views/waf/firewall-status.php:66
817
  msgid "Premium Protection Disabled"
823
  msgstr ""
824
 
825
  #: lib/menu_dashboard.php:100
826
+ #: lib/menu_dashboard.php:127
827
  #: lib/menu_dashboard_options.php:144
828
+ #: lib/menu_dashboard_options.php:171
829
  msgid "Renew License"
830
  msgstr ""
831
 
832
+ #: lib/menu_dashboard.php:109
833
+ #: lib/menu_dashboard_options.php:153
834
+ msgid "The license you were using has been removed from your account. Please reach out to <a href=\"mailto:billing@wordfence.com\">billing@wordfence.com</a> or create a Premium support case at <a href=\"https://support.wordfence.com/support/tickets\" target=\"_blank\">https://support.wordfence.com/support/tickets</a> for more information. Our staff is happy to help."
835
+ msgstr ""
836
+
837
+ #: lib/menu_dashboard.php:117
838
+ #: lib/menu_dashboard_options.php:161
839
  #: views/waf/firewall-status.php:67
840
+ msgid "As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by additional firewall rules and malware signatures. Upgrade to Premium today to improve your protection."
841
  msgstr ""
842
 
843
+ #: lib/menu_dashboard.php:118
844
+ #: lib/menu_dashboard_options.php:162
845
  #: lib/menu_firewall_waf.php:55
846
  #: lib/menu_firewall_waf.php:72
847
  #: lib/menu_scanner.php:80
848
  #: lib/menu_support.php:43
849
  #: lib/menu_tools_twoFactor.php:51
850
  #: views/blocking/blocking-create.php:179
851
+ #: views/blocking/blocking-status.php:23
852
  #: views/blocking/blocking-status.php:27
853
  #: views/blocking/options-group-advanced-country.php:85
854
  #: views/dashboard/options-group-dashboard.php:107
863
  msgid "Upgrade to Premium"
864
  msgstr ""
865
 
866
+ #: lib/menu_dashboard.php:124
867
+ #: lib/menu_dashboard.php:183
868
+ #: lib/menu_dashboard_options.php:168
869
+ #: lib/menu_dashboard_options.php:225
870
  msgid "Premium License Expiring"
871
  msgstr ""
872
 
873
+ #: lib/menu_dashboard.php:125
874
+ #: lib/menu_dashboard_options.php:169
875
  msgid "Auto-renew is disabled"
876
  msgstr ""
877
 
878
+ #: lib/menu_dashboard.php:134
879
+ #: lib/menu_dashboard_options.php:178
880
  msgid "Payment Method Expiring"
881
  msgstr ""
882
 
883
+ #: lib/menu_dashboard.php:137
884
+ #: lib/menu_dashboard_options.php:181
885
  msgid "Payment Method Expired"
886
  msgstr ""
887
 
888
+ #: lib/menu_dashboard.php:140
889
+ #: lib/menu_dashboard_options.php:184
890
  msgid "Payment Method Missing"
891
  msgstr ""
892
 
893
+ #: lib/menu_dashboard.php:143
894
+ #: lib/menu_dashboard_options.php:187
895
  msgid "Payment Method Invalid"
896
  msgstr ""
897
 
898
+ #: lib/menu_dashboard.php:149
899
+ #: lib/menu_dashboard.php:172
900
+ msgid "License renews today"
 
 
 
 
 
 
 
901
  msgstr ""
902
 
903
+ #: lib/menu_dashboard.php:152
904
+ msgid "License renews tomorrow"
 
 
 
905
  msgstr ""
906
 
907
+ #. translators: Number of days
908
+ #: lib/menu_dashboard.php:157
909
+ #: lib/menu_dashboard.php:178
910
+ msgid "License renews in %d days"
 
911
  msgstr ""
912
 
913
+ #: lib/menu_dashboard.php:165
914
+ #: lib/menu_dashboard_options.php:207
915
  msgid "Update Payment Method"
916
  msgstr ""
917
 
918
+ #: lib/menu_dashboard.php:175
919
+ msgid "License renews in 1 day"
 
920
  msgstr ""
921
 
922
+ #: lib/menu_dashboard.php:186
923
+ #: lib/menu_dashboard_options.php:228
924
  msgid "Review Payment Method"
925
  msgstr ""
926
 
927
+ #: lib/menu_dashboard.php:194
928
+ #: lib/menu_dashboard_options.php:236
929
  msgid "Wordfence Premium Enabled"
930
  msgstr ""
931
 
932
+ #: lib/menu_dashboard.php:220
933
+ #: lib/wordfenceClass.php:6558
934
  msgid "Tools"
935
  msgstr ""
936
 
937
+ #: lib/menu_dashboard.php:221
938
  msgid "Live Traffic, Whois Lookup, Import/Export, and Diagnostics"
939
  msgstr ""
940
 
941
+ #: lib/menu_dashboard.php:231
942
  #: lib/menu_firewall_waf.php:157
943
  #: lib/menu_scanner.php:139
944
  #: lib/menu_support.php:19
945
+ #: lib/wordfenceClass.php:6571
946
  msgid "Help"
947
  msgstr ""
948
 
949
+ #: lib/menu_dashboard.php:232
950
  #: lib/menu_firewall_waf.php:158
951
  #: lib/menu_scanner.php:140
952
  msgid "Find the documentation and help you need"
953
  msgstr ""
954
 
955
+ #: lib/menu_dashboard.php:242
956
  #: models/page/wfPage.php:103
957
  msgid "Global Options"
958
  msgstr ""
959
 
960
+ #: lib/menu_dashboard.php:243
961
  msgid "Manage global options for Wordfence such as alerts, premium status, and more"
962
  msgstr ""
963
 
964
+ #: lib/menu_dashboard.php:294
965
  msgid "This is your Dashboard"
966
  msgstr ""
967
 
968
+ #: lib/menu_dashboard.php:295
969
  msgid "The Wordfence Dashboard provides valuable insights into the current state of your site's security. You'll find useful data summarized here as well as important status updates and notifications."
970
  msgstr ""
971
 
972
+ #: lib/menu_dashboard.php:302
973
+ #: lib/menu_dashboard.php:318
974
+ #: lib/menu_dashboard.php:381
975
+ #: lib/menu_dashboard.php:398
976
+ #: lib/menu_dashboard.php:416
977
+ #: lib/menu_firewall_blocking.php:127
978
+ #: lib/menu_firewall_blocking.php:143
979
+ #: lib/menu_firewall_blocking.php:211
980
  #: lib/menu_firewall_waf.php:255
981
  #: lib/menu_firewall_waf.php:272
982
  #: lib/menu_firewall_waf.php:289
983
+ #: lib/menu_scanner.php:313
984
+ #: lib/menu_scanner.php:330
985
+ #: lib/menu_scanner.php:382
986
  #: views/tours/login-security.php:37
987
  #: views/tours/login-security.php:53
988
  msgid "Next"
989
  msgstr ""
990
 
991
+ #: lib/menu_dashboard.php:309
992
  msgid "Easily Monitor Your Wordfence Protection"
993
  msgstr ""
994
 
995
+ #: lib/menu_dashboard.php:310
996
  msgid "Each feature contains a status that reminds you what's enabled, disabled or needs attention. The Notifications section will highlight actions you need to take."
997
  msgstr ""
998
 
999
+ #: lib/menu_dashboard.php:317
1000
+ #: lib/menu_dashboard.php:334
1001
+ #: lib/menu_dashboard.php:397
1002
+ #: lib/menu_dashboard.php:415
1003
+ #: lib/menu_dashboard.php:432
1004
+ #: lib/menu_firewall_blocking.php:142
1005
+ #: lib/menu_firewall_blocking.php:158
1006
+ #: lib/menu_firewall_blocking.php:225
1007
  #: lib/menu_firewall_waf.php:271
1008
  #: lib/menu_firewall_waf.php:288
1009
  #: lib/menu_firewall_waf.php:306
1010
+ #: lib/menu_scanner.php:329
1011
+ #: lib/menu_scanner.php:345
1012
+ #: lib/menu_scanner.php:396
1013
  #: views/tours/login-security.php:52
1014
  #: views/tours/login-security.php:69
1015
  msgid "Previous"
1016
  msgstr ""
1017
 
1018
+ #: lib/menu_dashboard.php:325
1019
+ #: lib/menu_dashboard.php:405
1020
  msgid "Global Wordfence Options"
1021
  msgstr ""
1022
 
1023
+ #: lib/menu_dashboard.php:327
1024
  msgid "You'll find this icon throughout the plugin. Clicking it will show you the options and features for each section of Wordfence. From the dashboard, you can find the <strong>Global Options</strong> for Wordfence such as alerts, automatic updates, and managing your site's Premium License."
1025
  msgstr ""
1026
 
1027
+ #: lib/menu_dashboard.php:335
1028
+ #: lib/menu_dashboard.php:433
1029
+ #: lib/menu_firewall_blocking.php:159
1030
+ #: lib/menu_firewall_blocking.php:226
1031
  #: lib/menu_firewall_waf.php:307
1032
  #: lib/menu_firewall_waf.php:354
1033
+ #: lib/menu_scanner.php:346
1034
+ #: lib/menu_scanner.php:397
1035
+ #: lib/menu_tools_livetraffic.php:577
1036
+ #: lib/menu_tools_livetraffic.php:608
1037
  msgid "Got it"
1038
  msgstr ""
1039
 
1040
+ #. translators: Wordfence version.
1041
+ #: lib/menu_dashboard.php:371
1042
  msgid "You have successfully updated to Wordfence %s"
1043
  msgstr ""
1044
 
1045
+ #: lib/menu_dashboard.php:372
1046
  msgid "This update includes a number of significant interface changes. We'd like to walk you through some of them, but you can bypass the tour for a section at any time by closing the dialogs."
1047
  msgstr ""
1048
 
1049
+ #: lib/menu_dashboard.php:373
1050
  msgid "We welcome your feedback and comments at <a href=\"mailto:feedback@wordfence.com\">feedback@wordfence.com</a>. For a deeper dive on all of the changes, <a href=\"https://www.wordfence.com/blog/2018/01/introducing-wordfence-7/\" target=\"_blank\" rel=\"noopener noreferrer\">click here</a>."
1051
  msgstr ""
1052
 
1053
+ #: lib/menu_dashboard.php:388
1054
  msgid "Monitor Your Wordfence Protection"
1055
  msgstr ""
1056
 
1057
+ #: lib/menu_dashboard.php:389
1058
  msgid "Each feature contains a status percentage reminding you at a high level of what's enabled, disabled, or needing your attention. The Notifications section highlights actions you need to take."
1059
  msgstr ""
1060
 
1061
+ #: lib/menu_dashboard.php:407
1062
  msgid "Manage your Wordfence license, see alerts and automatic plugin updates, and import/export your settings."
1063
  msgstr ""
1064
 
1065
+ #: lib/menu_dashboard.php:423
1066
  msgid "Updated Navigation"
1067
  msgstr ""
1068
 
1069
+ #: lib/menu_dashboard.php:424
1070
  msgid "The main navigation no longer includes an <strong>Options</strong> link. Options are now accessed via the <strong>Options</strong> link on each feature's main page. Live Traffic is now located in the Tools section, and blocking is found under the Firewall. Shortcuts to add a <strong>Blocking</strong> link back to the main navigation are available under Blocking options."
1071
  msgstr ""
1072
 
1073
+ #: lib/menu_dashboard.php:473
1074
  msgid "Recommended Settings Change"
1075
  msgstr ""
1076
 
1077
+ #: lib/menu_dashboard.php:474
1078
  msgid "Greetings! The default configuration for Wordfence Live Traffic has changed. The new default saves only logins and blocked requests, while this site is currently recording all traffic. Would you like to change to the new default?"
1079
  msgstr ""
1080
 
1081
+ #: lib/menu_dashboard.php:474
1082
  msgid "Rate limiting based on type of request (human vs crawler) may be less accurate because this prevents loading the extra JavaScript used for that identification."
1083
  msgstr ""
1084
 
1085
+ #: lib/menu_dashboard.php:475
1086
  msgid "Yes Please"
1087
  msgstr ""
1088
 
1089
+ #: lib/menu_dashboard.php:477
1090
  #: views/onboarding/fresh-install.php:45
1091
  #: views/onboarding/modal-final-attempt.php:43
1092
  #: views/onboarding/plugin-header.php:67
1095
 
1096
  #: lib/menu_dashboard_options.php:11
1097
  #: lib/menu_dashboard_options.php:79
1098
+ #: lib/menu_options.php:272
1099
  msgid "Wordfence Global Options"
1100
  msgstr ""
1101
 
1111
  msgid "Learn more<span class=\"wf-hidden-xs\"> about Global Options</span>"
1112
  msgstr ""
1113
 
1114
+ #: lib/menu_dashboard_options.php:193
1115
+ #: lib/menu_dashboard_options.php:214
1116
+ msgid "today"
1117
+ msgstr ""
1118
+
1119
+ #: lib/menu_dashboard_options.php:196
1120
+ msgid "tomorrow"
1121
+ msgstr ""
1122
+
1123
+ #. translators: Number of days
1124
+ #: lib/menu_dashboard_options.php:199
1125
+ #: lib/menu_dashboard_options.php:220
1126
+ msgid "in %d days"
1127
+ msgstr ""
1128
+
1129
+ #: lib/menu_dashboard_options.php:205
1130
+ #: lib/menu_dashboard_options.php:226
1131
+ msgid "License renews %s"
1132
+ msgstr ""
1133
+
1134
+ #: lib/menu_dashboard_options.php:217
1135
+ msgid "in 1 day"
1136
+ msgstr ""
1137
+
1138
  #: lib/menu_dashboard_options.php:278
1139
+ #: lib/menu_dashboard_options.php:288
1140
+ #: lib/menu_options.php:405
1141
+ #: lib/menu_options.php:415
1142
  #: lib/menu_tools_importExport.php:7
1143
  #: lib/menu_tools_importExport.php:13
1144
  #: models/page/wfPage.php:121
1146
  msgid "Import/Export Options"
1147
  msgstr ""
1148
 
1149
+ #: lib/menu_dashboard_options.php:286
1150
  msgid "Importing and exporting of options has moved to the Tools page"
1151
  msgstr ""
1152
 
1158
 
1159
  #: lib/menu_firewall.php:21
1160
  #: lib/menu_firewall.php:41
1161
+ #: lib/menu_firewall_blocking.php:119
1162
  #: lib/menu_firewall_waf.php:142
1163
+ #: lib/wordfenceClass.php:6549
1164
  #: models/page/wfPage.php:109
1165
  msgid "Blocking"
1166
  msgstr ""
1171
  msgstr ""
1172
 
1173
  #: lib/menu_firewall.php:44
1174
+ #: lib/menu_firewall_blocking_options.php:94
1175
  msgid "Learn more<span class=\"wf-hidden-xs\"> about Blocking</span>"
1176
  msgstr ""
1177
 
1184
  msgid "Turn On"
1185
  msgstr ""
1186
 
1187
+ #. translators: PHP version.
1188
+ #: lib/menu_firewall_blocking.php:33
1189
  msgid "<strong>Note:</strong> The GeoIP database that is required for country blocking has been updated to a new format. This new format requires sites to run PHP 5.4 or newer, and this site is on PHP %s. To ensure country blocking continues functioning, please update PHP."
1190
  msgstr ""
1191
 
1192
+ #: lib/menu_firewall_blocking.php:34
1193
  msgid "More Information"
1194
  msgstr ""
1195
 
1196
+ #: lib/menu_firewall_blocking.php:40
1197
  msgid "Create a Blocking Rule"
1198
  msgstr ""
1199
 
1200
+ #: lib/menu_firewall_blocking.php:40
1201
  msgid "Edit Blocking Rule"
1202
  msgstr ""
1203
 
1204
+ #: lib/menu_firewall_blocking.php:120
1205
  msgid "Wordfence lets you take control of protecting your site with powerful blocking features. Block traffic based on IP, IP range, hostname, browser, or referrer. Country blocking is available for Premium customers."
1206
  msgstr ""
1207
 
1208
+ #: lib/menu_firewall_blocking.php:134
1209
+ #: lib/menu_firewall_blocking.php:204
1210
  msgid "Blocking Builder"
1211
  msgstr ""
1212
 
1213
+ #: lib/menu_firewall_blocking.php:135
1214
  msgid "All of your blocking rules are in one central location. Choose the Block Type, then enter the details for the rule. Once it has been added, you'll see it saved as a rule for your site."
1215
  msgstr ""
1216
 
1217
+ #: lib/menu_firewall_blocking.php:150
1218
+ #: lib/menu_firewall_blocking.php:218
1219
  msgid "Manage Blocking Rules"
1220
  msgstr ""
1221
 
1222
+ #: lib/menu_firewall_blocking.php:151
1223
  msgid "Here's where you'll see all the blocking rules you've created. You can also manage them as well as remove or modify them from this table."
1224
  msgstr ""
1225
 
1226
+ #: lib/menu_firewall_blocking.php:205
1227
  msgid "All of the blocking rules you create are now in one central location. Simply choose the block type and enter the details for the rule you want to create. Premium users have access to advanced country blocking options, found via the <strong>Options</strong> link."
1228
  msgstr ""
1229
 
1230
+ #: lib/menu_firewall_blocking.php:219
1231
  msgid "All blocking rules you create will show here. You can manage them as well as remove or modify them from the same location."
1232
  msgstr ""
1233
 
1234
  #: lib/menu_firewall_blocking_options.php:12
1235
+ #: lib/menu_firewall_blocking_options.php:92
1236
+ #: lib/menu_options.php:340
1237
  #: models/page/wfPage.php:111
1238
  #: views/blocking/blocking-status.php:14
1239
  msgid "Blocking Options"
1240
  msgstr ""
1241
 
1242
+ #. translators: Page title/label.
1243
+ #: lib/menu_firewall_blocking_options.php:51
1244
  #: lib/menu_firewall_waf_options.php:78
1245
  #: lib/menu_scanner_options.php:66
1246
  msgid "<span class=\"wf-hidden-xs\">Back to </span>%s"
1247
  msgstr ""
1248
 
1249
+ #: lib/menu_firewall_blocking_options.php:53
1250
  msgid "Are you sure you want to restore the default Blocking settings? This will undo any custom changes you have made to the options on this page. Any existing blocks will be preserved."
1251
  msgstr ""
1252
 
1253
+ #: lib/menu_firewall_blocking_options.php:104
1254
  msgid "General"
1255
  msgstr ""
1256
 
1257
+ #: lib/menu_firewall_blocking_options.php:118
1258
  msgid "Display Blocking menu option"
1259
  msgstr ""
1260
 
1348
  #: lib/menu_tools_diagnostic.php:300
1349
  #: lib/menu_tools_diagnostic.php:301
1350
  #: lib/menu_tools_diagnostic.php:304
1351
+ #: lib/wordfenceClass.php:6073
1352
  #: models/firewall/wfFirewall.php:41
1353
  #: views/diagnostics/text.php:154
1354
  #: views/diagnostics/text.php:159
1450
  #: lib/menu_firewall_waf.php:347
1451
  #: lib/menu_firewall_waf_options.php:23
1452
  #: lib/menu_firewall_waf_options.php:122
1453
+ #: lib/menu_options.php:303
1454
  #: models/page/wfPage.php:107
1455
  msgid "Firewall Options"
1456
  msgstr ""
1468
  msgstr ""
1469
 
1470
  #: lib/menu_options.php:24
1471
+ #: lib/menu_options.php:262
1472
+ #: lib/wordfenceClass.php:6566
1473
  msgid "All Options"
1474
  msgstr ""
1475
 
1608
 
1609
  #: lib/menu_options.php:96
1610
  #: views/dashboard/options-group-alert.php:140
1611
+ msgid "Only alert me when that administrator signs in from a new device"
1612
  msgstr ""
1613
 
1614
  #: lib/menu_options.php:97
1618
 
1619
  #: lib/menu_options.php:98
1620
  #: views/dashboard/options-group-alert.php:157
1621
+ msgid "Only alert me when that user signs in from a new device"
1622
  msgstr ""
1623
 
1624
  #: lib/menu_options.php:99
1744
 
1745
  #: lib/menu_options.php:125
1746
  #: views/waf/options-group-brute-force.php:226
1747
+ msgid "Disable WordPress application passwords"
1748
  msgstr ""
1749
 
1750
  #: lib/menu_options.php:126
1751
+ #: views/waf/options-group-brute-force.php:238
1752
+ msgid "Block IPs who send POST requests with blank User-Agent and Referer"
1753
  msgstr ""
1754
 
1755
  #: lib/menu_options.php:127
1756
+ #: views/waf/options-group-brute-force.php:248
1757
+ msgid "Custom text shown on block pages"
1758
  msgstr ""
1759
 
1760
  #: lib/menu_options.php:128
1761
  #: views/waf/options-group-brute-force.php:263
1762
+ msgid "Check password strength on profile update"
1763
  msgstr ""
1764
 
1765
  #: lib/menu_options.php:129
1766
+ #: views/waf/options-group-brute-force.php:275
1767
+ msgid "Participate in the Real-Time Wordfence Security Network"
1768
+ msgstr ""
1769
+
1770
+ #: lib/menu_options.php:130
1771
  #: views/waf/options-group-rate-limiting.php:38
1772
  msgid "Enable Rate Limiting and Advanced Blocking"
1773
  msgstr ""
1774
 
1775
+ #: lib/menu_options.php:131
1776
  #: views/waf/options-group-rate-limiting.php:60
1777
  msgid "How should we treat Google's crawlers"
1778
  msgstr ""
1779
 
1780
+ #: lib/menu_options.php:132
1781
  #: views/waf/options-group-rate-limiting.php:100
1782
  msgid "If anyone's requests exceed"
1783
  msgstr ""
1784
 
1785
+ #: lib/menu_options.php:133
1786
  #: views/waf/options-group-rate-limiting.php:117
1787
  msgid "If a crawler's page views exceed"
1788
  msgstr ""
1789
 
1790
+ #: lib/menu_options.php:134
1791
  #: views/waf/options-group-rate-limiting.php:134
1792
  msgid "If a crawler's pages not found (404s) exceed"
1793
  msgstr ""
1794
 
1795
+ #: lib/menu_options.php:135
1796
  #: views/waf/options-group-rate-limiting.php:151
1797
  msgid "If a human's page views exceed"
1798
  msgstr ""
1799
 
1800
+ #: lib/menu_options.php:136
1801
  #: views/waf/options-group-rate-limiting.php:168
1802
  msgid "If a human's pages not found (404s) exceed"
1803
  msgstr ""
1804
 
1805
+ #: lib/menu_options.php:137
1806
  #: views/waf/options-group-rate-limiting.php:184
1807
  msgid "How long is an IP address blocked when it breaks a rule"
1808
  msgstr ""
1809
 
1810
+ #: lib/menu_options.php:138
1811
  #: views/waf/options-group-rate-limiting.php:194
1812
  msgid "Allowlisted 404 URLs"
1813
  msgstr ""
1814
 
1815
+ #: lib/menu_options.php:139
1816
  msgid "Web Application Firewall Allowlisted URLs"
1817
  msgstr ""
1818
 
1819
+ #: lib/menu_options.php:140
1820
  msgid "Monitor background requests from an administrator's web browser for false positives (Front-end Website)"
1821
  msgstr ""
1822
 
1823
+ #: lib/menu_options.php:141
1824
  msgid "Monitor background requests from an administrator's web browser for false positives (Admin Panel)"
1825
  msgstr ""
1826
 
1827
+ #: lib/menu_options.php:142
1828
  msgid "What to do when we block someone visiting from a blocked country"
1829
  msgstr ""
1830
 
1831
+ #: lib/menu_options.php:143
1832
  msgid "URL to redirect blocked countries to"
1833
  msgstr ""
1834
 
1835
+ #: lib/menu_options.php:144
1836
  #: views/blocking/options-group-advanced-country.php:62
1837
  msgid "Block countries even if they are logged in"
1838
  msgstr ""
1839
 
1840
+ #: lib/menu_options.php:145
1841
  msgid "If user from a blocked country hits the relative URL ____ then redirect that user to ____ and set a cookie that will bypass all country blocking"
1842
  msgstr ""
1843
 
1844
+ #: lib/menu_options.php:146
1845
  msgid "If user who is allowed to access the site views the relative URL ____ then set a cookie that will bypass country blocking in future in case that user hits the site from a blocked country"
1846
  msgstr ""
1847
 
1848
+ #: lib/menu_options.php:147
1849
  #: views/scanner/scan-scheduling.php:12
1850
  msgid "Schedule Wordfence Scans"
1851
  msgstr ""
1852
 
1853
+ #: lib/menu_options.php:148
1854
  msgid "Scan Type"
1855
  msgstr ""
1856
 
1857
+ #: lib/menu_options.php:149
1858
  #: views/scanner/options-group-general.php:32
1859
  msgid "Check if this website is on a domain blocklist"
1860
  msgstr ""
1861
 
1862
+ #: lib/menu_options.php:150
1863
  msgid "Check if this website is being &quot;Spamvertised&quot;"
1864
  msgstr ""
1865
 
1866
+ #: lib/menu_options.php:151
1867
  #: views/scanner/options-group-general.php:34
1868
  msgid "Check if this website IP is generating spam"
1869
  msgstr ""
1870
 
1871
+ #: lib/menu_options.php:152
1872
  #: views/scanner/options-group-general.php:35
1873
  msgid "Scan for misconfigured How does Wordfence get IPs"
1874
  msgstr ""
1875
 
1876
+ #: lib/menu_options.php:153
1877
  #: views/scanner/options-group-general.php:36
1878
  msgid "Scan for publicly accessible configuration, backup, or log files"
1879
  msgstr ""
1880
 
1881
+ #: lib/menu_options.php:154
1882
  #: views/scanner/options-group-general.php:37
1883
  msgid "Scan for publicly accessible quarantined files"
1884
  msgstr ""
1885
 
1886
+ #: lib/menu_options.php:155
1887
  #: views/scanner/options-group-general.php:38
1888
  msgid "Scan core files against repository versions for changes"
1889
  msgstr ""
1890
 
1891
+ #: lib/menu_options.php:156
1892
  #: views/scanner/options-group-general.php:39
1893
  msgid "Scan theme files against repository versions for changes"
1894
  msgstr ""
1895
 
1896
+ #: lib/menu_options.php:157
1897
  #: views/scanner/options-group-general.php:40
1898
  msgid "Scan plugin files against repository versions for changes"
1899
  msgstr ""
1900
 
1901
+ #: lib/menu_options.php:158
1902
  #: views/scanner/options-group-general.php:41
1903
  msgid "Scan wp-admin and wp-includes for files not bundled with WordPress"
1904
  msgstr ""
1905
 
1906
+ #: lib/menu_options.php:159
1907
  #: views/scanner/options-group-general.php:42
1908
  msgid "Scan for signatures of known malicious files"
1909
  msgstr ""
1910
 
1911
+ #: lib/menu_options.php:160
1912
  #: views/scanner/options-group-general.php:43
1913
  msgid "Scan file contents for backdoors, trojans and suspicious code"
1914
  msgstr ""
1915
 
1916
+ #: lib/menu_options.php:161
1917
  #: views/scanner/options-group-general.php:44
1918
  msgid "Scan file contents for malicious URLs"
1919
  msgstr ""
1920
 
1921
+ #: lib/menu_options.php:162
1922
  #: views/scanner/options-group-general.php:45
1923
  msgid "Scan posts for known dangerous URLs and suspicious content"
1924
  msgstr ""
1925
 
1926
+ #: lib/menu_options.php:163
1927
  #: views/scanner/options-group-general.php:46
1928
  msgid "Scan comments for known dangerous URLs and suspicious content"
1929
  msgstr ""
1930
 
1931
+ #: lib/menu_options.php:164
1932
  #: views/scanner/options-group-general.php:47
1933
  msgid "Scan WordPress core, plugin, and theme options for known dangerous URLs and suspicious content"
1934
  msgstr ""
1935
 
1936
+ #: lib/menu_options.php:165
1937
  #: views/scanner/options-group-general.php:48
1938
  msgid "Scan for out of date, abandoned, and vulnerable plugins, themes, and WordPress versions"
1939
  msgstr ""
1940
 
1941
+ #: lib/menu_options.php:166
1942
  #: views/scanner/options-group-general.php:49
1943
  msgid "Scan for suspicious admin users created outside of WordPress"
1944
  msgstr ""
1945
 
1946
+ #: lib/menu_options.php:167
1947
  #: views/scanner/options-group-general.php:50
1948
  msgid "Check the strength of passwords"
1949
  msgstr ""
1950
 
1951
+ #: lib/menu_options.php:168
1952
  #: views/scanner/options-group-general.php:51
1953
  msgid "Monitor disk space"
1954
  msgstr ""
1955
 
1956
+ #: lib/menu_options.php:169
1957
  #: views/scanner/options-group-general.php:52
1958
  msgid "Monitor Web Application Firewall status"
1959
  msgstr ""
1960
 
1961
+ #: lib/menu_options.php:170
1962
  #: views/scanner/options-group-general.php:53
1963
  msgid "Scan files outside your WordPress installation"
1964
  msgstr ""
1965
 
1966
+ #: lib/menu_options.php:171
1967
  #: views/scanner/options-group-general.php:54
1968
  msgid "Scan images, binary, and other files as if they were executable"
1969
  msgstr ""
1970
 
1971
+ #: lib/menu_options.php:172
1972
  #: views/scanner/options-group-performance.php:32
1973
  msgid "Use low resource scanning (reduces server load by lengthening the scan duration)"
1974
  msgstr ""
1975
 
1976
+ #: lib/menu_options.php:173
1977
  #: views/scanner/options-group-performance.php:33
1978
  msgid "Limit the number of issues sent in the scan results email"
1979
  msgstr ""
1980
 
1981
+ #: lib/menu_options.php:174
1982
  #: views/scanner/options-group-performance.php:34
1983
  msgid "Time limit that a scan can run in seconds"
1984
  msgstr ""
1985
 
1986
+ #. translators: Time until.
1987
+ #: lib/menu_options.php:175
1988
  #: views/scanner/options-group-performance.php:35
1989
  msgid "How much memory should Wordfence request when scanning"
1990
  msgstr ""
1991
 
1992
+ #: lib/menu_options.php:176
1993
  msgid "Maximum execution time for each scan stage"
1994
  msgstr ""
1995
 
1996
+ #: lib/menu_options.php:177
1997
  msgid "Exclude files from scan that match these wildcard patterns"
1998
  msgstr ""
1999
 
2000
+ #: lib/menu_options.php:178
2001
  msgid "Additional scan signatures"
2002
  msgstr ""
2003
 
2004
+ #: lib/menu_options.php:179
2005
  msgid "Traffic logging mode (Live Traffic)"
2006
  msgstr ""
2007
 
2008
+ #: lib/menu_options.php:180
2009
  #: views/tools/options-group-live-traffic.php:78
2010
  msgid "Don't log signed-in users with publishing access"
2011
  msgstr ""
2012
 
2013
+ #: lib/menu_options.php:181
2014
  #: views/tools/options-group-live-traffic.php:87
2015
  msgid "List of comma separated usernames to ignore"
2016
  msgstr ""
2017
 
2018
+ #: lib/menu_options.php:182
2019
  #: views/tools/options-group-live-traffic.php:96
2020
  msgid "List of comma separated IP addresses to ignore"
2021
  msgstr ""
2022
 
2023
+ #: lib/menu_options.php:183
2024
  #: views/tools/options-group-live-traffic.php:105
2025
  msgid "Browser user-agent to ignore"
2026
  msgstr ""
2027
 
2028
+ #: lib/menu_options.php:184
2029
  #: views/tools/options-group-live-traffic.php:114
2030
  msgid "Amount of Live Traffic data to store (number of rows)"
2031
  msgstr ""
2032
 
2033
+ #: lib/menu_options.php:185
2034
  msgid "Maximum days to keep Live Traffic data"
2035
  msgstr ""
2036
 
2037
+ #: lib/menu_options.php:186
2038
  #: views/dashboard/options-group-import.php:31
2039
  msgid "Export this site's Wordfence options for import on another site"
2040
  msgstr ""
2041
 
2042
+ #: lib/menu_options.php:187
2043
  #: views/dashboard/options-group-import.php:44
2044
  msgid "Import Wordfence options from another site using a token"
2045
  msgstr ""
2046
 
2047
+ #: lib/menu_options.php:191
2048
  msgid "Require Cellphone Sign-in for all Administrators"
2049
  msgstr ""
2050
 
2051
+ #: lib/menu_options.php:192
2052
  msgid "Enable Separate Prompt for Two Factor Code"
2053
  msgstr ""
2054
 
2055
+ #: lib/menu_options.php:201
2056
  msgid "Are you sure you want to restore the default settings? This will undo any custom changes you have made to the options on this page. If you have manually disabled any rules or added any custom allowlisted URLs, those changes will not be overwritten."
2057
  msgstr ""
2058
 
2059
+ #: lib/menu_options.php:268
2060
  msgid "These options are also available throughout the plugin pages, in the relevant sections. This page is provided for easier setup for experienced Wordfence users."
2061
  msgstr ""
2062
 
2063
+ #: lib/menu_options.php:351
2064
  #: models/page/wfPage.php:115
2065
  msgid "Scan Options"
2066
  msgstr ""
2067
 
2068
+ #: lib/menu_options.php:383
2069
  msgid "Tool Options"
2070
  msgstr ""
2071
 
2072
+ #: lib/menu_options.php:413
2073
  msgid "Importing and exporting of options is available on the Tools page"
2074
  msgstr ""
2075
 
2076
+ #: lib/menu_scanner.php:10
2077
+ msgid "Status Updates Paused<br /><small>Click inside window to resume</small>"
2078
+ msgstr ""
2079
+
2080
  #: lib/menu_scanner.php:34
2081
  msgid "Learn more<span class=\"wf-hidden-xs\"> about the Scanner</span>"
2082
  msgstr ""
2108
  msgstr ""
2109
 
2110
  #: lib/menu_scanner.php:80
2111
+ #: lib/wordfenceClass.php:6582
2112
  msgid "Protect More Sites"
2113
  msgstr ""
2114
 
2163
  msgid "<strong>WARNING:</strong> If you delete the wrong file, it could cause your WordPress website to stop functioning, and you will probably have to restore from a backup."
2164
  msgstr ""
2165
 
2166
+ #. translators: Support URL.
2167
+ #: lib/menu_scanner.php:216
2168
  msgid "Do not delete files on your system unless you're ABSOLUTELY sure you know what you're doing. If you delete the wrong file it could cause your WordPress website to stop functioning and you will probably have to restore from backups. If you're unsure, Cancel and work with your hosting provider to clean your system of infected files. If you'd like to learn more, <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">click here for our help article</a>."
2169
  msgstr ""
2170
 
2171
+ #: lib/menu_scanner.php:218
2172
  msgid "Delete Files"
2173
  msgstr ""
2174
 
2175
+ #: lib/menu_scanner.php:226
2176
  msgid "Are you sure you want to repair?"
2177
  msgstr ""
2178
 
2179
+ #: lib/menu_scanner.php:227
2180
  msgid "Do not repair files on your system unless you're ABSOLUTELY sure you know what you're doing. If you repair the wrong file it could cause your WordPress website to stop functioning and you will probably have to restore from backups. If you're unsure, Cancel and work with your hosting provider to clean your system of infected files."
2181
  msgstr ""
2182
 
2183
+ #: lib/menu_scanner.php:229
2184
  msgid "Repair Files"
2185
  msgstr ""
2186
 
2187
+ #. translators: Time limit (number).
2188
+ #. translators: Support URL.
2189
+ #: lib/menu_scanner.php:239
2190
  #: lib/menu_tools_twoFactor.php:246
2191
  #: lib/menu_tools_twoFactor.php:255
2192
  #: lib/menu_tools_twoFactor.php:264
2193
  #: lib/menu_tools_twoFactor.php:284
2194
+ #: lib/wordfenceClass.php:4923
2195
+ #: lib/wordfenceClass.php:4929
2196
+ #: lib/wordfenceClass.php:4935
2197
+ #: lib/wordfenceClass.php:4942
2198
+ #: lib/wordfenceClass.php:4948
2199
+ #: lib/wordfenceClass.php:4955
2200
+ #: lib/wordfenceClass.php:4963
2201
+ #: lib/wordfenceClass.php:6015
2202
+ #: lib/wordfenceClass.php:6017
2203
+ #: lib/wordfenceClass.php:6068
2204
+ #: lib/wordfenceClass.php:7956
2205
+ #: lib/wordfenceClass.php:7963
2206
+ #: lib/wordfenceClass.php:8070
2207
+ #: lib/wordfenceClass.php:8134
2208
  #: views/dashboard/options-group-import.php:147
2209
  #: views/dashboard/options-group-import.php:157
2210
  #: views/dashboard/options-group-import.php:177
2219
  msgid "Close"
2220
  msgstr ""
2221
 
2222
+ #: lib/menu_scanner.php:306
2223
  msgid "A Wordfence scan looks for malware, malicious URLs, and patterns of infections by examining all of the files, posts, and comments on your WordPress website. It also checks your server and monitors your site's online reputation."
2224
  msgstr ""
2225
 
2226
+ #: lib/menu_scanner.php:320
2227
  msgid "Manage Scan Settings"
2228
  msgstr ""
2229
 
2230
+ #: lib/menu_scanner.php:322
2231
  msgid "Set up the way you want the scan to monitor your site security including custom scan configurations and scheduling."
2232
  msgstr ""
2233
 
2234
+ #: lib/menu_scanner.php:337
2235
  msgid "Start Your First Scan"
2236
  msgstr ""
2237
 
2238
+ #: lib/menu_scanner.php:338
2239
  msgid "By default, Wordfence will scan your site daily. Start your first scan now to see if your site has any security issues that need to be addressed. From here you can run manual scans any time you like."
2240
  msgstr ""
2241
 
2242
+ #: lib/menu_scanner.php:374
2243
  msgid "Scan Options &amp; Settings"
2244
  msgstr ""
2245
 
2246
+ #: lib/menu_scanner.php:376
2247
  msgid "All of your scan options, including scheduling, are now located here."
2248
  msgstr ""
2249
 
2250
+ #: lib/menu_scanner.php:389
2251
  msgid "Scan Progress and Activity"
2252
  msgstr ""
2253
 
2254
+ #: lib/menu_scanner.php:390
2255
  msgid "Track each scan stage as Wordfence scans your entire site. Along the way you can see the activity log one line at a time or expand the activity log for a more detailed view. Clicking on scan results will reveal detailed scan findings."
2256
  msgstr ""
2257
 
2263
  msgid "File System Credentials Required"
2264
  msgstr ""
2265
 
2266
+ #. translators: URL to the WordPress admin panel.
2267
+ #: lib/menu_scanner_credentials.php:68
2268
  msgid "Security token has expired. Click <a href=\"%s\">here</a> to return to the scan page."
2269
  msgstr ""
2270
 
2325
  msgid "Data Processing Agreement"
2326
  msgstr ""
2327
 
2328
+ #. translators: URL to support page.
2329
+ #: lib/menu_support.php:83
2330
  msgid "If you qualify as a data controller under the GDPR and need a data processing agreement, it can be <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">found here</a>."
2331
  msgstr ""
2332
 
2333
+ #: lib/menu_support.php:92
2334
  msgid "Agreement to New Terms and Privacy Policies"
2335
  msgstr ""
2336
 
2337
+ #: lib/menu_support.php:93
2338
  msgid "To continue using Defiant products and services including the Wordfence plugin, all customers must review and agree to the updated terms and privacy policies. These changes reflect our commitment to follow data protection best practices and regulations. The Wordfence interface will remain disabled until these terms are agreed to."
2339
  msgstr ""
2340
 
2341
+ #: lib/menu_support.php:106
2342
  msgid "All Documentation"
2343
  msgstr ""
2344
 
2345
+ #: lib/menu_support.php:114
2346
  msgid "Top Topics and Questions"
2347
  msgstr ""
2348
 
2349
+ #: lib/menu_support.php:162
2350
  msgid "Documentation"
2351
  msgstr ""
2352
 
2353
+ #: lib/menu_support.php:163
2354
  msgid "Documentation about Wordfence may be found on our website by clicking the button below or by clicking the <i class=\"wf-fa wf-fa-question-circle-o\" aria-hidden=\"true\"></i> links on any of the plugin's pages."
2355
  msgstr ""
2356
 
2357
+ #: lib/menu_support.php:164
2358
  msgid "View Documentation"
2359
  msgstr ""
2360
 
2361
+ #: lib/menu_support.php:269
2362
  #: views/onboarding/fresh-install.php:131
2363
  #: views/onboarding/plugin-header.php:167
2364
  msgid "Premium License Installed"
2365
  msgstr ""
2366
 
2367
+ #: lib/menu_support.php:269
2368
  #: views/onboarding/fresh-install.php:131
2369
  #: views/onboarding/plugin-header.php:167
2370
  msgid "Congratulations! Wordfence Premium is now active on your website. Please note that some Premium features are not enabled by default."
2371
  msgstr ""
2372
 
2373
+ #: lib/menu_support.php:269
2374
  #: views/onboarding/fresh-install.php:30
2375
  #: views/onboarding/modal-final-attempt.php:59
2376
  #: views/onboarding/plugin-header.php:61
2377
+ #: views/waf/waf-install.php:106
2378
  #: views/waf/waf-modal-wrapper.php:17
2379
+ #: views/waf/waf-uninstall.php:108
2380
  msgid "Continue"
2381
  msgstr ""
2382
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2383
  #: lib/menu_tools_diagnostic.php:24
2384
  #: models/page/wfPage.php:125
2385
  msgid "Diagnostics"
2440
  msgid "Used"
2441
  msgstr ""
2442
 
2443
+ #. translators: WordPress theme template directory.
2444
+ #. translators: WordPress theme stylesheet directory.
2445
+ #. translators: WordPress custom user table.
2446
+ #. translators: WordPress custom user meta table.
2447
  #: lib/menu_tools_diagnostic.php:217
2448
  #: lib/menu_tools_diagnostic.php:268
2449
  #: lib/menu_tools_diagnostic.php:269
2505
  msgid "Return value of is_multisite()"
2506
  msgstr ""
2507
 
2508
+ #. translators: WordPress plugins directory.
2509
  #: lib/menu_tools_diagnostic.php:265
2510
  #: lib/menu_tools_diagnostic.php:276
2511
  #: lib/menu_tools_diagnostic.php:278
2523
  #: lib/menu_tools_diagnostic.php:318
2524
  #: lib/menu_tools_diagnostic.php:319
2525
  #: lib/menu_tools_diagnostic.php:323
2526
+ #: lib/menu_tools_livetraffic.php:152
2527
  #: lib/wfDiagnostic.php:357
2528
  #: lib/wfDiagnostic.php:375
2529
  #: views/diagnostics/text.php:124
2546
  #: views/onboarding/fresh-install.php:18
2547
  #: views/onboarding/modal-final-attempt.php:25
2548
  #: views/onboarding/plugin-header.php:39
2549
+ #: views/reports/activity-report-email-inline.php:270
2550
  #: views/reports/activity-report.php:117
2551
  msgid "Yes"
2552
  msgstr ""
2564
  #: lib/menu_tools_diagnostic.php:318
2565
  #: lib/menu_tools_diagnostic.php:319
2566
  #: lib/menu_tools_diagnostic.php:323
2567
+ #: lib/menu_tools_livetraffic.php:153
2568
  #: lib/wfDiagnostic.php:357
2569
  #: lib/wfDiagnostic.php:375
2570
  #: views/diagnostics/text.php:124
2583
  #: views/onboarding/fresh-install.php:19
2584
  #: views/onboarding/modal-final-attempt.php:26
2585
  #: views/onboarding/plugin-header.php:40
2586
+ #: views/reports/activity-report-email-inline.php:270
2587
  #: views/reports/activity-report.php:117
2588
  msgid "No"
2589
  msgstr ""
2667
  msgid "\"wp-content\" folder is in default location"
2668
  msgstr ""
2669
 
2670
+ #. translators: WordPress content directory.
2671
+ #. translators: WordPress plugins directory.
2672
+ #. translators: WordPress languages directory.
2673
  #: lib/menu_tools_diagnostic.php:276
2674
  #: lib/menu_tools_diagnostic.php:278
2675
  #: lib/menu_tools_diagnostic.php:279
2679
  msgid "No: %s"
2680
  msgstr ""
2681
 
2682
+ #. translators: WordPress content directory.
2683
  #: lib/menu_tools_diagnostic.php:277
2684
  #: views/diagnostics/text.php:136
2685
  msgid "URL to the \"wp-content\" folder"
2690
  msgid "\"plugins\" folder is in default location"
2691
  msgstr ""
2692
 
2693
+ #. translators: WordPress plugins directory.
2694
  #: lib/menu_tools_diagnostic.php:279
2695
  #: views/diagnostics/text.php:138
2696
  msgid "\"languages\" folder is in default location"
2697
  msgstr ""
2698
 
2699
+ #. translators: WordPress languages directory.
2700
  #: lib/menu_tools_diagnostic.php:280
2701
  #: views/diagnostics/text.php:139
2702
  msgid "Language choice"
2712
  msgid "Theme template folder override"
2713
  msgstr ""
2714
 
2715
+ #. translators: WordPress theme template directory.
2716
+ #. translators: WordPress theme stylesheet directory.
2717
  #: lib/menu_tools_diagnostic.php:282
2718
  #: lib/menu_tools_diagnostic.php:283
2719
  #: views/diagnostics/text.php:141
2721
  msgid "Overridden: %s"
2722
  msgstr ""
2723
 
2724
+ #. translators: WordPress theme template directory.
2725
  #: lib/menu_tools_diagnostic.php:283
2726
  #: views/diagnostics/text.php:142
2727
  msgid "Theme stylesheet folder override"
2728
  msgstr ""
2729
 
2730
+ #. translators: WordPress theme stylesheet directory.
2731
  #: lib/menu_tools_diagnostic.php:284
2732
  #: views/diagnostics/text.php:143
2733
  msgid "Post editing automatic saving interval"
2750
  #: lib/wfDiagnostic.php:411
2751
  #: views/diagnostics/text.php:144
2752
  #: views/diagnostics/text.php:171
2753
+ #: views/scanner/issue-base.php:116
2754
  msgid "None"
2755
  msgstr ""
2756
 
2809
  msgid "Custom \"users\" table"
2810
  msgstr ""
2811
 
2812
+ #. translators: WordPress custom user table.
2813
+ #. translators: WordPress custom user meta table.
2814
  #: lib/menu_tools_diagnostic.php:296
2815
  #: lib/menu_tools_diagnostic.php:297
2816
  #: views/diagnostics/text.php:155
2818
  msgid "Set: %s"
2819
  msgstr ""
2820
 
2821
+ #. translators: WordPress custom user table.
2822
  #: lib/menu_tools_diagnostic.php:297
2823
  #: views/diagnostics/text.php:156
2824
  msgid "Custom \"usermeta\" table"
2825
  msgstr ""
2826
 
2827
+ #. translators: WordPress custom user meta table.
2828
  #: lib/menu_tools_diagnostic.php:298
2829
  #: views/diagnostics/text.php:157
2830
  msgid "Overridden permissions for a new folder"
2856
  msgstr ""
2857
 
2858
  #: lib/menu_tools_diagnostic.php:303
2859
+ #: lib/wordfenceClass.php:4242
2860
  #: views/diagnostics/text.php:162
2861
  msgid "Never"
2862
  msgstr ""
2981
  msgid "Status of installed plugins."
2982
  msgstr ""
2983
 
2984
+ #. translators: Plugin version.
2985
+ #. translators: Theme version.
2986
  #: lib/menu_tools_diagnostic.php:382
2987
  #: lib/menu_tools_diagnostic.php:428
2988
  #: lib/menu_tools_diagnostic.php:527
3042
  msgid "WordPress \"drop-in\" plugins that are active."
3043
  msgstr ""
3044
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3045
  #: lib/menu_tools_diagnostic.php:501
3046
  #: views/diagnostics/text.php:332
3047
+ #: views/reports/activity-report-email-inline.php:392
3048
  #: views/reports/activity-report.php:191
3049
  msgid "Themes"
3050
  msgstr ""
3093
  msgid "Unable to verify - table count too high"
3094
  msgstr ""
3095
 
3096
+ #: lib/menu_tools_diagnostic.php:648
3097
+ #: views/diagnostics/text.php:453
3098
  msgid "All Tables Exist"
3099
  msgstr ""
3100
 
3101
+ #. translators: 1. WordPress table prefix. 2. Wordfence table case. 3. List of database tables.
3102
+ #: lib/menu_tools_diagnostic.php:652
3103
+ msgid "Tables missing (prefix %1$s, %2$s): %3$s"
3104
  msgstr ""
3105
 
3106
+ #. translators: 1. WordPress table prefix. 2. Wordfence table case. 3. List of database tables.
3107
+ #. translators: 1. WordPress table prefix. 2. Wordfence tables.
3108
+ #: lib/menu_tools_diagnostic.php:652
3109
+ #: views/diagnostics/text.php:455
3110
  msgid "lowercase"
3111
  msgstr ""
3112
 
3113
+ #. translators: 1. WordPress table prefix. 2. Wordfence table case. 3. List of database tables.
3114
+ #. translators: 1. WordPress table prefix. 2. Wordfence tables.
3115
+ #: lib/menu_tools_diagnostic.php:652
3116
+ #: views/diagnostics/text.php:455
3117
  msgid "regular case"
3118
  msgstr ""
3119
 
3120
+ #. translators: Row/record count.
3121
+ #: lib/menu_tools_diagnostic.php:698
3122
+ #: views/diagnostics/text.php:489
3123
  msgid "and %d more"
3124
  msgstr ""
3125
 
3126
+ #: lib/menu_tools_diagnostic.php:717
3127
+ #: views/diagnostics/text.php:500
3128
  msgid "Log Files"
3129
  msgstr ""
3130
 
3131
+ #: lib/menu_tools_diagnostic.php:718
3132
+ #: views/diagnostics/text.php:500
3133
  msgid "PHP error logs generated by your site, if enabled by your host."
3134
  msgstr ""
3135
 
3136
+ #: lib/menu_tools_diagnostic.php:730
3137
+ #: views/diagnostics/text.php:506
3138
+ #: views/reports/activity-report-email-inline.php:341
3139
  #: views/scanner/issue-file.php:8
3140
  #: views/scanner/issue-knownfile.php:8
3141
  msgid "File"
3142
  msgstr ""
3143
 
3144
+ #: lib/menu_tools_diagnostic.php:731
3145
+ #: lib/menu_tools_diagnostic.php:770
3146
+ #: lib/wordfenceClass.php:6076
3147
  msgid "Download"
3148
  msgstr ""
3149
 
3150
+ #: lib/menu_tools_diagnostic.php:739
3151
+ #: views/diagnostics/text.php:513
3152
  msgid "No log files found."
3153
  msgstr ""
3154
 
3155
+ #: lib/menu_tools_diagnostic.php:759
3156
+ #: views/diagnostics/text.php:532
3157
  msgid "UTC"
3158
  msgstr ""
3159
 
3160
+ #: lib/menu_tools_diagnostic.php:770
3161
  msgid "Requires downloading from the server directly"
3162
  msgstr ""
3163
 
3164
+ #: lib/menu_tools_diagnostic.php:784
3165
+ #: views/diagnostics/text.php:553
3166
  msgid "Scan Issues"
3167
  msgstr ""
3168
 
3169
+ #. translators: Number of scan issues.
3170
+ #: lib/menu_tools_diagnostic.php:789
3171
+ #: views/diagnostics/text.php:561
3172
  msgid "New Issues (%d total)"
3173
  msgstr ""
3174
 
3175
+ #: lib/menu_tools_diagnostic.php:810
3176
+ #: lib/wordfenceClass.php:3947
3177
+ #: views/diagnostics/text.php:584
3178
  msgid "No New Issues"
3179
  msgstr ""
3180
 
3181
+ #: lib/menu_tools_diagnostic.php:825
3182
  msgid "Other Tests"
3183
  msgstr ""
3184
 
3185
+ #: lib/menu_tools_diagnostic.php:826
3186
  msgid "System configuration, memory test, send test email from this server."
3187
  msgstr ""
3188
 
3189
+ #: lib/menu_tools_diagnostic.php:837
3190
  msgid "Click to view your system's configuration in a new window"
3191
  msgstr ""
3192
 
3193
+ #: lib/menu_tools_diagnostic.php:843
3194
  msgid "Test your WordPress host's available memory"
3195
  msgstr ""
3196
 
3197
+ #: lib/menu_tools_diagnostic.php:849
3198
  msgid "Send a test email from this WordPress server to an email address:"
3199
  msgstr ""
3200
 
3201
+ #: lib/menu_tools_diagnostic.php:851
3202
  msgid "Send Test Email"
3203
  msgstr ""
3204
 
3205
+ #: lib/menu_tools_diagnostic.php:856
3206
  msgid "Send a test activity report email:"
3207
  msgstr ""
3208
 
3209
+ #: lib/menu_tools_diagnostic.php:858
3210
  msgid "Send Test Activity Report"
3211
  msgstr ""
3212
 
3213
+ #: lib/menu_tools_diagnostic.php:863
3214
  msgid "Clear all Wordfence Central connection data"
3215
  msgstr ""
3216
 
3217
+ #: lib/menu_tools_diagnostic.php:864
3218
  msgid "Clear Connection Data"
3219
  msgstr ""
3220
 
3221
+ #: lib/menu_tools_diagnostic.php:876
3222
  msgid "Debugging Options"
3223
  msgstr ""
3224
 
3225
+ #: lib/menu_tools_diagnostic.php:893
3226
  msgid "Enable debugging mode (increases database load)"
3227
  msgstr ""
3228
 
3229
+ #: lib/menu_tools_diagnostic.php:905
3230
  msgid "Start all scans remotely (Try this if your scans aren't starting and your site is publicly accessible)"
3231
  msgstr ""
3232
 
3233
+ #: lib/menu_tools_diagnostic.php:917
3234
  msgid "Enable SSL Verification (Disable this if you are consistently unable to connect to the Wordfence servers.)"
3235
  msgstr ""
3236
 
3237
+ #: lib/menu_tools_diagnostic.php:929
3238
  msgid "Disable reading of php://input"
3239
  msgstr ""
3240
 
3241
+ #: lib/menu_tools_diagnostic.php:941
3242
  msgid "Enable beta threat defense feed"
3243
  msgstr ""
3244
 
3245
+ #: lib/menu_tools_diagnostic.php:960
3246
+ #: lib/wordfenceClass.php:6137
3247
  msgid "Restore Defaults"
3248
  msgstr ""
3249
 
3250
+ #: lib/menu_tools_diagnostic.php:961
3251
+ #: lib/wordfenceClass.php:6062
3252
  msgid "Cancel Changes"
3253
  msgstr ""
3254
 
3255
+ #: lib/menu_tools_diagnostic.php:962
3256
+ #: lib/wordfenceClass.php:6140
3257
  msgid "Save Changes"
3258
  msgstr ""
3259
 
3260
+ #: lib/menu_tools_diagnostic.php:979
3261
  #: views/options/block-all-options-controls.php:162
3262
  #: views/options/block-controls.php:77
3263
  msgid "Confirm Restore Defaults"
3264
  msgstr ""
3265
 
3266
+ #: lib/menu_tools_diagnostic.php:980
3267
  msgid "Are you sure you want to restore the default Diagnostics settings? This will undo any custom changes you have made to the options on this page."
3268
  msgstr ""
3269
 
3270
+ #: lib/menu_tools_diagnostic.php:982
3271
  #: views/options/block-all-options-controls.php:165
3272
  #: views/options/block-controls.php:80
3273
  msgid "Restore<span class=\"wf-hidden-xs\"> Defaults</span>"
3274
  msgstr ""
3275
 
3276
+ #. translators: URL to support page.
3277
+ #: lib/menu_tools_importExport.php:16
3278
  msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wf-help-link\">Learn more<span class=\"wf-hidden-xs\"> about importing and exporting options</span></a>"
3279
  msgstr ""
3280
 
3281
+ #: lib/menu_tools_importExport.php:20
3282
  msgid "To clone one site's configuration to another, use the import/export tools below."
3283
  msgstr ""
3284
 
3285
+ #: lib/menu_tools_livetraffic.php:8
3286
+ #: lib/menu_tools_livetraffic.php:41
3287
+ #: lib/menu_tools_livetraffic.php:571
3288
+ #: lib/menu_tools_livetraffic.php:602
3289
+ #: lib/wordfenceClass.php:6560
3290
+ #: models/page/wfPage.php:119
3291
+ msgid "Live Traffic"
3292
+ msgstr ""
3293
+
3294
+ #. translators: URL to support page.
3295
+ #: lib/menu_tools_livetraffic.php:44
3296
  msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wf-help-link\">Learn more<span class=\"wf-hidden-xs\"> about Live Traffic</span></a>"
3297
  msgstr ""
3298
 
3299
+ #: lib/menu_tools_livetraffic.php:51
3300
  msgid "Live Updates Paused"
3301
  msgstr ""
3302
 
3303
+ #: lib/menu_tools_livetraffic.php:52
3304
  msgid "Click inside window to resume"
3305
  msgstr ""
3306
 
3307
+ #: lib/menu_tools_livetraffic.php:57
3308
  msgid "Wordfence Live Traffic shows you what is happening on your site in real-time, including user logins, hack attempts, and requests that were blocked by the Wordfence Firewall. You can choose to log security-related traffic only or all traffic. Traffic is logged directly on the server, which means it includes visits that don't execute JavaScript. Google and other JavaScript-based analytics packages typically only show visits from browsers that are operated by a human, while Live Traffic can show visits from crawlers like Google and Bing."
3309
  msgstr ""
3310
 
3311
+ #: lib/menu_tools_livetraffic.php:73
3312
  msgid "Traffic logging mode: Security-related traffic only"
3313
  msgstr ""
3314
 
3315
+ #. translators: URL to support page.
3316
+ #: lib/menu_tools_livetraffic.php:77
3317
+ #: lib/menu_tools_livetraffic.php:86
3318
  msgid " (host setting <a href=\"%s\" class=\"wfhelp\" target=\"_blank\" rel=\"noopener noreferrer\"></a>)"
3319
  msgstr ""
3320
 
3321
+ #: lib/menu_tools_livetraffic.php:78
3322
  msgid "Login and firewall activity will appear below."
3323
  msgstr ""
3324
 
3325
+ #: lib/menu_tools_livetraffic.php:82
3326
  msgid "Traffic logging mode: All traffic"
3327
  msgstr ""
3328
 
3329
+ #: lib/menu_tools_livetraffic.php:87
3330
  msgid "Regular traffic and security-related traffic will appear below."
3331
  msgstr ""
3332
 
3333
+ #: lib/menu_tools_livetraffic.php:100
3334
+ #: lib/menu_tools_livetraffic.php:227
3335
+ #: lib/menu_tools_livetraffic.php:458
3336
+ #: lib/wordfenceClass.php:6099
3337
  msgid "Human"
3338
  msgstr ""
3339
 
3340
+ #: lib/menu_tools_livetraffic.php:101
3341
+ #: lib/menu_tools_livetraffic.php:228
3342
+ #: lib/menu_tools_livetraffic.php:458
3343
+ #: lib/wordfenceClass.php:6061
3344
  msgid "Bot"
3345
  msgstr ""
3346
 
3347
+ #: lib/menu_tools_livetraffic.php:102
3348
  msgid "Warning"
3349
  msgstr ""
3350
 
3351
+ #: lib/menu_tools_livetraffic.php:103
3352
  #: lib/wfDiagnostic.php:746
3353
+ #: lib/wordfenceClass.php:6053
3354
  msgid "Blocked"
3355
  msgstr ""
3356
 
3357
+ #: lib/menu_tools_livetraffic.php:117
3358
  msgid "Show Advanced Filters"
3359
  msgstr ""
3360
 
3361
+ #: lib/menu_tools_livetraffic.php:124
3362
  msgid "Expand All Results"
3363
  msgstr ""
3364
 
3365
+ #: lib/menu_tools_livetraffic.php:166
3366
+ msgid "Add Filter"
3367
  msgstr ""
3368
 
3369
+ #: lib/menu_tools_livetraffic.php:173
3370
+ msgid "From:"
3371
  msgstr ""
3372
 
3373
+ #: lib/menu_tools_livetraffic.php:176
3374
+ #: lib/menu_tools_livetraffic.php:183
3375
+ msgid "Clear"
3376
  msgstr ""
3377
 
3378
+ #: lib/menu_tools_livetraffic.php:180
3379
+ msgid "To:"
3380
  msgstr ""
3381
 
3382
+ #: lib/menu_tools_livetraffic.php:187
3383
+ msgid "Group By:"
3384
  msgstr ""
3385
 
3386
+ #: lib/menu_tools_livetraffic.php:212
3387
+ msgid "An unknown location at IP"
3388
  msgstr ""
3389
 
3390
+ #: lib/menu_tools_livetraffic.php:217
3391
+ #: lib/menu_tools_livetraffic.php:435
3392
+ msgid "IP:"
3393
+ msgstr ""
3394
+
3395
+ #: lib/menu_tools_livetraffic.php:226
3396
+ #: views/scanner/issue-base.php:29
3397
+ #: views/scanner/issue-base.php:39
3398
+ msgid "Type:"
3399
+ msgstr ""
3400
+
3401
+ #: lib/menu_tools_livetraffic.php:233
3402
+ msgid "Username:"
3403
+ msgstr ""
3404
+
3405
+ #: lib/menu_tools_livetraffic.php:239
3406
+ msgid "HTTP Response Code:"
3407
+ msgstr ""
3408
+
3409
+ #: lib/menu_tools_livetraffic.php:245
3410
+ msgid "Firewall Response:"
3411
+ msgstr ""
3412
+
3413
+ #: lib/menu_tools_livetraffic.php:256
3414
+ msgid "Last Hit:"
3415
+ msgstr ""
3416
+
3417
+ #. translators: Time ago.
3418
+ #: lib/menu_tools_livetraffic.php:257
3419
+ msgid "Last hit was %s ago."
3420
+ msgstr ""
3421
+
3422
+ #: lib/menu_tools_livetraffic.php:263
3423
+ #: lib/menu_tools_livetraffic.php:442
3424
+ #: lib/menu_tools_livetraffic.php:465
3425
+ msgid "Unblock IP"
3426
+ msgstr ""
3427
+
3428
+ #: lib/menu_tools_livetraffic.php:266
3429
+ #: lib/menu_tools_livetraffic.php:447
3430
+ #: lib/menu_tools_livetraffic.php:471
3431
+ msgid "Unblock range"
3432
+ msgstr ""
3433
+
3434
+ #: lib/menu_tools_livetraffic.php:269
3435
+ #: lib/menu_tools_livetraffic.php:453
3436
+ #: lib/menu_tools_livetraffic.php:477
3437
+ msgid "Block IP"
3438
+ msgstr ""
3439
+
3440
+ #. translators: Number of HTTP requests.
3441
+ #: lib/menu_tools_livetraffic.php:275
3442
+ msgid "%s hits"
3443
+ msgstr ""
3444
+
3445
+ #: lib/menu_tools_livetraffic.php:286
3446
+ #: lib/wordfenceClass.php:6168
3447
+ msgid "Type"
3448
+ msgstr ""
3449
+
3450
+ #: lib/menu_tools_livetraffic.php:287
3451
+ msgid "Location"
3452
+ msgstr ""
3453
+
3454
+ #: lib/menu_tools_livetraffic.php:288
3455
+ msgid "Page Visited"
3456
+ msgstr ""
3457
+
3458
+ #: lib/menu_tools_livetraffic.php:289
3459
+ #: lib/wf503.php:338
3460
+ #: views/reports/activity-report-email-inline.php:294
3461
+ msgid "Time"
3462
+ msgstr ""
3463
+
3464
+ #: lib/menu_tools_livetraffic.php:290
3465
+ msgid "IP Address"
3466
+ msgstr ""
3467
+
3468
+ #: lib/menu_tools_livetraffic.php:291
3469
+ #: lib/wordfenceClass.php:4224
3470
+ #: views/blocking/blocking-create.php:193
3471
+ msgid "Hostname"
3472
+ msgstr ""
3473
+
3474
+ #: lib/menu_tools_livetraffic.php:292
3475
+ msgid "Response"
3476
+ msgstr ""
3477
+
3478
+ #: lib/menu_tools_livetraffic.php:293
3479
+ #: views/scanner/issue-wfPluginAbandoned.php:18
3480
+ #: views/scanner/issue-wfPluginAbandoned.php:19
3481
+ #: views/scanner/issue-wfPluginAbandoned.php:20
3482
+ #: views/scanner/issue-wfPluginRemoved.php:17
3483
+ #: views/scanner/issue-wfPluginRemoved.php:18
3484
+ #: views/scanner/issue-wfPluginUpgrade.php:18
3485
+ #: views/scanner/issue-wfPluginUpgrade.php:19
3486
+ #: views/scanner/issue-wfPluginUpgrade.php:20
3487
+ #: views/scanner/issue-wfPluginVulnerable.php:17
3488
+ #: views/scanner/issue-wfPluginVulnerable.php:18
3489
+ #: views/scanner/issue-wfPluginVulnerable.php:19
3490
+ #: views/scanner/issue-wfThemeUpgrade.php:18
3491
+ #: views/scanner/issue-wfThemeUpgrade.php:19
3492
+ #: views/scanner/issue-wfUpgrade.php:17
3493
+ msgid "View"
3494
+ msgstr ""
3495
+
3496
+ #: lib/menu_tools_livetraffic.php:307
3497
+ msgid "Unspecified"
3498
+ msgstr ""
3499
+
3500
+ #: lib/menu_tools_livetraffic.php:341
3501
+ msgid "Activity Detail"
3502
+ msgstr ""
3503
+
3504
+ #. translators: 1. User agent. 2. IP address
3505
+ #: lib/menu_tools_livetraffic.php:359
3506
+ msgid "%1$s at an unknown location at IP %2$s"
3507
+ msgstr ""
3508
+
3509
+ #. translators: IP address
3510
+ #: lib/menu_tools_livetraffic.php:364
3511
+ msgid "An unknown location at IP %s"
3512
+ msgstr ""
3513
+
3514
+ #. translators: 1. User agent. 2. HTTP referer. 3. Server response.
3515
+ #: lib/menu_tools_livetraffic.php:371
3516
+ msgid "%1$s arrived from %2$s and %3$s"
3517
+ msgstr ""
3518
+
3519
+ #. translators: 1. User agent. 2. HTTP referer. 3. Server response.
3520
+ #: lib/menu_tools_livetraffic.php:376
3521
+ msgid "%1$s left %2$s and %3$s"
3522
+ msgstr ""
3523
+
3524
+ #. translators: User agent.
3525
+ #: lib/menu_tools_livetraffic.php:382
3526
+ msgid "%s tried to access a <span style=\"color: #F00;\">non-existent page</span>"
3527
+ msgstr ""
3528
+
3529
+ #. translators: 1. User agent. 2. URL of page visited.
3530
+ #: lib/menu_tools_livetraffic.php:388
3531
+ msgid "%1$s visited %2$s"
3532
+ msgstr ""
3533
+
3534
+ #. translators: 1. User agent. 2. URL of page visited.
3535
+ #: lib/menu_tools_livetraffic.php:393
3536
+ msgid "%1$s was redirected when visiting %2$s"
3537
+ msgstr ""
3538
+
3539
+ #. translators: 1. User agent. 2. Firewall action (blocked, rate limited, etc). 3. Time ago.
3540
+ #: lib/menu_tools_livetraffic.php:398
3541
+ #: lib/menu_tools_livetraffic.php:403
3542
+ msgid "%1$s was %2$s at %3$s"
3543
+ msgstr ""
3544
+
3545
+ #. translators: 1. User agent. 2. WordPress username.
3546
+ #: lib/menu_tools_livetraffic.php:409
3547
+ msgid "%1$s logged in successfully as \"%2$s\"."
3548
+ msgstr ""
3549
+
3550
+ #. translators: WordPress username.
3551
+ #: lib/menu_tools_livetraffic.php:412
3552
+ msgid "%s logged out successfully."
3553
+ msgstr ""
3554
+
3555
+ #. translators: WordPress username.
3556
+ #: lib/menu_tools_livetraffic.php:415
3557
+ msgid "%s requested a password reset."
3558
+ msgstr ""
3559
+
3560
+ #. translators: 1. User agent. 2. WordPress username.
3561
+ #: lib/menu_tools_livetraffic.php:418
3562
+ msgid "%1$s attempted a <span style=\"color: #F00;\">failed login</span> as \"%2$s\"."
3563
+ msgstr ""
3564
+
3565
+ #. translators: 1. User agent. 2. WordPress username.
3566
+ #: lib/menu_tools_livetraffic.php:421
3567
+ msgid "%1$s attempted a <span style=\"color: #F00;\">failed login</span> using an invalid username \"%2$s\"."
3568
+ msgstr ""
3569
+
3570
+ #. translators: WordPress username.
3571
+ #: lib/menu_tools_livetraffic.php:424
3572
+ msgid "%s changed their password."
3573
+ msgstr ""
3574
+
3575
+ #: lib/menu_tools_livetraffic.php:458
3576
+ msgid "Human/Bot:"
3577
+ msgstr ""
3578
+
3579
+ #: lib/menu_tools_livetraffic.php:481
3580
+ msgid "Run Whois"
3581
+ msgstr ""
3582
+
3583
+ #: lib/menu_tools_livetraffic.php:484
3584
+ msgid "See recent traffic"
3585
+ msgstr ""
3586
+
3587
+ #: lib/menu_tools_livetraffic.php:484
3588
+ msgid "Recent"
3589
+ msgstr ""
3590
+
3591
+ #: lib/menu_tools_livetraffic.php:489
3592
+ msgid "If this is a false positive, you can exclude this parameter from being filtered by the firewall"
3593
+ msgstr ""
3594
+
3595
+ #: lib/menu_tools_livetraffic.php:490
3596
+ msgid "Add Param to Firewall Allowlist"
3597
+ msgstr ""
3598
+
3599
+ #: lib/menu_tools_livetraffic.php:508
3600
+ msgid "No requests to report yet."
3601
+ msgstr ""
3602
+
3603
+ #: lib/menu_tools_livetraffic.php:572
3604
+ msgid "Live traffic defaults to a summary view of all security-related traffic. Details are viewable by clicking anywhere within the summary record. To switch to the expanded view, click the <strong>Expand All Records</strong> switch."
3605
+ msgstr ""
3606
+
3607
+ #: lib/menu_tools_livetraffic.php:603
3608
+ msgid "Live traffic now defaults to a summary view. Details are viewable by clicking anywhere within the summary record. To switch to the expanded view, click the <strong>Expand All Records</strong> switch. New installations will only log security-related traffic by default, though your previous setting has been preserved."
3609
+ msgstr ""
3610
+
3611
+ #: lib/menu_tools_twoFactor.php:14
3612
+ #: lib/menu_tools_twoFactor.php:23
3613
+ #: models/page/wfPage.php:117
3614
+ msgid "Two-Factor Authentication"
3615
+ msgstr ""
3616
+
3617
+ #: lib/menu_tools_twoFactor.php:16
3618
+ msgid "Learn more<span class=\"wf-hidden-xs\"> about Two-Factor Authentication</span>"
3619
+ msgstr ""
3620
+
3621
+ #: lib/menu_tools_twoFactor.php:35
3622
+ msgid "2FA Mode: Legacy"
3623
+ msgstr ""
3624
+
3625
+ #: lib/menu_tools_twoFactor.php:35
3626
  msgid "Two-factor authentication is using legacy support, which enables SMS-based codes but is less compatible. An improved interface and use by non-administrators is available by activating the new login security module."
3627
  msgstr ""
3628
 
3676
  msgid "Two-Factor Authentication Users"
3677
  msgstr ""
3678
 
3679
+ #: lib/menu_tools_twoFactor.php:175
3680
+ #: views/waf/option-whitelist.php:109
3681
+ #: views/waf/options-group-whitelisted.php:86
3682
+ #: views/waf/options-group-whitelisted.php:99
3683
+ msgid "User"
3684
+ msgstr ""
3685
+
3686
+ #: lib/menu_tools_twoFactor.php:176
3687
+ msgid "Mode"
3688
+ msgstr ""
3689
+
3690
+ #: lib/menu_tools_twoFactor.php:177
3691
+ #: views/diagnostics/text.php:225
3692
+ #: views/diagnostics/text.php:263
3693
+ #: views/diagnostics/text.php:317
3694
+ #: views/diagnostics/text.php:337
3695
+ #: views/scanner/issue-base.php:52
3696
+ #: views/scanner/issue-wafStatus.php:12
3697
+ #: views/scanner/issue-wafStatus.php:21
3698
+ msgid "Status"
3699
+ msgstr ""
3700
+
3701
+ #: lib/menu_tools_twoFactor.php:178
3702
+ #: views/waf/option-whitelist.php:102
3703
+ msgid "Delete"
3704
+ msgstr ""
3705
+
3706
+ #. translators: Phone number.
3707
  #: lib/menu_tools_twoFactor.php:186
3708
  msgid "Phone (%s)"
3709
  msgstr ""
3812
  msgid "Your site is now using the legacy two-factor authentication system."
3813
  msgstr ""
3814
 
3815
+ #: lib/menu_tools_whois.php:7
3816
+ #: lib/menu_tools_whois.php:16
3817
+ #: lib/menu_tools_whois.php:75
3818
+ #: models/page/wfPage.php:123
3819
+ msgid "Whois Lookup"
3820
+ msgstr ""
3821
+
3822
+ #. translators: URL to support page.
3823
+ #: lib/menu_tools_whois.php:19
3824
  msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wf-help-link\">Learn more<span class=\"wf-hidden-xs\"> about Whois Lookup</span></a>"
3825
  msgstr ""
3826
 
3827
+ #: lib/menu_tools_whois.php:23
3828
  msgid "The whois service gives you a way to look up who owns an IP address or domain name that is visiting your website or is engaging in malicious activity on your website."
3829
  msgstr ""
3830
 
3831
+ #: lib/menu_tools_whois.php:36
3832
  msgid "How to block a network"
3833
  msgstr ""
3834
 
3835
+ #: lib/menu_tools_whois.php:95
3836
+ #: lib/wordfenceClass.php:6081
3837
+ msgid "Enter a valid IP or domain"
3838
+ msgstr ""
3839
+
3840
+ #: lib/menu_tools_whois.php:95
3841
+ #: lib/wordfenceClass.php:6124
3842
+ msgid "Please enter a valid IP address or domain name for your whois lookup."
3843
+ msgstr ""
3844
+
3845
+ #: lib/menu_tools_whois.php:99
3846
+ #: lib/wordfenceClass.php:6105
3847
+ msgid "Loading..."
3848
+ msgstr ""
3849
+
3850
+ #: lib/menu_tools_whois.php:104
3851
+ #: lib/wordfenceClass.php:6111
3852
+ msgid "Look up IP or Domain"
3853
  msgstr ""
3854
 
3855
  #: lib/menu_wordfence_central.php:10
3878
 
3879
  #: lib/menu_wordfence_central.php:44
3880
  #: lib/menu_wordfence_central.php:57
3881
+ #: lib/wordfenceClass.php:6576
3882
  msgid "Wordfence Central"
3883
  msgstr ""
3884
 
3885
+ #. translators: 1. Email address. 2. Localized date.
3886
+ #: lib/menu_wordfence_central.php:67
3887
+ msgid "Activated - connected by %1$s on %2$s"
3888
  msgstr ""
3889
 
3890
+ #: lib/menu_wordfence_central.php:77
3891
  msgid "Wordfence Central Installation Process"
3892
  msgstr ""
3893
 
3894
+ #: lib/menu_wordfence_central.php:112
3895
  msgid "Disconnect Site"
3896
  msgstr ""
3897
 
3898
+ #: lib/menu_wordfence_central.php:118
3899
  msgid "To connect your site your site to Wordfence Central, use the link below:"
3900
  msgstr ""
3901
 
3902
+ #: lib/menu_wordfence_central.php:120
3903
  msgid "Connect Site"
3904
  msgstr ""
3905
 
3958
  msgid "Specific config options to set."
3959
  msgstr ""
3960
 
3961
+ #. translators: Error message.
3962
+ #: lib/rest-api/wfRESTConfigController.php:215
3963
+ #: lib/rest-api/wfRESTConfigController.php:258
3964
+ #: lib/wordfenceClass.php:4508
3965
  msgid "An error occurred while saving the configuration: %s"
3966
  msgstr ""
3967
 
3968
+ #. translators: Error message.
3969
+ #: lib/rest-api/wfRESTConfigController.php:226
3970
+ #: lib/rest-api/wfRESTConfigController.php:269
3971
+ #: lib/wordfenceClass.php:4517
3972
  msgid "Errors occurred while saving the configuration: %s"
3973
  msgstr ""
3974
 
3975
+ #: lib/rest-api/wfRESTConfigController.php:231
3976
+ #: lib/rest-api/wfRESTConfigController.php:274
3977
+ #: lib/wordfenceClass.php:4522
3978
  msgid "Errors occurred while saving the configuration."
3979
  msgstr ""
3980
 
3981
+ #. translators: Error message.
3982
+ #: lib/rest-api/wfRESTConfigController.php:247
3983
+ #: lib/rest-api/wfRESTConfigController.php:288
3984
  msgid "A server error occurred while saving the configuration: %s"
3985
  msgstr ""
3986
 
3987
+ #: lib/rest-api/wfRESTConfigController.php:293
3988
  msgid "Validation error: 'fields' parameter is empty or not an array."
3989
  msgstr ""
3990
 
4000
  msgid "Number of scan results to return."
4001
  msgstr ""
4002
 
4003
+ #. translators: Localized date.
4004
  #: lib/rest-api/wfRESTScanController.php:84
4005
  msgid "Wordfence scan starting at %s from Wordfence Central"
4006
  msgstr ""
4013
  msgid "SUM_KILLED:A request was received to stop the previous scan from Wordfence Central."
4014
  msgstr ""
4015
 
4016
+ #: lib/sysinfo.php:5
4017
+ msgid "Wordfence System Info"
4018
+ msgstr ""
4019
+
4020
+ #: lib/viewFullActivityLog.php:12
4021
+ msgid "Wordfence Full Activity Log"
4022
+ msgstr ""
4023
+
4024
  #: lib/wf503.php:5
4025
  msgid "Your access to this site has been limited"
4026
  msgstr ""
4027
 
4028
+ #: lib/wf503.php:321
4029
+ msgid "Your access to this site has been limited by the site owner"
4030
+ msgstr ""
4031
+
4032
+ #: lib/wf503.php:322
4033
+ msgid "Your access to this service has been limited. (HTTP response code 503)"
4034
+ msgstr ""
4035
+
4036
+ #: lib/wf503.php:323
4037
+ #: lib/wfLockedOut.php:328
4038
+ msgid "If you think you have been blocked in error, contact the owner of this site for assistance."
4039
+ msgstr ""
4040
+
4041
+ #: lib/wf503.php:331
4042
+ #: lib/wfLockedOut.php:340
4043
+ msgid "Block Technical Data"
4044
+ msgstr ""
4045
+
4046
  #: lib/wf503.php:334
4047
  msgid "Block Reason"
4048
  msgstr ""
4049
 
4050
+ #: lib/wf503.php:354
4051
+ #: lib/wfLockedOut.php:363
4052
+ msgid "About Wordfence"
4053
+ msgstr ""
4054
+
4055
+ #: lib/wf503.php:355
4056
+ #: lib/wfLockedOut.php:364
4057
+ msgid "Wordfence is a security plugin installed on over 3 million WordPress sites. The owner of this site is using Wordfence to manage access to their site."
4058
+ msgstr ""
4059
+
4060
+ #: lib/wf503.php:356
4061
+ #: lib/wfLockedOut.php:365
4062
+ msgid "You can also read the documentation to learn about Wordfence's blocking tools, or visit wordfence.com to learn more about Wordfence."
4063
  msgstr ""
4064
 
4065
+ #. translators: Support URL.
4066
  #: lib/wf503.php:360
4067
  #: lib/wfLockedOut.php:369
4068
  msgid "Click here to learn more: <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation</a>"
4069
  msgstr ""
4070
 
4071
+ #. translators: Localized date.
4072
  #: lib/wf503.php:361
4073
  #: lib/wfLockedOut.php:370
4074
  msgid "Generated by Wordfence at %s"
4075
  msgstr ""
4076
 
4077
+ #. translators: Localized date.
4078
  #: lib/wf503.php:361
4079
  #: lib/wfLockedOut.php:370
4080
  msgid "Your computer's time:"
4081
  msgstr ""
4082
 
4083
+ #. translators: URL to the WordPress admin panel.
4084
+ #: lib/wfActivityReport.php:507
4085
  #: lib/wfIssues.php:487
4086
  msgid "No longer an administrator for this site? <a href=\"%s\" target=\"_blank\">Click here</a> to stop receiving security alerts."
4087
  msgstr ""
4088
 
4089
+ #. translators: 1. Site URL. 2. Localized date.
4090
+ #: lib/wfActivityReport.php:508
4091
+ msgid "Wordfence activity for %1$s on %2$s"
4092
+ msgstr ""
4093
+
4094
+ #: lib/wfActivityReport.php:584
4095
+ #: lib/wordfenceClass.php:8298
4096
+ msgid "Blocked because the IP is blocklisted"
4097
+ msgstr ""
4098
+
4099
+ #. translators: Reason for firewall action.
4100
+ #: lib/wfActivityReport.php:587
4101
+ #: lib/wordfenceClass.php:8301
4102
+ msgid "Blocked for %s"
4103
+ msgstr ""
4104
+
4105
+ #. translators: 1. Reason for firewall action. 2. Input parameter. 2. Input parameter value.
4106
+ #: lib/wfActivityReport.php:599
4107
+ #: lib/wordfenceClass.php:8315
4108
+ msgid "Blocked for %1$s in query string: %2$s = %3$s"
4109
+ msgstr ""
4110
+
4111
+ #. translators: 1. Reason for firewall action. 2. Input parameter. 2. Input parameter value.
4112
+ #: lib/wfActivityReport.php:602
4113
+ #: lib/wordfenceClass.php:8320
4114
+ msgid "Blocked for %1$s in POST body: %2$s = %3$s"
4115
+ msgstr ""
4116
+
4117
+ #. translators: 1. Reason for firewall action. 2. Input parameter. 2. Input parameter value.
4118
+ #: lib/wfActivityReport.php:605
4119
+ #: lib/wordfenceClass.php:8325
4120
+ msgid "Blocked for %1$s in cookie: %2$s = %3$s"
4121
+ msgstr ""
4122
+
4123
+ #. translators: 1. Reason for firewall action. 2. Input parameter. 2. Input parameter value.
4124
+ #: lib/wfActivityReport.php:608
4125
+ #: lib/wordfenceClass.php:8330
4126
+ msgid "Blocked for %1$s in file: %2$s = %3$s"
4127
+ msgstr ""
4128
+
4129
+ #: lib/wfActivityReport.php:752
4130
+ #: lib/wfDiagnostic.php:478
4131
+ #: models/block/wfBlock.php:95
4132
+ msgid "Unknown"
4133
+ msgstr ""
4134
+
4135
+ #: lib/wfAdminNoticeQueue.php:180
4136
+ #: lib/wordfenceClass.php:6074
4137
+ #: lib/wordfenceClass.php:6326
4138
+ #: lib/wordfenceClass.php:8819
4139
+ msgid "Dismiss"
4140
  msgstr ""
4141
 
4142
+ #. translators: IP address.
4143
  #: lib/wfAlerts.php:29
4144
  msgid "Wordfence has blocked IP address %s."
4145
  msgstr ""
4146
 
4147
+ #. translators: Description of firewall action.
4148
  #: lib/wfAlerts.php:30
4149
  msgid "The reason is: \"%s\"."
4150
  msgstr ""
4151
 
4152
+ #. translators: Time until.
4153
  #: lib/wfAlerts.php:32
4154
  msgid "The duration of the block is %s."
4155
  msgstr ""
4156
 
4157
+ #. translators: IP address.
4158
  #: lib/wfAlerts.php:34
4159
  msgid "Blocking IP %s"
4160
  msgstr ""
4161
 
4162
+ #. translators: Software version.
4163
  #: lib/wfAlerts.php:53
4164
  msgid "Wordfence Upgraded to version %s"
4165
  msgstr ""
4166
 
4167
+ #. translators: Software version.
4168
  #: lib/wfAlerts.php:53
4169
  msgid "Your Wordfence installation has been upgraded to version %s"
4170
  msgstr ""
4173
  msgid "Wordfence WAF Deactivated"
4174
  msgstr ""
4175
 
4176
+ #. translators: WP username.
4177
  #: lib/wfAlerts.php:75
4178
  msgid "A user with username \"%s\" deactivated the Wordfence Web Application Firewall on your WordPress site."
4179
  msgstr ""
4182
  msgid "Wordfence Deactivated"
4183
  msgstr ""
4184
 
4185
+ #. translators: WP username.
4186
  #: lib/wfAlerts.php:96
4187
  msgid "A user with username \"%s\" deactivated Wordfence on your WordPress site."
4188
  msgstr ""
4191
  msgid "Password recovery attempted"
4192
  msgstr ""
4193
 
4194
+ #. translators: Email address.
4195
  #: lib/wfAlerts.php:118
4196
  msgid "Someone tried to recover the password for user with email address: %s"
4197
  msgstr ""
4198
 
4199
+ #. translators: 1. IP address. 2. Description of firewall action.
4200
+ #: lib/wfAlerts.php:142
4201
+ msgid "A user with IP address %1$s has been locked out from signing in or using the password recovery form for the following reason: %2$s."
4202
  msgstr ""
4203
 
4204
+ #. translators: Time until.
4205
+ #: lib/wfAlerts.php:144
4206
  msgid "The duration of the lockout is %s."
4207
  msgstr ""
4208
 
4209
+ #: lib/wfAlerts.php:146
4210
  msgid "User locked out from signing in"
4211
  msgstr ""
4212
 
4213
+ #: lib/wfAlerts.php:179
4214
  msgid "Admin Login"
4215
  msgstr ""
4216
 
4217
+ #. translators: WP username.
4218
+ #: lib/wfAlerts.php:179
4219
  msgid "A user with username \"%s\" who has administrator access signed in to your WordPress site."
4220
  msgstr ""
4221
 
4222
+ #: lib/wfAlerts.php:213
4223
  msgid "User login"
4224
  msgstr ""
4225
 
4226
+ #. translators: WP username.
4227
+ #: lib/wfAlerts.php:213
4228
  msgid "A non-admin user with username \"%s\" signed in to your WordPress site."
4229
  msgstr ""
4230
 
4231
+ #: lib/wfAlerts.php:241
4232
  msgid "User login blocked for insecure password"
4233
  msgstr ""
4234
 
4235
+ #. translators: 1. WP username. 2. Reset password URL. 3. Support URL.
4236
+ #: lib/wfAlerts.php:243
4237
+ msgid "A user with username \"%1$s\" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%2$s) to reactivate this account. Learn More: %3$s"
4238
  msgstr ""
4239
 
4240
+ #: lib/wfAlerts.php:260
4241
  msgid "Increased Attack Rate"
4242
  msgstr ""
4243
 
4244
+ #: lib/wfAPI.php:31
4245
+ msgid "SSL is not supported by your web server and is required to use this function. Please ask your hosting provider or site admin to install cURL with openSSL to use this feature."
4246
+ msgstr ""
4247
+
4248
+ #. translators: API call/action/endpoint.
4249
+ #: lib/wfAPI.php:39
4250
+ msgid "We received an empty data response from the Wordfence scanning servers when calling the '%s' function."
4251
+ msgstr ""
4252
+
4253
+ #: lib/wfAPI.php:73
4254
+ msgid "The Wordfence license you're using does not match this site's address. Premium features are disabled."
4255
+ msgstr ""
4256
+
4257
+ #. translators: API call/action/endpoint.
4258
+ #: lib/wfAPI.php:101
4259
+ msgid "We received a data structure that is not the expected array when contacting the Wordfence scanning servers and calling the '%s' function."
4260
+ msgstr ""
4261
+
4262
+ #. translators: API version.
4263
+ #: lib/wfAPI.php:110
4264
+ msgid "Calling Wordfence API v%s:"
4265
+ msgstr ""
4266
+
4267
+ #. translators: Error message.
4268
+ #: lib/wfAPI.php:136
4269
+ msgid "There was an error connecting to the Wordfence scanning servers: %s"
4270
+ msgstr ""
4271
+
4272
+ #: lib/wfAPI.php:138
4273
+ msgid "There was an unknown error connecting to the Wordfence scanning servers."
4274
+ msgstr ""
4275
+
4276
  #: lib/wfBulkCountries.php:5
4277
  msgid "Andorra"
4278
  msgstr ""
5273
  msgid "Zimbabwe"
5274
  msgstr ""
5275
 
5276
+ #. translators: 1. HTTP status code. 2. Error message.
5277
+ #: lib/wfCentralAPI.php:201
5278
+ msgid "HTTP %1$d received from Wordfence Central: %2$s"
5279
  msgstr ""
5280
 
5281
+ #: lib/wfCentralAPI.php:263
5282
+ #: lib/wfCentralAPI.php:319
5283
  msgid "Unable to authenticate with Wordfence Central."
5284
  msgstr ""
5285
 
5286
+ #: lib/wfCentralAPI.php:282
5287
  msgid "Wordfence Central site ID has not been created yet."
5288
  msgstr ""
5289
 
5290
+ #: lib/wfCentralAPI.php:286
5291
  msgid "Wordfence Central secret key has not been created yet."
5292
  msgstr ""
5293
 
5294
+ #: lib/wfCentralAPI.php:298
5295
  msgid "Invalid response received from Wordfence Central when fetching nonce."
5296
  msgstr ""
5297
 
5298
+ #: lib/wfCentralAPI.php:316
5299
  msgid "Invalid response received from Wordfence Central when fetching token."
5300
  msgstr ""
5301
 
5302
+ #. translators: 1. Key in key-value store. 2. Value in key-value store.
5303
+ #: lib/wfConfig.php:482
5304
+ msgid "wfConfig::set() got an array as second param with key: %1$s and value: %2$s"
5305
+ msgstr ""
5306
+
5307
+ #. translators: Key in key-value store.
5308
+ #: lib/wfConfig.php:627
5309
+ msgid "Error reassembling value for %s"
5310
+ msgstr ""
5311
+
5312
+ #. translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message.
5313
+ #: lib/wfConfig.php:721
5314
+ #: lib/wfConfig.php:730
5315
+ #: lib/wfConfig.php:737
5316
+ #: lib/wfConfig.php:747
5317
+ #: lib/wfConfig.php:754
5318
+ msgid "Error writing value chunk for %1$s (MySQLi error: [%2$s] %3$s)"
5319
+ msgstr ""
5320
+
5321
+ #. translators: Key in key-value store.
5322
+ #: lib/wfConfig.php:766
5323
+ msgid "Error writing value header for %s"
5324
+ msgstr ""
5325
+
5326
+ #. translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message.
5327
+ #: lib/wfConfig.php:779
5328
+ #: lib/wfConfig.php:790
5329
+ #: lib/wfConfig.php:800
5330
+ msgid "Error writing value for %1$s (MySQLi error: [%2$s] %3$s)"
5331
+ msgstr ""
5332
+
5333
+ #. translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message.
5334
+ #: lib/wfConfig.php:807
5335
+ msgid "Error finishing writing value for %1$s (MySQLi error: [%2$s] %3$s)"
5336
+ msgstr ""
5337
+
5338
+ #. translators: Support URL.
5339
+ #: lib/wfConfig.php:977
5340
  msgid "Wordfence Upgrade not run. Please modify your .htaccess"
5341
  msgstr ""
5342
 
5343
+ #. translators: Support URL.
5344
+ #: lib/wfConfig.php:977
5345
  msgid ""
5346
  "To preserve the integrity of your website we are not running Wordfence auto-update.\n"
5347
  "You are running the LiteSpeed web server which has been known to cause a problem with Wordfence auto-update.\n"
5353
  ""
5354
  msgstr ""
5355
 
5356
+ #: lib/wfConfig.php:1100
5357
+ msgid "Unable to save the .htaccess file needed to disable script execution in the uploads directory. Please check your permissions on that directory."
5358
  msgstr ""
5359
 
5360
+ #: lib/wfConfig.php:1137
5361
+ msgid "Unable to remove code execution protections applied to the .htaccess file in the uploads directory. Please check your permissions on that file."
5362
  msgstr ""
5363
 
5364
  #: lib/wfConfig.php:1174
5365
+ #: lib/wordfenceClass.php:7419
5366
+ msgid "The grace period end time must be in the future."
5367
+ msgstr ""
5368
+
5369
+ #: lib/wfConfig.php:1183
5370
+ msgid "Unknown firewall mode."
5371
+ msgstr ""
5372
+
5373
+ #: lib/wfConfig.php:1202
5374
  msgid "The following emails are invalid: "
5375
  msgstr ""
5376
 
5377
+ #. translators: Regular expression.
5378
+ #: lib/wfConfig.php:1215
5379
  msgid "\"%s\" is not a valid regular expression."
5380
  msgstr ""
5381
 
5382
+ #: lib/wfConfig.php:1234
5383
  msgid "Please make sure you separate your IP addresses with commas. The following allowlisted IP addresses are invalid: "
5384
  msgstr ""
5385
 
5386
+ #: lib/wfConfig.php:1253
5387
  msgid "The following users you selected to ignore in live traffic reports are not valid on this system: "
5388
  msgstr ""
5389
 
5390
+ #: lib/wfConfig.php:1270
5391
  msgid "The following IPs you selected to ignore in live traffic reports are not valid: "
5392
  msgstr ""
5393
 
5394
+ #: lib/wfConfig.php:1287
5395
  msgid "The following IPs/ranges you selected to trust as proxies are not valid: "
5396
  msgstr ""
5397
 
5398
+ #: lib/wfConfig.php:1297
5399
  msgid "An empty license key was entered."
5400
  msgstr ""
5401
 
5402
+ #: lib/wfConfig.php:1300
5403
+ #: lib/wordfenceClass.php:4393
5404
  msgid "The license key entered is not in a valid format. It must contain only numbers and the letters A-F."
5405
  msgstr ""
5406
 
5407
+ #: lib/wfConfig.php:1312
5408
+ msgid "A wildcard cannot be used to exclude all files from the scan."
5409
+ msgstr ""
5410
+
5411
+ #: lib/wfConfig.php:1779
5412
+ #: lib/wfConfig.php:1801
5413
+ msgid "The Wordfence server's response did not contain the expected elements."
5414
+ msgstr ""
5415
+
5416
+ #: lib/wfConfig.php:1783
5417
  msgid "Your options have been saved, but you left your license key blank, so we tried to get you a free license key from the Wordfence servers. There was a problem fetching the free key: "
5418
  msgstr ""
5419
 
5420
+ #: lib/wfConfig.php:1805
5421
  msgid "Your options have been saved. However we noticed you changed your license key, and we tried to verify it with the Wordfence servers but received an error: "
5422
  msgstr ""
5423
 
5424
+ #: lib/wfConfig.php:1849
5425
  msgid "Your options have been saved. However we tried to verify your license key with the Wordfence servers and received an error: "
5426
  msgstr ""
5427
 
5561
  msgid "PHP version, important PHP extensions."
5562
  msgstr ""
5563
 
5564
+ #. translators: Support URL.
5565
  #: lib/wfDiagnostic.php:110
5566
  msgid "PHP version >= PHP 5.6.20<br><em> (<a href=\"https://wordpress.org/about/requirements/\" target=\"_blank\" rel=\"noopener noreferrer\">Minimum version required by WordPress</a>)</em> <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wfhelp\"></a>"
5567
  msgstr ""
5568
 
5569
+ #. translators: Support URL.
5570
  #: lib/wfDiagnostic.php:111
5571
  msgid "Process Owner"
5572
  msgstr ""
5656
  msgid "WordPress Time Zone"
5657
  msgstr ""
5658
 
5659
+ #. translators: Number of jobs.
5660
  #: lib/wfDiagnostic.php:197
5661
+ msgid "%d Job Overdue"
5662
+ msgid_plural "%d Jobs Overdue"
5663
+ msgstr[0] ""
5664
+ msgstr[1] ""
 
 
5665
 
5666
+ #. translators: Number of jobs.
5667
  #: lib/wfDiagnostic.php:197
5668
  msgid "Normal"
5669
  msgstr ""
5673
  msgid "No files readable"
5674
  msgstr ""
5675
 
5676
+ #. translators: File name.
5677
  #: lib/wfDiagnostic.php:231
5678
  #: lib/wfDiagnostic.php:267
5679
  msgid "File \"%s\" does not exist"
5680
  msgstr ""
5681
 
5682
+ #. translators: File path.
5683
  #: lib/wfDiagnostic.php:234
5684
  msgid "File \"%s\" is unreadable"
5685
  msgstr ""
5689
  msgid "No files writable"
5690
  msgstr ""
5691
 
5692
+ #. translators: File name.
5693
  #: lib/wfDiagnostic.php:270
5694
  msgid "File \"%s\" is unwritable"
5695
  msgstr ""
5706
  msgid "(default)"
5707
  msgstr ""
5708
 
5709
+ #. translators: Unix file permissions in octal (example 0777).
5710
  #: lib/wfDiagnostic.php:388
5711
  msgid "%s - using constant"
5712
  msgstr ""
5713
 
5714
+ #. translators: Unix file permissions in octal (example 0777).
5715
  #: lib/wfDiagnostic.php:401
5716
  msgid "%s - using template"
5717
  msgstr ""
5724
  msgid "Unavailable"
5725
  msgstr ""
5726
 
 
 
 
 
 
5727
  #: lib/wfDiagnostic.php:607
5728
  #: lib/wfDiagnostic.php:610
5729
  msgid "wp_remote_post() test to noc1.wordfence.com failed! Response was: "
5733
  msgid "This likely means that your hosting provider is blocking requests to noc1.wordfence.com or has set up a proxy that is not behaving itself."
5734
  msgstr ""
5735
 
 
 
 
 
5736
  #: lib/wfDiagnostic.php:644
5737
  #: lib/wfDiagnostic.php:647
5738
  msgid "wp_remote_post() test back to this server failed! Response was: "
5742
  msgid "This additional info may help you diagnose the issue. The response headers we received were:"
5743
  msgstr ""
5744
 
5745
+ #. translators: PHP super global key.
5746
  #: lib/wfDiagnostic.php:677
5747
  msgid "We cannot read $_SERVER[%s]"
5748
  msgstr ""
5768
  msgid "An error occurred: Invalid options format received."
5769
  msgstr ""
5770
 
5771
+ #. translators: Error message.
5772
+ #: lib/wfImportExportController.php:107
5773
+ #: lib/wfImportExportController.php:114
5774
+ msgid "An error occurred: %s"
5775
+ msgstr ""
5776
+
5777
+ #. translators: Error message.
5778
+ #: lib/wfImportExportController.php:110
5779
+ msgid "Invalid response: %s"
5780
+ msgstr ""
5781
+
5782
  #: lib/wfLockedOut.php:10
5783
  msgid "You are temporarily locked out"
5784
  msgstr ""
5785
 
5786
+ #: lib/wfLockedOut.php:326
5787
+ msgid "Your access to this site has been temporarily limited by the site owner"
5788
+ msgstr ""
5789
+
5790
+ #: lib/wfLockedOut.php:327
5791
+ msgid "Your access to this service has been temporarily limited. Please try again in a few minutes. (HTTP response code 503)"
5792
+ msgstr ""
5793
+
5794
+ #: lib/wfLockedOut.php:335
5795
+ msgid "Return to the site home page"
5796
+ msgstr ""
5797
+
5798
  #: lib/wfLockedOut.php:336
5799
  msgid "Attempt to return to the admin login page (you may still be locked out)"
5800
  msgstr ""
5801
 
5802
+ #: lib/wfLockedOut.php:343
5803
+ msgid "Block Reason:"
5804
+ msgstr ""
5805
+
5806
+ #: lib/wfLockedOut.php:344
5807
+ msgid "You have been temporarily locked out of this system. This means that you will not be able to log in for a while."
5808
+ msgstr ""
5809
+
5810
  #: lib/wfLog.php:217
5811
  msgid "Exceeded the maximum global requests per minute for crawlers or humans."
5812
  msgstr ""
5827
  msgid "Exceeded the maximum number of page not found errors per minute for humans."
5828
  msgstr ""
5829
 
5830
+ #. translators: Error message.
5831
+ #: lib/wfLog.php:309
5832
+ msgid "Invalid log type to wfLog: %s"
5833
+ msgstr ""
5834
+
5835
+ #. translators: Error message.
5836
+ #: lib/wfLog.php:343
5837
+ msgid "getHits got invalid hitType: %s"
5838
+ msgstr ""
5839
+
5840
+ #: lib/wfLog.php:555
5841
+ msgid "UA/Referrer/IP Range not allowed"
5842
+ msgstr ""
5843
+
5844
  #: lib/wfLog.php:556
5845
  msgid "Advanced blocking in effect."
5846
  msgstr ""
5849
  msgid "redirected to bypass URL"
5850
  msgstr ""
5851
 
5852
+ #. translators: URL
5853
  #: lib/wfLog.php:582
5854
  msgid "blocked access via country blocking and redirected to URL (%s)"
5855
  msgstr ""
5856
 
5857
  #: lib/wfLog.php:597
5858
+ #: models/block/wfBlock.php:1439
5859
  msgid "blocked access via country blocking"
5860
  msgstr ""
5861
 
5862
  #: lib/wfLog.php:600
5863
+ #: models/block/wfBlock.php:1442
5864
  #: waf/wfWAFIPBlocksController.php:71
5865
  msgid "Access from your area has been temporarily limited for security reasons"
5866
  msgstr ""
5867
 
5868
  #: lib/wfLog.php:615
5869
+ #: lib/wordfenceClass.php:6112
5870
  #: waf/wfWAFIPBlocksController.php:97
5871
  msgid "Manual block by administrator"
5872
  msgstr ""
5873
 
5874
+ #. translators: 1. IP address. 2. Description of firewall action.
5875
  #: lib/wfLog.php:643
5876
+ msgid "Blocking IP %1$s. %2$s"
5877
  msgstr ""
5878
 
5879
+ #. translators: 1. IP address. 2. Description of firewall action.
5880
  #: lib/wfLog.php:655
5881
+ msgid "Throttling IP %1$s. %2$s"
5882
+ msgstr ""
5883
+
5884
+ #. translators: Error message.
5885
+ #: lib/wfScan.php:42
5886
+ msgid "Could not connect to database to start scan: %s"
5887
+ msgstr ""
5888
+
5889
+ #: lib/wfScan.php:45
5890
+ msgid "Looks like the Wordfence database tables have been deleted. You can fix this by de-activating and re-activating the Wordfence plugin from your Plugins menu."
5891
+ msgstr ""
5892
+
5893
+ #: lib/wfScan.php:49
5894
+ msgid "Cron test received and message printed"
5895
+ msgstr ""
5896
+
5897
+ #: lib/wfScan.php:53
5898
+ msgid "Scan engine received request."
5899
+ msgstr ""
5900
+
5901
+ #: lib/wfScan.php:56
5902
+ msgid "Verifying start request signature."
5903
  msgstr ""
5904
 
5905
  #: lib/wfScan.php:58
5906
  msgid "The signature on the request to start a scan is invalid. Please try again."
5907
  msgstr ""
5908
 
5909
+ #: lib/wfScan.php:62
5910
+ msgid "Fetching stored cronkey for comparison."
5911
+ msgstr ""
5912
+
5913
  #: lib/wfScan.php:65
5914
  msgid "[invalid]"
5915
  msgstr ""
5919
  msgid "[none]"
5920
  msgstr ""
5921
 
5922
+ #. translators: 1. WordPress nonce. 2. WordPress nonce.
5923
  #: lib/wfScan.php:67
5924
+ msgid "Checking cronkey: %1$s (expecting %2$s)"
5925
  msgstr ""
5926
 
5927
+ #: lib/wfScan.php:69
5928
+ msgid "Wordfence scan script accessed directly, or WF did not receive a cronkey."
 
5929
  msgstr ""
5930
 
5931
+ #: lib/wfScan.php:81
5932
+ msgid "Wordfence could not find a saved cron key to start the scan so assuming it started and exiting."
5933
  msgstr ""
5934
 
5935
+ #: lib/wfScan.php:85
5936
+ msgid "Checking saved cronkey against cronkey param"
5937
  msgstr ""
5938
 
5939
+ #. translators: 1. WordPress nonce (used for debugging). 2. WordPress nonce (used for debugging). 3. WordPress nonce (used for debugging).
5940
+ #: lib/wfScan.php:90
5941
+ msgid "Wordfence could not start a scan because the cron key does not match the saved key. Saved: %1$s Sent: %2$s Current unexploded: %3$s"
5942
  msgstr ""
5943
 
5944
+ #: lib/wfScan.php:110
5945
+ msgid "Checking if scan is already running"
5946
  msgstr ""
5947
 
5948
+ #: lib/wfScan.php:112
5949
+ msgid "There is already a scan running."
5950
  msgstr ""
5951
 
5952
+ #: lib/wfScan.php:121
5953
+ msgid "Using low resource scanning"
5954
  msgstr ""
5955
 
5956
+ #: lib/wfScan.php:124
5957
+ msgid "Requesting max memory"
5958
  msgstr ""
5959
 
5960
+ #: lib/wfScan.php:126
5961
+ msgid "Setting up error handling environment"
5962
  msgstr ""
5963
 
5964
+ #: lib/wfScan.php:134
5965
+ msgid "Setting up scanRunning and starting scan"
5966
  msgstr ""
5967
 
5968
+ #. translators: Error message (used for debugging).
5969
+ #: lib/wfScan.php:139
5970
+ msgid "Got a true deserialized value back from 'wfsd_engine' with type: %s"
5971
  msgstr ""
5972
 
5973
+ #. translators: Error message (used for debugging).
5974
+ #: lib/wfScan.php:143
5975
+ msgid "Scan can't continue - stored data not found after a fork. Got type: %s"
5976
  msgstr ""
5977
 
5978
+ #: lib/wfScan.php:145
5979
+ #: lib/wfScan.php:148
5980
+ msgid "Scan can't continue - stored data not found after a fork."
5981
  msgstr ""
5982
 
5983
+ #. translators: Error message.
5984
+ #: lib/wfScan.php:149
5985
+ #: lib/wfScan.php:315
5986
+ msgid "Previous scan terminated with an error. See below."
5987
  msgstr ""
5988
 
5989
+ #: lib/wfScan.php:172
5990
+ msgid "Contacting Wordfence to initiate scan"
5991
  msgstr ""
5992
 
5993
+ #: lib/wfScan.php:202
5994
+ msgid "Initiating quick scan"
5995
  msgstr ""
5996
 
5997
+ #. translators: 1. Bytes of memory. 2. Bytes of memory.
5998
+ #. translators: 1. Memory in bytes. 2. Memory in bytes.
5999
+ #: lib/wfScan.php:213
6000
+ #: lib/wfScan.php:225
6001
+ #: lib/wfScan.php:248
6002
+ #: lib/wfScan.php:263
6003
+ #: lib/wfScan.php:278
6004
+ #: lib/wfScan.php:293
6005
+ #: lib/wfScanEngine.php:442
6006
+ msgid "Wordfence used %1$s of memory for scan. Server peak memory usage was: %2$s"
6007
  msgstr ""
6008
 
6009
+ #. translators: Error message.
6010
+ #: lib/wfScan.php:217
6011
+ #: lib/wfScan.php:229
6012
+ #: lib/wfScan.php:252
6013
+ #: lib/wfScan.php:267
6014
+ #: lib/wfScan.php:282
6015
+ #: lib/wfScan.php:297
6016
+ #: lib/wfScan.php:314
6017
+ msgid "Scan terminated with error: %s"
6018
  msgstr ""
6019
 
6020
+ #: lib/wfScan.php:300
6021
+ msgid "Wordfence scan failed because of license site URL conflict"
6022
  msgstr ""
6023
 
6024
+ #. translators: Error message.
6025
+ #: lib/wfScan.php:352
6026
+ msgid "Scan Engine Error: %s"
6027
  msgstr ""
6028
 
6029
+ #. translators: Number of scan results.
6030
+ #: lib/wfScanEngine.php:113
6031
+ msgid "%d issue found in most recent scan"
6032
+ msgid_plural "%d issues found in most recent scan"
6033
+ msgstr[0] ""
6034
+ msgstr[1] ""
6035
+
6036
+ #. translators: 1. Time duration. 2. Support URL.
6037
+ #: lib/wfScanEngine.php:278
6038
+ msgid "The scan time limit of %1$s has been exceeded and the scan will be terminated. This limit can be customized on the options page. <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">Get More Information</a>"
6039
  msgstr ""
6040
 
6041
+ #: lib/wfScanEngine.php:282
6042
+ msgid "Scan Time Limit Exceeded"
6043
  msgstr ""
6044
 
6045
+ #. translators: 1. Number of files. 2. Number of plugins. 3. Number of themes. 4. Number of posts. 5. Number of comments. 6. Number of URLs. 7. Time duration.
6046
+ #: lib/wfScanEngine.php:287
6047
+ msgid "Scan interrupted. Scanned %1$d files, %2$d plugins, %3$d themes, %4$d posts, %5$d comments and %6$d URLs in %7$s."
6048
  msgstr ""
6049
 
6050
+ #. translators: Number of scan results.
6051
+ #: lib/wfScanEngine.php:300
6052
+ msgid "Scan interrupted. You have %d new issue to fix. See below."
6053
+ msgid_plural "Scan interrupted. You have %d new issues to fix. See below."
6054
+ msgstr[0] ""
6055
+ msgstr[1] ""
6056
+
6057
+ #: lib/wfScanEngine.php:309
6058
+ msgid "Scan interrupted. No problems found prior to stopping."
6059
  msgstr ""
6060
 
6061
+ #. translators: 1. Software version. 2. Software version.
6062
+ #: lib/wfScanEngine.php:321
6063
+ msgid "Aborting scan because WordPress updated from version %1$s to %2$s. The scan will be reattempted later."
6064
  msgstr ""
6065
 
6066
+ #: lib/wfScanEngine.php:351
6067
+ msgid "Forking during hash scan to ensure continuity."
 
 
 
6068
  msgstr ""
6069
 
6070
+ #: lib/wfScanEngine.php:357
6071
+ msgid "Entered fork()"
6072
  msgstr ""
6073
 
6074
+ #: lib/wfScanEngine.php:360
6075
+ msgid "Calling startScan(true)"
6076
  msgstr ""
6077
 
6078
+ #. translators: 1. Number of files. 2. Number of plugins. 3. Number of themes. 4. Number of posts. 5. Number of comments. 6. Number of URLs. 7. Time duration.
6079
+ #: lib/wfScanEngine.php:450
6080
+ msgid "Scan Complete. Scanned %1$d files, %2$d plugins, %3$d themes, %4$d posts, %5$d comments and %6$d URLs in %7$s."
6081
  msgstr ""
6082
 
6083
+ #. translators: 1. Time duration.
6084
+ #: lib/wfScanEngine.php:462
6085
+ msgid "Quick Scan Complete. Scanned in %s."
6086
  msgstr ""
6087
 
6088
+ #. translators: Number of scan results.
6089
+ #: lib/wfScanEngine.php:471
6090
+ msgid "%d ignored issue was also detected."
6091
+ msgid_plural "%d ignored issues were also detected."
6092
+ msgstr[0] ""
6093
+ msgstr[1] ""
6094
+
6095
+ #. translators: Number of scan results.
6096
+ #: lib/wfScanEngine.php:482
6097
+ msgid "Scan complete. You have %d new issue to fix."
6098
+ msgid_plural "Scan complete. You have %d new issues to fix."
6099
+ msgstr[0] ""
6100
+ msgstr[1] ""
6101
+
6102
+ #: lib/wfScanEngine.php:490
6103
+ msgid "See below."
6104
  msgstr ""
6105
 
6106
+ #: lib/wfScanEngine.php:493
6107
+ msgid "Scan complete. Congratulations, no new problems found."
6108
  msgstr ""
6109
 
6110
+ #: lib/wfScanEngine.php:504
6111
+ msgid "Checking if your site IP is generating spam"
6112
  msgstr ""
6113
 
6114
+ #: lib/wfScanEngine.php:523
6115
+ msgid "Checking if your IP is generating spam is for paid members only"
6116
  msgstr ""
6117
 
6118
+ #: lib/wfScanEngine.php:530
6119
+ msgid "Checking if your site is on a domain blocklist"
6120
  msgstr ""
6121
 
6122
+ #: lib/wfScanEngine.php:535
6123
+ msgid "Checking if your site is on a domain blocklist is for paid members only"
6124
  msgstr ""
6125
 
6126
+ #. translators: Error message.
6127
+ #: lib/wfScanEngine.php:571
6128
+ msgid "Error checking domain blocklists: %s"
6129
  msgstr ""
6130
 
6131
+ #. translators: WordPress site ID.
6132
+ #: lib/wfScanEngine.php:605
6133
+ msgid "The multisite blog with ID %d is listed on Google's Safe Browsing malware list."
6134
  msgstr ""
6135
 
6136
+ #: lib/wfScanEngine.php:608
6137
+ msgid "Your site is listed on Google's Safe Browsing malware list."
6138
  msgstr ""
6139
 
6140
+ #. translators: 1. URL. 2. URL.
6141
+ #: lib/wfScanEngine.php:612
6142
+ msgid "The URL %1$s is on the malware list. More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%2$s&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>."
6143
  msgstr ""
6144
 
6145
+ #. translators: WordPress site ID.
6146
+ #: lib/wfScanEngine.php:618
6147
+ msgid "The multisite blog with ID %d is listed on Google's Safe Browsing phishing list."
6148
  msgstr ""
6149
 
6150
+ #: lib/wfScanEngine.php:621
6151
+ msgid "Your site is listed on Google's Safe Browsing phishing list."
6152
  msgstr ""
6153
 
6154
+ #. translators: 1. URL. 2. URL.
6155
+ #: lib/wfScanEngine.php:625
6156
+ msgid "The URL %1$s is on the phishing list. More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%2$s&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>."
6157
  msgstr ""
6158
 
6159
+ #. translators: WordPress site ID.
6160
+ #: lib/wfScanEngine.php:631
6161
+ msgid "The multisite blog with ID %d is listed on the Wordfence domain blocklist."
6162
  msgstr ""
6163
 
6164
+ #: lib/wfScanEngine.php:634
6165
+ msgid "Your site is listed on the Wordfence domain blocklist."
6166
  msgstr ""
6167
 
6168
+ #. translators: URL.
6169
+ #: lib/wfScanEngine.php:638
6170
+ msgid "The URL %s is on the blocklist."
6171
  msgstr ""
6172
 
6173
+ #. translators: WordPress site ID.
6174
+ #: lib/wfScanEngine.php:644
6175
+ msgid "The multisite blog with ID %d is listed on a domain blocklist."
6176
  msgstr ""
6177
 
6178
+ #: lib/wfScanEngine.php:647
6179
+ msgid "Your site is listed on a domain blocklist."
 
6180
  msgstr ""
6181
 
6182
+ #. translators: URL.
6183
+ #: lib/wfScanEngine.php:649
6184
+ msgid "The URL is: %s"
6185
  msgstr ""
6186
 
6187
+ #: lib/wfScanEngine.php:669
6188
+ msgid "Checking for the most secure way to get IPs"
 
6189
  msgstr ""
6190
 
6191
+ #: lib/wfScanEngine.php:696
6192
+ msgid "Unable to accurately detect IPs"
6193
  msgstr ""
6194
 
6195
+ #. translators: Support URL.
6196
+ #: lib/wfScanEngine.php:697
6197
+ msgid "Wordfence was unable to validate a test request to your website. This can happen if your website is behind a proxy that does not use one of the standard ways to convey the IP of the request or it is unreachable publicly. IP blocking and live traffic information may not be accurate. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Get More Information</a>"
6198
  msgstr ""
6199
 
6200
+ #: lib/wfScanEngine.php:707
6201
+ #: lib/wordfenceClass.php:6303
6202
+ msgid "For maximum security use PHP's built in REMOTE_ADDR."
6203
  msgstr ""
6204
 
6205
+ #: lib/wfScanEngine.php:709
6206
+ #: lib/wordfenceClass.php:6306
6207
+ msgid "This site appears to be behind a front-end proxy, so using the X-Forwarded-For HTTP header will resolve to the correct IPs."
6208
  msgstr ""
6209
 
6210
+ #: lib/wfScanEngine.php:711
6211
+ #: lib/wordfenceClass.php:6309
6212
+ msgid "This site appears to be behind a front-end proxy, so using the X-Real-IP HTTP header will resolve to the correct IPs."
6213
  msgstr ""
6214
 
6215
+ #: lib/wfScanEngine.php:713
6216
+ #: lib/wordfenceClass.php:6312
6217
+ msgid "This site appears to be behind Cloudflare, so using the Cloudflare \"CF-Connecting-IP\" HTTP header will resolve to the correct IPs."
6218
  msgstr ""
6219
 
6220
+ #: lib/wfScanEngine.php:717
6221
+ msgid "'How does Wordfence get IPs' is misconfigured"
6222
  msgstr ""
6223
 
6224
+ #. translators: Support URL.
6225
+ #: lib/wfScanEngine.php:720
6226
+ msgid "A test request to this website was detected on a different value for this setting. IP blocking and live traffic information may not be accurate. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Get More Information</a>"
6227
  msgstr ""
6228
 
6229
+ #: lib/wfScanEngine.php:741
6230
+ msgid "Check for publicly accessible configuration files, backup files and logs"
 
 
6231
  msgstr ""
6232
 
6233
+ #. translators: File path.
6234
+ #: lib/wfScanEngine.php:792
6235
+ msgid "Publicly accessible config, backup, or log file found: %s"
6236
  msgstr ""
6237
 
6238
+ #. translators: 1. URL to publicly accessible file. 2. Support URL.
6239
+ #: lib/wfScanEngine.php:795
6240
+ msgid "<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%1$s</a> is publicly accessible and may expose source code or sensitive information about your site. Files such as this one are commonly checked for by scanners and should be made inaccessible. Alternately, some can be removed if you are certain your site does not need them. Sites using the nginx web server may need manual configuration changes to protect such files. <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn more</a>"
6241
  msgstr ""
6242
 
6243
+ #: lib/wfScanEngine.php:824
6244
+ msgid "Checking if your server discloses the path to the document root"
6245
  msgstr ""
6246
 
6247
+ #: lib/wfScanEngine.php:834
6248
+ msgid "Web server exposes the document root"
6249
  msgstr ""
6250
 
6251
+ #: lib/wfScanEngine.php:835
6252
+ msgid "Full Path Disclosure (FPD) vulnerabilities enable the attacker to see the path to the webroot/file. e.g.: /home/user/htdocs/file/. Certain vulnerabilities, such as using the load_file() (within a SQL Injection) query to view the page source, require the attacker to have the full path to the file they wish to view."
6253
  msgstr ""
6254
 
6255
+ #: lib/wfScanEngine.php:861
6256
+ msgid "Directory listing is enabled"
6257
  msgstr ""
6258
 
6259
+ #: lib/wfScanEngine.php:862
6260
+ msgid "Directory listing provides an attacker with the complete index of all the resources located inside of the directory. The specific risks and consequences vary depending on which files are listed and accessible, but it is recommended that you disable it unless it is needed."
 
6261
  msgstr ""
6262
 
6263
+ #: lib/wfScanEngine.php:878
6264
+ msgid "Checking if your site is being Spamvertised"
6265
  msgstr ""
6266
 
6267
+ #: lib/wfScanEngine.php:897
6268
+ msgid "Check if your site is being Spamvertized is for paid members only"
6269
  msgstr ""
6270
 
6271
+ #: lib/wfScanEngine.php:918
6272
+ msgid "Wordfence could not read the contents of your base WordPress directory. This usually indicates your permissions are so strict that your web server can't read your WordPress directory."
 
6273
  msgstr ""
6274
 
6275
+ #: lib/wfScanEngine.php:955
6276
+ msgid "Checking for paths skipped due to scan settings"
 
6277
  msgstr ""
6278
 
6279
+ #. translators: Number of paths skipped in scan.
6280
+ #: lib/wfScanEngine.php:968
6281
+ msgid ", and %d more."
6282
  msgstr ""
6283
 
6284
+ #. translators: Number of paths skipped in scan.
6285
+ #: lib/wfScanEngine.php:992
6286
+ msgid "%d path was skipped for the malware scan due to scan settings"
6287
+ msgid_plural "%d paths were skipped for the malware scan due to scan settings"
6288
+ msgstr[0] ""
6289
+ msgstr[1] ""
6290
+
6291
+ #. translators: 1. Number of paths skipped in scan. 2. Support URL. 3. List of skipped paths.
6292
+ #: lib/wfScanEngine.php:995
6293
+ msgid "The option \"Scan files outside your WordPress installation\" is off by default, which means %1$d path and its file(s) will not be scanned for malware or unauthorized changes. To continue skipping this path, you may ignore this issue. Or to start scanning it, enable the option and subsequent scans will include it. Some paths may not be necessary to scan, so this is optional. <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a><br><br>The path skipped is %3$s"
6294
+ msgid_plural "The option \"Scan files outside your WordPress installation\" is off by default, which means %1$d paths and their file(s) will not be scanned for malware or unauthorized changes. To continue skipping these paths, you may ignore this issue. Or to start scanning them, enable the option and subsequent scans will include them. Some paths may not be necessary to scan, so this is optional. <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a><br><br>The paths skipped are %3$s"
6295
+ msgstr[0] ""
6296
+ msgstr[1] ""
6297
+
6298
+ #: lib/wfScanEngine.php:1023
6299
+ msgid "Including files that are outside the WordPress installation in the scan."
6300
  msgstr ""
6301
 
6302
+ #: lib/wfScanEngine.php:1026
6303
+ msgid "Getting plugin list from WordPress"
6304
  msgstr ""
6305
 
6306
+ #. translators: Number of plugins.
6307
+ #: lib/wfScanEngine.php:1028
6308
+ msgid "Found %d plugin"
6309
+ msgid_plural "Found %d plugins"
6310
+ msgstr[0] ""
6311
+ msgstr[1] ""
6312
+
6313
+ #: lib/wfScanEngine.php:1030
6314
+ msgid "Getting theme list from WordPress"
6315
  msgstr ""
6316
 
6317
+ #. translators: Number of themes.
6318
+ #: lib/wfScanEngine.php:1032
6319
+ msgid "Found %d theme"
6320
+ msgid_plural "Found %d themes"
6321
+ msgstr[0] ""
6322
+ msgstr[1] ""
6323
+
6324
+ #: lib/wfScanEngine.php:1049
6325
+ msgid "Scanning file contents for infections and vulnerabilities"
6326
  msgstr ""
6327
 
6328
+ #: lib/wfScanEngine.php:1052
6329
+ msgid "Skipping scan of file contents for infections and vulnerabilities"
6330
  msgstr ""
6331
 
6332
+ #: lib/wfScanEngine.php:1056
6333
+ msgid "Scanning file contents for URLs on a domain blocklist"
 
 
6334
  msgstr ""
6335
 
6336
+ #: lib/wfScanEngine.php:1059
6337
+ msgid "Skipping scan of file contents for URLs on a domain blocklist"
6338
  msgstr ""
6339
 
6340
+ #: lib/wfScanEngine.php:1064
6341
+ msgid "Starting scan of file contents"
6342
  msgstr ""
6343
 
6344
+ #: lib/wfScanEngine.php:1080
6345
+ msgid "Done file contents scan"
6346
  msgstr ""
6347
 
6348
+ #. translators: Scan result description.
6349
+ #: lib/wfScanEngine.php:1088
6350
+ #: lib/wfScanEngine.php:2252
6351
+ #: lib/wfScanEngine.php:2294
6352
+ msgid "Adding issue: %s"
6353
  msgstr ""
6354
 
6355
+ #: lib/wfScanEngine.php:1121
6356
+ msgid "Scanning for publicly accessible quarantined files"
6357
  msgstr ""
6358
 
6359
+ #. translators: File path.
6360
+ #: lib/wfScanEngine.php:1126
6361
+ msgid "Testing accessibility of: %s"
6362
  msgstr ""
6363
 
6364
+ #. translators: File path.
6365
+ #: lib/wfScanEngine.php:1135
6366
+ msgid "Publicly accessible quarantined file found: %s"
6367
  msgstr ""
6368
 
6369
+ #. translators: URL to publicly accessible file.
6370
+ #: lib/wfScanEngine.php:1138
6371
+ msgid "<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%1$s</a> is publicly accessible and may expose source code or sensitive information about your site. Files such as this one are commonly checked for by scanners and should be removed or made inaccessible."
6372
  msgstr ""
6373
 
6374
+ #: lib/wfScanEngine.php:1162
6375
+ msgid "Scanning posts for URLs on a domain blocklist"
6376
  msgstr ""
6377
 
6378
+ #. translators: Number of posts left to scan.
6379
+ #: lib/wfScanEngine.php:1185
6380
+ msgid "Scanning posts with %d left to scan."
6381
  msgstr ""
6382
 
6383
+ #: lib/wfScanEngine.php:1207
6384
+ msgid "Post title contains suspicious code"
6385
  msgstr ""
6386
 
6387
+ #: lib/wfScanEngine.php:1208
6388
+ msgid "This post contains code that is suspicious. Please check the title of the post and confirm that the code in the title is not malicious."
6389
  msgstr ""
6390
 
6391
+ #: lib/wfScanEngine.php:1231
6392
+ msgid "Examining URLs found in posts we scanned for dangerous websites"
6393
  msgstr ""
6394
 
6395
+ #: lib/wfScanEngine.php:1233
6396
+ #: lib/wfScanEngine.php:2215
6397
+ msgid "Done examining URLs"
6398
  msgstr ""
6399
 
6400
+ #. translators: 1. WordPress Post type. 2. URL.
6401
+ #: lib/wfScanEngine.php:1269
6402
+ #: lib/wfScanEngine.php:1289
6403
+ msgid "%1$s contains a suspected malware URL: %2$s"
6404
  msgstr ""
6405
 
6406
+ #. translators: 1. WordPress Post type. 2. URL. 3. URL.
6407
+ #: lib/wfScanEngine.php:1275
6408
+ msgid "This %1$s contains a suspected malware URL listed on Google's list of malware sites. The URL is: %2$s - More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%3$s&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>."
6409
  msgstr ""
6410
 
6411
+ #. translators: 1. WordPress Post type. 2. URL.
6412
+ #: lib/wfScanEngine.php:1281
6413
+ msgid "%1$s contains a suspected phishing site URL: %2$s"
6414
  msgstr ""
6415
 
6416
+ #. translators: 1. WordPress Post type. 2. URL.
6417
+ #. translators: 1. WordPress post type. 2. URL.
6418
+ #: lib/wfScanEngine.php:1284
6419
+ #: lib/wfScanEngine.php:1427
6420
+ msgid "This %1$s contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. The URL is: %2$s"
6421
  msgstr ""
6422
 
6423
+ #. translators: 1. WordPress Post type. 2. URL.
6424
+ #. translators: 1. WordPress post type. 2. URL.
6425
+ #: lib/wfScanEngine.php:1292
6426
+ #: lib/wfScanEngine.php:1435
6427
+ msgid "This %1$s contains a URL that is currently listed on Wordfence's domain blocklist. The URL is: %2$s"
6428
  msgstr ""
6429
 
6430
+ #. translators: Scan result description.
6431
+ #: lib/wfScanEngine.php:1301
6432
+ msgid "Adding issue: %1$s"
6433
  msgstr ""
6434
 
6435
+ #: lib/wfScanEngine.php:1337
6436
+ msgid "Scanning comments for URLs on a domain blocklist"
6437
  msgstr ""
6438
 
6439
+ #. translators: Number of comments left to scan.
6440
+ #: lib/wfScanEngine.php:1361
6441
+ msgid "Scanning comments with %d left to scan."
6442
  msgstr ""
6443
 
6444
+ #. translators: 1. WordPress post type. 2. WordPress author username.
6445
+ #: lib/wfScanEngine.php:1415
6446
+ msgid "%1$s with author %2$s contains a suspected malware URL."
6447
  msgstr ""
6448
 
6449
+ #. translators: 1. WordPress post type. 2. URL. 3. URL.
6450
+ #: lib/wfScanEngine.php:1418
6451
+ msgid "This %$1s contains a suspected malware URL listed on Google's list of malware sites. The URL is: %2$s - More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%3$s&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>."
6452
  msgstr ""
6453
 
6454
+ #. translators: WordPress post type.
6455
+ #: lib/wfScanEngine.php:1424
6456
+ msgid "%s contains a suspected phishing site URL."
6457
  msgstr ""
6458
 
6459
+ #. translators: URL.
6460
+ #: lib/wfScanEngine.php:1432
6461
+ msgid "%s contains a suspected malware URL."
6462
  msgstr ""
6463
 
6464
+ #. translators: WordPress username.
6465
+ #: lib/wfScanEngine.php:1480
6466
+ msgid "Author: %s"
6467
  msgstr ""
6468
 
6469
+ #. translators: Email address.
6470
+ #: lib/wfScanEngine.php:1483
6471
+ msgid "Email: %s"
6472
  msgstr ""
6473
 
6474
+ #. translators: IP address.
6475
+ #: lib/wfScanEngine.php:1485
6476
+ msgid "Source IP: %s"
6477
  msgstr ""
6478
 
6479
+ #. translators: Comment description.
6480
+ #: lib/wfScanEngine.php:1486
6481
+ msgid "Scanning comment with %s"
6482
  msgstr ""
6483
 
6484
+ #. translators: Comment description.
6485
+ #: lib/wfScanEngine.php:1499
6486
+ #: lib/wfScanEngine.php:1505
6487
+ msgid "Marking comment as spam for containing a malware URL. Comment has %s"
6488
  msgstr ""
6489
 
6490
+ #. translators: Comment description.
6491
+ #: lib/wfScanEngine.php:1502
6492
+ msgid "Marking comment as spam for containing a phishing URL. Comment has %s"
6493
  msgstr ""
6494
 
6495
+ #. translators: Comment description.
6496
+ #: lib/wfScanEngine.php:1512
6497
+ msgid "Scanned comment with %s"
6498
  msgstr ""
6499
 
6500
+ #: lib/wfScanEngine.php:1563
6501
+ msgid "Scanning for weak passwords"
6502
  msgstr ""
6503
 
6504
+ #: lib/wfScanEngine.php:1574
6505
+ msgid "We were unable to generate the user list for your password check."
 
6506
  msgstr ""
6507
 
6508
+ #. translators: Number of users.
6509
+ #: lib/wfScanEngine.php:1590
6510
+ msgid "Starting password strength check on %d user."
6511
+ msgid_plural "Starting password strength check on %d users."
6512
+ msgstr[0] ""
6513
+ msgstr[1] ""
6514
+
6515
+ #. translators: Number of users.
6516
+ #: lib/wfScanEngine.php:1599
6517
+ msgid "Total of %d users left to process in password strength check."
6518
+ msgid_plural "Total of %d users left to process in password strength check."
6519
+ msgstr[0] ""
6520
+ msgstr[1] ""
6521
+
6522
+ #. translators: WordPress user ID.
6523
+ #: lib/wfScanEngine.php:1634
6524
+ msgid "Could not get username for user with ID %d when checking password strength."
6525
  msgstr ""
6526
 
6527
+ #. translators: 1. WordPress username. 2. WordPress user ID.
6528
+ #: lib/wfScanEngine.php:1640
6529
+ msgid "Checking password strength of user '%1$s' with ID %2$d"
6530
  msgstr ""
6531
 
6532
+ #. translators: 1. WordPress username. 2. WordPress capability.
6533
+ #: lib/wfScanEngine.php:1648
6534
+ msgid "User \"%1$s\" with \"%2$s\" access has an easy password."
6535
  msgstr ""
6536
 
6537
+ #. translators: WordPress capability.
6538
+ #: lib/wfScanEngine.php:1654
6539
+ msgid "A user with the a role of '%s' has a password that is easy to guess. Please change this password yourself or ask the user to change it."
6540
  msgstr ""
6541
 
6542
+ #. translators: WordPress username.
6543
+ #: lib/wfScanEngine.php:1662
6544
+ msgid "User \"%s\" with 'subscriber' access has a very easy password."
6545
  msgstr ""
6546
 
6547
+ #: lib/wfScanEngine.php:1663
6548
+ msgid "A user with 'subscriber' access has a password that is very easy to guess. Please either change it or ask the user to change their password."
6549
  msgstr ""
6550
 
6551
+ #. translators: Scan result description.
6552
+ #: lib/wfScanEngine.php:1670
6553
+ msgid "Adding issue %s"
 
 
 
6554
  msgstr ""
6555
 
6556
+ #. translators: WordPress username.
6557
+ #: lib/wfScanEngine.php:1687
6558
+ msgid "Completed checking password strength of user '%s'"
6559
  msgstr ""
6560
 
6561
+ #: lib/wfScanEngine.php:1720
6562
+ msgid "Scanning to check available disk space"
6563
  msgstr ""
6564
 
6565
+ #: lib/wfScanEngine.php:1727
6566
+ msgid "Unable to access available disk space information"
6567
  msgstr ""
6568
 
6569
+ #. translators: 1. Number of bytes. 2. Number of bytes.
6570
+ #: lib/wfScanEngine.php:1736
6571
+ msgid "Total disk space: %1$s -- Free disk space: %2$s"
6572
  msgstr ""
6573
 
6574
+ #. translators: Number of bytes.
6575
+ #: lib/wfScanEngine.php:1741
6576
+ msgid "The disk has %s MB available"
6577
  msgstr ""
6578
 
6579
+ #. translators: Number of bytes.
6580
+ #: lib/wfScanEngine.php:1756
6581
+ msgid "You have %s disk space remaining"
6582
  msgstr ""
6583
 
6584
+ #. translators: Number of bytes.
6585
+ #: lib/wfScanEngine.php:1757
6586
+ msgid "You only have %s of your disk space remaining. Please free up disk space or your website may stop serving requests."
6587
  msgstr ""
6588
 
6589
+ #: lib/wfScanEngine.php:1770
6590
+ msgid "Checking Web Application Firewall status"
6591
  msgstr ""
6592
 
6593
+ #: lib/wfScanEngine.php:1781
6594
+ msgid "Web Application Firewall is disabled"
 
6595
  msgstr ""
6596
 
6597
+ #. translators: Support URL.
6598
+ #: lib/wfScanEngine.php:1782
6599
+ msgid "Wordfence's Web Application Firewall has been unexpectedly disabled. If you see a notice at the top of the Wordfence admin pages that says \"The Wordfence Web Application Firewall cannot run,\" click the link in that message to rebuild the configuration. If this does not work, you may need to fix file permissions. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">More Details</a>"
6600
  msgstr ""
6601
 
6602
+ #: lib/wfScanEngine.php:1797
6603
+ msgid "Scanning for old themes, plugins and core files"
6604
  msgstr ""
6605
 
6606
+ #: lib/wfScanEngine.php:1883
6607
+ msgid "Your WordPress version is out of date"
6608
  msgstr ""
6609
 
6610
+ #. translators: Software version.
6611
+ #: lib/wfScanEngine.php:1884
6612
+ msgid "WordPress version %s is now available. Please upgrade immediately to get the latest security updates from WordPress."
6613
  msgstr ""
6614
 
6615
+ #. translators: 1. Plugin name. 2. Software version. 3. Software version.
6616
+ #: lib/wfScanEngine.php:1911
6617
+ msgid "The Plugin \"%1$s\" needs an upgrade (%2$s -> %3$s)."
6618
  msgstr ""
6619
 
6620
+ #. translators: Theme name.
6621
+ #: lib/wfScanEngine.php:1918
6622
+ #: lib/wfScanEngine.php:1952
6623
+ msgid "You need to upgrade \"%s\" to the newest version to ensure you have any security fixes the developer has released."
6624
  msgstr ""
6625
 
6626
+ #. translators: 1. Theme name. 2. Software version. 3. Software version.
6627
+ #: lib/wfScanEngine.php:1945
6628
+ msgid "The Theme \"%1$s\" needs an upgrade (%2$s -> %3$s)."
6629
  msgstr ""
6630
 
6631
+ #. translators: 1. Plugin name. 2. Software version. 3. Software version.
6632
+ #: lib/wfScanEngine.php:1991
6633
+ msgid "The Plugin \"%1$s\" appears to be abandoned (updated %2$s, tested to WP %3$s)."
6634
  msgstr ""
6635
 
6636
+ #. translators: 1. Plugin name. 2. Software version.
6637
+ #: lib/wfScanEngine.php:1998
6638
+ msgid "It was last updated %1$s ago and tested up to WordPress %2$s."
6639
  msgstr ""
6640
 
6641
+ #. translators: 1. Plugin name. 2. Software version.
6642
+ #: lib/wfScanEngine.php:2005
6643
+ msgid "The Plugin \"%1$s\" appears to be abandoned (updated %2$s)."
6644
  msgstr ""
6645
 
6646
+ #. translators: Time duration.
6647
+ #: lib/wfScanEngine.php:2011
6648
+ msgid "It was last updated %s ago."
6649
  msgstr ""
6650
 
6651
+ #: lib/wfScanEngine.php:2017
6652
+ #: lib/wfScanEngine.php:2056
6653
+ msgid "It has unpatched security issues and may have compatibility problems with the current version of WordPress."
6654
  msgstr ""
6655
 
6656
+ #: lib/wfScanEngine.php:2019
6657
+ #: lib/wfScanEngine.php:2058
6658
+ msgid "Plugins can be removed from wordpress.org for various reasons. This can include benign issues like a plugin author discontinuing development or moving the plugin distribution to their own site, but some might also be due to security issues. In any case, future updates may or may not be available, so it is worth investigating the cause and deciding whether to temporarily or permanently replace or remove the plugin."
6659
  msgstr ""
6660
 
6661
+ #. translators: Support URL.
6662
+ #: lib/wfScanEngine.php:2023
6663
+ #: lib/wfScanEngine.php:2062
6664
+ #: lib/wfScanEngine.php:2250
6665
+ #: lib/wfScanEngine.php:2292
6666
+ msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Get more information.</a>"
6667
  msgstr ""
6668
 
6669
+ #. translators: Plugin name.
6670
+ #: lib/wfScanEngine.php:2054
6671
+ msgid "The Plugin \"%s\" has been removed from wordpress.org."
6672
  msgstr ""
6673
 
6674
+ #: lib/wfScanEngine.php:2107
6675
+ msgid "Scanning for admin users not created through WordPress"
6676
  msgstr ""
6677
 
6678
+ #. translators: WordPress username.
6679
+ #: lib/wfScanEngine.php:2129
6680
+ msgid "An admin user with the username %s was created outside of WordPress."
6681
  msgstr ""
6682
 
6683
+ #. translators: WordPress username.
6684
+ #: lib/wfScanEngine.php:2130
6685
+ msgid "An admin user with the username %s was created outside of WordPress. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it."
6686
  msgstr ""
6687
 
6688
+ #. translators: WordPress username.
6689
+ #: lib/wfScanEngine.php:2156
6690
+ msgid "An admin user with a suspicious username %s was found."
6691
  msgstr ""
6692
 
6693
+ #. translators: WordPress username.
6694
+ #: lib/wfScanEngine.php:2157
6695
+ msgid "An admin user with a suspicious username %s was found. Administrators accounts with usernames similar to this are commonly seen created by hackers. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it."
6696
  msgstr ""
6697
 
6698
+ #: lib/wfScanEngine.php:2178
6699
+ msgid "Scanning for suspicious site options"
6700
  msgstr ""
6701
 
6702
+ #: lib/wfScanEngine.php:2213
6703
+ msgid "Examining URLs found in the options we scanned for dangerous websites"
6704
+ msgstr ""
6705
+
6706
+ #. translators: URL.
6707
+ #: lib/wfScanEngine.php:2237
6708
+ #: lib/wfScanEngine.php:2243
6709
+ msgid "Option contains a suspected malware URL: %s"
6710
+ msgstr ""
6711
+
6712
+ #. translators: URL.
6713
+ #: lib/wfScanEngine.php:2238
6714
+ msgid "This option contains a suspected malware URL listed on Google's list of malware sites. It may indicate your site is infected with malware. The URL is: %s"
6715
+ msgstr ""
6716
+
6717
+ #. translators: URL.
6718
+ #: lib/wfScanEngine.php:2240
6719
+ msgid "Option contains a suspected phishing site URL: %s"
6720
+ msgstr ""
6721
+
6722
+ #. translators: URL.
6723
+ #: lib/wfScanEngine.php:2241
6724
+ msgid "This option contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. It may indicate your site is infected with malware. The URL is: %s"
6725
+ msgstr ""
6726
+
6727
+ #. translators: URL.
6728
+ #: lib/wfScanEngine.php:2244
6729
+ msgid "This option contains a URL that is currently listed on Wordfence's domain blocklist. It may indicate your site is infected with malware. The URL is: %s"
6730
+ msgstr ""
6731
+
6732
+ #: lib/wfScanEngine.php:2284
6733
+ msgid "Checking for future GeoIP support"
6734
+ msgstr ""
6735
+
6736
+ #: lib/wfScanEngine.php:2289
6737
+ msgid "PHP Update Needed for Country Blocking"
6738
+ msgstr ""
6739
+
6740
+ #. translators: Software version.
6741
+ #: lib/wfScanEngine.php:2290
6742
+ msgid "The GeoIP database that is required for country blocking has been updated to a new format. This new format requires sites to run PHP 5.4 or newer, and this site is on PHP %s. To ensure country blocking continues functioning, please update PHP."
6743
+ msgstr ""
6744
+
6745
+ #: lib/wfScanEngine.php:2339
6746
+ msgid "Previous scan was stopped successfully."
6747
+ msgstr ""
6748
+
6749
+ #: lib/wfScanEngine.php:2340
6750
+ msgid "Scan was stopped on administrator request."
6751
+ msgstr ""
6752
+
6753
+ #: lib/wfScanEngine.php:2356
6754
+ msgid "Entering start scan routine"
6755
+ msgstr ""
6756
+
6757
+ #: lib/wfScanEngine.php:2359
6758
+ msgid "A scan is already running. Use the stop scan button if you would like to terminate the current scan."
6759
+ msgstr ""
6760
+
6761
+ #. translators: Support URL.
6762
+ #: lib/wfScanEngine.php:2377
6763
+ msgid "Test result of scan start URL fetch: %s"
6764
+ msgstr ""
6765
+
6766
+ #. translators: WordPress admin panel URL.
6767
+ #: lib/wfScanEngine.php:2386
6768
+ msgid "Starting cron with normal ajax at URL %s"
6769
+ msgstr ""
6770
+
6771
+ #. translators: Error message.
6772
+ #. translators: WordPress admin panel URL.
6773
+ #: lib/wfScanEngine.php:2408
6774
+ #: lib/wfScanEngine.php:2443
6775
+ msgid "There was an error starting the scan: %s."
6776
+ msgstr ""
6777
+
6778
+ #: lib/wfScanEngine.php:2410
6779
+ #: lib/wfScanEngine.php:2445
6780
+ msgid "There was an unknown error starting the scan."
6781
+ msgstr ""
6782
+
6783
+ #: lib/wfScanEngine.php:2417
6784
+ #: lib/wfScanEngine.php:2451
6785
+ msgid "Scan process ended after forking."
6786
+ msgstr ""
6787
+
6788
+ #. translators: WordPress admin panel URL.
6789
+ #: lib/wfScanEngine.php:2421
6790
+ msgid "Starting cron via proxy at URL %s"
6791
+ msgstr ""
6792
+
6793
+ #. translators: Time in seconds.
6794
+ #: lib/wfScanEngine.php:2497
6795
+ msgid "Got value from wf config maxExecutionTime: %s"
6796
+ msgstr ""
6797
+
6798
+ #. translators: Time in seconds.
6799
+ #: lib/wfScanEngine.php:2501
6800
+ msgid "getMaxExecutionTime() returning config value: %s"
6801
+ msgstr ""
6802
+
6803
+ #. translators: PHP ini value.
6804
+ #: lib/wfScanEngine.php:2508
6805
+ msgid "Got max_execution_time value from ini: %s"
6806
+ msgstr ""
6807
+
6808
+ #. translators: 1. PHP ini setting. 2. Time in seconds.
6809
+ #: lib/wfScanEngine.php:2515
6810
+ msgid "ini value of %1$d is higher than value for WORDFENCE_SCAN_MAX_INI_EXECUTION_TIME (%2$d), reducing"
6811
+ msgstr ""
6812
+
6813
+ #. translators: PHP ini setting.
6814
+ #: lib/wfScanEngine.php:2525
6815
+ msgid "getMaxExecutionTime() returning half ini value: %d"
6816
+ msgstr ""
6817
+
6818
+ #: lib/wfScanEngine.php:2531
6819
+ msgid "getMaxExecutionTime() returning default of: 15"
6820
+ msgstr ""
6821
+
6822
+ #. translators: 1. HTTP status code.
6823
+ #: lib/wfScanEngine.php:2733
6824
+ msgid "Got error response from Wordfence servers: %s"
6825
+ msgstr ""
6826
+
6827
+ #: lib/wfScanEngine.php:2737
6828
+ msgid "Invalid response from Wordfence servers."
6829
+ msgstr ""
6830
+
6831
+ #: lib/wfUnlockMsg.php:2
6832
+ msgid "If you are a WordPress user with administrative privileges on this site please enter your email in the box below and click &quot;Send&quot;. You will then receive an email that helps you regain access."
6833
+ msgstr ""
6834
+
6835
+ #: lib/wfUnlockMsg.php:6
6836
+ msgid "Send Unlock Email"
6837
+ msgstr ""
6838
+
6839
+ #: lib/wfUtils.php:25
6840
+ msgid "a moment"
6841
+ msgstr ""
6842
+
6843
+ #: lib/wfUtils.php:60
6844
+ msgid "year"
6845
+ msgid_plural "years"
6846
+ msgstr[0] ""
6847
+ msgstr[1] ""
6848
+
6849
+ #: lib/wfUtils.php:61
6850
+ #: lib/wfUtils.php:64
6851
+ #: lib/wfUtils.php:95
6852
+ msgid "month"
6853
+ msgid_plural "months"
6854
+ msgstr[0] ""
6855
+ msgstr[1] ""
6856
+
6857
+ #: lib/wfUtils.php:65
6858
+ #: lib/wfUtils.php:68
6859
+ #: lib/wfUtils.php:101
6860
+ msgid "day"
6861
+ msgid_plural "days"
6862
+ msgstr[0] ""
6863
+ msgstr[1] ""
6864
+
6865
+ #: lib/wfUtils.php:69
6866
+ #: lib/wfUtils.php:72
6867
+ #: lib/wfUtils.php:107
6868
+ msgid "hour"
6869
+ msgid_plural "hours"
6870
+ msgstr[0] ""
6871
+ msgstr[1] ""
6872
+
6873
+ #: lib/wfUtils.php:73
6874
+ #: lib/wfUtils.php:76
6875
+ #: lib/wfUtils.php:113
6876
+ msgid "minute"
6877
+ msgid_plural "minutes"
6878
+ msgstr[0] ""
6879
+ msgstr[1] ""
6880
+
6881
+ #: lib/wfUtils.php:80
6882
+ msgid "less than a minute"
6883
+ msgstr ""
6884
+
6885
+ #. translators: Number of seconds.
6886
+ #: lib/wfUtils.php:82
6887
+ msgid "%d seconds"
6888
+ msgstr ""
6889
+
6890
+ #: lib/wfUtils.php:116
6891
+ msgid "second"
6892
+ msgid_plural "seconds"
6893
+ msgstr[0] ""
6894
+ msgstr[1] ""
6895
+
6896
+ #: lib/wfUtils.php:120
6897
+ msgid "less than 1 second"
6898
+ msgstr ""
6899
+
6900
+ #: lib/wfUtils.php:1203
6901
+ #: lib/wfUtils.php:1212
6902
+ msgid "Wordfence error: No encryption key found!"
6903
+ msgstr ""
6904
+
6905
+ #. translators: Error message.
6906
+ #: lib/wfUtils.php:1484
6907
+ msgid "Call to Wordfence API to resolve IPs failed: %s"
6908
+ msgstr ""
6909
+
6910
+ #: lib/wfVersionCheckController.php:49
6911
+ #: lib/wfVersionCheckController.php:74
6912
+ msgid "PHP version too old"
6913
+ msgstr ""
6914
+
6915
+ #. translators: 1. PHP version. 2. PHP version.
6916
+ #: lib/wfVersionCheckController.php:52
6917
+ msgid "Your site is using a PHP version (%1$s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
6918
+ msgstr ""
6919
+
6920
+ #. translators: Support URL.
6921
+ #. translators: 1. WordPress version. 2. WordPress version.
6922
+ #: lib/wfVersionCheckController.php:57
6923
+ #: lib/wfVersionCheckController.php:80
6924
+ #: lib/wfVersionCheckController.php:156
6925
+ #: lib/wfVersionCheckController.php:178
6926
+ msgid "Learn More: %s"
6927
+ msgstr ""
6928
+
6929
+ #. translators: 1. PHP version. 2. PHP version.
6930
+ #: lib/wfVersionCheckController.php:65
6931
+ msgid "<strong>WARNING: </strong> Your site is using a PHP version (%1$s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
6932
+ msgstr ""
6933
+
6934
+ #. translators: 1. PHP version. 2. PHP version.
6935
+ #: lib/wfVersionCheckController.php:77
6936
+ msgid "Your site is using a PHP version (%1$s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
6937
+ msgstr ""
6938
+
6939
+ #. translators: 1. PHP version. 2. PHP version.
6940
+ #: lib/wfVersionCheckController.php:88
6941
+ msgid "<strong>WARNING: </strong> Your site is using a PHP version (%1$s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
6942
+ msgstr ""
6943
+
6944
+ #: lib/wfVersionCheckController.php:150
6945
+ #: lib/wfVersionCheckController.php:175
6946
+ msgid "WordPress version too old"
6947
+ msgstr ""
6948
+
6949
+ #. translators: 1. WordPress version. 2. WordPress version.
6950
+ #: lib/wfVersionCheckController.php:153
6951
+ msgid "Your site is using a WordPress version (%1$s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
6952
+ msgstr ""
6953
+
6954
+ #. translators: 1. WordPress version. 2. WordPress version.
6955
+ #: lib/wfVersionCheckController.php:164
6956
+ msgid "<strong>WARNING: </strong> Your site is using a WordPress version (%1$s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
6957
+ msgstr ""
6958
+
6959
+ #. translators: 1. WordPress version. 2. WordPress version.
6960
+ #: lib/wfVersionCheckController.php:178
6961
+ msgid "Your site is using a WordPress version (%1$s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
6962
+ msgstr ""
6963
+
6964
+ #. translators: 1. WordPress version. 2. WordPress version.
6965
+ #: lib/wfVersionCheckController.php:186
6966
+ msgid "<strong>WARNING: </strong> Your site is using a WordPress version (%1$s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later."
6967
+ msgstr ""
6968
+
6969
+ #. translators: File path.
6970
+ #: lib/wfView.php:52
6971
+ msgid "The view %s does not exist or is not readable."
6972
+ msgstr ""
6973
+
6974
+ #: lib/wfView.php:70
6975
+ msgid "The view could not be loaded."
6976
+ msgstr ""
6977
+
6978
+ #: lib/wfViewResult.php:8
6979
+ msgid "Wordfence: File Viewer"
6980
+ msgstr ""
6981
+
6982
+ #: lib/wfViewResult.php:11
6983
+ msgid "File Size:"
6984
+ msgstr ""
6985
+
6986
+ #: lib/wfViewResult.php:12
6987
+ msgid "File last modified:"
6988
+ msgstr ""
6989
+
6990
+ #: lib/wordfenceClass.php:177
6991
+ msgid ""
6992
+ "To ensure uninterrupted Premium Wordfence protection on your site,\n"
6993
+ "please renew your license by visiting http://www.wordfence.com/ Sign in, go to your dashboard,\n"
6994
+ "select the license about to expire and click the button to renew that license."
6995
+ msgstr ""
6996
+
6997
+ #: lib/wordfenceClass.php:207
6998
+ msgid "Your Premium Wordfence License is set to auto-renew in 10 days."
6999
+ msgstr ""
7000
+
7001
+ #: lib/wordfenceClass.php:208
7002
+ msgid "To update your license settings please visit http://www.wordfence.com/zz9/dashboard"
7003
+ msgstr ""
7004
+
7005
+ #: lib/wordfenceClass.php:220
7006
+ msgid "Your Premium Wordfence License expires in less than 2 weeks."
7007
+ msgstr ""
7008
+
7009
+ #: lib/wordfenceClass.php:223
7010
+ msgid "Your Premium Wordfence License expires in less than a week."
7011
+ msgstr ""
7012
+
7013
+ #: lib/wordfenceClass.php:226
7014
+ msgid "Your Premium Wordfence License expires in 2 days."
7015
+ msgstr ""
7016
+
7017
+ #: lib/wordfenceClass.php:229
7018
+ msgid "Your Premium Wordfence License expires in 1 day."
7019
+ msgstr ""
7020
+
7021
+ #: lib/wordfenceClass.php:233
7022
+ msgid "Your Wordfence Premium License has Expired!"
7023
+ msgstr ""
7024
+
7025
+ #: lib/wordfenceClass.php:264
7026
+ msgid "The Wordfence Premium License in use on this site has been removed from your account."
7027
+ msgstr ""
7028
+
7029
+ #: lib/wordfenceClass.php:264
7030
+ msgid "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."
7031
+ msgstr ""
7032
+
7033
+ #. translators: Wordfence license key.
7034
+ #: lib/wordfenceClass.php:270
7035
+ msgid "Could not verify Wordfence License: %s"
7036
+ msgstr ""
7037
+
7038
+ #. translators: WordPress version.
7039
+ #: lib/wordfenceClass.php:352
7040
+ msgid "WordPress (v%s)"
7041
+ msgstr ""
7042
+
7043
+ #. translators: Number of plugins.
7044
+ #: lib/wordfenceClass.php:356
7045
+ msgid "%d plugin"
7046
+ msgid_plural "%d plugins"
7047
+ msgstr[0] ""
7048
+ msgstr[1] ""
7049
+
7050
+ #. translators: Number of themes.
7051
+ #: lib/wordfenceClass.php:361
7052
+ msgid "%d theme"
7053
+ msgid_plural "%d themes"
7054
+ msgstr[0] ""
7055
+ msgstr[1] ""
7056
+
7057
+ #: lib/wordfenceClass.php:365
7058
+ msgid "An update is available for "
7059
+ msgid_plural "Updates are available for "
7060
+ msgstr[0] ""
7061
+ msgstr[1] ""
7062
+
7063
+ #: lib/wordfenceClass.php:370
7064
+ msgid "and "
7065
+ msgstr ""
7066
+
7067
+ #. translators: Wordfence version.
7068
+ #: lib/wordfenceClass.php:409
7069
+ msgid "`runInstall` called with previous version = %s"
7070
+ msgstr ""
7071
+
7072
+ #: lib/wordfenceClass.php:461
7073
+ #: lib/wordfenceClass.php:4021
7074
+ msgid "Could not understand the response we received from the Wordfence servers when applying for a free license key."
7075
+ msgstr ""
7076
+
7077
+ #: lib/wordfenceClass.php:825
7078
+ msgid "Automatically generated from previous country blocking settings"
7079
+ msgstr ""
7080
+
7081
+ #: lib/wordfenceClass.php:1254
7082
+ msgid "Application passwords have been disabled by Wordfence."
7083
+ msgstr ""
7084
+
7085
+ #: lib/wordfenceClass.php:1365
7086
+ #: lib/wordfenceClass.php:6585
7087
+ msgid "Upgrade To Premium"
7088
+ msgstr ""
7089
+
7090
+ #: lib/wordfenceClass.php:1384
7091
+ msgid "wp_mail from address is incomplete, attempting to fix"
7092
+ msgstr ""
7093
+
7094
+ #. translators: Email address.
7095
+ #: lib/wordfenceClass.php:1394
7096
+ msgid "Fixing wp_mail from address: %s"
7097
+ msgstr ""
7098
+
7099
+ #: lib/wordfenceClass.php:1487
7100
+ msgid "You appear to have logged out or you are not an admin. Please sign-out and sign-in again."
7101
+ msgstr ""
7102
+
7103
+ #: lib/wordfenceClass.php:1492
7104
+ msgid "Your browser sent an invalid security token to Wordfence. Please try reloading this page or signing out and in again."
7105
+ msgstr ""
7106
+
7107
+ #: lib/wordfenceClass.php:1498
7108
+ msgid "Wordfence encountered an internal error executing that request."
7109
+ msgstr ""
7110
+
7111
+ #. translators: Error message.
7112
+ #: lib/wordfenceClass.php:1604
7113
+ msgid "2FA Migration Error: %s"
7114
+ msgstr ""
7115
+
7116
+ #: lib/wordfenceClass.php:1644
7117
+ msgid "Please choose a stronger password. Try including numbers, symbols, and a mix of upper and lowercase letters and remove common words."
7118
+ msgstr ""
7119
+
7120
+ #: lib/wordfenceClass.php:1650
7121
+ msgid "Passwords containing a space followed by \"wf\" without quotes are not allowed."
7122
+ msgstr ""
7123
+
7124
+ #. translators: Support URL.
7125
+ #: lib/wordfenceClass.php:1665
7126
+ msgid "Please choose a different password. The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. <a href=\"%s\">Learn More</a>"
7127
+ msgstr ""
7128
+
7129
+ #: lib/wordfenceClass.php:1793
7130
+ #: lib/wordfenceClass.php:1976
7131
+ msgid "Sorry but your browser sent an invalid security token when trying to use this form."
7132
+ msgstr ""
7133
+
7134
+ #: lib/wordfenceClass.php:1798
7135
+ msgid "Please wait 3 minutes and try again"
7136
+ msgstr ""
7137
+
7138
+ #: lib/wordfenceClass.php:1799
7139
+ msgid "You have used this form too much. Please wait 3 minutes and try again."
7140
+ msgstr ""
7141
+
7142
+ #: lib/wordfenceClass.php:1838
7143
+ msgid "Unlock email requested"
7144
+ msgstr ""
7145
+
7146
+ #: lib/wordfenceClass.php:1840
7147
+ msgid "Your request was received"
7148
+ msgstr ""
7149
+
7150
+ #. translators: Email address.
7151
+ #: lib/wordfenceClass.php:1841
7152
+ msgid "We received a request to email \"%s\" instructions to unlock their access. If that is the email address of a site administrator or someone on the Wordfence alert list, they have been emailed instructions on how to regain access to this system. The instructions we sent will expire 30 minutes from now."
7153
+ msgstr ""
7154
+
7155
+ #: lib/wordfenceClass.php:1847
7156
+ msgid "Invalid key provided for authentication."
7157
+ msgstr ""
7158
+
7159
+ #: lib/wordfenceClass.php:1858
7160
+ msgid "Request received via unlock email link to unblock all IPs."
7161
+ msgstr ""
7162
+
7163
+ #: lib/wordfenceClass.php:1867
7164
+ msgid "Request received via unlock email link to unblock all IPs via disabling firewall rules."
7165
+ msgstr ""
7166
+
7167
+ #: lib/wordfenceClass.php:1875
7168
+ msgid "Invalid function specified. Please check the link we emailed you and make sure it was not cut-off by your email reader."
7169
+ msgstr ""
7170
+
7171
+ #: lib/wordfenceClass.php:1920
7172
+ msgid "Unsubscribe Requested"
7173
+ msgstr ""
7174
+
7175
+ #: lib/wordfenceClass.php:1982
7176
+ msgid "An error occurred while saving the license."
7177
+ msgstr ""
7178
+
7179
+ #. translators: Error message.
7180
+ #: lib/wordfenceClass.php:1984
7181
+ #: lib/wordfenceClass.php:2004
7182
+ msgid "An error occurred while saving the license: %s"
7183
+ msgstr ""
7184
+
7185
+ #: lib/wordfenceClass.php:2020
7186
+ msgid "Rescheduled missing daily cron"
7187
+ msgstr ""
7188
+
7189
+ #: lib/wordfenceClass.php:2025
7190
+ msgid "Rescheduled missing hourly cron"
7191
+ msgstr ""
7192
+
7193
+ #: lib/wordfenceClass.php:2379
7194
+ #: lib/wordfenceClass.php:2383
7195
+ msgid "Accessed a banned URL"
7196
+ msgstr ""
7197
+
7198
+ #: lib/wordfenceClass.php:2390
7199
+ #: lib/wordfenceClass.php:2394
7200
+ msgid "POST received with blank user-agent and referer"
7201
+ msgstr ""
7202
+
7203
+ #: lib/wordfenceClass.php:2528
7204
+ msgid "<strong>ERROR</strong>: You can't register using that username"
7205
+ msgstr ""
7206
+
7207
+ #. translators: 1. WordPress admin panel URL. 2. Support URL.
7208
+ #: lib/wordfenceClass.php:2736
7209
+ #: lib/wordfenceClass.php:2872
7210
+ msgid "<strong>WARNING: </strong>The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href=\"%1$s\">change your password</a>. <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
7211
+ msgstr ""
7212
+
7213
+ #. translators: 1. Reset password URL. 2. Support URL.
7214
+ #: lib/wordfenceClass.php:3027
7215
+ #: lib/wordfenceClass.php:3063
7216
+ msgid "<strong>WARNING: </strong>Your login has been allowed because you have previously logged in from the same IP, but you will be blocked if your IP changes. The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href=\"%1$s\">change your password</a>. <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
7217
+ msgstr ""
7218
+
7219
+ #. translators: WordPress username.
7220
+ #: lib/wordfenceClass.php:3052
7221
+ msgid "A user with username \"%s\" who has administrator access tried to sign in to your WordPress site. Access was denied because all administrator accounts are required to have Cellphone Sign-in enabled but this account does not."
7222
+ msgstr ""
7223
+
7224
+ #: lib/wordfenceClass.php:3093
7225
+ msgid "Blocked by Wordfence Security Network"
7226
+ msgstr ""
7227
+
7228
+ #: lib/wordfenceClass.php:3123
7229
+ msgid "Blocked by login security setting"
7230
+ msgstr ""
7231
+
7232
+ #. translators: WordPress username.
7233
+ #: lib/wordfenceClass.php:3133
7234
+ msgid "Used an invalid username '%s' to try to sign in"
7235
+ msgstr ""
7236
+
7237
+ #. translators: 1. Login attempt limit. 2. WordPress username.
7238
+ #: lib/wordfenceClass.php:3152
7239
+ msgid "Exceeded the maximum number of login failures which is: %1$s. The last username they tried to sign in with was: '%2$s'"
7240
+ msgstr ""
7241
+
7242
+ #: lib/wordfenceClass.php:3510
7243
+ msgid "An invalid type was specified to get file."
7244
+ msgstr ""
7245
+
7246
+ #: lib/wordfenceClass.php:3526
7247
+ msgid "We could not fetch a core WordPress file from the Wordfence API."
7248
+ msgstr ""
7249
+
7250
+ #: lib/wordfenceClass.php:3585
7251
+ msgid "Wordfence Test Email"
7252
+ msgstr ""
7253
+
7254
+ #. translators: 1. Site URL. 2. IP address.
7255
+ #: lib/wordfenceClass.php:3585
7256
+ msgid ""
7257
+ "This is a test email from %1$s.\n"
7258
+ "The IP address that requested this was: %2$s"
7259
+ msgstr ""
7260
+
7261
+ #: lib/wordfenceClass.php:3592
7262
+ msgid "Cellphone Sign-in is only available to paid members. <a href=\"https://www.wordfence.com/gnl1twoFac3/wordfence-signup/\" target=\"_blank\" rel=\"noopener noreferrer\">Click here to upgrade now.</a>"
7263
+ msgstr ""
7264
+
7265
+ #: lib/wordfenceClass.php:3599
7266
+ msgid "The username you specified does not exist."
7267
+ msgstr ""
7268
+
7269
+ #: lib/wordfenceClass.php:3608
7270
+ msgid "The username you specified is already enabled."
7271
+ msgstr ""
7272
+
7273
+ #: lib/wordfenceClass.php:3613
7274
+ msgid "Unknown authentication mode."
7275
+ msgstr ""
7276
+
7277
+ #: lib/wordfenceClass.php:3618
7278
+ msgid "The phone number you entered must start with a '+', then country code and then area code and number. For example, a number in the United States with country code '1' would look like this: +1-123-555-1234"
7279
+ msgstr ""
7280
+
7281
+ #. translators: Error message.
7282
+ #: lib/wordfenceClass.php:3625
7283
+ #: lib/wordfenceClass.php:3657
7284
+ #: lib/wordfenceClass.php:3720
7285
+ msgid "Could not contact Wordfence servers to generate a verification code: %s"
7286
+ msgstr ""
7287
+
7288
+ #. translators: Error message.
7289
+ #: lib/wordfenceClass.php:3637
7290
+ #: lib/wordfenceClass.php:3681
7291
+ msgid "Could not generate verification code: %s"
7292
+ msgstr ""
7293
+
7294
+ #. translators: Error message.
7295
+ #: lib/wordfenceClass.php:3638
7296
+ #: lib/wordfenceClass.php:3682
7297
+ msgid "We could not generate a verification code."
7298
+ msgstr ""
7299
+
7300
+ #: lib/wordfenceClass.php:3698
7301
+ msgid "Unknown two-factor authentication mode."
7302
+ msgstr ""
7303
+
7304
+ #: lib/wordfenceClass.php:3731
7305
+ msgid "The code you entered is invalid. Cellphone sign-in will not be enabled for this user until you enter a valid code."
7306
+ msgstr ""
7307
+
7308
+ #: lib/wordfenceClass.php:3736
7309
+ msgid "We could not find the user you are trying to activate. They may have been removed from the list of Cellphone Sign-in users. Please reload this page."
7310
+ msgstr ""
7311
+
7312
+ #: lib/wordfenceClass.php:3818
7313
+ msgid "That user has already been removed from the list."
7314
+ msgstr ""
7315
+
7316
+ #: lib/wordfenceClass.php:3838
7317
+ msgid "No scan is scheduled"
7318
+ msgstr ""
7319
+
7320
+ #: lib/wordfenceClass.php:3843
7321
+ msgid "Next scan is starting now"
7322
+ msgstr ""
7323
+
7324
+ #. translators: 1. Time until. 2. Localized date.
7325
+ #: lib/wordfenceClass.php:3846
7326
+ msgid "Next scan in %1$s (%2$s)"
7327
+ msgstr ""
7328
+
7329
+ #. translators: Localized date.
7330
+ #: lib/wordfenceClass.php:3863
7331
+ msgid "Scheduled Wordfence scan starting at %s"
7332
+ msgstr ""
7333
+
7334
+ #: lib/wordfenceClass.php:3886
7335
+ msgid "Sorry but this feature is only available for paid customers."
7336
+ msgstr ""
7337
+
7338
+ #. translators: Site URL.
7339
+ #: lib/wordfenceClass.php:3900
7340
+ msgid "SITE: %s"
7341
+ msgstr ""
7342
+
7343
+ #. translators: Plugin version.
7344
+ #: lib/wordfenceClass.php:3901
7345
+ msgid "PLUGIN VERSION: %s"
7346
+ msgstr ""
7347
+
7348
+ #. translators: WordPress version.
7349
+ #: lib/wordfenceClass.php:3902
7350
+ msgid "WORDPRESS VERSION: %s"
7351
+ msgstr ""
7352
+
7353
+ #. translators: Wordfence license key.
7354
+ #: lib/wordfenceClass.php:3903
7355
+ msgid "LICENSE KEY: %s"
7356
+ msgstr ""
7357
+
7358
+ #. translators: Email address.
7359
+ #: lib/wordfenceClass.php:3904
7360
+ msgid "ADMIN EMAIL: %s"
7361
+ msgstr ""
7362
+
7363
+ #. translators: Email address.
7364
+ #: lib/wordfenceClass.php:3905
7365
+ msgid "LOG:"
7366
+ msgstr ""
7367
+
7368
+ #: lib/wordfenceClass.php:3921
7369
+ msgid "# Scan Issues"
7370
+ msgstr ""
7371
+
7372
+ #. translators: Number of scan results.
7373
+ #: lib/wordfenceClass.php:3926
7374
+ msgid "## New Issues (%d total)"
7375
+ msgstr ""
7376
+
7377
+ #. translators: Number of scan results.
7378
+ #: lib/wordfenceClass.php:3953
7379
+ msgid "## Ignored Issues (%d total)"
7380
+ msgstr ""
7381
+
7382
+ #: lib/wordfenceClass.php:3974
7383
+ msgid "No Ignored Issues"
7384
+ msgstr ""
7385
+
7386
+ #: lib/wordfenceClass.php:3996
7387
+ msgid "Wordfence Activity Log"
7388
+ msgstr ""
7389
+
7390
+ #. translators: Error message.
7391
+ #: lib/wordfenceClass.php:4024
7392
+ msgid "Could not fetch free license key from Wordfence: %s"
7393
+ msgstr ""
7394
+
7395
+ #: lib/wordfenceClass.php:4109
7396
+ msgid "We could not find your .htaccess file to modify it."
7397
+ msgstr ""
7398
+
7399
+ #. translators: Error message.
7400
+ #: lib/wordfenceClass.php:4114
7401
+ msgid "We found your .htaccess file but could not open it for writing: %s"
7402
+ msgstr ""
7403
+
7404
+ #: lib/wordfenceClass.php:4197
7405
+ msgid "All Countries"
7406
+ msgstr ""
7407
+
7408
+ #: lib/wordfenceClass.php:4200
7409
+ msgid "1 Country"
7410
+ msgstr ""
7411
+
7412
+ #. translators: Number of countries.
7413
+ #: lib/wordfenceClass.php:4203
7414
+ msgid "%d Countries"
7415
+ msgstr ""
7416
+
7417
+ #: lib/wordfenceClass.php:4207
7418
+ msgid "Entire Site"
7419
+ msgstr ""
7420
+
7421
+ #: lib/wordfenceClass.php:4210
7422
+ msgid "Login Only"
7423
+ msgstr ""
7424
+
7425
+ #: lib/wordfenceClass.php:4213
7426
+ msgid "Site Except Login"
7427
+ msgstr ""
7428
+
7429
+ #: lib/wordfenceClass.php:4221
7430
+ msgid "IP Range"
7431
+ msgstr ""
7432
+
7433
+ #. translators: 2FA backup codes.
7434
+ #: lib/wordfenceClass.php:4222
7435
+ #: lib/wordfenceClass.php:6174
7436
+ msgid "User Agent"
7437
+ msgstr ""
7438
+
7439
+ #: lib/wordfenceClass.php:4223
7440
+ #: views/blocking/blocking-create.php:201
7441
+ msgid "Referrer"
7442
+ msgstr ""
7443
+
7444
+ #: lib/wordfenceClass.php:4238
7445
+ msgid "Permanent"
7446
+ msgstr ""
7447
+
7448
+ #: lib/wordfenceClass.php:4310
7449
+ msgid "An error occurred while creating the block."
7450
+ msgstr ""
7451
+
7452
+ #: lib/wordfenceClass.php:4316
7453
+ msgid "No block parameters were provided."
7454
+ msgstr ""
7455
+
7456
+ #: lib/wordfenceClass.php:4353
7457
+ #: lib/wordfenceClass.php:4385
7458
+ msgid "No blocks were provided."
7459
+ msgstr ""
7460
+
7461
+ #: lib/wordfenceClass.php:4417
7462
+ msgid "The license provided is already in use on another site."
7463
+ msgstr ""
7464
+
7465
+ #: lib/wordfenceClass.php:4422
7466
+ msgid "The Wordfence activation server returned an unexpected response. Please try again."
7467
+ msgstr ""
7468
+
7469
+ #: lib/wordfenceClass.php:4428
7470
+ msgid "We received an error while trying to activate the license with the Wordfence servers: "
7471
+ msgstr ""
7472
+
7473
+ #: lib/wordfenceClass.php:4441
7474
+ msgid "No license was provided to install."
7475
+ msgstr ""
7476
+
7477
+ #: lib/wordfenceClass.php:4492
7478
+ msgid "An unknown configuration section was provided."
7479
+ msgstr ""
7480
+
7481
+ #: lib/wordfenceClass.php:4498
7482
+ msgid "No configuration section was provided."
7483
+ msgstr ""
7484
+
7485
+ #: lib/wordfenceClass.php:4544
7486
+ #: lib/wordfenceClass.php:4549
7487
+ msgid "An error occurred while saving the configuration."
7488
+ msgstr ""
7489
+
7490
+ #: lib/wordfenceClass.php:4560
7491
+ msgid "No configuration changes were provided to save."
7492
+ msgstr ""
7493
+
7494
+ #: lib/wordfenceClass.php:4591
7495
+ #: lib/wordfenceClass.php:5216
7496
+ #: lib/wordfenceClass.php:5247
7497
+ #: lib/wordfenceClass.php:7217
7498
+ #: lib/wordfenceClass.php:7252
7499
+ #: lib/wordfenceClass.php:7284
7500
+ msgid "We could not find that issue in our database."
7501
+ msgstr ""
7502
+
7503
+ #: lib/wordfenceClass.php:4601
7504
+ msgid "An error occurred while trying to hide the file."
7505
+ msgstr ""
7506
+
7507
+ #: lib/wordfenceClass.php:4614
7508
+ msgid "An invalid file was requested for hiding."
7509
+ msgstr ""
7510
+
7511
+ #: lib/wordfenceClass.php:4641
7512
+ #: lib/wordfenceClass.php:5227
7513
+ msgid "You don't have permission to repair .htaccess. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file."
7514
+ msgstr ""
7515
+
7516
+ #: lib/wordfenceClass.php:4665
7517
+ msgid "Manual permanent block by admin"
7518
+ msgstr ""
7519
+
7520
+ #: lib/wordfenceClass.php:4701
7521
+ msgid "Please enter a valid IP address to block."
7522
+ msgstr ""
7523
+
7524
+ #: lib/wordfenceClass.php:4704
7525
+ msgid "You can't block your own IP address."
7526
+ msgstr ""
7527
+
7528
+ #. translators: IP address.
7529
+ #: lib/wordfenceClass.php:4708
7530
+ msgid "The IP address %s is allowlisted and can't be blocked. You can remove this IP from the allowlist on the Wordfence options page."
7531
+ msgstr ""
7532
+
7533
+ #. translators: IP address.
7534
+ #: lib/wordfenceClass.php:4710
7535
+ msgid "The IP address %s is in a range of IP addresses that Wordfence does not block. The IP range may be internal or belong to a service safe to allow access for."
7536
+ msgstr ""
7537
+
7538
+ #: lib/wordfenceClass.php:4716
7539
+ msgid "The IP address you're trying to block belongs to Google. Your options are currently set to not block these crawlers. Change this in Wordfence options if you want to manually block Google."
7540
+ msgstr ""
7541
+
7542
+ #: lib/wordfenceClass.php:4759
7543
+ msgid "An invalid operation was called."
7544
+ msgstr ""
7545
+
7546
+ #: lib/wordfenceClass.php:4769
7547
+ msgid "An invalid status was specified when trying to update that issue."
7548
+ msgstr ""
7549
+
7550
+ #: lib/wordfenceClass.php:4781
7551
+ msgid "Scan stop request received."
7552
+ msgstr ""
7553
+
7554
+ #: lib/wordfenceClass.php:4782
7555
+ msgid "A request was received to stop the previous scan."
7556
+ msgstr ""
7557
+
7558
+ #: lib/wordfenceClass.php:4831
7559
+ msgid "Idle"
7560
+ msgstr ""
7561
+
7562
+ #. translators: Localized date.
7563
+ #: lib/wordfenceClass.php:4840
7564
+ msgid "Scan completed on %s"
7565
+ msgstr ""
7566
+
7567
+ #: lib/wordfenceClass.php:4847
7568
+ msgid "Last scan failed"
7569
+ msgstr ""
7570
+
7571
+ #. translators: Time until.
7572
+ #: lib/wordfenceClass.php:4910
7573
+ msgid "more than %s"
7574
+ msgstr ""
7575
+
7576
+ #. translators: Localized date.
7577
+ #: lib/wordfenceClass.php:4914
7578
+ msgid "The current scan looks like it has failed. Its last status update was <span id=\"wf-scan-failed-time-ago\">%s</span> ago. You may continue to wait in case it resumes or stop and restart the scan. Some sites may need adjustments to run scans reliably."
7579
+ msgstr ""
7580
+
7581
+ #. translators: Localized date.
7582
+ #: lib/wordfenceClass.php:4914
7583
+ #: lib/wordfenceClass.php:4922
7584
+ #: lib/wordfenceClass.php:4941
7585
+ #: lib/wordfenceClass.php:4953
7586
+ #: lib/wordfenceClass.php:4961
7587
+ msgid "Click here for steps you can try."
7588
+ msgstr ""
7589
+
7590
+ #. translators: Localized date.
7591
+ #: lib/wordfenceClass.php:4915
7592
+ msgid "Cancel Scan"
7593
+ msgstr ""
7594
+
7595
+ #: lib/wordfenceClass.php:4922
7596
+ msgid "The previous scan has failed. Some sites may need adjustments to run scans reliably."
7597
+ msgstr ""
7598
+
7599
+ #. translators: Time limit (number).
7600
+ #: lib/wordfenceClass.php:4928
7601
+ msgid "The previous scan has terminated because the time limit of %s was reached. This limit can be customized on the options page."
7602
+ msgstr ""
7603
+
7604
+ #: lib/wordfenceClass.php:4934
7605
+ msgid "The previous scan has terminated because we detected an update occurring during the scan."
7606
+ msgstr ""
7607
+
7608
+ #: lib/wordfenceClass.php:4941
7609
+ msgid "The scan has failed to start. This is often because the site either cannot make outbound requests or is blocked from connecting to itself."
7610
+ msgstr ""
7611
+
7612
+ #: lib/wordfenceClass.php:4947
7613
+ msgid "Scans are not functional because SSL is unavailable."
7614
+ msgstr ""
7615
+
7616
+ #: lib/wordfenceClass.php:4953
7617
+ msgid "The scan has failed because we were unable to contact the Wordfence servers. Some sites may need adjustments to run scans reliably."
7618
+ msgstr ""
7619
+
7620
+ #: lib/wordfenceClass.php:4961
7621
+ msgid "The scan has failed because we received an unexpected response from the Wordfence servers. This may be a temporary error, though some sites may need adjustments to run scans reliably."
7622
+ msgstr ""
7623
+
7624
+ #: lib/wordfenceClass.php:4988
7625
+ msgid "Invalid email address given."
7626
+ msgstr ""
7627
+
7628
+ #: lib/wordfenceClass.php:5013
7629
+ #: lib/wordfenceClass.php:5138
7630
+ msgid "Deleting an infected wp-config.php file must be done outside of Wordfence. The wp-config.php file contains your database credentials, which you will need to restore normal site operations. Your site will NOT function once the wp-config.php file has been deleted."
7631
+ msgstr ""
7632
+
7633
+ #. translators: 1. File path. 2. Error message.
7634
+ #: lib/wordfenceClass.php:5022
7635
+ msgid "Could not delete file %1$s. Error was: %2$s"
7636
+ msgstr ""
7637
+
7638
+ #. translators: File path.
7639
+ #: lib/wordfenceClass.php:5046
7640
+ msgid "We could not retrieve the original file of %s to do a repair."
7641
+ msgstr ""
7642
+
7643
+ #. translators: File path.
7644
+ #: lib/wordfenceClass.php:5051
7645
+ msgid "An invalid file %s was specified for repair."
7646
+ msgstr ""
7647
+
7648
+ #. translators: File path.
7649
+ #: lib/wordfenceClass.php:5059
7650
+ msgid "You don't have permission to repair %s. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file."
7651
+ msgstr ""
7652
+
7653
+ #. translators: 1. File path. 2. Error message.
7654
+ #: lib/wordfenceClass.php:5062
7655
+ msgid "We could not write to %1$s. The error was: %2$s"
7656
+ msgstr ""
7657
+
7658
+ #. translators: 1. File path. 2. Number of bytes.
7659
+ #: lib/wordfenceClass.php:5073
7660
+ msgid "We could not write to %1$s. (%2$d bytes written) You may not have permission to modify files on your WordPress server."
7661
+ msgstr ""
7662
+
7663
+ #: lib/wordfenceClass.php:5085
7664
+ msgid "Deleted some files with errors"
7665
+ msgstr ""
7666
+
7667
+ #: lib/wordfenceClass.php:5085
7668
+ msgid "Repaired some files with errors"
7669
+ msgstr ""
7670
+
7671
+ #. translators: 1. Number of files. 2. Error message.
7672
+ #: lib/wordfenceClass.php:5088
7673
+ msgid "Deleted %1$d files but we encountered the following errors with other files: %2$s"
7674
+ msgstr ""
7675
+
7676
+ #. translators: 1. Number of files. 2. Error message.
7677
+ #: lib/wordfenceClass.php:5090
7678
+ msgid "Repaired %1$d files but we encountered the following errors with other files: %2$s"
7679
+ msgstr ""
7680
+
7681
+ #. translators: Number of files.
7682
+ #: lib/wordfenceClass.php:5094
7683
+ msgid "Deleted %d files successfully"
7684
+ msgstr ""
7685
+
7686
+ #. translators: Number of files.
7687
+ #: lib/wordfenceClass.php:5094
7688
+ msgid "Repaired %d files successfully"
7689
+ msgstr ""
7690
+
7691
+ #. translators: Number of files.
7692
+ #: lib/wordfenceClass.php:5095
7693
+ msgid "Deleted %d files successfully. No errors were encountered."
7694
+ msgstr ""
7695
+
7696
+ #. translators: Number of files.
7697
+ #: lib/wordfenceClass.php:5095
7698
+ msgid "Repaired %d files successfully. No errors were encountered."
7699
+ msgstr ""
7700
+
7701
+ #: lib/wordfenceClass.php:5098
7702
+ msgid "Could not delete files"
7703
+ msgstr ""
7704
+
7705
+ #: lib/wordfenceClass.php:5098
7706
+ msgid "Could not repair files"
7707
+ msgstr ""
7708
+
7709
+ #. translators: Error message.
7710
+ #: lib/wordfenceClass.php:5101
7711
+ msgid "We could not delete any of the files you selected. We encountered the following errors: %s"
7712
+ msgstr ""
7713
+
7714
+ #. translators: Error message.
7715
+ #: lib/wordfenceClass.php:5103
7716
+ msgid "We could not repair any of the files you selected. We encountered the following errors: %s"
7717
+ msgstr ""
7718
+
7719
+ #: lib/wordfenceClass.php:5106
7720
+ msgid "Nothing done"
7721
+ msgstr ""
7722
+
7723
+ #: lib/wordfenceClass.php:5107
7724
+ msgid "We didn't delete anything and no errors were found."
7725
+ msgstr ""
7726
+
7727
+ #: lib/wordfenceClass.php:5107
7728
+ msgid "We didn't repair anything and no errors were found."
7729
+ msgstr ""
7730
+
7731
+ #: lib/wordfenceClass.php:5115
7732
+ msgid "Invalid bulk operation selected"
7733
+ msgstr ""
7734
+
7735
+ #: lib/wordfenceClass.php:5125
7736
+ msgid "Could not delete file because we could not find that issue."
7737
+ msgstr ""
7738
+
7739
+ #: lib/wordfenceClass.php:5128
7740
+ msgid "Could not delete file because that issue does not appear to be a file related issue."
7741
+ msgstr ""
7742
+
7743
+ #: lib/wordfenceClass.php:5134
7744
+ msgid "An invalid file was requested for deletion."
7745
+ msgstr ""
7746
+
7747
+ #. translators: 1. File path. 2. Error message.
7748
+ #: lib/wordfenceClass.php:5177
7749
+ msgid "Could not delete file %1$s. The error was: %2$s"
7750
+ msgstr ""
7751
+
7752
+ #: lib/wordfenceClass.php:5190
7753
+ msgid "Could not remove the option because we could not find that issue."
7754
+ msgstr ""
7755
+
7756
+ #: lib/wordfenceClass.php:5193
7757
+ msgid "Could not remove the option because that issue does not appear to be a database related issue."
7758
+ msgstr ""
7759
+
7760
+ #. translators: 1. WordPress option. 2. Error message.
7761
+ #: lib/wordfenceClass.php:5206
7762
+ msgid "Could not remove the option %1$s. The error was: %2$s"
7763
+ msgstr ""
7764
+
7765
+ #: lib/wordfenceClass.php:5233
7766
+ msgid "Modifying the .htaccess file did not resolve the issue, so the original .htaccess file was restored. You can fix this manually by setting <code>display_errors</code> to <code>Off</code> in your php.ini if your site is on a VPS or dedicated server that you control."
7767
+ msgstr ""
7768
+
7769
+ #: lib/wordfenceClass.php:5275
7770
+ msgid "We could not get the original file to do a repair."
7771
+ msgstr ""
7772
+
7773
+ #: lib/wordfenceClass.php:5279
7774
+ msgid "An invalid file was specified for repair."
7775
+ msgstr ""
7776
+
7777
+ #: lib/wordfenceClass.php:5294
7778
+ msgid "We could not write to that file. You may not have permission to modify files on your WordPress server."
7779
+ msgstr ""
7780
+
7781
+ #: lib/wordfenceClass.php:5298
7782
+ msgid "Ajax request received to start scan."
7783
+ msgstr ""
7784
+
7785
+ #. translators: Number of URLs.
7786
+ #: lib/wordfenceClass.php:5353
7787
+ msgid "Page contains %d malware URL: "
7788
+ msgid_plural "Page contains %d malware URLs: "
7789
+ msgstr[0] ""
7790
+ msgstr[1] ""
7791
+
7792
+ #: lib/wordfenceClass.php:5356
7793
+ msgid "Run a Scan"
7794
+ msgstr ""
7795
+
7796
+ #: lib/wordfenceClass.php:5404
7797
+ msgid "Unknown dashboard data set."
7798
+ msgstr ""
7799
+
7800
+ #: lib/wordfenceClass.php:5435
7801
+ msgid "Bad security token. It may have been more than 12 hours since you reloaded the page you came from. Try reloading the page you came from. If that doesn't work, please sign out and sign-in again."
7802
+ msgstr ""
7803
+
7804
+ #: lib/wordfenceClass.php:5622
7805
+ msgid "An invalid IP address was specified."
7806
+ msgstr ""
7807
+
7808
+ #: lib/wordfenceClass.php:5675
7809
+ #: lib/wordfenceClass.php:5715
7810
+ #: lib/wordfenceClass.php:5753
7811
+ msgid "File access blocked. (WORDFENCE_DISABLE_FILE_VIEWER is true)"
7812
+ msgstr ""
7813
+
7814
+ #: lib/wordfenceClass.php:5680
7815
+ #: lib/wordfenceClass.php:5758
7816
+ msgid "Invalid file requested. (Relative paths not allowed)"
7817
+ msgstr ""
7818
+
7819
+ #: lib/wordfenceClass.php:5684
7820
+ #: lib/wordfenceClass.php:5719
7821
+ #: lib/wordfenceClass.php:5762
7822
+ msgid "File contains illegal characters."
7823
+ msgstr ""
7824
+
7825
+ #. translators: Error message.
7826
+ #: lib/wordfenceClass.php:5694
7827
+ msgid "We could not open the requested file for reading. The error was: %s"
7828
+ msgstr ""
7829
+
7830
+ #: lib/wordfenceClass.php:5702
7831
+ msgid "Greater than 2 Gigs"
7832
+ msgstr ""
7833
+
7834
+ #: lib/wordfenceClass.php:5707
7835
+ msgid "Unknown file size."
7836
+ msgstr ""
7837
+
7838
+ #: lib/wordfenceClass.php:5728
7839
+ msgid "We could not get the contents of the original file to do a comparison."
7840
+ msgstr ""
7841
+
7842
+ #: lib/wordfenceClass.php:5766
7843
+ msgid "File does not exist."
7844
+ msgstr ""
7845
+
7846
+ #: lib/wordfenceClass.php:6016
7847
+ #: views/dashboard/options-group-import.php:167
7848
+ msgid "Reload"
7849
+ msgstr ""
7850
+
7851
+ #: lib/wordfenceClass.php:6033
7852
+ msgid "${totalIPs} addresses in this network"
7853
+ msgstr ""
7854
+
7855
+ #. translators: 1. Description of firewall action. 2. Description of input parameters.
7856
+ #: lib/wordfenceClass.php:6034
7857
+ msgid "%s in POST body: %s"
7858
+ msgstr ""
7859
+
7860
+ #. translators: 1. Description of firewall action. 2. Description of input parameters.
7861
+ #: lib/wordfenceClass.php:6035
7862
+ msgid "%s in cookie: %s"
7863
+ msgstr ""
7864
+
7865
+ #. translators: 1. Description of firewall action. 2. Description of input parameters.
7866
+ #: lib/wordfenceClass.php:6036
7867
+ msgid "%s in file: %s"
7868
+ msgstr ""
7869
+
7870
+ #. translators: 1. Description of firewall action. 2. Description of input parameters.
7871
+ #: lib/wordfenceClass.php:6037
7872
+ msgid "%s in query string: %s"
7873
+ msgstr ""
7874
+
7875
+ #. translators: Domain name.
7876
+ #: lib/wordfenceClass.php:6038
7877
+ msgid "%s is not valid hostname"
7878
+ msgstr ""
7879
+
7880
+ #. translators: Domain name.
7881
+ #: lib/wordfenceClass.php:6039
7882
+ msgid ".htaccess Updated"
7883
+ msgstr ""
7884
+
7885
+ #: lib/wordfenceClass.php:6040
7886
+ msgid ".htaccess change"
7887
+ msgstr ""
7888
+
7889
+ #: lib/wordfenceClass.php:6041
7890
+ msgid "404 Not Found"
7891
+ msgstr ""
7892
+
7893
+ #: lib/wordfenceClass.php:6042
7894
+ msgid "Activity Log Sent"
7895
+ msgstr ""
7896
+
7897
+ #: lib/wordfenceClass.php:6043
7898
+ msgid "Add action to allowlist"
7899
+ msgstr ""
7900
+
7901
+ #: lib/wordfenceClass.php:6044
7902
+ msgid "Add code to .htaccess"
7903
+ msgstr ""
7904
+
7905
+ #: lib/wordfenceClass.php:6045
7906
+ msgid "All Hits"
7907
+ msgstr ""
7908
+
7909
+ #. translators: WordPress username.
7910
+ #: lib/wordfenceClass.php:6046
7911
+ msgid "All capabilties of admin user %s were successfully revoked."
7912
+ msgstr ""
7913
+
7914
+ #: lib/wordfenceClass.php:6048
7915
+ msgid "An error occurred when adding the request to the allowlist."
7916
+ msgstr ""
7917
+
7918
+ #: lib/wordfenceClass.php:6049
7919
+ msgid "Are you sure you want to allowlist this action?"
7920
+ msgstr ""
7921
+
7922
+ #: lib/wordfenceClass.php:6050
7923
+ msgid "Authentication Code"
7924
+ msgstr ""
7925
+
7926
+ #: lib/wordfenceClass.php:6051
7927
+ msgid "Background Request Blocked"
7928
+ msgstr ""
7929
+
7930
+ #: lib/wordfenceClass.php:6052
7931
+ msgid "Block This Network"
7932
+ msgstr ""
7933
+
7934
+ #: lib/wordfenceClass.php:6054
7935
+ msgid "Blocked By Firewall"
7936
+ msgstr ""
7937
+
7938
+ #: lib/wordfenceClass.php:6055
7939
+ msgid "Blocked WAF"
7940
+ msgstr ""
7941
+
7942
+ #: lib/wordfenceClass.php:6056
7943
+ msgid "Blocked by Wordfence"
7944
+ msgstr ""
7945
+
7946
+ #: lib/wordfenceClass.php:6057
7947
+ msgid "Blocked by Wordfence plugin settings"
7948
+ msgstr ""
7949
+
7950
+ #: lib/wordfenceClass.php:6058
7951
+ msgid "Blocked by the Wordfence Application Firewall and plugin settings"
7952
+ msgstr ""
7953
+
7954
+ #: lib/wordfenceClass.php:6059
7955
+ msgid "Blocked by the Wordfence Security Network"
7956
+ msgstr ""
7957
+
7958
+ #: lib/wordfenceClass.php:6060
7959
+ msgid "Blocked by the Wordfence Web Application Firewall"
7960
+ msgstr ""
7961
+
7962
+ #: lib/wordfenceClass.php:6063
7963
+ msgid "Cellphone Sign-In Recovery Codes"
7964
+ msgstr ""
7965
+
7966
+ #: lib/wordfenceClass.php:6064
7967
+ msgid "Cellphone Sign-in activated for user."
7968
+ msgstr ""
7969
+
7970
+ #: lib/wordfenceClass.php:6065
7971
+ msgid "Click here to download a backup copy of this file now"
7972
+ msgstr ""
7973
+
7974
+ #: lib/wordfenceClass.php:6066
7975
+ msgid "Click here to download a backup copy of your .htaccess file now"
7976
+ msgstr ""
7977
+
7978
+ #: lib/wordfenceClass.php:6067
7979
+ msgid "Click to fix .htaccess"
7980
+ msgstr ""
7981
+
7982
+ #: lib/wordfenceClass.php:6069
7983
+ msgid "Crawlers"
7984
+ msgstr ""
7985
+
7986
+ #: lib/wordfenceClass.php:6070
7987
+ msgid "Diagnostic report has been sent successfully."
7988
+ msgstr ""
7989
+
7990
+ #: lib/wordfenceClass.php:6071
7991
+ msgid "Directory Listing Disabled"
7992
+ msgstr ""
7993
+
7994
+ #: lib/wordfenceClass.php:6072
7995
+ msgid "Directory listing has been disabled on your server."
7996
+ msgstr ""
7997
+
7998
+ #: lib/wordfenceClass.php:6075
7999
+ msgid "Don't ask again"
8000
+ msgstr ""
8001
+
8002
+ #: lib/wordfenceClass.php:6077
8003
+ msgid "Download Backup File"
8004
+ msgstr ""
8005
+
8006
+ #: lib/wordfenceClass.php:6078
8007
+ msgid "Each line of 16 letters and numbers is a single recovery code, with optional spaces for readability. When typing your password, enter \"wf\" followed by the entire code like \"mypassword wf1234 5678 90AB CDEF\". If your site shows a separate prompt for entering a code after entering only your username and password, enter only the code like \"1234 5678 90AB CDEF\". Your recovery codes are:"
8008
+ msgstr ""
8009
+
8010
+ #: lib/wordfenceClass.php:6079
8011
+ msgid "Email Diagnostic Report"
8012
+ msgstr ""
8013
+
8014
+ #: lib/wordfenceClass.php:6080
8015
+ msgid "Email Wordfence Activity Log"
8016
+ msgstr ""
8017
+
8018
+ #: lib/wordfenceClass.php:6082
8019
+ msgid "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."
8020
+ msgstr ""
8021
+
8022
+ #: lib/wordfenceClass.php:6083
8023
+ msgid "Error"
8024
+ msgstr ""
8025
+
8026
+ #: lib/wordfenceClass.php:6084
8027
+ msgid "Error Enabling All Options Page"
8028
+ msgstr ""
8029
+
8030
+ #: lib/wordfenceClass.php:6085
8031
+ msgid "Error Restoring Defaults"
8032
+ msgstr ""
8033
+
8034
+ #: lib/wordfenceClass.php:6086
8035
+ msgid "Error Saving Option"
8036
+ msgstr ""
8037
+
8038
+ #: lib/wordfenceClass.php:6087
8039
+ msgid "Error Saving Options"
8040
+ msgstr ""
8041
+
8042
+ #: lib/wordfenceClass.php:6088
8043
+ msgid "Failed Login"
8044
+ msgstr ""
8045
+
8046
+ #: lib/wordfenceClass.php:6089
8047
+ msgid "Failed Login: Invalid Username"
8048
+ msgstr ""
8049
+
8050
+ #: lib/wordfenceClass.php:6090
8051
+ msgid "Failed Login: Valid Username"
8052
+ msgstr ""
8053
+
8054
+ #: lib/wordfenceClass.php:6091
8055
+ msgid "File hidden successfully"
8056
+ msgstr ""
8057
+
8058
+ #: lib/wordfenceClass.php:6092
8059
+ msgid "File restored OK"
8060
+ msgstr ""
8061
+
8062
+ #: lib/wordfenceClass.php:6093
8063
+ msgid "Filter Traffic"
8064
+ msgstr ""
8065
+
8066
+ #: lib/wordfenceClass.php:6094
8067
+ msgid "Firewall Response"
8068
+ msgstr ""
8069
+
8070
+ #: lib/wordfenceClass.php:6095
8071
+ #: views/scanner/issue-wpscan_fullPathDiscl.php:8
8072
+ msgid "Full Path Disclosure"
8073
+ msgstr ""
8074
+
8075
+ #: lib/wordfenceClass.php:6096
8076
+ msgid "Google Bot"
8077
+ msgstr ""
8078
+
8079
+ #: lib/wordfenceClass.php:6097
8080
+ msgid "Google Crawlers"
8081
+ msgstr ""
8082
+
8083
+ #: lib/wordfenceClass.php:6098
8084
+ msgid "HTTP Response Code"
8085
+ msgstr ""
8086
+
8087
+ #: lib/wordfenceClass.php:6100
8088
+ msgid "Humans"
8089
+ msgstr ""
8090
+
8091
+ #: lib/wordfenceClass.php:6102
8092
+ msgid "Key:"
8093
+ msgstr ""
8094
+
8095
+ #. translators: Localized date.
8096
+ #: lib/wordfenceClass.php:6103
8097
+ msgid "Last Updated: %s"
8098
+ msgstr ""
8099
+
8100
+ #. translators: Localized date.
8101
+ #: lib/wordfenceClass.php:6104
8102
+ msgid "Learn more about repairing modified files."
8103
+ msgstr ""
8104
+
8105
+ #: lib/wordfenceClass.php:6106
8106
+ msgid "Locked Out"
8107
+ msgstr ""
8108
+
8109
+ #: lib/wordfenceClass.php:6107
8110
+ msgid "Locked out from logging in"
8111
+ msgstr ""
8112
+
8113
+ #: lib/wordfenceClass.php:6108
8114
+ msgid "Logged In"
8115
+ msgstr ""
8116
+
8117
+ #: lib/wordfenceClass.php:6109
8118
+ msgid "Logins"
8119
+ msgstr ""
8120
+
8121
+ #: lib/wordfenceClass.php:6110
8122
+ msgid "Logins and Logouts"
8123
+ msgstr ""
8124
+
8125
+ #. translators: Localized date.
8126
+ #: lib/wordfenceClass.php:6113
8127
+ msgid "Next Update Check: %s"
8128
+ msgstr ""
8129
+
8130
+ #. translators: Localized date.
8131
+ #: lib/wordfenceClass.php:6114
8132
+ msgid "No activity to report yet. Please complete your first scan."
8133
+ msgstr ""
8134
+
8135
+ #: lib/wordfenceClass.php:6115
8136
+ msgid "No issues have been ignored."
8137
+ msgstr ""
8138
+
8139
+ #: lib/wordfenceClass.php:6116
8140
+ msgid "No new issues have been found."
8141
+ msgstr ""
8142
+
8143
+ #: lib/wordfenceClass.php:6117
8144
+ msgid "No rules were updated. Please verify you have permissions to write to the /wp-content/wflogs directory."
8145
+ msgstr ""
8146
+
8147
+ #: lib/wordfenceClass.php:6118
8148
+ msgid "No rules were updated. Please verify your website can reach the Wordfence servers."
8149
+ msgstr ""
8150
+
8151
+ #: lib/wordfenceClass.php:6119
8152
+ msgid "No rules were updated. Your website has reached the maximum number of rule update requests. Please try again later."
8153
+ msgstr ""
8154
+
8155
+ #: lib/wordfenceClass.php:6120
8156
+ msgid "Note: Status will update when changes are saved"
8157
+ msgstr ""
8158
+
8159
+ #: lib/wordfenceClass.php:6121
8160
+ msgid "OK"
8161
+ msgstr ""
8162
+
8163
+ #: lib/wordfenceClass.php:6122
8164
+ msgid "Pages Not Found"
8165
+ msgstr ""
8166
+
8167
+ #: lib/wordfenceClass.php:6123
8168
+ msgid "Paid Members Only"
8169
+ msgstr ""
8170
+
8171
+ #: lib/wordfenceClass.php:6125
8172
+ msgid "Please enter a valid email address."
8173
+ msgstr ""
8174
+
8175
+ #: lib/wordfenceClass.php:6126
8176
+ msgid "Please include your support ticket number or forum username."
8177
+ msgstr ""
8178
+
8179
+ #: lib/wordfenceClass.php:6127
8180
+ msgid "Please make a backup of this file before proceeding. If you need to restore this backup file, you can copy it to the following path from your site's root:"
8181
+ msgstr ""
8182
+
8183
+ #: lib/wordfenceClass.php:6128
8184
+ msgid "Please specify a reason"
8185
+ msgstr ""
8186
+
8187
+ #: lib/wordfenceClass.php:6129
8188
+ msgid "Please specify a valid IP address range in the form of \"1.2.3.4 - 1.2.3.5\" without quotes. Make sure the dash between the IP addresses in a normal dash (a minus sign on your keyboard) and not another character that looks like a dash."
8189
+ msgstr ""
8190
+
8191
+ #: lib/wordfenceClass.php:6130
8192
+ msgid "Please specify either an IP address range, Hostname or a web browser pattern to match."
8193
+ msgstr ""
8194
+
8195
+ #: lib/wordfenceClass.php:6131
8196
+ msgid "Recent Activity"
8197
+ msgstr ""
8198
+
8199
+ #: lib/wordfenceClass.php:6132
8200
+ msgid "Recovery Codes"
8201
+ msgstr ""
8202
+
8203
+ #: lib/wordfenceClass.php:6133
8204
+ msgid "Redirected"
8205
+ msgstr ""
8206
+
8207
+ #: lib/wordfenceClass.php:6134
8208
+ msgid "Redirected by Country Blocking bypass URL"
8209
+ msgstr ""
8210
+
8211
+ #: lib/wordfenceClass.php:6135
8212
+ msgid "Referer"
8213
+ msgstr ""
8214
+
8215
+ #: lib/wordfenceClass.php:6136
8216
+ msgid "Registered Users"
8217
+ msgstr ""
8218
+
8219
+ #: lib/wordfenceClass.php:6138
8220
+ msgid "Rule Update Failed"
8221
+ msgstr ""
8222
+
8223
+ #: lib/wordfenceClass.php:6139
8224
+ msgid "Rules Updated"
8225
+ msgstr ""
8226
+
8227
+ #: lib/wordfenceClass.php:6141
8228
+ msgid "Scan Complete."
8229
+ msgstr ""
8230
+
8231
+ #: lib/wordfenceClass.php:6142
8232
+ msgid "Scan the code below with your authenticator app to add this account. Some authenticator apps also allow you to type in the text version instead."
8233
+ msgstr ""
8234
+
8235
+ #: lib/wordfenceClass.php:6143
8236
+ msgid "Security Event"
8237
+ msgstr ""
8238
+
8239
+ #: lib/wordfenceClass.php:6144
8240
+ msgid "Send"
8241
+ msgstr ""
8242
+
8243
+ #: lib/wordfenceClass.php:6145
8244
+ msgid "Sorry, but no data for that IP or domain was found."
8245
+ msgstr ""
8246
+
8247
+ #: lib/wordfenceClass.php:6146
8248
+ msgid "Specify a valid IP range"
8249
+ msgstr ""
8250
+
8251
+ #: lib/wordfenceClass.php:6147
8252
+ msgid "Specify a valid hostname"
8253
+ msgstr ""
8254
+
8255
+ #: lib/wordfenceClass.php:6148
8256
+ msgid "Specify an IP range, Hostname or Browser pattern"
8257
+ msgstr ""
8258
+
8259
+ #: lib/wordfenceClass.php:6149
8260
+ msgid "Success deleting file"
8261
+ msgstr ""
8262
+
8263
+ #: lib/wordfenceClass.php:6150
8264
+ msgid "Success removing option"
8265
+ msgstr ""
8266
+
8267
+ #: lib/wordfenceClass.php:6151
8268
+ msgid "Success restoring file"
8269
+ msgstr ""
8270
+
8271
+ #: lib/wordfenceClass.php:6152
8272
+ msgid "Success updating option"
8273
+ msgstr ""
8274
+
8275
+ #: lib/wordfenceClass.php:6153
8276
+ msgid "Successfully deleted admin"
8277
+ msgstr ""
8278
+
8279
+ #: lib/wordfenceClass.php:6154
8280
+ msgid "Successfully revoked admin"
8281
+ msgstr ""
8282
+
8283
+ #: lib/wordfenceClass.php:6155
8284
+ msgid "Test Email Sent"
8285
+ msgstr ""
8286
+
8287
+ #: lib/wordfenceClass.php:6156
8288
+ msgid "The 'How does Wordfence get IPs' option was successfully updated to the recommended value."
8289
+ msgstr ""
8290
+
8291
+ #: lib/wordfenceClass.php:6157
8292
+ msgid "The Full Path disclosure issue has been fixed"
8293
+ msgstr ""
8294
+
8295
+ #. translators: WordPress username.
8296
+ #: lib/wordfenceClass.php:6158
8297
+ msgid "The admin user %s was successfully deleted."
8298
+ msgstr ""
8299
+
8300
+ #. translators: File path.
8301
+ #: lib/wordfenceClass.php:6159
8302
+ msgid "The file %s was successfully deleted."
8303
+ msgstr ""
8304
+
8305
+ #. translators: File path.
8306
+ #: lib/wordfenceClass.php:6160
8307
+ msgid "The file %s was successfully hidden from public view."
8308
+ msgstr ""
8309
+
8310
+ #. translators: File path.
8311
+ #: lib/wordfenceClass.php:6161
8312
+ msgid "The file %s was successfully restored."
8313
+ msgstr ""
8314
+
8315
+ #. translators: WordPress option.
8316
+ #: lib/wordfenceClass.php:6162
8317
+ msgid "The option %s was successfully removed."
8318
+ msgstr ""
8319
+
8320
+ #. translators: WordPress option.
8321
+ #: lib/wordfenceClass.php:6163
8322
+ msgid "The request has been allowlisted. Please try it again."
8323
+ msgstr ""
8324
+
8325
+ #: lib/wordfenceClass.php:6164
8326
+ msgid "There was an error while sending the email."
8327
+ msgstr ""
8328
+
8329
+ #: lib/wordfenceClass.php:6165
8330
+ msgid "This will be shown only once. Keep these codes somewhere safe."
8331
+ msgstr ""
8332
+
8333
+ #: lib/wordfenceClass.php:6166
8334
+ msgid "Throttled"
8335
+ msgstr ""
8336
+
8337
+ #: lib/wordfenceClass.php:6167
8338
+ msgid "Two Factor Status"
8339
+ msgstr ""
8340
+
8341
+ #. translators: HTTP client type.
8342
+ #: lib/wordfenceClass.php:6169
8343
+ msgid "Type: %s"
8344
+ msgstr ""
8345
+
8346
+ #. translators: HTTP client type.
8347
+ #: lib/wordfenceClass.php:6170
8348
+ #: views/scanner/issue-checkGSB.php:8
8349
+ #: views/scanner/issue-commentBadURL.php:8
8350
+ #: views/scanner/issue-configReadable.php:12
8351
+ #: views/scanner/issue-configReadable.php:23
8352
+ #: views/scanner/issue-optionBadURL.php:8
8353
+ #: views/scanner/issue-postBadURL.php:8
8354
+ #: views/scanner/issue-publiclyAccessible.php:12
8355
+ #: views/scanner/issue-publiclyAccessible.php:23
8356
+ #: views/scanner/issue-wpscan_directoryList.php:12
8357
+ #: views/scanner/issue-wpscan_directoryList.php:23
8358
+ #: views/scanner/issue-wpscan_fullPathDiscl.php:12
8359
+ #: views/scanner/issue-wpscan_fullPathDiscl.php:23
8360
+ #: views/waf/option-whitelist.php:9
8361
+ #: views/waf/option-whitelist.php:106
8362
+ #: views/waf/options-group-whitelisted.php:82
8363
+ #: views/waf/options-group-whitelisted.php:95
8364
+ msgid "URL"
8365
+ msgstr ""
8366
+
8367
+ #: lib/wordfenceClass.php:6171
8368
+ msgid "Unable to automatically hide file"
8369
+ msgstr ""
8370
+
8371
+ #. translators: 2FA backup codes.
8372
+ #: lib/wordfenceClass.php:6172
8373
+ msgid "Use one of these %s codes to log in if you are unable to access your phone. Codes are 16 characters long, plus optional spaces. Each one may be used only once."
8374
+ msgstr ""
8375
+
8376
+ #. translators: 2FA backup codes.
8377
+ #: lib/wordfenceClass.php:6173
8378
+ msgid "Use one of these %s codes to log in if you lose access to your authenticator device. Codes are 16 characters long, plus optional spaces. Each one may be used only once."
8379
+ msgstr ""
8380
+
8381
+ #: lib/wordfenceClass.php:6175
8382
+ msgid "User ID"
8383
+ msgstr ""
8384
+
8385
+ #: lib/wordfenceClass.php:6177
8386
+ msgid "WHOIS LOOKUP"
8387
+ msgstr ""
8388
+
8389
+ #: lib/wordfenceClass.php:6178
8390
+ msgid "We are about to change your <em>.htaccess</em> file. Please make a backup of this file before proceeding."
8391
+ msgstr ""
8392
+
8393
+ #. translators: Error message.
8394
+ #: lib/wordfenceClass.php:6179
8395
+ msgid "We can't modify your .htaccess file for you because: %s"
8396
+ msgstr ""
8397
+
8398
+ #. translators: Error message.
8399
+ #: lib/wordfenceClass.php:6180
8400
+ msgid "We encountered a problem"
8401
+ msgstr ""
8402
+
8403
+ #. translators: URL.
8404
+ #: lib/wordfenceClass.php:6181
8405
+ msgid "Wordfence Firewall blocked a background request to WordPress for the URL %s. If this occurred as a result of an intentional action, you may consider allowlisting the request to allow it in the future."
8406
+ msgstr ""
8407
+
8408
+ #. translators: URL.
8409
+ #: lib/wordfenceClass.php:6182
8410
+ msgid "Wordfence is working..."
8411
+ msgstr ""
8412
+
8413
+ #: lib/wordfenceClass.php:6183
8414
+ msgid "You are using Nginx as your web server. You'll need to disable autoindexing in your nginx.conf. See the <a target='_blank' rel='noopener noreferrer' href='http://nginx.org/en/docs/http/ngx_http_autoindex_module.html'>Nginx docs for more info</a> on how to do this."
8415
+ msgstr ""
8416
+
8417
+ #: lib/wordfenceClass.php:6184
8418
+ msgid "You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. You will need to manually delete or hide those files."
8419
+ msgstr ""
8420
+
8421
+ #: lib/wordfenceClass.php:6185
8422
+ msgid "You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. You will need to manually modify your php.ini to disable <em>display_error</em>"
8423
+ msgstr ""
8424
+
8425
+ #: lib/wordfenceClass.php:6186
8426
+ msgid "You forgot to include a reason you're blocking this IP range. We ask you to include this for your own record keeping."
8427
+ msgstr ""
8428
+
8429
+ #: lib/wordfenceClass.php:6187
8430
+ msgid "You have unsaved changes to your options. If you leave this page, those changes will be lost."
8431
+ msgstr ""
8432
+
8433
+ #: lib/wordfenceClass.php:6188
8434
+ msgid "Your .htaccess has been updated successfully. Please verify your site is functioning normally."
8435
+ msgstr ""
8436
+
8437
+ #. translators: Email address.
8438
+ #: lib/wordfenceClass.php:6189
8439
+ msgid "Your Wordfence activity log was sent to %s"
8440
+ msgstr ""
8441
+
8442
+ #. translators: Email address.
8443
+ #: lib/wordfenceClass.php:6190
8444
+ msgid "Your rules have been updated successfully."
8445
+ msgstr ""
8446
+
8447
+ #: lib/wordfenceClass.php:6191
8448
+ msgid "Your rules have been updated successfully. You are currently using the free version of Wordfence. Upgrade to Wordfence premium to have your rules updated automatically as new threats emerge. <a href=\"https://www.wordfence.com/wafUpdateRules1/wordfence-signup/\">Click here to purchase a premium license</a>. <em>Note: Your rules will still update every 30 days as a free user.</em>"
8449
+ msgstr ""
8450
+
8451
+ #. translators: wp_mail() return value.
8452
+ #: lib/wordfenceClass.php:6192
8453
+ msgid "Your test email was sent to the requested email address. The result we received from the WordPress wp_mail() function was: %s<br /><br />A 'True' result means WordPress thinks the mail was sent without errors. A 'False' result means that WordPress encountered an error sending your mail. Note that it's possible to get a 'True' response with an error elsewhere in your mail system that may cause emails to not be delivered."
8454
+ msgstr ""
8455
+
8456
+ #. translators: wp_mail() return value.
8457
+ #: lib/wordfenceClass.php:6193
8458
+ msgid "blocked by firewall"
8459
+ msgstr ""
8460
+
8461
+ #. translators: Reason for firewall action.
8462
+ #: lib/wordfenceClass.php:6194
8463
+ msgid "blocked by firewall for %s"
8464
+ msgstr ""
8465
+
8466
+ #. translators: Reason for firewall action.
8467
+ #: lib/wordfenceClass.php:6195
8468
+ msgid "blocked by real-time IP blocklist"
8469
+ msgstr ""
8470
+
8471
+ #: lib/wordfenceClass.php:6196
8472
+ msgid "blocked by the Wordfence Security Network"
8473
+ msgstr ""
8474
+
8475
+ #. translators: Reason for firewall action.
8476
+ #: lib/wordfenceClass.php:6197
8477
+ msgid "blocked for %s"
8478
+ msgstr ""
8479
+
8480
+ #. translators: Reason for firewall action.
8481
+ #: lib/wordfenceClass.php:6198
8482
+ msgid "locked out from logging in"
8483
+ msgstr ""
8484
+
8485
+ #: lib/wordfenceClass.php:6211
8486
+ msgid "Wordfence generated an error on activation. The output we received during activation was:"
8487
+ msgstr ""
8488
+
8489
+ #: lib/wordfenceClass.php:6218
8490
+ msgid "Wordfence could not register with the Wordfence scanning servers when it activated."
8491
+ msgstr ""
8492
+
8493
+ #: lib/wordfenceClass.php:6219
8494
+ msgid "You can try to fix this by deactivating Wordfence and then activating it again, so Wordfence will retry registering for you. If you keep seeing this error, it usually means your WordPress server can't connect to our scanning servers, or your wfConfig database table cannot be created to save the key. You can try asking your host to allow your server to connect to noc1.wordfence.com or check the wfConfig database table and database privileges."
8495
+ msgstr ""
8496
+
8497
+ #: lib/wordfenceClass.php:6233
8498
+ msgid "The Wordfence Web Application Firewall cannot run."
8499
+ msgstr ""
8500
+
8501
+ #. translators: 1. WordPress admin panel URL. 2. Support URL.
8502
+ #: lib/wordfenceClass.php:6236
8503
+ msgid "The configuration files are corrupt or inaccessible by the web server, which is preventing the WAF from functioning. Please verify the web server has permission to access the configuration files. You may also try to rebuild the configuration file by <a href=\"%1$s\">clicking here</a>. It will automatically resume normal operation when it is fixed. <a class=\"wfhelp\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"%2$s\"></a>"
8504
+ msgstr ""
8505
+
8506
+ #: lib/wordfenceClass.php:6252
8507
+ #: lib/wordfenceClass.php:6271
8508
+ msgid "The Wordfence Web Application Firewall needs a configuration update."
8509
+ msgstr ""
8510
+
8511
+ #. translators: 1. WordPress admin panel URL. 2. Support URL.
8512
+ #: lib/wordfenceClass.php:6255
8513
+ msgid "It is currently configured to use an older version of PHP and may become deactivated if PHP is updated. You may perform the configuration update automatically by <a href=\"%1$s\">clicking here</a>. <a class=\"wfhelp\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"%2$s\"></a>"
8514
+ msgstr ""
8515
+
8516
+ #. translators: 1. WordPress admin panel URL. 2. Support URL.
8517
+ #: lib/wordfenceClass.php:6274
8518
+ msgid "It is not currently in extended protection mode but was configured to use an older version of PHP and may have become deactivated when PHP was updated. You may perform the configuration update automatically by <a href=\"%1$s\">clicking here</a> or use the \"Optimize the Wordfence Firewall\" button on the Firewall Options page. <a class=\"wfhelp\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"%2$s\"></a>"
8519
+ msgstr ""
8520
+
8521
+ #: lib/wordfenceClass.php:6280
8522
+ msgid "The Wordfence Web Application Firewall is in read-only mode."
8523
+ msgstr ""
8524
+
8525
+ #: lib/wordfenceClass.php:6289
8526
+ msgid "This site is currently using PHP's built in REMOTE_ADDR."
8527
+ msgstr ""
8528
+
8529
+ #: lib/wordfenceClass.php:6292
8530
+ msgid "This site is currently using the X-Forwarded-For HTTP header, which should only be used when the site is behind a front-end proxy that outputs this header."
8531
+ msgstr ""
8532
+
8533
+ #: lib/wordfenceClass.php:6295
8534
+ msgid "This site is currently using the X-Real-IP HTTP header, which should only be used when the site is behind a front-end proxy that outputs this header."
8535
+ msgstr ""
8536
+
8537
+ #: lib/wordfenceClass.php:6298
8538
+ msgid "This site is currently using the Cloudflare \"CF-Connecting-IP\" HTTP header, which should only be used when the site is behind Cloudflare."
8539
+ msgstr ""
8540
+
8541
+ #: lib/wordfenceClass.php:6315
8542
+ msgid "Your 'How does Wordfence get IPs' setting is misconfigured."
8543
+ msgstr ""
8544
+
8545
+ #: lib/wordfenceClass.php:6317
8546
+ msgid "Click here to use the recommended setting"
8547
+ msgstr ""
8548
+
8549
+ #: lib/wordfenceClass.php:6319
8550
+ #: views/onboarding/fresh-install.php:39
8551
+ msgid "or"
8552
+ msgstr ""
8553
+
8554
+ #: lib/wordfenceClass.php:6321
8555
+ msgid "visit the options page"
8556
+ msgstr ""
8557
+
8558
+ #: lib/wordfenceClass.php:6323
8559
+ msgid "to manually update it."
8560
+ msgstr ""
8561
+
8562
+ #: lib/wordfenceClass.php:6331
8563
+ msgid "Do you want Wordfence to stay up-to-date automatically?"
8564
+ msgstr ""
8565
+
8566
+ #: lib/wordfenceClass.php:6333
8567
+ msgid "Yes, enable auto-update."
8568
+ msgstr ""
8569
+
8570
+ #: lib/wordfenceClass.php:6335
8571
+ msgid "No thanks."
8572
+ msgstr ""
8573
+
8574
+ #. translators: Localized date.
8575
+ #: lib/wordfenceClass.php:6418
8576
+ msgid "The last rules update for the Wordfence Web Application Firewall was unsuccessful. The last successful update check was %s, so this site may be missing new rules added since then."
8577
+ msgstr ""
8578
+
8579
+ #. translators: 1. Localized date. 2. WordPress admin panel URL.
8580
+ #: lib/wordfenceClass.php:6426
8581
+ msgid "You may wait for the next automatic attempt at %1$s or try to <a href=\"%2$s\">Manually Update</a> by clicking the \"Manually Refresh Rules\" button below the Rules list."
8582
+ msgstr ""
8583
+
8584
+ #. translators: WordPress admin panel URL.
8585
+ #: lib/wordfenceClass.php:6432
8586
+ msgid "You may wait for the next automatic attempt or try to <a href=\"%s\">Manually Update</a> by clicking the \"Manually Refresh Rules\" button below the Rules list."
8587
+ msgstr ""
8588
+
8589
+ #. translators: WordPress admin panel URL.
8590
+ #: lib/wordfenceClass.php:6437
8591
+ msgid "You may wait for the next automatic attempt at %s or log into the parent site to manually update by clicking the \"Manually Refresh Rules\" button below the Rules list."
8592
+ msgstr ""
8593
+
8594
+ #: lib/wordfenceClass.php:6440
8595
+ msgid "You may wait for the next automatic attempt or log into the parent site to manually update by clicking the \"Manually Refresh Rules\" button below the Rules list."
8596
+ msgstr ""
8597
+
8598
+ #: lib/wordfenceClass.php:6543
8599
+ #: models/page/wfPage.php:101
8600
+ msgid "Dashboard"
8601
+ msgstr ""
8602
+
8603
+ #. translators: Number of notifications.
8604
+ #: lib/wordfenceClass.php:6623
8605
+ msgid "You have %d new Wordfence notification."
8606
+ msgid_plural "You have %d new Wordfence notifications."
8607
+ msgstr[0] ""
8608
+ msgstr[1] ""
8609
+
8610
+ #: lib/wordfenceClass.php:6647
8611
+ msgid "JavaScript Errors"
8612
+ msgstr ""
8613
+
8614
+ #: lib/wordfenceClass.php:6653
8615
+ msgid "Malware URLs"
8616
+ msgstr ""
8617
+
8618
+ #. translators: WordPress admin panel URL.
8619
+ #: lib/wordfenceClass.php:6771
8620
+ #: lib/wordfenceClass.php:6834
8621
+ msgid "<a href=\"%s\">Click here</a> to rebuild the configuration file."
8622
+ msgstr ""
8623
+
8624
+ #. translators: File path.
8625
+ #: lib/wordfenceClass.php:6782
8626
+ #: lib/wordfenceClass.php:6845
8627
+ msgid "We were unable to write to %s which the WAF uses for storage. Please update permissions on the parent directory so the web server can write to it."
8628
+ msgstr ""
8629
+
8630
+ #: lib/wordfenceClass.php:6792
8631
+ #: lib/wordfenceClass.php:6855
8632
+ msgid "An error occured when fetching the WAF configuration from the database."
8633
+ msgstr ""
8634
+
8635
+ #. translators: Plugin name.
8636
+ #: lib/wordfenceClass.php:6877
8637
+ msgid "The Wordfence Live Traffic feature has been disabled because you have %s active which is not compatible with Wordfence Live Traffic."
8638
+ msgstr ""
8639
+
8640
+ #. translators: 1. Plugin name.
8641
+ #: lib/wordfenceClass.php:6879
8642
+ msgid "If you want to reenable Wordfence Live Traffic, you need to deactivate %1$s and then go to the Wordfence options page and reenable Live Traffic there. Wordfence does work with %1$s, however Live Traffic will be disabled and the Wordfence firewall will also count less hits per visitor because of the %1$s caching function. All other functions should work correctly."
8643
+ msgstr ""
8644
+
8645
+ #. translators: File path.
8646
+ #: lib/wordfenceClass.php:6940
8647
+ msgid "The file <code>%s</code> was restored successfully."
8648
+ msgstr ""
8649
+
8650
+ #: lib/wordfenceClass.php:6945
8651
+ msgid "There was an error restoring the file."
8652
+ msgstr ""
8653
+
8654
+ #: lib/wordfenceClass.php:6955
8655
+ #: lib/wordfenceClass.php:6978
8656
+ msgid "Return to scan results"
8657
+ msgstr ""
8658
+
8659
+ #. translators: File path.
8660
+ #: lib/wordfenceClass.php:6964
8661
+ msgid "The file <code>%s</code> was deleted successfully."
8662
+ msgstr ""
8663
+
8664
+ #: lib/wordfenceClass.php:6968
8665
+ msgid "There was an error deleting the file."
8666
+ msgstr ""
8667
+
8668
+ #. translators: IP address.
8669
+ #: lib/wordfenceClass.php:7036
8670
+ msgid ""
8671
+ "User IP: %s\n"
8672
+ ""
8673
+ msgstr ""
8674
+
8675
+ #. translators: Domain name.
8676
+ #: lib/wordfenceClass.php:7039
8677
+ msgid ""
8678
+ "User hostname: %s\n"
8679
+ ""
8680
+ msgstr ""
8681
+
8682
+ #: lib/wordfenceClass.php:7043
8683
+ msgid "User location: "
8684
+ msgstr ""
8685
+
8686
+ #. translators: WordPress admin panel URL.
8687
+ #: lib/wordfenceClass.php:7098
8688
+ msgid "No longer an administrator for this site? Click here to stop receiving security alerts: %s"
8689
+ msgstr ""
8690
+
8691
+ #: lib/wordfenceClass.php:7138
8692
+ msgid "The IP you provided must be in dotted quad notation or use ranges with square brackets. e.g. 10.11.12.13 or 10.11.12.[1-50]"
8693
+ msgstr ""
8694
+
8695
+ #: lib/wordfenceClass.php:7157
8696
+ msgid "Invalid email address provided."
8697
+ msgstr ""
8698
+
8699
+ #: lib/wordfenceClass.php:7162
8700
+ msgid "Test email sent successfully"
8701
+ msgstr ""
8702
+
8703
+ #: lib/wordfenceClass.php:7163
8704
+ msgid "Test email failed to send."
8705
+ msgstr ""
8706
+
8707
+ #. translators: Localized date range.
8708
+ #: lib/wordfenceClass.php:7181
8709
+ msgid "Wordfence activity in the past %s"
8710
+ msgstr ""
8711
+
8712
+ #: lib/wordfenceClass.php:7221
8713
+ #: lib/wordfenceClass.php:7225
8714
+ #: lib/wordfenceClass.php:7256
8715
+ msgid "We could not find that user in the database."
8716
+ msgstr ""
8717
+
8718
+ #: lib/wordfenceClass.php:7229
8719
+ msgid "This user's email is the network admin email. It will need to be changed before deleting this user."
8720
+ msgstr ""
8721
+
8722
+ #: lib/wordfenceClass.php:7293
8723
+ msgid "Wordfence could not find your .htaccess file."
8724
+ msgstr ""
8725
+
8726
+ #: lib/wordfenceClass.php:7309
8727
+ msgid "Updating the .htaccess did not fix the issue. You may need to add <code>Options -Indexes</code> to your httpd.conf if using Apache, or find documentation on how to disable directory listing for your web server."
8728
+ msgstr ""
8729
+
8730
+ #: lib/wordfenceClass.php:7315
8731
+ msgid "There was an error writing to your .htaccess file."
8732
+ msgstr ""
8733
+
8734
+ #: lib/wordfenceClass.php:7394
8735
+ msgid "Required parameters not sent."
8736
+ msgstr ""
8737
+
8738
+ #: lib/wordfenceClass.php:7404
8739
+ msgid "The WAF is currently in read-only mode and will not save any configuration changes."
8740
+ msgstr ""
8741
+
8742
+ #: lib/wordfenceClass.php:7442
8743
+ #: views/waf/option-whitelist.php:60
8744
+ msgid "Allowlisted via Firewall Options page"
8745
+ msgstr ""
8746
+
8747
+ #: lib/wordfenceClass.php:7729
8748
+ msgid "Allowlisted via Live Traffic"
8749
+ msgstr ""
8750
+
8751
+ #: lib/wordfenceClass.php:7893
8752
+ #: lib/wordfenceClass.php:7990
8753
+ msgid "A valid server configuration was not provided."
8754
+ msgstr ""
8755
+
8756
+ #: lib/wordfenceClass.php:7904
8757
+ #: lib/wordfenceClass.php:8011
8758
+ msgid "Filesystem Credentials Required"
8759
+ msgstr ""
8760
+
8761
+ #. translators: Support URL.
8762
+ #: lib/wordfenceClass.php:7906
8763
+ #: lib/wordfenceClass.php:7930
8764
+ #: lib/wordfenceClass.php:7974
8765
+ msgid "If you cannot complete the setup process, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">click here for help</a>"
8766
+ msgstr ""
8767
+
8768
+ #. translators: Support URL.
8769
+ #: lib/wordfenceClass.php:7907
8770
+ msgid "Once you have entered credentials, click Continue to complete the setup."
8771
+ msgstr ""
8772
+
8773
+ #: lib/wordfenceClass.php:7928
8774
+ #: lib/wordfenceClass.php:8036
8775
+ msgid "Filesystem Permission Error"
8776
+ msgstr ""
8777
+
8778
+ #: lib/wordfenceClass.php:7954
8779
+ msgid "Manual Installation Instructions"
8780
+ msgstr ""
8781
+
8782
+ #: lib/wordfenceClass.php:7961
8783
+ msgid "Installation Successful"
8784
+ msgstr ""
8785
+
8786
+ #: lib/wordfenceClass.php:7972
8787
+ msgid "Installation Failed"
8788
+ msgstr ""
8789
+
8790
+ #. translators: Support URL.
8791
+ #: lib/wordfenceClass.php:8013
8792
+ #: lib/wordfenceClass.php:8038
8793
+ #: lib/wordfenceClass.php:8069
8794
+ #: lib/wordfenceClass.php:8098
8795
+ #: lib/wordfenceClass.php:8144
8796
+ #: views/waf/waf-uninstall.php:13
8797
+ msgid "If you cannot complete the uninstall process, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">click here for help</a>"
8798
+ msgstr ""
8799
+
8800
+ #. translators: Support URL.
8801
+ #: lib/wordfenceClass.php:8014
8802
+ msgid "Once you have entered credentials, click Continue to complete uninstallation."
8803
+ msgstr ""
8804
+
8805
+ #: lib/wordfenceClass.php:8058
8806
+ msgid "The <code>auto_prepend_file</code> setting has been successfully removed from <code>.htaccess</code> and <code>.user.ini</code>. Once this change takes effect, Extended Protection Mode will be disabled."
8807
+ msgstr ""
8808
+
8809
+ #: lib/wordfenceClass.php:8060
8810
+ msgid "Any previous value for <code>auto_prepend_file</code> will need to be re-enabled manually if still needed."
8811
+ msgstr ""
8812
+
8813
+ #. translators: Time until.
8814
+ #: lib/wordfenceClass.php:8064
8815
+ msgid "Waiting for it to take effect. This may take up to %s."
8816
+ msgstr ""
8817
+
8818
+ #: lib/wordfenceClass.php:8067
8819
+ msgid "Waiting for Changes"
8820
+ msgstr ""
8821
+
8822
+ #: lib/wordfenceClass.php:8089
8823
+ msgid "Extended Protection Mode has not been disabled. This may be because <code>auto_prepend_file</code> is configured somewhere else or the value is still cached by PHP."
8824
+ msgstr ""
8825
+
8826
+ #: lib/wordfenceClass.php:8091
8827
+ msgid "Retrying Failed."
8828
+ msgstr ""
8829
+
8830
+ #: lib/wordfenceClass.php:8093
8831
+ msgid "Try Again"
8832
+ msgstr ""
8833
+
8834
+ #: lib/wordfenceClass.php:8096
8835
+ msgid "Unable to Uninstall"
8836
+ msgstr ""
8837
+
8838
+ #: lib/wordfenceClass.php:8132
8839
+ msgid "Uninstallation Complete"
8840
+ msgstr ""
8841
+
8842
+ #: lib/wordfenceClass.php:8142
8843
+ msgid "Uninstallation Failed"
8844
+ msgstr ""
8845
+
8846
+ #. translators: 1. Number of attacks/blocks. 2. Time since.
8847
+ #: lib/wordfenceClass.php:8285
8848
+ msgid "The Wordfence Web Application Firewall has blocked %1$d attacks over the last %2$s. Below is a sample of these recent attacks:"
8849
+ msgstr ""
8850
+
8851
+ #: lib/wordfenceClass.php:8818
8852
+ msgid "To make your site as secure as possible, take a moment to optimize the Wordfence Web Application Firewall:"
8853
+ msgstr ""
8854
+
8855
+ #: lib/wordfenceClass.php:8818
8856
+ msgid "Click here to configure"
8857
+ msgstr ""
8858
+
8859
+ #. translators: Support URL.
8860
+ #: lib/wordfenceClass.php:8821
8861
+ msgid "If you cannot complete the setup process, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">click here for help</a>."
8862
+ msgstr ""
8863
+
8864
+ #: lib/wordfenceClass.php:8827
8865
+ #: views/waf/waf-install-success.php:14
8866
+ msgid "Nice work! The firewall is now optimized."
8867
+ msgstr ""
8868
+
8869
+ #: lib/wordfenceClass.php:8829
8870
+ #: lib/wordfenceClass.php:8841
8871
+ #: views/waf/waf-install-success.php:16
8872
+ #: views/waf/waf-uninstall-success.php:19
8873
+ msgid "The changes have not yet taken effect. If you are using LiteSpeed or IIS as your web server or CGI/FastCGI interface, you may need to wait a few minutes for the changes to take effect since the configuration files are sometimes cached. You also may need to select a different server configuration in order to complete this step, but wait for a few minutes before trying. You can try refreshing this page."
8874
+ msgstr ""
8875
+
8876
+ #: lib/wordfenceClass.php:8835
8877
+ #: views/waf/waf-uninstall-success.php:15
8878
+ msgid "Uninstallation was successful!"
8879
+ msgstr ""
8880
+
8881
+ #: lib/wordfenceClass.php:8838
8882
+ #: views/waf/waf-uninstall-success.php:17
8883
+ msgid "Uninstallation from this site was successful! The Wordfence Firewall is still active because it is installed in another WordPress installation."
8884
+ msgstr ""
8885
+
8886
+ #: lib/wordfenceClass.php:8846
8887
+ msgid "The update was successful!"
8888
+ msgstr ""
8889
+
8890
+ #: lib/wordfenceClass.php:8982
8891
+ msgid "Auth grant is invalid."
8892
+ msgstr ""
8893
+
8894
+ #: lib/wordfenceClass.php:9045
8895
+ #: lib/wordfenceClass.php:9182
8896
+ msgid "Access token not found."
8897
+ msgstr ""
8898
+
8899
+ #: lib/wordfenceClass.php:9090
8900
+ #: lib/wordfenceClass.php:9157
8901
+ msgid "Invalid response from Wordfence Central."
8902
+ msgstr ""
8903
+
8904
+ #: lib/wordfenceClass.php:9133
8905
+ msgid "Auth grant not found."
8906
+ msgstr ""
8907
+
8908
+ #: lib/wordfenceClass.php:9399
8909
+ msgid "We were unable to create the <code>wordfence-waf.php</code> file in the root of the WordPress installation. It's possible WordPress cannot write to the <code>wordfence-waf.php</code> file because of file permissions. Please verify the permissions are correct and retry the installation."
8910
+ msgstr ""
8911
+
8912
+ #: lib/wordfenceClass.php:9491
8913
+ #: lib/wordfenceClass.php:9562
8914
+ msgid "We were unable to make changes to the .htaccess file. It's possible WordPress cannot write to the .htaccess file because of file permissions, which may have been set by another security plugin, or you may have set them manually. Please verify the permissions allow the web server to write to the file, and retry the installation."
8915
+ msgstr ""
8916
+
8917
+ #. translators: File path.
8918
+ #: lib/wordfenceClass.php:9532
8919
+ #: lib/wordfenceClass.php:9580
8920
+ msgid "We were unable to make changes to the %1$s file. It's possible WordPress cannot write to the %1$s file because of file permissions. Please verify the permissions are correct and retry the installation."
8921
  msgstr ""
8922
 
8923
+ #: lib/wordfenceClass.php:9596
8924
+ msgid "We were unable to remove the <code>wordfence-waf.php</code> file in the root of the WordPress installation. It's possible WordPress cannot remove the <code>wordfence-waf.php</code> file because of file permissions. Please verify the permissions are correct and retry the removal."
8925
  msgstr ""
8926
 
8927
+ #: lib/wordfenceHash.php:68
8928
+ msgid "Fetching core, theme and plugin file signatures from Wordfence"
8929
  msgstr ""
8930
 
8931
+ #: lib/wordfenceHash.php:77
8932
+ msgid "Fetching list of known malware files from Wordfence"
8933
  msgstr ""
8934
 
8935
+ #: lib/wordfenceHash.php:81
8936
+ msgid "Using cached malware prefixes"
 
8937
  msgstr ""
8938
 
8939
+ #: lib/wordfenceHash.php:84
8940
+ msgid "Fetching fresh malware prefixes"
8941
  msgstr ""
8942
 
8943
+ #: lib/wordfenceHash.php:89
8944
+ msgid "Could not fetch malware signatures from Wordfence servers."
 
8945
  msgstr ""
8946
 
8947
+ #: lib/wordfenceHash.php:94
8948
+ msgid "Malware data received from Wordfence servers was not valid."
8949
  msgstr ""
8950
 
8951
+ #: lib/wordfenceHash.php:106
8952
+ msgid "Fetching list of known core files from Wordfence"
8953
  msgstr ""
8954
 
8955
+ #: lib/wordfenceHash.php:110
8956
+ msgid "Using cached core hashes"
8957
  msgstr ""
8958
 
8959
+ #: lib/wordfenceHash.php:113
8960
+ msgid "Fetching fresh core hashes"
8961
  msgstr ""
8962
 
8963
+ #: lib/wordfenceHash.php:118
8964
+ msgid "Could not fetch core hashes from Wordfence servers."
8965
  msgstr ""
8966
 
8967
+ #: lib/wordfenceHash.php:123
8968
+ msgid "Core hashes data received from Wordfence servers was not valid."
8969
  msgstr ""
8970
 
8971
+ #: lib/wordfenceHash.php:138
8972
+ msgid "Could not read directory %s to do scan."
 
 
8973
  msgstr ""
8974
 
8975
+ #: lib/wordfenceHash.php:147
8976
+ msgid "Comparing core WordPress files against originals in repository"
 
 
8977
  msgstr ""
8978
 
8979
+ #: lib/wordfenceHash.php:147
8980
+ msgid "Skipping core scan"
8981
  msgstr ""
8982
 
8983
+ #: lib/wordfenceHash.php:148
8984
+ msgid "Comparing open source themes against WordPress.org originals"
8985
  msgstr ""
8986
 
8987
+ #: lib/wordfenceHash.php:148
8988
+ msgid "Skipping theme scan"
8989
  msgstr ""
8990
 
8991
+ #: lib/wordfenceHash.php:149
8992
+ msgid "Comparing plugins against WordPress.org originals"
8993
  msgstr ""
8994
 
8995
+ #: lib/wordfenceHash.php:149
8996
+ msgid "Skipping plugin scan"
 
8997
  msgstr ""
8998
 
8999
+ #: lib/wordfenceHash.php:150
9000
+ msgid "Scanning for known malware files"
 
9001
  msgstr ""
9002
 
9003
+ #: lib/wordfenceHash.php:150
9004
+ msgid "Skipping malware scan"
 
 
 
9005
  msgstr ""
9006
 
9007
+ #: lib/wordfenceHash.php:151
9008
+ msgid "Scanning for unknown files in wp-admin and wp-includes"
9009
  msgstr ""
9010
 
9011
+ #: lib/wordfenceHash.php:151
9012
+ msgid "Skipping unknown core file scan"
 
9013
  msgstr ""
9014
 
9015
+ #. translators: WordPress version.
9016
+ #: lib/wordfenceHash.php:164
9017
+ msgid "Unknown WordPress core version: %s"
9018
  msgstr ""
9019
 
9020
+ #. translators: WordPress version.
9021
+ #: lib/wordfenceHash.php:165
9022
+ msgid "The core files scan will not be run because this version of WordPress is not currently indexed by Wordfence. This may be due to using a prerelease version or because the servers are still indexing a new release. If you are using an official WordPress release, this issue will automatically dismiss once the version is indexed and another scan is run."
9023
  msgstr ""
9024
 
9025
+ #. translators: File path.
9026
+ #: lib/wordfenceHash.php:198
9027
+ msgid "Wordfence file scanner detected a possible infinite loop. Exiting on file: %s"
9028
  msgstr ""
9029
 
9030
+ #: lib/wordfenceHash.php:201
9031
+ msgid "Indexing files for scanning"
 
 
 
 
 
9032
  msgstr ""
9033
 
9034
+ #. translators: Time in seconds.
9035
+ #: lib/wordfenceHash.php:227
9036
+ msgid "Index time: %s"
9037
  msgstr ""
9038
 
9039
+ #: lib/wordfenceHash.php:232
9040
+ msgid "Beginning file hashing"
9041
  msgstr ""
9042
 
9043
+ #: lib/wordfenceHash.php:238
9044
+ msgid "Processing pending issues"
9045
  msgstr ""
9046
 
9047
+ #. translators: 1. Number of files. 2. Data in bytes.
9048
+ #: lib/wordfenceHash.php:241
9049
+ msgid "Analyzed %1$d files containing %2$s of data."
9050
  msgstr ""
9051
 
9052
+ #: lib/wordfenceHash.php:250
9053
+ msgid "Invalid response from Wordfence API during check_possible_malware"
9054
  msgstr ""
9055
 
9056
+ #. translators: File path.
9057
+ #: lib/wordfenceHash.php:263
9058
+ msgid "This file is suspected malware: %s"
9059
  msgstr ""
9060
 
9061
+ #. translators: Malware name/title.
9062
+ #: lib/wordfenceHash.php:264
9063
+ msgid "This file's signature matches a known malware file. The title of the malware is '%s'. Immediately inspect this file using the 'View' option below and consider deleting it from your server."
9064
  msgstr ""
9065
 
9066
+ #. translators: File path.
9067
+ #: lib/wordfenceHash.php:311
9068
+ #: lib/wordfenceHash.php:342
9069
+ msgid "Found .suspected file: %s"
9070
  msgstr ""
9071
 
9072
+ #. translators: File path.
9073
+ #: lib/wordfenceHash.php:323
9074
+ #: lib/wordfenceHash.php:351
9075
+ msgid "Skipping unneeded hash: %s"
9076
  msgstr ""
9077
 
9078
+ #. translators: Number of files.
9079
+ #: lib/wordfenceHash.php:375
9080
+ msgid "%d files indexed"
9081
  msgstr ""
9082
 
9083
+ #. translators: File path.
9084
+ #: lib/wordfenceHash.php:406
9085
+ msgid "Forking during indexing: %s"
9086
  msgstr ""
9087
 
9088
+ #. translators: PHP max execution time.
9089
+ #: lib/wordfenceHash.php:409
9090
+ msgid "Calling fork() from wordfenceHash with maxExecTime: %s"
 
9091
  msgstr ""
9092
 
9093
+ #. translators: File path.
9094
+ #: lib/wordfenceHash.php:447
9095
+ msgid "Skipping file larger than max size: %s"
9096
  msgstr ""
9097
 
9098
+ #. translators: 1. File path. 2. Memory in bytes.
9099
+ #: lib/wordfenceHash.php:452
9100
+ msgid "Scanning: %1$s (Mem:%2$s)"
9101
  msgstr ""
9102
 
9103
+ #. translators: File path.
9104
+ #: lib/wordfenceHash.php:455
9105
+ msgid "Scanning: %s"
9106
  msgstr ""
9107
 
9108
+ #. translators: File path.
9109
+ #: lib/wordfenceHash.php:494
9110
+ msgid "WordPress core file modified: %s"
9111
  msgstr ""
9112
 
9113
+ #. translators: File path.
9114
+ #: lib/wordfenceHash.php:495
9115
+ msgid "This WordPress core file has been modified and differs from the original file distributed with this version of WordPress."
9116
  msgstr ""
9117
 
9118
+ #. translators: File path.
9119
+ #: lib/wordfenceHash.php:530
9120
+ msgid "Modified plugin file: %s"
9121
  msgstr ""
9122
 
9123
+ #. translators: 1. Plugin name. 2. Plugin version. 3. Support URL.
9124
+ #: lib/wordfenceHash.php:533
9125
+ msgid "This file belongs to plugin \"%1$s\" version \"%2$s\" and has been modified from the file that is distributed by WordPress.org for this version. Please use the link to see how the file has changed. If you have modified this file yourself, you can safely ignore this warning. If you see a lot of changed files in a plugin that have been made by the author, then try uninstalling and reinstalling the plugin to force an upgrade. Doing this is a workaround for plugin authors who don't manage their code correctly. <a href=\"%3$s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
9126
  msgstr ""
9127
 
9128
+ #. translators: File path.
9129
+ #: lib/wordfenceHash.php:576
9130
+ msgid "Modified theme file: %s"
9131
  msgstr ""
9132
 
9133
+ #. translators: 1. Plugin name. 2. Plugin version. 3. Support URL.
9134
+ #: lib/wordfenceHash.php:579
9135
+ msgid "This file belongs to theme \"%1$s\" version \"%2$s\" and has been modified from the original distribution. It is common for site owners to modify their theme files, so if you have modified this file yourself you can safely ignore this warning. <a href=\"%3$s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
9136
  msgstr ""
9137
 
9138
+ #. translators: File path.
9139
+ #: lib/wordfenceHash.php:612
9140
  msgid "Old WordPress core file not removed during update: %s"
9141
  msgstr ""
9142
 
9143
+ #. translators: File path.
9144
+ #: lib/wordfenceHash.php:613
9145
  msgid "This file is in a WordPress core location but is from an older version of WordPress and not used with your current version. Hosting or permissions issues can cause these files to get left behind when WordPress is updated and they should be removed if possible."
9146
  msgstr ""
9147
 
9148
+ #. translators: File path.
9149
+ #: lib/wordfenceHash.php:629
9150
+ #: lib/wordfenceHash.php:649
9151
  msgid "Unknown file in WordPress core: %s"
9152
  msgstr ""
9153
 
9154
+ #. translators: File path.
9155
+ #: lib/wordfenceHash.php:630
9156
  msgid "This file is in a WordPress core location but is not distributed with this version of WordPress. This scan often includes files left over from a previous WordPress version, but it may also find files added by another plugin, files added by your host, or malicious files added by an attacker."
9157
  msgstr ""
9158
 
9159
+ #. translators: Support URL.
9160
+ #: lib/wordfenceHash.php:650
9161
  msgid "This file is in a WordPress core location but is not distributed with this version of WordPress. This scan often includes files left over from a previous WordPress version, but it may also find files added by another plugin, files added by your host, or malicious files added by an attacker. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
9162
  msgstr ""
9163
 
9164
+ #. translators: 1. Number of files. 2. Data in bytes.
9165
+ #: lib/wordfenceHash.php:678
9166
+ msgid "Analyzed %1$d files containing %2$s of data so far"
9167
+ msgstr ""
9168
+
9169
+ #. translators: Number of scan results.
9170
+ #: lib/wordfenceHash.php:762
9171
  msgid "(+ %d more)"
9172
  msgstr ""
9173
 
9174
+ #. translators: Number of files.
9175
+ #: lib/wordfenceHash.php:763
9176
  msgid "%d more similar files were found."
9177
  msgstr ""
9178
 
9179
+ #. translators: Number of files.
9180
+ #: lib/wordfenceHash.php:763
9181
  msgid "1 more similar file was found."
9182
  msgstr ""
9183
 
9184
+ #. translators: Number of files.
9185
+ #: lib/wordfenceHash.php:763
9186
  msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
9187
  msgstr ""
9188
 
9190
  msgid "Wordfence could not get the attack signature patterns from the scanning server."
9191
  msgstr ""
9192
 
9193
+ #: lib/wordfenceScanner.php:96
9194
  msgid "Wordfence received malformed attack signature patterns from the scanning server."
9195
  msgstr ""
9196
 
9197
+ #: lib/wordfenceScanner.php:102
9198
  msgid "A regex Wordfence received from its servers is invalid. The pattern is: "
9199
  msgstr ""
9200
 
9201
+ #. translators: PHP ini setting (number).
9202
+ #: lib/wordfenceScanner.php:199
9203
  msgid "Backtrack limit is %d, reducing to 1000000"
9204
  msgstr ""
9205
 
9206
+ #: lib/wordfenceScanner.php:212
9207
  msgid "Detected loop in malware scan, aborting."
9208
  msgstr ""
9209
 
9210
+ #: lib/wordfenceScanner.php:219
9211
  msgid "No files remaining for malware scan."
9212
  msgstr ""
9213
 
9214
+ #. translators: File path.
9215
+ #: lib/wordfenceScanner.php:283
9216
  msgid "Encountered file that is too large: %s - Skipping."
9217
  msgstr ""
9218
 
9219
+ #. translators: 1. File path. 2. File size. 3. Memory in bytes.
9220
+ #: lib/wordfenceScanner.php:294
9221
+ msgid "Scanning contents: %1$s (Size: %2$s Mem: %3$s)"
9222
  msgstr ""
9223
 
9224
+ #. translators: 1. File path. 2. File size.
9225
+ #: lib/wordfenceScanner.php:302
9226
+ msgid "Scanning contents: %1$s (Size: %2$s)"
9227
  msgstr ""
9228
 
9229
+ #: lib/wordfenceScanner.php:335
9230
  msgid "This file was detected because you have enabled \"Scan images, binary, and other files as if they were executable\", which treats non-PHP files as if they were PHP code. This option is more aggressive than the usual scans, and may cause false positives."
9231
  msgstr ""
9232
 
9233
+ #: lib/wordfenceScanner.php:338
9234
  msgid "This file was detected because you have enabled HIGH SENSITIVITY scanning. This option is more aggressive than the usual scans, and may cause false positives."
9235
  msgstr ""
9236
 
9237
+ #: lib/wordfenceScanner.php:349
9238
  msgid "File is an old version of TimThumb which is vulnerable."
9239
  msgstr ""
9240
 
9241
+ #: lib/wordfenceScanner.php:350
9242
  msgid "This file appears to be an old version of the TimThumb script which makes your system vulnerable to attackers. Please upgrade the theme or plugin that uses this or remove it."
9243
  msgstr ""
9244
 
9245
+ #. translators: Malware signature rule ID.
9246
+ #: lib/wordfenceScanner.php:371
9247
  msgid "Resuming malware scan at rule %s."
9248
  msgstr ""
9249
 
9250
+ #: lib/wordfenceScanner.php:405
9251
  msgid "This file appears to be installed or modified by a hacker to perform malicious activity. If you know about this file you can choose to ignore it to exclude it from future scans."
9252
  msgstr ""
9253
 
9254
+ #: lib/wordfenceScanner.php:416
9255
+ msgid "File appears to be malicious or unsafe: %s"
9256
  msgstr ""
9257
 
9258
+ #: lib/wordfenceScanner.php:417
9259
+ msgid "The matched text in this file is: %s"
9260
  msgstr ""
9261
 
9262
+ #. translators: Scan result type.
9263
+ #: lib/wordfenceScanner.php:417
9264
+ msgid "The issue type is: %s"
9265
  msgstr ""
9266
 
9267
+ #. translators: Scan result description.
9268
+ #: lib/wordfenceScanner.php:417
9269
+ msgid "Description: %s"
9270
  msgstr ""
9271
 
9272
+ #. translators: Malware signature rule ID.
9273
+ #: lib/wordfenceScanner.php:435
9274
  msgid "Forking during malware scan (%s) to ensure continuity."
9275
  msgstr ""
9276
 
9277
+ #: lib/wordfenceScanner.php:457
9278
  msgid "This file may contain malicious executable code: "
9279
  msgstr ""
9280
 
9281
+ #. translators: Malware signature matched text.
9282
+ #: lib/wordfenceScanner.php:458
9283
+ msgid "This file is a PHP executable file and contains the word \"eval\" (without quotes) and the word \"%s\" (without quotes). The eval() function along with an encoding function like the one mentioned are commonly used by hackers to hide their code. If you know about this file you can choose to ignore it to exclude it from future scans. This file was detected because you have enabled HIGH SENSITIVITY scanning. This option is more aggressive than the usual scans, and may cause false positives."
9284
  msgstr ""
9285
 
9286
+ #: lib/wordfenceScanner.php:495
9287
  msgid "Asking Wordfence to check URLs against malware list."
9288
  msgstr ""
9289
 
9290
+ #: lib/wordfenceScanner.php:523
9291
+ #: lib/wordfenceScanner.php:565
9292
  msgid "File contains suspected malware URL: "
9293
  msgstr ""
9294
 
9295
+ #. translators: 1. Malware signature matched text. 2. Malicious URL. 3. Malicious URL.
9296
+ #: lib/wordfenceScanner.php:526
9297
+ msgid "This file contains a suspected malware URL listed on Google's list of malware sites. Wordfence decodes %1$s when scanning files so the URL may not be visible if you view this file. The URL is: %2$s - More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%3$s&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>."
9298
  msgstr ""
9299
 
9300
+ #: lib/wordfenceScanner.php:547
9301
  msgid "File contains suspected phishing URL: "
9302
  msgstr ""
9303
 
9304
+ #: lib/wordfenceScanner.php:548
9305
  msgid "This file contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. The URL is: "
9306
  msgstr ""
9307
 
9308
+ #: lib/wordfenceScanner.php:566
9309
  msgid "This file contains a URL that is currently listed on Wordfence's domain blocklist. The URL is: "
9310
  msgstr ""
9311
 
9312
+ #: lib/wordfenceScanner.php:582
9313
  msgid "Finalizing malware scan results"
9314
  msgstr ""
9315
 
9316
+ #. translators: 1. Number of fils. 2. Seconds in millisecond precision.
9317
+ #: lib/wordfenceScanner.php:604
9318
+ msgid "Scanned contents of %1$d additional files at %2$.2f per second"
9319
+ msgstr ""
9320
+
9321
+ #. translators: URL
9322
+ #: lib/wordfenceURLHoover.php:130
9323
+ msgid "Found protocol-relative URL: %s"
9324
+ msgstr ""
9325
+
9326
+ #: lib/wordfenceURLHoover.php:188
9327
+ msgid "Gathering host keys."
9328
+ msgstr ""
9329
+
9330
+ #: lib/wordfenceURLHoover.php:195
9331
+ msgid "Using MySQLi directly."
9332
+ msgstr ""
9333
+
9334
+ #. translators: Number of domains.
9335
+ #: lib/wordfenceURLHoover.php:233
9336
+ msgid "Checking %d host keys against Wordfence scanning servers."
9337
+ msgstr ""
9338
+
9339
+ #: lib/wordfenceURLHoover.php:235
9340
+ msgid "Done host key check."
9341
+ msgstr ""
9342
+
9343
+ #. translators: 1. Number of URLs. 2. Number of files.
9344
+ #: lib/wordfenceURLHoover.php:319
9345
+ msgid "Checking %1$d URLs from %2$d sources."
9346
+ msgstr ""
9347
+
9348
+ #: lib/wordfenceURLHoover.php:324
9349
+ msgid "Done URL check."
9350
  msgstr ""
9351
 
9352
  #: models/block/wfBlock.php:84
9385
  msgid "Invalid IP address."
9386
  msgstr ""
9387
 
9388
+ #. translators: Support URL
9389
  #: models/block/wfBlock.php:180
9390
  msgid "This IP address is in a range of addresses that Wordfence does not block. The IP range may be internal or belong to a service that is always allowed. Allowlisting of external services can be disabled. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
9391
  msgstr ""
9454
  msgid "Repair the Wordfence Firewall configuration."
9455
  msgstr ""
9456
 
 
 
 
 
 
 
 
9457
  #: models/firewall/wfFirewall.php:452
9458
  msgid "Enable Firewall."
9459
  msgstr ""
9487
  msgid "Enable Brute Force Protection."
9488
  msgstr ""
9489
 
 
 
 
 
9490
  #: models/page/wfPage.php:127
9491
  msgid "Support"
9492
  msgstr ""
9533
  msgid "Enable Premium Reputation Checks."
9534
  msgstr ""
9535
 
 
 
 
 
 
 
 
9536
  #: models/scanner/wfScanner.php:820
9537
  msgid "Enable scan option to check if this website is being \"Spamvertised\"."
9538
  msgstr ""
9549
  msgid "User defined scan pattern"
9550
  msgstr ""
9551
 
9552
+ #. translators: 1. Day of week. 2. Hour of day. 3. Localized date.
9553
+ #: models/scanner/wfScanner.php:1204
9554
+ msgid "Scheduled time for day %s hour %s is: %s"
9555
+ msgstr ""
9556
+
9557
+ #. translators: Site URL
9558
  #: views/blocking/block-list.php:11
9559
  msgid "Current blocks<span class=\"wf-hidden-xs\"> for %s</span>"
9560
  msgstr ""
9606
  msgid "Expiration"
9607
  msgstr ""
9608
 
 
 
 
 
 
 
 
 
9609
  #: views/blocking/block-list.php:74
9610
  msgid "Last Attempt"
9611
  msgstr ""
9630
  msgid "Unblocking"
9631
  msgstr ""
9632
 
 
 
 
 
 
 
 
 
9633
  #: views/blocking/blocking-create.php:13
9634
  msgid "Block<span class=\"wf-hidden-xs\"> this IP Address</span>"
9635
  msgstr ""
9646
  msgid "Update<span class=\"wf-hidden-xs\"> Block</span>"
9647
  msgstr ""
9648
 
 
 
 
 
 
 
 
 
9649
  #: views/blocking/blocking-create.php:15
9650
  msgid "Block<span class=\"wf-hidden-xs\"> Visitors Matching this Pattern</span>"
9651
  msgstr ""
9678
  msgid "<span class=\"wf-hidden-xs\">Block access to the rest of the site</span><span class=\"wf-visible-xs\">Rest of site</span>"
9679
  msgstr ""
9680
 
9681
+ #. translators: Support URL
9682
  #: views/blocking/blocking-create.php:149
9683
+ msgid "If you use Google Ads, blocking countries from accessing the entire site is not recommended. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
9684
  msgstr ""
9685
 
9686
  #: views/blocking/blocking-create.php:153
9749
  msgid "Manage global blocking options."
9750
  msgstr ""
9751
 
9752
+ #: views/blocking/blocking-status.php:24
9753
+ msgid "Enable country blocking by upgrading to Premium."
9754
+ msgstr ""
9755
+
9756
  #: views/blocking/country-modal.php:24
9757
  msgid "Select Countries to Block from List"
9758
  msgstr ""
9845
  msgid "The Wordfence license provided has been installed."
9846
  msgstr ""
9847
 
9848
+ #. translators: WordPress admin URL
9849
  #: views/common/license.php:106
9850
  msgid "Return to the <a href=\"%s\">Wordfence Admin Page</a>"
9851
  msgstr ""
9868
  msgid "Your computer's time: "
9869
  msgstr ""
9870
 
9871
+ #: views/common/page-title.php:18
9872
+ msgid "Go:"
9873
+ msgstr ""
9874
+
9875
+ #: views/common/page-title.php:20
9876
+ msgid "Go to"
9877
  msgstr ""
9878
 
9879
  #: views/common/status-tooltip.php:19
9913
  msgid "Please enter an email address to unsubscribe from alerts. If this email address exists on the alert email list, it will receive a confirmation link to unsubscribe."
9914
  msgstr ""
9915
 
9916
+ #. translators: Email address.
9917
  #: views/common/unsubscribe.php:120
9918
  msgid "Please confirm the unsubscribe request for %s."
9919
  msgstr ""
9946
  msgid "Use the Cloudflare \"CF-Connecting-IP\" HTTP header to get a visitor IP. Only use if you're using Cloudflare."
9947
  msgstr ""
9948
 
9949
+ #: views/dashboard/option-howgetips.php:32
9950
+ msgid "Detected IP(s):"
9951
+ msgstr ""
9952
+
9953
+ #: views/dashboard/option-howgetips.php:34
9954
+ msgid "Edit trusted proxies"
9955
+ msgstr ""
9956
+
9957
  #: views/dashboard/option-howgetips.php:51
9958
  msgid "These IPs (or CIDR ranges) will be ignored when determining the requesting IP via the X-Forwarded-For HTTP header. Enter one IP or CIDR range per line."
9959
  msgstr ""
9969
  #: views/dashboard/options-group-alert.php:73
9970
  #: views/scanner/issue-base.php:32
9971
  #: views/scanner/issue-base.php:41
9972
+ #: views/scanner/issue-base.php:104
9973
  msgid "Critical"
9974
  msgstr ""
9975
 
9976
  #: views/dashboard/options-group-alert.php:74
9977
  #: views/scanner/issue-base.php:33
9978
  #: views/scanner/issue-base.php:42
9979
+ #: views/scanner/issue-base.php:107
9980
  msgid "High"
9981
  msgstr ""
9982
 
9983
  #: views/dashboard/options-group-alert.php:75
9984
  #: views/scanner/issue-base.php:34
9985
  #: views/scanner/issue-base.php:43
9986
+ #: views/scanner/issue-base.php:110
9987
  msgid "Medium"
9988
  msgstr ""
9989
 
9990
  #: views/dashboard/options-group-alert.php:76
9991
  #: views/scanner/issue-base.php:35
9992
  #: views/scanner/issue-base.php:44
9993
+ #: views/scanner/issue-base.php:113
9994
  msgid "Low"
9995
  msgstr ""
9996
 
10183
  msgid "Name"
10184
  msgstr ""
10185
 
 
 
 
 
 
 
 
 
 
 
10186
  #: views/diagnostics/text.php:381
10187
  msgid "Run Time"
10188
  msgstr ""
10191
  msgid "Job"
10192
  msgstr ""
10193
 
10194
+ #. translators: 1. WordPress table prefix. 2. Wordfence tables.
10195
+ #: views/diagnostics/text.php:455
10196
+ msgid "Tables missing (prefix %1$s, %2$s): %s"
10197
+ msgstr ""
10198
+
10199
  #: views/gdpr/banner.php:8
10200
  msgid "Wordfence's terms of use and privacy policy have changed"
10201
  msgstr ""
10234
  msgid "Wordfence - Securing your WordPress Website"
10235
  msgstr ""
10236
 
10237
+ #. translators: Wordfence version.
10238
  #: views/onboarding/fresh-install.php:10
10239
  msgid "You have successfully installed Wordfence %s"
10240
  msgstr ""
10241
 
10242
+ #. translators: Wordfence version.
10243
  #: views/onboarding/fresh-install.php:11
10244
  #: views/onboarding/modal-final-attempt.php:18
10245
  #: views/onboarding/plugin-header.php:32
10270
  msgid "By checking this box, I agree to the Wordfence <a href=\"https://www.wordfence.com/terms-of-use/\" target=\"_blank\" rel=\"noopener noreferrer\">terms</a> and <a href=\"https://www.wordfence.com/privacy-policy/\" target=\"_blank\" rel=\"noopener noreferrer\">privacy policy</a>"
10271
  msgstr ""
10272
 
10273
+ #. translators: Support URL.
10274
  #: views/onboarding/fresh-install.php:28
10275
  #: views/onboarding/modal-final-attempt.php:57
10276
  #: views/onboarding/plugin-header.php:59
10389
  msgid "Collapse All"
10390
  msgstr ""
10391
 
10392
+ #. translators: 1. Start date. 2. End date.
10393
+ #: views/reports/activity-report-email-inline.php:13
10394
+ msgid "Wordfence activity from <br><strong>%1$s</strong> to <strong>%2$s</strong>"
10395
  msgstr ""
10396
 
10397
+ #. translators: 1. Site URL. 2. Start date. 3. End date.
10398
+ #: views/reports/activity-report-email-inline.php:130
10399
+ msgid "This email was sent from your website <a href=\"%1$s\">%1$s</a> and is a summary of security related activity that Wordfence monitors for the period %2$s to %3$s."
10400
  msgstr ""
10401
 
10402
+ #: views/reports/activity-report-email-inline.php:134
10403
  msgid "NOTE: You are using the free version of Wordfence and are missing out on features like cellphone sign-in, country blocking and detecting if your site IP is sending spam. <a href=\"http://www.wordfence.com/zz6/\">Click here to upgrade to Wordfence Premium now</a>."
10404
  msgstr ""
10405
 
 
 
 
 
10406
  #: views/reports/activity-report-email-inline.php:138
10407
+ msgid "Top 10 IPs Blocked"
 
 
 
 
10408
  msgstr ""
10409
 
10410
+ #: views/reports/activity-report-email-inline.php:174
10411
+ #: views/reports/activity-report-email-inline.php:228
10412
  #: views/reports/activity-report.php:34
10413
  #: views/reports/activity-report.php:78
10414
  msgid "(Unknown)"
10415
  msgstr ""
10416
 
10417
+ #: views/reports/activity-report-email-inline.php:183
10418
+ #: views/reports/activity-report-email-inline.php:238
10419
  msgid "No data currently."
10420
  msgstr ""
10421
 
10422
+ #: views/reports/activity-report-email-inline.php:191
10423
  #: views/reports/activity-report.php:51
10424
  msgid "Update Blocked IPs"
10425
  msgstr ""
10426
 
10427
+ #: views/reports/activity-report-email-inline.php:196
10428
  msgid "Top 10 Countries Blocked"
10429
  msgstr ""
10430
 
10431
+ #: views/reports/activity-report-email-inline.php:202
10432
  #: views/reports/activity-report.php:62
10433
  msgid "Total IPs Blocked"
10434
  msgstr ""
10435
 
10436
+ #: views/reports/activity-report-email-inline.php:246
10437
  #: views/reports/activity-report.php:96
10438
  msgid "Update Blocked Countries"
10439
  msgstr ""
10440
 
10441
+ #: views/reports/activity-report-email-inline.php:251
10442
  msgid "Top 10 Failed Logins"
10443
  msgstr ""
10444
 
10445
+ #: views/reports/activity-report-email-inline.php:258
 
 
 
 
 
 
 
 
 
 
10446
  #: views/reports/activity-report.php:108
10447
  msgid "Existing User"
10448
  msgstr ""
10449
 
10450
+ #: views/reports/activity-report-email-inline.php:276
10451
  #: views/reports/activity-report.php:123
10452
  msgid "No failed logins yet."
10453
  msgstr ""
10454
 
10455
+ #: views/reports/activity-report-email-inline.php:284
10456
  #: views/reports/activity-report.php:131
10457
  msgid "Update Login Security Options"
10458
  msgstr ""
10459
 
10460
+ #: views/reports/activity-report-email-inline.php:289
10461
  msgid "Recently Blocked Attacks"
10462
  msgstr ""
10463
 
10464
+ #: views/reports/activity-report-email-inline.php:295
10465
  msgid "IP / Action"
10466
  msgstr ""
10467
 
10468
+ #: views/reports/activity-report-email-inline.php:316
10469
  msgid "No blocked attacks yet."
10470
  msgstr ""
10471
 
10472
+ #: views/reports/activity-report-email-inline.php:326
10473
  msgid "and %d additional attacks"
10474
  msgstr ""
10475
 
10476
+ #: views/reports/activity-report-email-inline.php:330
10477
  msgid "View Recent Traffic"
10478
  msgstr ""
10479
 
10480
+ #: views/reports/activity-report-email-inline.php:335
10481
  msgid "Recently Modified Files"
10482
  msgstr ""
10483
 
10484
+ #: views/reports/activity-report-email-inline.php:340
10485
  msgid "Modified"
10486
  msgstr ""
10487
 
10488
+ #: views/reports/activity-report-email-inline.php:361
10489
  msgid "This list may include WordPress core/plugin/theme updates, error logs, cache files, and other normal changes."
10490
  msgstr ""
10491
 
10492
+ #: views/reports/activity-report-email-inline.php:365
10493
  #: views/reports/activity-report.php:164
10494
  msgid "Updates Needed"
10495
  msgstr ""
10496
 
10497
+ #: views/reports/activity-report-email-inline.php:373
10498
  #: views/reports/activity-report.php:172
10499
  msgid "Core"
10500
  msgstr ""
10501
 
10502
+ #. translators: WordPress version.
10503
+ #: views/reports/activity-report-email-inline.php:375
10504
  #: views/reports/activity-report.php:174
10505
  msgid "A new version of WordPress (v%s) is available."
10506
  msgstr ""
10507
 
10508
+ #: views/reports/activity-report-email-inline.php:379
10509
  #: views/reports/activity-report.php:178
10510
  msgid "Plugins"
10511
  msgstr ""
10512
 
10513
+ #. translators: Plugin name.
10514
+ #. translators: Plugin version.
10515
+ #: views/reports/activity-report-email-inline.php:386
10516
  #: views/reports/activity-report.php:185
10517
  msgid "A new version of the plugin \"%s\" is available."
10518
  msgstr ""
10519
 
10520
+ #. translators: Plugin name.
10521
+ #. translators: Theme name.
10522
+ #: views/reports/activity-report-email-inline.php:386
10523
+ #: views/reports/activity-report-email-inline.php:399
10524
  msgid "<strong>This update includes security-related fixes.</strong>"
10525
  msgstr ""
10526
 
10527
+ #. translators: Theme name.
10528
+ #. translators: Theme version.
10529
+ #: views/reports/activity-report-email-inline.php:399
10530
  #: views/reports/activity-report.php:198
10531
  msgid "A new version of the theme \"%s\" is available."
10532
  msgstr ""
10533
 
10534
+ #: views/reports/activity-report-email-inline.php:407
10535
  #: views/reports/activity-report.php:205
10536
  msgid "Update Now"
10537
  msgstr ""
10538
 
10539
+ #: views/reports/activity-report-email-inline.php:411
10540
  #: views/reports/activity-report.php:207
10541
  msgid "No updates are available at this time."
10542
  msgstr ""
10543
 
10544
+ #. translators: 1. Site URL. 2. WordPress admin panel URL. 3. WordPress admin panel URL.
10545
+ #: views/reports/activity-report-email-inline.php:418
10546
+ msgid "If you would like to sign-in to <a href=\"%1$s\">%1$s</a> please <a href=\"%2$s\">click here</a> now. You can change the frequency of this email or turn it on and off by visiting your <a href=\"%3$s\">Wordfence options page</a>."
10547
  msgstr ""
10548
 
10549
+ #. translators: Number of IPs.
10550
  #: views/reports/activity-report.php:9
10551
  msgid "Top %d IPs Blocked"
10552
  msgstr ""
10555
  msgid "No IPs blocked yet."
10556
  msgstr ""
10557
 
10558
+ #. translators: Number of countries.
10559
  #: views/reports/activity-report.php:56
10560
  msgid "Top %d Countries Blocked"
10561
  msgstr ""
10564
  msgid "No requests blocked yet."
10565
  msgstr ""
10566
 
10567
+ #. translators: Number of failed logins.
10568
  #: views/reports/activity-report.php:101
10569
  msgid "Top %d Failed Logins"
10570
  msgstr ""
10571
 
10572
+ #. translators: Seconds with millisecond precision.
10573
  #: views/reports/activity-report.php:210
10574
  msgid "Generated in %.4f seconds"
10575
  msgstr ""
10576
 
 
 
 
 
 
10577
  #: views/scanner/issue-base.php:31
10578
  msgid "Issue Found "
10579
  msgstr ""
10587
  msgstr ""
10588
 
10589
  #: views/scanner/issue-base.php:52
10590
+ #: views/scanner/issue-base.php:98
10591
  msgid "Ignored"
10592
  msgstr ""
10593
 
10599
  msgid "ago"
10600
  msgstr ""
10601
 
10602
+ #. translators: Localized date.
10603
+ #: views/scanner/issue-base.php:100
10604
  msgid "Issue Found: %s"
10605
  msgstr ""
10606
 
10607
+ #. translators: Severity level.
10608
+ #: views/scanner/issue-base.php:120
10609
  msgid "Severity: %s"
10610
  msgstr ""
10611
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10612
  #: views/scanner/issue-checkGSB.php:10
10613
  #: views/scanner/issue-checkHowGetIPs.php:10
10614
  #: views/scanner/issue-checkSpamIP.php:10
11067
  msgid "Plugin URL"
11068
  msgstr ""
11069
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11070
  #: views/scanner/issue-wfPluginAbandoned.php:19
11071
  #: views/scanner/issue-wfPluginAbandoned.php:36
11072
  #: views/scanner/issue-wfPluginUpgrade.php:36
11171
  msgid "Directory Listing Enabled"
11172
  msgstr ""
11173
 
11174
+ #: views/scanner/option-scan-signatures.php:27
11175
+ msgid "Add Additional Signatures"
11176
  msgstr ""
11177
 
11178
  #: views/scanner/options-group-advanced.php:23
11213
  msgid "0 or empty means unlimited issues will be sent"
11214
  msgstr ""
11215
 
11216
+ #. translators: Time until.
11217
  #: views/scanner/options-group-performance.php:34
11218
  msgid "0 or empty means the default of %s will be used"
11219
  msgstr ""
11220
 
11221
+ #. translators: Time until.
11222
  #: views/scanner/options-group-performance.php:35
11223
  msgid "Memory size in megabytes"
11224
  msgstr ""
11227
  msgid "Maximum execution time for each scan stage "
11228
  msgstr ""
11229
 
11230
+ #. translators: PHP max execution time (number).
11231
  #: views/scanner/options-group-performance.php:36
11232
  msgid "0 for default. Must be %d or greater and 10-20 or higher is recommended for most servers"
11233
  msgstr ""
11500
  msgstr ""
11501
 
11502
  #: views/scanner/scanner-status.php:54
11503
+ msgid "As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by additional firewall rules and malware signatures as well as the Wordfence real-time IP blocklist. Upgrade to Premium today to improve your protection."
11504
  msgstr ""
11505
 
11506
  #: views/scanner/scanner-status.php:60
11524
  msgstr ""
11525
 
11526
  #: views/scanner/site-cleaning-bottom.php:12
11527
+ msgid "Need help from the WordPress security experts?"
11528
  msgstr ""
11529
 
11530
  #: views/scanner/site-cleaning-bottom.php:13
11531
+ msgid "Wordfence security analysts can help you tighten site security or remove an active infection for good. All security services include a detailed report and a <strong class=\"wf-blue\">Wordfence Premium license, with a 1-year clean site guarantee.</strong>"
11532
  msgstr ""
11533
 
11534
  #: views/scanner/site-cleaning-bottom.php:15
11559
  msgid "Two-Factor Authentication Options"
11560
  msgstr ""
11561
 
11562
+ #. translators: Support URL.
11563
  #: views/tools/options-group-2fa.php:51
11564
  msgid "<strong>Require Cellphone Sign-in for all Administrators<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wfhelp wf-inline-help\"></a></strong><br><em>Note:</em> This setting requires at least one administrator to have Cellphone Sign-in enabled. On multisite, this option applies only to super admins."
11565
  msgstr ""
11566
 
11567
+ #. translators: Support URL.
11568
  #: views/tools/options-group-2fa.php:63
11569
  msgid "<strong>Enable Separate Prompt for Two-Factor Code<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wfhelp wf-inline-help\"></a></strong><br><em>Note:</em> This setting changes the behavior for obtaining the two-factor authentication code from using the password field to showing a separate prompt. If your theme overrides the default login page, you may not be able to use this option."
11570
  msgstr ""
11571
 
11572
+ #. translators: Support URL.
11573
  #: views/tools/options-group-2fa.php:64
11574
  msgid "<br><strong>This setting will be ignored because the PHP configuration option <code>output_buffering</code> is off.</strong>"
11575
  msgstr ""
11634
  msgid "Done"
11635
  msgstr ""
11636
 
11637
+ #. translators: 1. PHP version. 2. Wordfence version.
11638
+ #: views/unsupported-php/admin-message.php:11
11639
+ msgid "You are running PHP version %1$s that is not supported by Wordfence %2$s. Wordfence features will not be available until PHP has been upgraded. We recommend using PHP version 7.4, but Wordfence will run on PHP version 5.3 at a minimum."
11640
+ msgstr ""
11641
+
11642
  #: views/waf/firewall-status.php:16
11643
  msgid "Wordfence Firewall &amp; Premium Enabled"
11644
  msgstr ""
11663
  msgid "Learning Mode Enabled"
11664
  msgstr ""
11665
 
11666
+ #. translators: Localized date.
11667
  #: views/waf/firewall-status.php:56
11668
  msgid "Learning Mode Until %s"
11669
  msgstr ""
11670
 
11671
+ #. translators: Localized date.
11672
  #: views/waf/firewall-status.php:57
11673
  msgid "<i class=\"wf-fa wf-fa-lightbulb-o wf-tip\" aria-hidden=\"true\"></i> When you first install the Wordfence Web Application Firewall, it will be in learning mode. This allows Wordfence to learn about your site so that we can understand how to protect it and how to allow normal visitors through the firewall. We recommend you let Wordfence learn for a week before you enable the firewall."
11674
  msgstr ""
11730
  msgstr ""
11731
 
11732
  #: views/waf/option-whitelist.php:53
11733
+ msgid "An allowlist entry for this URL and parameter already exists."
 
 
 
 
 
 
 
 
11734
  msgstr ""
11735
 
11736
  #: views/waf/option-whitelist.php:102
11749
  msgid "Source"
11750
  msgstr ""
11751
 
 
 
 
 
 
 
11752
  #: views/waf/option-whitelist.php:112
11753
  msgid "Filter Value"
11754
  msgstr ""
11762
  msgstr ""
11763
 
11764
  #: views/waf/options-group-advanced-firewall.php:54
11765
+ msgid "Allowlisted IPs must be separated by commas or placed on separate lines. You can specify ranges using the following formats: 127.0.0.1/24, 127.0.0.[1-100], or 127.0.0.1-127.0.1.100<br/>Wordfence automatically allowlists <a href=\"http://en.wikipedia.org/wiki/Private_network\" target=\"_blank\" rel=\"noopener noreferrer\">private networks</a> because these are not routable on the public Internet."
11766
  msgstr ""
11767
 
11768
  #: views/waf/options-group-advanced-firewall.php:101
11793
  msgid "Basic Firewall Options"
11794
  msgstr ""
11795
 
11796
+ #. translators: WordPress admin URL.
11797
  #: views/waf/options-group-basic-firewall.php:36
11798
  #: views/waf/options-group-basic-firewall.php:469
11799
  #: views/waf/options-group-whitelisted.php:35
11812
  msgid "Learning Mode:"
11813
  msgstr ""
11814
 
11815
+ #. translators: Support URL.
11816
  #: views/waf/options-group-basic-firewall.php:41
11817
  msgid "When you first install the Wordfence Web Application Firewall, it will be in learning mode. This allows Wordfence to learn about your site so that we can understand how to protect it and how to allow normal visitors through the firewall. We recommend you let Wordfence learn for a week before you enable the firewall. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
11818
  msgstr ""
11819
 
11820
+ #. translators: Support URL.
11821
  #: views/waf/options-group-basic-firewall.php:42
11822
  msgid "Disabled:"
11823
  msgstr ""
11824
 
11825
+ #. translators: Support URL.
11826
  #: views/waf/options-group-basic-firewall.php:42
11827
  msgid "In this mode, the Wordfence Web Application Firewall is functionally turned off and does not run any of its rules or analyze the request in any way."
11828
  msgstr ""
11847
  msgid "All PHP requests will be processed by the firewall prior to running."
11848
  msgstr ""
11849
 
11850
+ #. translators: Support URL.
11851
  #: views/waf/options-group-basic-firewall.php:168
11852
  msgid "If you're moving to a new host or a new installation location, you may need to temporarily disable extended protection to avoid any file not found errors. Use this action to remove the configuration changes that enable extended protection mode or you can <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">remove them manually</a>."
11853
  msgstr ""
11854
 
11855
+ #. translators: Support URL.
11856
  #: views/waf/options-group-basic-firewall.php:169
11857
  msgid "Remove Extended Protection"
11858
  msgstr ""
11878
  msgid "The plugin will load as a regular plugin after WordPress has been loaded, and while it can block many malicious requests, some vulnerable plugins or WordPress itself may run vulnerable code before all plugins are loaded."
11879
  msgstr ""
11880
 
11881
+ #: views/waf/options-group-basic-firewall.php:292
11882
+ msgid "Error During Setup"
11883
+ msgstr ""
11884
+
11885
  #: views/waf/options-group-basic-firewall.php:466
11886
  msgid "Premium Feature:"
11887
  msgstr ""
11927
  msgid "Prevent discovery of usernames through '/?author=N' scans, the oEmbed API, the WordPress REST API, and WordPress XML Sitemaps"
11928
  msgstr ""
11929
 
11930
+ #: views/waf/options-group-brute-force.php:250
11931
  msgid "HTML tags will be stripped prior to output and line breaks will be converted into the appropriate tags."
11932
  msgstr ""
11933
 
11947
  msgid "Treat Google like any other Crawler"
11948
  msgstr ""
11949
 
11950
+ #. translators: Number of HTTP requests.
11951
  #: views/waf/options-group-rate-limiting.php:68
11952
  #: views/waf/options-group-rate-limiting.php:69
11953
  #: views/waf/options-group-rate-limiting.php:70
12015
  msgid "No allowlisted URLs currently set."
12016
  msgstr ""
12017
 
12018
+ #. translators: Support URL.
12019
  #: views/waf/status-tooltip-learning-mode.php:6
12020
  msgid "The Web Application Firewall is currently in Learning Mode. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Learn More</a>"
12021
  msgstr ""
12024
  msgid "The required file has been created. You'll need to insert the following code into your <code>php.ini</code> to finish installation:"
12025
  msgstr ""
12026
 
12027
+ #. translators: Support URL.
12028
  #: views/waf/waf-install-manual.php:12
12029
  msgid "You can find more details on alternative setup steps, including installation on SiteGround or for multiple sites sharing a single php.ini, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">in our documentation</a>."
12030
  msgstr ""
12031
 
12032
+ #: views/waf/waf-install.php:9
12033
+ msgid "Optimize Wordfence Firewall"
12034
  msgstr ""
12035
 
12036
+ #: views/waf/waf-install.php:13
12037
+ msgid "If you cannot complete the setup process, "
 
12038
  msgstr ""
12039
 
12040
+ #: views/waf/waf-install.php:13
12041
+ msgid "click here for help"
12042
  msgstr ""
12043
 
12044
  #: views/waf/waf-install.php:22
12050
  msgstr ""
12051
 
12052
  #: views/waf/waf-install.php:26
12053
+ msgid "If you don't recognize this file, please <a href=\"https://wordpress.org/support/plugin/wordfence\" target=\"_blank\" rel=\"noopener noreferrer\">contact us on the WordPress support forums</a> before proceeding."
 
 
12054
  msgstr ""
12055
 
12056
+ #: views/waf/waf-install.php:27
12057
  msgid "You can proceed with the installation and we will include this from within our <code>wordfence-waf.php</code> file which should maintain compatibility with your site, or you can opt to override the existing PHP setting."
12058
  msgstr ""
12059
 
12060
+ #: views/waf/waf-install.php:28
12061
  msgid "Include"
12062
  msgstr ""
12063
 
12064
+ #: views/waf/waf-install.php:28
12065
  msgid "Override"
12066
  msgstr ""
12067
 
12068
+ #: views/waf/waf-install.php:30
12069
  msgid "NOTE:"
12070
  msgstr ""
12071
 
12072
+ #: views/waf/waf-install.php:30
12073
  msgid "If you have separate WordPress installations with Wordfence installed within a subdirectory of this site, it is recommended that you perform the Firewall installation procedure on those sites before this one."
12074
  msgstr ""
12075
 
12076
+ #: views/waf/waf-install.php:34
12077
  #: views/waf/waf-uninstall.php:40
12078
  msgid "Apache + mod_php"
12079
  msgstr ""
12080
 
12081
+ #: views/waf/waf-install.php:35
12082
  #: views/waf/waf-uninstall.php:41
12083
  msgid "Apache + suPHP"
12084
  msgstr ""
12085
 
12086
+ #: views/waf/waf-install.php:36
12087
  #: views/waf/waf-uninstall.php:42
12088
  msgid "Apache + CGI/FastCGI"
12089
  msgstr ""
12090
 
12091
+ #: views/waf/waf-install.php:37
12092
  #: views/waf/waf-uninstall.php:43
12093
  msgid "LiteSpeed/lsapi"
12094
  msgstr ""
12095
 
12096
+ #: views/waf/waf-install.php:38
12097
  #: views/waf/waf-uninstall.php:44
12098
  msgid "NGINX"
12099
  msgstr ""
12100
 
12101
+ #: views/waf/waf-install.php:39
12102
  #: views/waf/waf-uninstall.php:45
12103
  msgid "Windows (IIS)"
12104
  msgstr ""
12105
 
12106
+ #: views/waf/waf-install.php:40
12107
  msgid "Manual Configuration"
12108
  msgstr ""
12109
 
12110
+ #: views/waf/waf-install.php:56
12111
+ #: views/waf/waf-uninstall.php:61
12112
  msgid "If you know your web server's configuration, please select it from the list below."
12113
  msgstr ""
12114
 
12115
+ #: views/waf/waf-install.php:58
12116
  msgid "We've preselected your server configuration based on our tests, but if you know your web server's configuration, please select it now. You can also choose \"Manual Configuration\" for alternate installation details."
12117
  msgstr ""
12118
 
12119
+ #. translators: 1. PHP ini setting. 2. Support URL.
12120
+ #: views/waf/waf-install.php:63
12121
+ msgid "Part of the Firewall configuration procedure for NGINX depends on creating a <code>%1$s</code> file in the root of your WordPress installation. This file can contain sensitive information and public access to it should be restricted. We have <a href=\"%2$s\" target=\"_blank\" rel=\"noreferrer noopener\">instructions on our documentation site</a> on what directives to put in your nginx.conf to fix this."
12122
  msgstr ""
12123
 
12124
+ #: views/waf/waf-install.php:65
 
 
 
 
12125
  msgid "If you are using a web server not listed in the dropdown or if file permissions prevent the installer from completing successfully, you will need to perform the change manually. Click Continue below to create the required file and view manual installation instructions."
12126
  msgstr ""
12127
 
12128
+ #: views/waf/waf-install.php:86
12129
+ #: views/waf/waf-uninstall.php:87
12130
  msgid "Please download a backup of the following files before we make the necessary changes:"
12131
  msgstr ""
12132
 
12133
+ #. translators: File path.
12134
+ #: views/waf/waf-install.php:96
12135
+ #: views/waf/waf-uninstall.php:97
12136
  msgid "Download %s"
12137
  msgstr ""
12138
 
12139
+ #: views/waf/waf-install.php:105
12140
  msgid "Once you have downloaded the files, click Continue to complete the setup."
12141
  msgstr ""
12142
 
 
 
 
 
 
 
 
 
12143
  #: views/waf/waf-uninstall.php:9
12144
  msgid "Uninstall Wordfence Firewall"
12145
  msgstr ""
12148
  msgid "Extended Protection Mode of the Wordfence Web Application Firewall uses the PHP ini setting called <code>auto_prepend_file</code> in order to ensure it runs before any potentially vulnerable code runs. This PHP setting currently refers to the Wordfence file at:"
12149
  msgstr ""
12150
 
12151
+ #. translators: Support URL.
12152
  #: views/waf/waf-uninstall.php:34
12153
  msgid "Automatic uninstallation cannot be completed, but you may still be able to <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">manually uninstall extended protection</a>."
12154
  msgstr ""
12157
  msgid "Before this file can be deleted, the configuration for the <code>auto_prepend_file</code> setting needs to be removed."
12158
  msgstr ""
12159
 
12160
+ #: views/waf/waf-uninstall.php:63
12161
  msgid "We've preselected your server configuration based on our tests, but if you know your web server's configuration, please select it now."
12162
  msgstr ""
12163
 
12164
+ #: views/waf/waf-uninstall.php:107
12165
  msgid "Once you have downloaded the files, click Continue to complete uninstallation."
12166
  msgstr ""
lib/GeoLite2-Country.mmdb CHANGED
Binary file
lib/IPTraf.php CHANGED
@@ -4,8 +4,13 @@
4
  <head>
5
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
  <link rel='stylesheet' id='wordfence-main-style-css' href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/iptraf.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>' type='text/css' media='all' />
 
7
  <body>
8
- <h1>Wordfence: All recent hits for IP address <?php echo wp_kses($IP, array()); if($reverseLookup){ echo '[' . wp_kses($reverseLookup, array()) . ']'; } ?></h1>
9
- <div class="footer">&copy;&nbsp;2011 to <?php echo date('Y'); ?> Wordfence &mdash; Visit <a href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.</div>
 
 
 
 
10
  </body>
11
- </html>
4
  <head>
5
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
  <link rel='stylesheet' id='wordfence-main-style-css' href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/iptraf.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>' type='text/css' media='all' />
7
+ </head>
8
  <body>
9
+ <h1><?php echo esc_html(sprintf(
10
+ /* translators: IP address. */
11
+ __('Wordfence: All recent hits for IP address %s', 'wordfence'), wp_kses($IP, array()) . (($reverseLookup) ? '[' . wp_kses($reverseLookup, array()) . ']' : ''))) ?></h1>
12
+ <div class="footer"><?php echo wp_kses(sprintf(
13
+ /* translators: 1. year (2011). 2. year (2020) */
14
+ __('&copy;&nbsp;%d to %d Wordfence &mdash; Visit <a href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.', 'wordfence'), date_i18n('Y', WORDFENCE_EPOCH), date_i18n('Y')), array('a'=>array('href'=>array()))) ?></div>
15
  </body>
16
+ </html>
lib/IPTrafList.php CHANGED
@@ -10,56 +10,51 @@ if (!wfUtils::isAdmin()) {
10
  <table border="0" cellpadding="2" cellspacing="0" class="wf-recent-traffic-table">
11
  <?php foreach ($results as $key => $v) { ?>
12
  <tr>
13
- <th>Time:</th>
14
- <td><?php echo $v['timeAgo'] ?> ago -- <?php echo date(DATE_RFC822, $v['ctime']); ?> -- <?php echo $v['ctime']; ?> in Unixtime</td>
 
 
15
  </tr>
16
  <?php if ($v['timeSinceLastHit']) {
17
- echo '<th>Secs since last hit:</th><td>' . $v['timeSinceLastHit'] . '</td></tr>';
18
  } ?>
19
- <?php if (wfUtils::hasXSS($v['URL'])) { ?>
20
- <tr>
21
- <th>URL:</th>
22
- <td><span style="color: #F00;">Possible XSS code filtered out for your security</span></td>
23
- </tr>
24
- <?php } else { ?>
25
- <tr>
26
- <th>URL:</th>
27
- <td>
28
- <a href="<?php echo wp_kses($v['URL'], array()); ?>" target="_blank" rel="noopener noreferrer"><?php echo $v['URL']; ?></a>
29
- </td>
30
- </tr>
31
- <?php } ?>
32
  <tr>
33
  <th>Type:</th>
34
  <td><?php
35
- if ($v['statusCode'] == '404') {
36
- echo '<span style="color: #F00;">Page not found</span>';
37
  }
38
  else if ($v['type'] == 'hit') {
39
- echo 'Normal request';
40
  } ?></td>
41
  </tr>
42
  <?php if ($v['referer']) { ?>
43
  <tr>
44
- <th>Referrer:</th>
45
  <td>
46
- <a href="<?php echo $v['referer']; ?>" target="_blank" rel="noopener noreferrer"><?php echo $v['referer']; ?></a>
47
  </td></tr><?php } ?>
48
  <tr>
49
- <th>Full Browser ID:</th>
50
- <td><?php echo esc_html($v['UA'], array()); ?></td>
51
  </tr>
52
  <?php if ($v['user']) { ?>
53
  <tr>
54
- <th>User:</th>
55
  <td>
56
- <a href="<?php echo $v['user']['editLink']; ?>" target="_blank" rel="noopener noreferrer"><span data-userid="<?php echo esc_attr($v['user']['ID']); ?>" class="wfAvatar"></span><?php echo $v['user']['display_name']; ?></a>
57
  </td>
58
  </tr>
59
  <?php } ?>
60
  <?php if ($v['loc']) { ?>
61
  <tr>
62
- <th>Location:</th>
63
  <td>
64
  <span class="wf-flag <?php echo esc_attr('wf-flag-' . strtolower($v['loc']['countryCode'])); ?>" title="<?php echo esc_attr($v['loc']['countryName']); ?>"></span>
65
  <?php if ($v['loc']['city']) {
@@ -78,4 +73,4 @@ if (!wfUtils::isAdmin()) {
78
  </tr>
79
  <?php } ?>
80
 
81
- </table>
10
  <table border="0" cellpadding="2" cellspacing="0" class="wf-recent-traffic-table">
11
  <?php foreach ($results as $key => $v) { ?>
12
  <tr>
13
+ <th><?php esc_html_e('Time:', 'wordfence') ?></th>
14
+ <td><?php esc_html(sprintf(
15
+ /* translators: 1. Time ago, example: 2 hours, 40 seconds. 2. Localized date. 3. Unix timestamp. */
16
+ __('%1$s ago -- %2$s -- %3$s in Unixtime', 'wordfence'), $v['timeAgo'], date(DATE_RFC822, $v['ctime']), $v['ctime'])) ?></td>
17
  </tr>
18
  <?php if ($v['timeSinceLastHit']) {
19
+ echo '<th>' . esc_html__('Seconds since last hit:', 'wordfence') . '</th><td>' . $v['timeSinceLastHit'] . '</td></tr>';
20
  } ?>
21
+ <tr>
22
+ <th><?php esc_html_e('URL:', 'wordfence') ?></th>
23
+ <td>
24
+ <a href="<?php echo esc_url($v['URL']) ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html($v['URL']); ?></a>
25
+ </td>
26
+ </tr>
 
 
 
 
 
 
 
27
  <tr>
28
  <th>Type:</th>
29
  <td><?php
30
+ if ($v['statusCode'] == '404') {
31
+ echo '<span style="color: #F00;">' . esc_html('Page not found', 'wordfence') . '</span>';
32
  }
33
  else if ($v['type'] == 'hit') {
34
+ esc_html_e('Normal request', 'wordfence');
35
  } ?></td>
36
  </tr>
37
  <?php if ($v['referer']) { ?>
38
  <tr>
39
+ <th><?php esc_html_e('Referrer:', 'wordfence') ?></th>
40
  <td>
41
+ <a href="<?php echo esc_url($v['referer']); ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html($v['referer']); ?></a>
42
  </td></tr><?php } ?>
43
  <tr>
44
+ <th><?php esc_html_e('Full Browser ID:', 'wordfence') ?></th>
45
+ <td><?php echo esc_html($v['UA']); ?></td>
46
  </tr>
47
  <?php if ($v['user']) { ?>
48
  <tr>
49
+ <th><?php esc_html_e('User:', 'wordfence') ?></th>
50
  <td>
51
+ <a href="<?php echo esc_url($v['user']['editLink']); ?>" target="_blank" rel="noopener noreferrer"><span data-userid="<?php echo esc_attr($v['user']['ID']); ?>" class="wfAvatar"></span><?php echo esc_html($v['user']['display_name']); ?></a>
52
  </td>
53
  </tr>
54
  <?php } ?>
55
  <?php if ($v['loc']) { ?>
56
  <tr>
57
+ <th><?php esc_html_e('Location:', 'wordfence') ?></th>
58
  <td>
59
  <span class="wf-flag <?php echo esc_attr('wf-flag-' . strtolower($v['loc']['countryCode'])); ?>" title="<?php echo esc_attr($v['loc']['countryName']); ?>"></span>
60
  <?php if ($v['loc']['city']) {
73
  </tr>
74
  <?php } ?>
75
 
76
+ </table>
lib/conntest.php DELETED
@@ -1,86 +0,0 @@
1
- <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
- <?php if(! wfUtils::isAdmin()){ exit(); } ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
- <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
4
- <head>
5
- <title>Wordfence Connectivity Tester</title>
6
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7
- <body>
8
- <h1>Wordfence connectivity tester</h1>
9
- <br /><br />
10
- DNS lookup for noc1.wordfence.com returns: <?php echo gethostbyname('noc1.wordfence.com'); ?><br /><br />
11
- <?php
12
- $curlContent = "";
13
- function curlWrite($h, $d){
14
- global $curlContent;
15
- $curlContent .= $d;
16
- return strlen($d);
17
- }
18
- function doWPostTest($protocol){
19
- echo "<br /><b>Starting wp_remote_post() test</b><br />\n";
20
- $cronURL = admin_url('admin-ajax.php');
21
- $cronURL = preg_replace('/^(https?:\/\/)/i', '://noc1.wordfence.com/scanptest/', $cronURL);
22
- $cronURL .= '?action=wordfence_doScan&isFork=0&cronKey=47e9d1fa6a675b5999999333';
23
- $cronURL = $protocol . $cronURL;
24
- $result = wp_remote_post($cronURL, array(
25
- 'timeout' => 10, //Must be less than max execution time or more than 2 HTTP children will be occupied by scan
26
- 'blocking' => true, //Non-blocking seems to block anyway, so we use blocking
27
- // This causes cURL to throw errors in some versions since WordPress uses its own certificate bundle ('CA certificate set, but certificate verification is disabled')
28
- // 'sslverify' => false,
29
- 'headers' => array()
30
- ));
31
- if( (! is_wp_error($result)) && $result['response']['code'] == 200 && strpos($result['body'], "scanptestok") !== false){
32
- echo "wp_remote_post() test to noc1.wordfence.com passed!<br />\n";
33
- } else if(is_wp_error($result)){
34
- echo "wp_remote_post() test to noc1.wordfence.com failed! Response was: " . $result->get_error_message() . "<br />\n";
35
- } else {
36
- echo "wp_remote_post() test to noc1.wordfence.com failed! Response was: " . $result['response']['code'] . " " . $result['response']['message'] . "<br />\n";
37
- echo "This likely means that your hosting provider is blocking requests to noc1.wordfence.com or has set up a proxy that is not behaving itself.<br />\n";
38
- echo "This additional info may help you diagnose the issue. The response headers we received were:<br />\n";
39
- foreach($result['headers'] as $key => $value){
40
- echo "$key => $value<br />\n";
41
- }
42
- }
43
- }
44
- function doCurlTest($protocol){
45
- if(! function_exists('curl_init')){
46
- echo "<br /><b style='color: #F00;'>CURL is not installed</b>. Asking your hosting provider to install and enable CURL may improve any connection problems.</b><br />\n";
47
- return;
48
- }
49
- echo "<br /><b>STARTING CURL $protocol CONNECTION TEST....</b><br />\n";
50
- global $curlContent;
51
- $curlContent = "";
52
- $curl = curl_init($protocol . '://noc1.wordfence.com/');
53
- if(defined('WP_PROXY_HOST') && defined('WP_PROXY_PORT') && wfUtils::hostNotExcludedFromProxy('noc1.wordfence.com') ){
54
- curl_setopt($curl, CURLOPT_HTTPPROXYTUNNEL, 0);
55
- curl_setopt($curl, CURLOPT_PROXY, WP_PROXY_HOST . ':' . WP_PROXY_PORT);
56
- if(defined('WP_PROXY_USERNAME') && defined('WP_PROXY_PASSWORD')){
57
- curl_setopt($curl, CURLOPT_PROXYUSERPWD, WP_PROXY_USERNAME . ':' . WP_PROXY_PASSWORD);
58
- }
59
- }
60
-
61
- curl_setopt ($curl, CURLOPT_TIMEOUT, 900);
62
- curl_setopt ($curl, CURLOPT_USERAGENT, "Wordfence.com UA " . (defined('WORDFENCE_VERSION') ? WORDFENCE_VERSION : '[Unknown version]') );
63
- curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
64
- curl_setopt ($curl, CURLOPT_HEADER, 0);
65
- curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, false);
66
- curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, false);
67
- curl_setopt ($curl, CURLOPT_WRITEFUNCTION, 'curlWrite');
68
- curl_exec($curl);
69
- $httpStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
70
- if(strpos($curlContent, 'Your site did not send a license key') !== false){
71
- echo "Curl connectivity test passed.<br /><br />\n";
72
- } else {
73
- $curlErrorNo = curl_errno($curl);
74
- $curlError = curl_error($curl);
75
- echo "Curl connectivity test failed with response: <pre>$curlContent</pre>";
76
- echo "<br />Curl HTTP status: $httpStatus<br />Curl error code: $curlErrorNo<br />Curl Error: $curlError<br /><br />\n";
77
- }
78
- }
79
- doCurlTest('http');
80
- doCurlTest('https');
81
- doWPostTest('http');
82
- doWPostTest('https');
83
- ?>
84
- </body>
85
- </html>
86
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/cronview.php DELETED
@@ -1,33 +0,0 @@
1
- <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
- <?php if ( ! wfUtils::isAdmin() ) {
3
- exit();
4
- } ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
- <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
7
- <head>
8
- <title>Wordfence Cron Viewer</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
10
- <link rel='stylesheet' id='wordfence-main-style-css'
11
- href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/phpinfo.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>'
12
- type='text/css' media='all'/>
13
- <body>
14
- <h1>Wordfence Cron Viewer</h1>
15
- <p style="width: 400px;">This page is used for debugging and shows a list of scheduled jobs on your system. Our staff may ask you to send them the
16
- data on this page as part of a troubleshooting process.</p>
17
- <?php
18
- $cron = _get_cron_array();
19
-
20
- foreach ( $cron as $timestamp => $values ) {
21
- if ( is_array( $values ) ) {
22
- foreach ( $values as $cron_job => $v ) {
23
- if (is_numeric($timestamp)) {
24
- echo date( 'r', $timestamp ) . " : " . $cron_job . "<br />";
25
- }
26
- }
27
- }
28
- }
29
- ?>
30
-
31
- <div class="diffFooter">&copy;&nbsp;2011 to <?php echo date('Y'); ?> Wordfence &mdash; Visit <a href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.</div>
32
- </body>
33
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/dashboard/widget_content_countries.php CHANGED
@@ -3,8 +3,8 @@
3
  <table class="wf-table wf-table-hover">
4
  <thead>
5
  <tr>
6
- <th colspan="2">Country</th>
7
- <th>Block Count</th>
8
  </tr>
9
  </thead>
10
  <tbody>
3
  <table class="wf-table wf-table-hover">
4
  <thead>
5
  <tr>
6
+ <th colspan="2"><?php esc_html_e('Country', 'wordfence') ?></th>
7
+ <th><?php esc_html_e('Block Count', 'wordfence') ?></th>
8
  </tr>
9
  </thead>
10
  <tbody>
lib/dashboard/widget_content_ips.php CHANGED
@@ -3,9 +3,9 @@
3
  <table class="wf-table wf-table-hover">
4
  <thead>
5
  <tr>
6
- <th>IP</th>
7
- <th colspan="2">Country</th>
8
- <th>Block Count</th>
9
  </tr>
10
  </thead>
11
  <tbody>
3
  <table class="wf-table wf-table-hover">
4
  <thead>
5
  <tr>
6
+ <th><?php esc_html_e('IP', 'wordfence') ?></th>
7
+ <th colspan="2"><?php esc_html_e('Country', 'wordfence') ?></th>
8
+ <th><?php esc_html_e('Block Count', 'wordfence') ?></th>
9
  </tr>
10
  </thead>
11
  <tbody>
lib/dashboard/widget_content_logins.php CHANGED
@@ -3,9 +3,9 @@
3
  <table class="wf-table wf-table-hover">
4
  <thead>
5
  <tr>
6
- <th>Username</th>
7
- <th>IP</th>
8
- <th>Date</th>
9
  </tr>
10
  </thead>
11
  <tbody>
3
  <table class="wf-table wf-table-hover">
4
  <thead>
5
  <tr>
6
+ <th><?php esc_html_e('Username', 'wordfence') ?></th>
7
+ <th><?php esc_html_e('IP', 'wordfence') ?></th>
8
+ <th><?php esc_html_e('Date', 'wordfence') ?></th>
9
  </tr>
10
  </thead>
11
  <tbody>
lib/dashboard/widget_countries.php CHANGED
@@ -6,14 +6,14 @@
6
  <div class="wf-dashboard-item-inner">
7
  <div class="wf-dashboard-item-content">
8
  <div class="wf-dashboard-item-title">
9
- <strong>Top Countries by Number of Attacks - Last 7 Days</strong>
10
  </div>
11
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
12
  </div>
13
  </div>
14
  <div class="wf-dashboard-item-extra">
15
  <?php if ($firewall->learningModeStatus() !== false): ?>
16
- <div class="wf-widget-learning-mode"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100.11 100.44"><path d="M96.14,30.67a50.7,50.7,0,0,0-10.66-16A50,50,0,0,0,69.51,4,49.57,49.57,0,0,0,30.6,4a50,50,0,0,0-16,10.69A50.69,50.69,0,0,0,4,30.67,50,50,0,0,0,4,69.74a50.62,50.62,0,0,0,10.66,16,50,50,0,0,0,16,10.69,49.54,49.54,0,0,0,38.91,0,50,50,0,0,0,16-10.69,50.56,50.56,0,0,0,10.66-16,50,50,0,0,0,0-39.07Zm-75.74,39a35.77,35.77,0,0,1-1-37.35,35.21,35.21,0,0,1,12.91-13A34.65,34.65,0,0,1,50.06,14.6a34.22,34.22,0,0,1,19.55,5.93ZM82.71,64a35.4,35.4,0,0,1-7.56,11.37A36,36,0,0,1,63.84,83a34.32,34.32,0,0,1-13.79,2.84A34.85,34.85,0,0,1,30.7,80L79.84,31a34.57,34.57,0,0,1,5.67,19.23A35.17,35.17,0,0,1,82.71,64Zm0,0"/></svg><span><?php _e('No Data Available During Learning Mode', 'wordfence'); ?></span></div>
17
  <?php else: ?>
18
  <ul class="wf-dashboard-item-list">
19
  <li>
@@ -22,20 +22,20 @@
22
  <div class="wf-dashboard-toggle-btns">
23
  <ul class="wf-pagination wf-pagination-sm">
24
  <li class="wf-active"><a href="#" class="wf-dashboard-countries" data-grouping="local">Local Site</a></li>
25
- <li><a href="#" class="wf-dashboard-countries" data-grouping="network">Wordfence Network</a></li>
26
  </ul>
27
  </div>
28
  <?php endif; ?>
29
  <div class="wf-countries wf-countries-local">
30
  <?php if (!isset($d->countriesLocal) || count($d->countriesLocal) == 0): ?>
31
- <div class="wf-dashboard-item-list-text"><p><em>No blocks have been recorded.</em></p></div>
32
  <?php else: ?>
33
  <?php $data = array_slice($d->countriesLocal, 0, min(10, count($d->countriesLocal)), true); include(dirname(__FILE__) . '/widget_content_countries.php'); ?>
34
  <?php endif; ?>
35
  </div>
36
  <div class="wf-countries wf-countries-network wf-hidden">
37
  <?php if (!isset($d->countriesNetwork) || count($d->countriesNetwork) == 0): ?>
38
- <div class="wf-dashboard-item-list-text"><p><em>No blocks have been recorded.</em></p></div>
39
  <?php else: ?>
40
  <?php $data = array_slice($d->countriesNetwork, 0, min(10, count($d->countriesNetwork)), true); include(dirname(__FILE__) . '/widget_content_countries.php'); ?>
41
  <?php endif; ?>
6
  <div class="wf-dashboard-item-inner">
7
  <div class="wf-dashboard-item-content">
8
  <div class="wf-dashboard-item-title">
9
+ <strong><?php esc_html_e('Top Countries by Number of Attacks - Last 7 Days', 'wordfence') ?></strong>
10
  </div>
11
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
12
  </div>
13
  </div>
14
  <div class="wf-dashboard-item-extra">
15
  <?php if ($firewall->learningModeStatus() !== false): ?>
16
+ <div class="wf-widget-learning-mode"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100.11 100.44"><path d="M96.14,30.67a50.7,50.7,0,0,0-10.66-16A50,50,0,0,0,69.51,4,49.57,49.57,0,0,0,30.6,4a50,50,0,0,0-16,10.69A50.69,50.69,0,0,0,4,30.67,50,50,0,0,0,4,69.74a50.62,50.62,0,0,0,10.66,16,50,50,0,0,0,16,10.69,49.54,49.54,0,0,0,38.91,0,50,50,0,0,0,16-10.69,50.56,50.56,0,0,0,10.66-16,50,50,0,0,0,0-39.07Zm-75.74,39a35.77,35.77,0,0,1-1-37.35,35.21,35.21,0,0,1,12.91-13A34.65,34.65,0,0,1,50.06,14.6a34.22,34.22,0,0,1,19.55,5.93ZM82.71,64a35.4,35.4,0,0,1-7.56,11.37A36,36,0,0,1,63.84,83a34.32,34.32,0,0,1-13.79,2.84A34.85,34.85,0,0,1,30.7,80L79.84,31a34.57,34.57,0,0,1,5.67,19.23A35.17,35.17,0,0,1,82.71,64Zm0,0"/></svg><span><?php esc_html_e('No Data Available During Learning Mode', 'wordfence'); ?></span></div>
17
  <?php else: ?>
18
  <ul class="wf-dashboard-item-list">
19
  <li>
22
  <div class="wf-dashboard-toggle-btns">
23
  <ul class="wf-pagination wf-pagination-sm">
24
  <li class="wf-active"><a href="#" class="wf-dashboard-countries" data-grouping="local">Local Site</a></li>
25
+ <li><a href="#" class="wf-dashboard-countries" data-grouping="network"><?php esc_html_e('Wordfence Network', 'wordfence') ?></a></li>
26
  </ul>
27
  </div>
28
  <?php endif; ?>
29
  <div class="wf-countries wf-countries-local">
30
  <?php if (!isset($d->countriesLocal) || count($d->countriesLocal) == 0): ?>
31
+ <div class="wf-dashboard-item-list-text"><p><em><?php esc_html_e('No blocks have been recorded.', 'wordfence') ?></em></p></div>
32
  <?php else: ?>
33
  <?php $data = array_slice($d->countriesLocal, 0, min(10, count($d->countriesLocal)), true); include(dirname(__FILE__) . '/widget_content_countries.php'); ?>
34
  <?php endif; ?>
35
  </div>
36
  <div class="wf-countries wf-countries-network wf-hidden">
37
  <?php if (!isset($d->countriesNetwork) || count($d->countriesNetwork) == 0): ?>
38
+ <div class="wf-dashboard-item-list-text"><p><em><?php esc_html_e('No blocks have been recorded.', 'wordfence') ?></em></p></div>
39
  <?php else: ?>
40
  <?php $data = array_slice($d->countriesNetwork, 0, min(10, count($d->countriesNetwork)), true); include(dirname(__FILE__) . '/widget_content_countries.php'); ?>
41
  <?php endif; ?>
lib/dashboard/widget_ips.php CHANGED
@@ -11,52 +11,52 @@ if (!isset($limit)) { $limit = 10; $initial = true; }
11
  <div class="wf-dashboard-item-inner">
12
  <div class="wf-dashboard-item-content">
13
  <div class="wf-dashboard-item-title">
14
- <strong>Top IPs Blocked</strong>
15
  </div>
16
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
17
  </div>
18
  </div>
19
  <div class="wf-dashboard-item-extra">
20
  <?php if ($firewall->learningModeStatus() !== false): ?>
21
- <div class="wf-widget-learning-mode"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100.11 100.44"><path d="M96.14,30.67a50.7,50.7,0,0,0-10.66-16A50,50,0,0,0,69.51,4,49.57,49.57,0,0,0,30.6,4a50,50,0,0,0-16,10.69A50.69,50.69,0,0,0,4,30.67,50,50,0,0,0,4,69.74a50.62,50.62,0,0,0,10.66,16,50,50,0,0,0,16,10.69,49.54,49.54,0,0,0,38.91,0,50,50,0,0,0,16-10.69,50.56,50.56,0,0,0,10.66-16,50,50,0,0,0,0-39.07Zm-75.74,39a35.77,35.77,0,0,1-1-37.35,35.21,35.21,0,0,1,12.91-13A34.65,34.65,0,0,1,50.06,14.6a34.22,34.22,0,0,1,19.55,5.93ZM82.71,64a35.4,35.4,0,0,1-7.56,11.37A36,36,0,0,1,63.84,83a34.32,34.32,0,0,1-13.79,2.84A34.85,34.85,0,0,1,30.7,80L79.84,31a34.57,34.57,0,0,1,5.67,19.23A35.17,35.17,0,0,1,82.71,64Zm0,0"/></svg><span><?php _e('No Data Available During Learning Mode', 'wordfence'); ?></span></div>
22
  <?php else: ?>
23
  <ul class="wf-dashboard-item-list">
24
  <li>
25
  <div>
26
  <div class="wf-dashboard-toggle-btns">
27
  <ul class="wf-pagination wf-pagination-sm">
28
- <li class="wf-active"><a href="#" class="wf-dashboard-ips" data-grouping="24h">24 Hours</a></li>
29
- <li><a href="#" class="wf-dashboard-ips" data-grouping="7d">7 Days</a></li>
30
- <li><a href="#" class="wf-dashboard-ips" data-grouping="30d">30 Days</a></li>
31
  </ul>
32
  </div>
33
  <div class="wf-ips wf-ips-24h">
34
  <?php if (count($d->ips24h) == 0): ?>
35
- <div class="wf-dashboard-item-list-text"><p><em>No blocks have been recorded.</em></p></div>
36
  <?php else: ?>
37
  <?php $data = array_slice($d->ips24h, 0, min($limit, count($d->ips24h)), true); include(dirname(__FILE__) . '/widget_content_ips.php'); ?>
38
  <?php if (count($d->ips24h) > $limit && $initial): ?>
39
- <div class="wf-dashboard-item-list-text"><div class="wf-dashboard-show-more" data-grouping="ips" data-period="24h"><a href="#">Show more</a></div></div>
40
  <?php endif; ?>
41
  <?php endif; ?>
42
  </div>
43
  <div class="wf-ips wf-ips-7d wf-hidden">
44
  <?php if (count($d->ips7d) == 0): ?>
45
- <div class="wf-dashboard-item-list-text"><p><em>No blocks have been recorded.</em></p></div>
46
  <?php else: ?>
47
  <?php $data = array_slice($d->ips7d, 0, min($limit, count($d->ips7d)), true); include(dirname(__FILE__) . '/widget_content_ips.php'); ?>
48
  <?php if (count($d->ips7d) > $limit && $initial): ?>
49
- <div class="wf-dashboard-item-list-text"><div class="wf-dashboard-show-more" data-grouping="ips" data-period="7d"><a href="#">Show more</a></div></div>
50
  <?php endif; ?>
51
  <?php endif; ?>
52
  </div>
53
  <div class="wf-ips wf-ips-30d wf-hidden">
54
  <?php if (count($d->ips30d) == 0): ?>
55
- <div class="wf-dashboard-item-list-text"><p><em>No blocks have been recorded.</em></p></div>
56
  <?php else: ?>
57
  <?php $data = array_slice($d->ips30d, 0, min($limit, count($d->ips30d)), true); include(dirname(__FILE__) . '/widget_content_ips.php'); ?>
58
  <?php if (count($d->ips30d) > $limit && $initial): ?>
59
- <div class="wf-dashboard-item-list-text"><div class="wf-dashboard-show-more" data-grouping="ips" data-period="30d"><a href="#">Show more</a></div></div>
60
  <?php endif; ?>
61
  <?php endif; ?>
62
  </div>
@@ -93,7 +93,7 @@ if (!isset($limit)) { $limit = 10; $initial = true; }
93
  $(self).closest('.wf-ips').find('table').replaceWith(table);
94
  }
95
  else {
96
- WFAD.colorboxModal('300px', 'An error occurred', 'We encountered an error trying load more data.');
97
  $(this).closest('.wf-dashboard-item-list-text').fadeIn();
98
  }
99
  });
@@ -112,9 +112,9 @@ if (!isset($limit)) { $limit = 10; $initial = true; }
112
  <table class="wf-table wf-table-hover">
113
  <thead>
114
  <tr>
115
- <th>IP</th>
116
- <th colspan="2">Country</th>
117
- <th>Block Count</th>
118
  </tr>
119
  </thead>
120
  <tbody>
11
  <div class="wf-dashboard-item-inner">
12
  <div class="wf-dashboard-item-content">
13
  <div class="wf-dashboard-item-title">
14
+ <strong><?php esc_html_e('Top IPs Blocked', 'wordfence') ?></strong>
15
  </div>
16
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
17
  </div>
18
  </div>
19
  <div class="wf-dashboard-item-extra">
20
  <?php if ($firewall->learningModeStatus() !== false): ?>
21
+ <div class="wf-widget-learning-mode"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100.11 100.44"><path d="M96.14,30.67a50.7,50.7,0,0,0-10.66-16A50,50,0,0,0,69.51,4,49.57,49.57,0,0,0,30.6,4a50,50,0,0,0-16,10.69A50.69,50.69,0,0,0,4,30.67,50,50,0,0,0,4,69.74a50.62,50.62,0,0,0,10.66,16,50,50,0,0,0,16,10.69,49.54,49.54,0,0,0,38.91,0,50,50,0,0,0,16-10.69,50.56,50.56,0,0,0,10.66-16,50,50,0,0,0,0-39.07Zm-75.74,39a35.77,35.77,0,0,1-1-37.35,35.21,35.21,0,0,1,12.91-13A34.65,34.65,0,0,1,50.06,14.6a34.22,34.22,0,0,1,19.55,5.93ZM82.71,64a35.4,35.4,0,0,1-7.56,11.37A36,36,0,0,1,63.84,83a34.32,34.32,0,0,1-13.79,2.84A34.85,34.85,0,0,1,30.7,80L79.84,31a34.57,34.57,0,0,1,5.67,19.23A35.17,35.17,0,0,1,82.71,64Zm0,0"/></svg><span><?php esc_html_e('No Data Available During Learning Mode', 'wordfence'); ?></span></div>
22
  <?php else: ?>
23
  <ul class="wf-dashboard-item-list">
24
  <li>
25
  <div>
26
  <div class="wf-dashboard-toggle-btns">
27
  <ul class="wf-pagination wf-pagination-sm">
28
+ <li class="wf-active"><a href="#" class="wf-dashboard-ips" data-grouping="24h"><?php esc_html_e('24 Hours', 'wordfence') ?></a></li>
29
+ <li><a href="#" class="wf-dashboard-ips" data-grouping="7d"><?php esc_html_e('7 Days', 'wordfence') ?></a></li>
30
+ <li><a href="#" class="wf-dashboard-ips" data-grouping="30d"><?php esc_html_e('30 Days', 'wordfence') ?></a></li>
31
  </ul>
32
  </div>
33
  <div class="wf-ips wf-ips-24h">
34
  <?php if (count($d->ips24h) == 0): ?>
35
+ <div class="wf-dashboard-item-list-text"><p><em><?php esc_html_e('No blocks have been recorded.', 'wordfence') ?></em></p></div>
36
  <?php else: ?>
37
  <?php $data = array_slice($d->ips24h, 0, min($limit, count($d->ips24h)), true); include(dirname(__FILE__) . '/widget_content_ips.php'); ?>
38
  <?php if (count($d->ips24h) > $limit && $initial): ?>
39
+ <div class="wf-dashboard-item-list-text"><div class="wf-dashboard-show-more" data-grouping="ips" data-period="24h"><a href="#"><?php esc_html_e('Show more', 'wordfence') ?></a></div></div>
40
  <?php endif; ?>
41
  <?php endif; ?>
42
  </div>
43
  <div class="wf-ips wf-ips-7d wf-hidden">
44
  <?php if (count($d->ips7d) == 0): ?>
45
+ <div class="wf-dashboard-item-list-text"><p><em><?php esc_html_e('No blocks have been recorded.', 'wordfence') ?></em></p></div>
46
  <?php else: ?>
47
  <?php $data = array_slice($d->ips7d, 0, min($limit, count($d->ips7d)), true); include(dirname(__FILE__) . '/widget_content_ips.php'); ?>
48
  <?php if (count($d->ips7d) > $limit && $initial): ?>
49
+ <div class="wf-dashboard-item-list-text"><div class="wf-dashboard-show-more" data-grouping="ips" data-period="7d"><a href="#"><?php esc_html_e('Show more', 'wordfence') ?></a></div></div>
50
  <?php endif; ?>
51
  <?php endif; ?>
52
  </div>
53
  <div class="wf-ips wf-ips-30d wf-hidden">
54
  <?php if (count($d->ips30d) == 0): ?>
55
+ <div class="wf-dashboard-item-list-text"><p><em><?php esc_html_e('No blocks have been recorded.', 'wordfence') ?></em></p></div>
56
  <?php else: ?>
57
  <?php $data = array_slice($d->ips30d, 0, min($limit, count($d->ips30d)), true); include(dirname(__FILE__) . '/widget_content_ips.php'); ?>
58
  <?php if (count($d->ips30d) > $limit && $initial): ?>
59
+ <div class="wf-dashboard-item-list-text"><div class="wf-dashboard-show-more" data-grouping="ips" data-period="30d"><a href="#"><?php esc_html_e('Show more', 'wordfence') ?></a></div></div>
60
  <?php endif; ?>
61
  <?php endif; ?>
62
  </div>
93
  $(self).closest('.wf-ips').find('table').replaceWith(table);
94
  }
95
  else {
96
+ WFAD.colorboxModal('300px', <?php echo json_encode(__('An error occurred', 'wordfence')) ?>, <?php echo json_encode(__('We encountered an error trying load more data.', 'wordfence')) ?>);
97
  $(this).closest('.wf-dashboard-item-list-text').fadeIn();
98
  }
99
  });
112
  <table class="wf-table wf-table-hover">
113
  <thead>
114
  <tr>
115
+ <th><?php esc_html_e('IP', 'wordfence') ?></th>
116
+ <th colspan="2"><?php esc_html_e('Country', 'wordfence') ?></th>
117
+ <th><?php esc_html_e('Block Count', 'wordfence') ?></th>
118
  </tr>
119
  </thead>
120
  <tbody>
lib/dashboard/widget_localattacks.php CHANGED
@@ -5,14 +5,16 @@
5
  <div class="wf-dashboard-item-inner">
6
  <div class="wf-dashboard-item-content">
7
  <div class="wf-dashboard-item-title">
8
- <strong><?php _e('Firewall Summary:', 'wordfence'); ?> </strong><?php printf(__('Attacks Blocked for %s', 'wordfence'), esc_html(preg_replace('/^[^:]+:\/\//', '', network_site_url()))); ?>
 
 
9
  </div>
10
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
11
  </div>
12
  </div>
13
  <div class="wf-dashboard-item-extra">
14
  <?php if ($firewall->learningModeStatus() !== false): ?>
15
- <div class="wf-widget-learning-mode"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100.11 100.44"><path d="M96.14,30.67a50.7,50.7,0,0,0-10.66-16A50,50,0,0,0,69.51,4,49.57,49.57,0,0,0,30.6,4a50,50,0,0,0-16,10.69A50.69,50.69,0,0,0,4,30.67,50,50,0,0,0,4,69.74a50.62,50.62,0,0,0,10.66,16,50,50,0,0,0,16,10.69,49.54,49.54,0,0,0,38.91,0,50,50,0,0,0,16-10.69,50.56,50.56,0,0,0,10.66-16,50,50,0,0,0,0-39.07Zm-75.74,39a35.77,35.77,0,0,1-1-37.35,35.21,35.21,0,0,1,12.91-13A34.65,34.65,0,0,1,50.06,14.6a34.22,34.22,0,0,1,19.55,5.93ZM82.71,64a35.4,35.4,0,0,1-7.56,11.37A36,36,0,0,1,63.84,83a34.32,34.32,0,0,1-13.79,2.84A34.85,34.85,0,0,1,30.7,80L79.84,31a34.57,34.57,0,0,1,5.67,19.23A35.17,35.17,0,0,1,82.71,64Zm0,0"/></svg><span><?php _e('No Data Available During Learning Mode', 'wordfence'); ?></span></div>
16
  <?php else: ?>
17
  <ul class="wf-dashboard-item-list">
18
  <li class="wf-flex-vertical wf-flex-full-width">
@@ -27,19 +29,19 @@
27
 
28
  if (!$hasSome):
29
  ?>
30
- <div class="wf-dashboard-item-list-text"><p><em><?php _e('No blocks have been recorded.', 'wordfence'); ?></em></p></div>
31
  <?php else: ?>
32
  <table class="wf-blocks-summary">
33
  <thead>
34
  <tr>
35
- <th><?php _e('<span class="wf-hidden-xs">Block </span>Type', 'wordfence'); ?></th>
36
  <?php
37
  $totals = array('24h' => 0, '7d' => 0, '30d' => 0);
38
  foreach ($d->localBlocks as $row): ?>
39
  <th width="25%"<?php if ($row['type'] == wfActivityReport::BLOCK_TYPE_BLACKLIST && !wfConfig::get('isPaid')) { echo ' class="wf-premium"'; } ?>><?php echo esc_html($row['title']); ?></th>
40
  <?php $totals['24h'] += $row['24h']; $totals['7d'] += $row['7d']; $totals['30d'] += $row['30d']; ?>
41
  <?php endforeach; ?>
42
- <th width="25%"><?php _e('Total', 'wordfence'); ?></th>
43
  </tr>
44
  </thead>
45
  <tbody>
@@ -59,13 +61,13 @@
59
  <tr>
60
  <th></th>
61
  <?php foreach ($d->localBlocks as $row): ?>
62
- <td<?php if ($row['type'] == wfActivityReport::BLOCK_TYPE_BLACKLIST && !wfConfig::get('isPaid')) { echo ' class="wf-premium"'; } ?>><?php if ($row['type'] == wfActivityReport::BLOCK_TYPE_BLACKLIST && !wfConfig::get('isPaid')) { _e('Premium', 'wordfence'); } ?></td>
63
  <?php endforeach; ?>
64
  <td></td>
65
  </tr>
66
  </tfoot>
67
  </table>
68
- <p class="wf-right wf-no-top"><a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_WIDGET_LOCAL_ATTACKS); ?>" target="_blank" rel="noopener noreferrer"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i> <?php _e('How are these categorized?', 'wordfence'); ?></a></p>
69
  <?php endif; ?>
70
  </li>
71
  </ul>
5
  <div class="wf-dashboard-item-inner">
6
  <div class="wf-dashboard-item-content">
7
  <div class="wf-dashboard-item-title">
8
+ <strong><?php esc_html_e('Firewall Summary:', 'wordfence'); ?> </strong><?php echo esc_html(sprintf(
9
+ /* translators: The site's domain name. */
10
+ __('Attacks Blocked for %s', 'wordfence'), preg_replace('/^[^:]+:\/\//', '', network_site_url()))); ?>
11
  </div>
12
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
13
  </div>
14
  </div>
15
  <div class="wf-dashboard-item-extra">
16
  <?php if ($firewall->learningModeStatus() !== false): ?>
17
+ <div class="wf-widget-learning-mode"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100.11 100.44"><path d="M96.14,30.67a50.7,50.7,0,0,0-10.66-16A50,50,0,0,0,69.51,4,49.57,49.57,0,0,0,30.6,4a50,50,0,0,0-16,10.69A50.69,50.69,0,0,0,4,30.67,50,50,0,0,0,4,69.74a50.62,50.62,0,0,0,10.66,16,50,50,0,0,0,16,10.69,49.54,49.54,0,0,0,38.91,0,50,50,0,0,0,16-10.69,50.56,50.56,0,0,0,10.66-16,50,50,0,0,0,0-39.07Zm-75.74,39a35.77,35.77,0,0,1-1-37.35,35.21,35.21,0,0,1,12.91-13A34.65,34.65,0,0,1,50.06,14.6a34.22,34.22,0,0,1,19.55,5.93ZM82.71,64a35.4,35.4,0,0,1-7.56,11.37A36,36,0,0,1,63.84,83a34.32,34.32,0,0,1-13.79,2.84A34.85,34.85,0,0,1,30.7,80L79.84,31a34.57,34.57,0,0,1,5.67,19.23A35.17,35.17,0,0,1,82.71,64Zm0,0"/></svg><span><?php esc_html_e('No Data Available During Learning Mode', 'wordfence'); ?></span></div>
18
  <?php else: ?>
19
  <ul class="wf-dashboard-item-list">
20
  <li class="wf-flex-vertical wf-flex-full-width">
29
 
30
  if (!$hasSome):
31
  ?>
32
+ <div class="wf-dashboard-item-list-text"><p><em><?php esc_html_e('No blocks have been recorded.', 'wordfence'); ?></em></p></div>
33
  <?php else: ?>
34
  <table class="wf-blocks-summary">
35
  <thead>
36
  <tr>
37
+ <th><?php echo wp_kses(__('<span class="wf-hidden-xs">Block </span>Type', 'wordfence'), array('span'=>array('class'=>array()))); ?></th>
38
  <?php
39
  $totals = array('24h' => 0, '7d' => 0, '30d' => 0);
40
  foreach ($d->localBlocks as $row): ?>
41
  <th width="25%"<?php if ($row['type'] == wfActivityReport::BLOCK_TYPE_BLACKLIST && !wfConfig::get('isPaid')) { echo ' class="wf-premium"'; } ?>><?php echo esc_html($row['title']); ?></th>
42
  <?php $totals['24h'] += $row['24h']; $totals['7d'] += $row['7d']; $totals['30d'] += $row['30d']; ?>
43
  <?php endforeach; ?>
44
+ <th width="25%"><?php esc_html_e('Total', 'wordfence'); ?></th>
45
  </tr>
46
  </thead>
47
  <tbody>
61
  <tr>
62
  <th></th>
63
  <?php foreach ($d->localBlocks as $row): ?>
64
+ <td<?php if ($row['type'] == wfActivityReport::BLOCK_TYPE_BLACKLIST && !wfConfig::get('isPaid')) { echo ' class="wf-premium"'; } ?>><?php if ($row['type'] == wfActivityReport::BLOCK_TYPE_BLACKLIST && !wfConfig::get('isPaid')) { esc_html_e('Premium', 'wordfence'); } ?></td>
65
  <?php endforeach; ?>
66
  <td></td>
67
  </tr>
68
  </tfoot>
69
  </table>
70
+ <p class="wf-right wf-no-top"><a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_WIDGET_LOCAL_ATTACKS); ?>" target="_blank" rel="noopener noreferrer"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i> <?php esc_html_e('How are these categorized?', 'wordfence'); ?></a></p>
71
  <?php endif; ?>
72
  </li>
73
  </ul>
lib/dashboard/widget_logins.php CHANGED
@@ -6,7 +6,7 @@
6
  <div class="wf-dashboard-item-inner">
7
  <div class="wf-dashboard-item-content">
8
  <div class="wf-dashboard-item-title">
9
- <strong>Login Attempts</strong>
10
  </div>
11
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
12
  </div>
@@ -17,27 +17,27 @@
17
  <div>
18
  <div class="wf-dashboard-toggle-btns">
19
  <ul class="wf-pagination wf-pagination-sm">
20
- <li class="wf-active"><a href="#" class="wf-dashboard-login-attempts" data-grouping="success">Successful</a></li>
21
- <li><a href="#" class="wf-dashboard-login-attempts" data-grouping="fail">Failed</a></li>
22
  </ul>
23
  </div>
24
  <div class="wf-recent-logins wf-recent-logins-success">
25
  <?php if (count($d->loginsSuccess) == 0): ?>
26
- <div class="wf-dashboard-item-list-text"><p><em>No successful logins have been recorded.</em></p></div>
27
  <?php else: ?>
28
  <?php $data = array_slice($d->loginsSuccess, 0, min(10, count($d->loginsSuccess)), true); include(dirname(__FILE__) . '/widget_content_logins.php'); ?>
29
  <?php if (count($d->loginsSuccess) > 10): ?>
30
- <div class="wf-dashboard-item-list-text"><div class="wf-dashboard-show-more" data-grouping="logins" data-period="success"><a href="#">Show more</a></div></div>
31
  <?php endif; ?>
32
  <?php endif; ?>
33
  </div>
34
  <div class="wf-recent-logins wf-recent-logins-fail wf-hidden">
35
  <?php if (count($d->loginsFail) == 0): ?>
36
- <div class="wf-dashboard-item-list-text"><p><em>No failed logins have been recorded.</em></p></div>
37
  <?php else: ?>
38
  <?php $data = array_slice($d->loginsFail, 0, min(10, count($d->loginsFail)), true); include(dirname(__FILE__) . '/widget_content_logins.php'); ?>
39
  <?php if (count($d->loginsFail) > 10): ?>
40
- <div class="wf-dashboard-item-list-text"><div class="wf-dashboard-show-more" data-grouping="logins" data-period="fail"><a href="#">Show more</a></div></div>
41
  <?php endif; ?>
42
  <?php endif; ?>
43
  </div>
@@ -74,7 +74,7 @@
74
  $(self).closest('.wf-recent-logins').find('table').replaceWith(table);
75
  }
76
  else {
77
- WFAD.colorboxModal('300px', 'An error occurred', 'We encountered an error trying load more data.');
78
  $(this).closest('.wf-dashboard-item-list-text').fadeIn();
79
  }
80
  });
@@ -92,9 +92,9 @@
92
  <table class="wf-table wf-table-hover">
93
  <thead>
94
  <tr>
95
- <th>Username</th>
96
- <th>IP</th>
97
- <th>Date</th>
98
  </tr>
99
  </thead>
100
  <tbody>
6
  <div class="wf-dashboard-item-inner">
7
  <div class="wf-dashboard-item-content">
8
  <div class="wf-dashboard-item-title">
9
+ <strong><?php esc_html_e('Login Attempts', 'wordfence') ?></strong>
10
  </div>
11
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
12
  </div>
17
  <div>
18
  <div class="wf-dashboard-toggle-btns">
19
  <ul class="wf-pagination wf-pagination-sm">
20
+ <li class="wf-active"><a href="#" class="wf-dashboard-login-attempts" data-grouping="success"><?php esc_html_e('Successful', 'wordfence') ?></a></li>
21
+ <li><a href="#" class="wf-dashboard-login-attempts" data-grouping="fail"><?php esc_html_e('Failed', 'wordfence') ?></a></li>
22
  </ul>
23
  </div>
24
  <div class="wf-recent-logins wf-recent-logins-success">
25
  <?php if (count($d->loginsSuccess) == 0): ?>
26
+ <div class="wf-dashboard-item-list-text"><p><em><?php esc_html_e('No successful logins have been recorded.', 'wordfence') ?></em></p></div>
27
  <?php else: ?>
28
  <?php $data = array_slice($d->loginsSuccess, 0, min(10, count($d->loginsSuccess)), true); include(dirname(__FILE__) . '/widget_content_logins.php'); ?>
29
  <?php if (count($d->loginsSuccess) > 10): ?>
30
+ <div class="wf-dashboard-item-list-text"><div class="wf-dashboard-show-more" data-grouping="logins" data-period="success"><a href="#"><?php esc_html_e('Show more', 'wordfence') ?></a></div></div>
31
  <?php endif; ?>
32
  <?php endif; ?>
33
  </div>
34
  <div class="wf-recent-logins wf-recent-logins-fail wf-hidden">
35
  <?php if (count($d->loginsFail) == 0): ?>
36
+ <div class="wf-dashboard-item-list-text"><p><em><?php esc_html_e('No failed logins have been recorded.', 'wordfence') ?></em></p></div>
37
  <?php else: ?>
38
  <?php $data = array_slice($d->loginsFail, 0, min(10, count($d->loginsFail)), true); include(dirname(__FILE__) . '/widget_content_logins.php'); ?>
39
  <?php if (count($d->loginsFail) > 10): ?>
40
+ <div class="wf-dashboard-item-list-text"><div class="wf-dashboard-show-more" data-grouping="logins" data-period="fail"><a href="#"><?php esc_html_e('Show more', 'wordfence') ?></a></div></div>
41
  <?php endif; ?>
42
  <?php endif; ?>
43
  </div>
74
  $(self).closest('.wf-recent-logins').find('table').replaceWith(table);
75
  }
76
  else {
77
+ WFAD.colorboxModal('300px', <?php echo json_encode(__('An error occurred', 'wordfence')) ?>, <?php echo json_encode(__('We encountered an error trying load more data.', 'wordfence')) ?>);
78
  $(this).closest('.wf-dashboard-item-list-text').fadeIn();
79
  }
80
  });
92
  <table class="wf-table wf-table-hover">
93
  <thead>
94
  <tr>
95
+ <th><?php esc_html_e('Username', 'wordfence') ?></th>
96
+ <th><?php esc_html_e('IP', 'wordfence') ?></th>
97
+ <th><?php esc_html_e('Date', 'wordfence') ?></th>
98
  </tr>
99
  </thead>
100
  <tbody>
lib/dashboard/widget_networkattacks.php CHANGED
@@ -5,7 +5,7 @@
5
  <div class="wf-dashboard-item-inner">
6
  <div class="wf-dashboard-item-content">
7
  <div class="wf-dashboard-item-title">
8
- <strong><?php _e('Total Attacks Blocked:', 'wordfence'); ?> </strong><?php _e('Wordfence Network', 'wordfence'); ?>
9
  </div>
10
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
11
  </div>
@@ -14,14 +14,14 @@
14
  <ul class="wf-dashboard-item-list">
15
  <li>
16
  <?php if ($d->networkBlock24h === null): ?>
17
- <div class="wf-dashboard-item-list-text"><p><em><?php _e('Blocked attack counts not available yet.', 'wordfence'); ?></em></p></div>
18
  <?php else: ?>
19
  <div class="wf-dashboard-graph-wrapper">
20
  <div class="wf-dashboard-toggle-btns">
21
  <ul class="wf-pagination wf-pagination-sm">
22
- <li class="wf-active"><a href="#" class="wf-dashboard-graph-attacks" data-grouping="24h"><?php _e('24 Hours', 'wordfence'); ?></a></li>
23
  <!-- <li><a href="#" class="wf-dashboard-graph-attacks" data-grouping="7d">7 Days</a></li> -->
24
- <li><a href="#" class="wf-dashboard-graph-attacks" data-grouping="30d"><?php _e('30 Days', 'wordfence'); ?></a></li>
25
  </ul>
26
  </div>
27
  <div class="wf-dashboard-network-blocks"><canvas id="wf-dashboard-network-blocks-24h"></canvas></div>
@@ -30,8 +30,9 @@
30
  </div>
31
  <script type="application/javascript">
32
  <?php
 
33
  $styling = <<<STYLING
34
- label: "Total Attacks",
35
  fill: false,
36
  lineTension: 0.1,
37
  backgroundColor: "rgba(75,192,192,0.4)",
@@ -203,7 +204,9 @@ STYLING;
203
  <?php endif; ?>
204
  </li>
205
  </ul>
206
- <p class="wf-dashboard-last-updated"><?php printf(__('Last Updated: %s ago', 'wordfence'), esc_html(wfUtils::makeTimeAgo(time() - $d->lastGenerated))); ?></p>
 
 
207
  </div>
208
  </div>
209
  </div>
5
  <div class="wf-dashboard-item-inner">
6
  <div class="wf-dashboard-item-content">
7
  <div class="wf-dashboard-item-title">
8
+ <strong><?php esc_html_e('Total Attacks Blocked:', 'wordfence'); ?> </strong><?php esc_html_e('Wordfence Network', 'wordfence'); ?>
9
  </div>
10
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
11
  </div>
14
  <ul class="wf-dashboard-item-list">
15
  <li>
16
  <?php if ($d->networkBlock24h === null): ?>
17
+ <div class="wf-dashboard-item-list-text"><p><em><?php esc_html_e('Blocked attack counts not available yet.', 'wordfence'); ?></em></p></div>
18
  <?php else: ?>
19
  <div class="wf-dashboard-graph-wrapper">
20
  <div class="wf-dashboard-toggle-btns">
21
  <ul class="wf-pagination wf-pagination-sm">
22
+ <li class="wf-active"><a href="#" class="wf-dashboard-graph-attacks" data-grouping="24h"><?php esc_html_e('24 Hours', 'wordfence'); ?></a></li>
23
  <!-- <li><a href="#" class="wf-dashboard-graph-attacks" data-grouping="7d">7 Days</a></li> -->
24
+ <li><a href="#" class="wf-dashboard-graph-attacks" data-grouping="30d"><?php esc_html_e('30 Days', 'wordfence'); ?></a></li>
25
  </ul>
26
  </div>
27
  <div class="wf-dashboard-network-blocks"><canvas id="wf-dashboard-network-blocks-24h"></canvas></div>
30
  </div>
31
  <script type="application/javascript">
32
  <?php
33
+ $totalAttacksString = json_encode(__("Total Attacks", 'wordfence'));
34
  $styling = <<<STYLING
35
+ label: $totalAttacksString,
36
  fill: false,
37
  lineTension: 0.1,
38
  backgroundColor: "rgba(75,192,192,0.4)",
204
  <?php endif; ?>
205
  </li>
206
  </ul>
207
+ <p class="wf-dashboard-last-updated"><?php echo esc_html(sprintf(
208
+ /* translators: Time since. Example: 1 minute, 2 seconds */
209
+ __('Last Updated: %s ago', 'wordfence'), wfUtils::makeTimeAgo(time() - $d->lastGenerated))); ?></p>
210
  </div>
211
  </div>
212
  </div>
lib/dashboard/widget_notifications.php CHANGED
@@ -5,7 +5,7 @@
5
  <div class="wf-dashboard-item-inner">
6
  <div class="wf-dashboard-item-content">
7
  <div class="wf-dashboard-item-title">
8
- <strong>Notifications</strong><span class="wf-dashboard-badge wf-notification-count-container wf-notification-count-value<?php echo (count($d->notifications) == 0 ? ' wf-hidden' : ''); ?>"><?php echo number_format_i18n(count($d->notifications)); ?></span>
9
  </div>
10
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
11
  </div>
@@ -22,7 +22,7 @@
22
  </li>
23
  <?php endforeach; ?>
24
  <?php if (count($d->notifications) == 0): ?>
25
- <li class="wf-notifications-empty">No notifications received</li>
26
  <?php endif; ?>
27
  </ul>
28
  </div>
@@ -34,12 +34,16 @@
34
  <div class="wf-central-dashboard">
35
  <img class="wf-central-dashboard-logo" src="<?php echo wfUtils::getBaseURL() ?>images/wf-central-logo.svg" alt="Wordfence Central">
36
  <div class="wf-central-dashboard-copy">
37
- <p><strong><?php _e('Wordfence Central Status', 'wordfence') ?></strong></p>
38
  <p><?php
39
  if ($d->wordfenceCentralConnected) {
40
- printf(__('Connected by %s on %s', 'wordfence'), esc_html($d->wordfenceCentralConnectEmail), esc_html(date_i18n(get_option('date_format'), $d->wordfenceCentralConnectTime)));
 
 
41
  } elseif ($d->wordfenceCentralDisconnected) {
42
- printf(__('Disconnected by %s on %s', 'wordfence'), esc_html($d->wordfenceCentralDisconnectEmail), esc_html(date_i18n(get_option('date_format'), $d->wordfenceCentralDisconnectTime)));
 
 
43
  } elseif (wfCentral::isPartialConnection()) {
44
  _e('It looks like you\'ve tried to connect this site to Wordfence Central, but the installation did not finish.', 'wordfence');
45
  } else {
@@ -51,18 +55,18 @@
51
  <p>
52
  <a href="<?php echo WORDFENCE_CENTRAL_URL_SEC ?>/sites/connection-issues?complete-setup=<?php echo esc_attr(wfConfig::get('wordfenceCentralSiteID')) ?>"
53
  class="wf-central-resume wf-btn wf-btn-sm wf-btn-primary"
54
- ><?php _e('Resume Installation', 'wordfence') ?></a>
55
- <a href="#" class="wf-central-disconnect wf-btn wf-btn-sm wf-btn-default"><strong><?php _e('Disconnect This Site', 'wordfence') ?></strong></a>
56
  </p>
57
  <?php else: ?>
58
  <p class="wf-flex-row-1">
59
  <?php if ($d->wordfenceCentralConnected): ?>
60
- <a href="#" class="wf-central-disconnect"><strong><?php _e('Disconnect This Site', 'wordfence') ?></strong></a>
61
  <?php else: ?>
62
- <a href="<?php echo WORDFENCE_CENTRAL_URL_SEC ?>?newsite=<?php echo esc_attr(home_url()) ?>"><strong><?php _e($d->wordfenceCentralDisconnected ? 'Reconnect This Site' : 'Connect This Site', 'wordfence') ?></strong></a>
63
  <?php endif; ?>
64
  </p>
65
- <p class="wf-flex-row-1 wf-right wf-nowrap"><a href="<?php echo esc_url(WORDFENCE_CENTRAL_URL_SEC) ?>" target="_blank" rel="noopener noreferrer"><strong><?php _e('Visit Wordfence Central', 'wordfence') ?></strong></a></p>
66
  <?php endif ?>
67
 
68
  </div>
@@ -131,4 +135,4 @@
131
  'secondaryButtons' => array(array('id' => 'wf-central-prompt-disconnect', 'label' => __('Disconnect', 'wordfence'), 'link' => '#')),
132
  ))->render();
133
  ?>
134
- </script>
5
  <div class="wf-dashboard-item-inner">
6
  <div class="wf-dashboard-item-content">
7
  <div class="wf-dashboard-item-title">
8
+ <strong><?php esc_html_e('Notifications', 'wordfence') ?></strong><span class="wf-dashboard-badge wf-notification-count-container wf-notification-count-value<?php echo (count($d->notifications) == 0 ? ' wf-hidden' : ''); ?>"><?php echo number_format_i18n(count($d->notifications)); ?></span>
9
  </div>
10
  <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
11
  </div>
22
  </li>
23
  <?php endforeach; ?>
24
  <?php if (count($d->notifications) == 0): ?>
25
+ <li class="wf-notifications-empty"><?php esc_html_e('No notifications received', 'wordfence') ?></li>
26
  <?php endif; ?>
27
  </ul>
28
  </div>
34
  <div class="wf-central-dashboard">
35
  <img class="wf-central-dashboard-logo" src="<?php echo wfUtils::getBaseURL() ?>images/wf-central-logo.svg" alt="Wordfence Central">
36
  <div class="wf-central-dashboard-copy">
37
+ <p><strong><?php esc_html_e('Wordfence Central Status', 'wordfence') ?></strong></p>
38
  <p><?php
39
  if ($d->wordfenceCentralConnected) {
40
+ echo esc_html(sprintf(
41
+ /* translators: 1. Email address. 2. Localized date. */
42
+ __('Connected by %1$s on %2$s', 'wordfence'), $d->wordfenceCentralConnectEmail, date_i18n(get_option('date_format'), $d->wordfenceCentralConnectTime)));
43
  } elseif ($d->wordfenceCentralDisconnected) {
44
+ echo esc_html(sprintf(
45
+ /* translators: 1. Email address. 2. Localized date. */
46
+ __('Disconnected by %1$s on %2$s', 'wordfence'), $d->wordfenceCentralDisconnectEmail, date_i18n(get_option('date_format'), $d->wordfenceCentralDisconnectTime)));
47
  } elseif (wfCentral::isPartialConnection()) {
48
  _e('It looks like you\'ve tried to connect this site to Wordfence Central, but the installation did not finish.', 'wordfence');
49
  } else {
55
  <p>
56
  <a href="<?php echo WORDFENCE_CENTRAL_URL_SEC ?>/sites/connection-issues?complete-setup=<?php echo esc_attr(wfConfig::get('wordfenceCentralSiteID')) ?>"
57
  class="wf-central-resume wf-btn wf-btn-sm wf-btn-primary"
58
+ ><?php esc_html_e('Resume Installation', 'wordfence') ?></a>
59
+ <a href="#" class="wf-central-disconnect wf-btn wf-btn-sm wf-btn-default"><strong><?php esc_html_e('Disconnect This Site', 'wordfence') ?></strong></a>
60
  </p>
61
  <?php else: ?>
62
  <p class="wf-flex-row-1">
63
  <?php if ($d->wordfenceCentralConnected): ?>
64
+ <a href="#" class="wf-central-disconnect"><strong><?php esc_html_e('Disconnect This Site', 'wordfence') ?></strong></a>
65
  <?php else: ?>
66
+ <a href="<?php echo WORDFENCE_CENTRAL_URL_SEC ?>?newsite=<?php echo esc_attr(home_url()) ?>"><strong><?php $d->wordfenceCentralDisconnected ? esc_html_e('Reconnect This Site', 'wordfence') : esc_html_e('Connect This Site', 'wordfence') ?></strong></a>
67
  <?php endif; ?>
68
  </p>
69
+ <p class="wf-flex-row-1 wf-right wf-nowrap"><a href="<?php echo esc_url(WORDFENCE_CENTRAL_URL_SEC) ?>" target="_blank" rel="noopener noreferrer"><strong><?php esc_html_e('Visit Wordfence Central', 'wordfence') ?></strong></a></p>
70
  <?php endif ?>
71
 
72
  </div>
135
  'secondaryButtons' => array(array('id' => 'wf-central-prompt-disconnect', 'label' => __('Disconnect', 'wordfence'), 'link' => '#')),
136
  ))->render();
137
  ?>
138
+ </script>
lib/dashboard/widget_tdf.php DELETED
@@ -1,53 +0,0 @@
1
- <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
- <div class="wf-row">
3
- <div class="wf-col-xs-12">
4
- <div class="wf-dashboard-item active">
5
- <div class="wf-dashboard-item-inner">
6
- <div class="wf-dashboard-item-content">
7
- <div class="wf-dashboard-item-title">
8
- <strong>Threat Defense Feed - Total Firewall Rules and Malware Signatures</strong>
9
- </div>
10
- <div class="wf-dashboard-item-action"><div class="wf-dashboard-item-action-disclosure"></div></div>
11
- </div>
12
- </div>
13
- <div class="wf-dashboard-item-extra">
14
- <ul class="wf-dashboard-item-list">
15
- <li>
16
- <?php if ($d->tdfCommunity === null): ?>
17
- <div class="wf-dashboard-item-list-text"><em>Threat Defense Feed statistics will be updated soon.</em></div>
18
- <?php else: ?>
19
- <ul class="wf-dashboard-item-list wf-dashboard-item-list-horizontal">
20
- <li>
21
- <div class="wf-dashboard-item-labeled-count">
22
- <div class="wf-dashboard-item-labeled-count-count"><?php echo $d->tdfCommunity; ?></div>
23
- <div class="wf-dashboard-item-labeled-count-label">Free Count</div>
24
- </div>
25
- </li>
26
- <li>
27
- <div class="wf-dashboard-item-labeled-count">
28
- <div class="wf-dashboard-item-labeled-count-count"><?php echo $d->tdfPremium; ?></div>
29
- <div class="wf-dashboard-item-labeled-count-label">Premium Count</div>
30
- </div>
31
- </li>
32
- </ul>
33
- <?php endif; ?>
34
- </li>
35
- <?php if (!wfConfig::get('isPaid')): ?>
36
- <li>
37
- <div class="wf-dashboard-item-list-text">
38
- <p>As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by an additional <?php echo ($d->tdfPremium - $d->tdfCommunity); ?> firewall rules and malware signatures. Upgrade to Premium today to improve your protection.</p>
39
- <p><a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/gnl1scanUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer">Upgrade to Premium</a></p>
40
- </div>
41
- </li>
42
- <?php else: ?>
43
- <li>
44
- <div class="wf-dashboard-item-list-text">
45
- <p>As a Premium user you receive updates to the Threat Defense Feed in real-time. You are currently protected by an additional <?php echo ($d->tdfPremium - $d->tdfCommunity); ?> firewall rules and malware signatures.</p>
46
- </div>
47
- </li>
48
- <?php endif; ?>
49
- </ul>
50
- </div>
51
- </div>
52
- </div>
53
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/dbview.php DELETED
@@ -1,32 +0,0 @@
1
- <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
- <?php if ( ! wfUtils::isAdmin() ) {
3
- exit();
4
- } ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
- <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
7
- <head>
8
- <title>Wordfence DB Table Viewer</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
10
- <link rel='stylesheet' id='wordfence-main-style-css'
11
- href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/phpinfo.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>'
12
- type='text/css' media='all'/>
13
- <body>
14
- <h1>Wordfence Database Table Viewer</h1>
15
- <p style="width: 400px;">This page is used for debugging and shows a list of database tables and their status on your system. Our staff may ask you to send them the
16
- data on this page as part of a troubleshooting process.</p>
17
- <?php
18
- $wfdb = new wfDB();
19
- $q = $wfdb->querySelect("show table status");
20
- foreach($q as $val){
21
- foreach($val as $tkey => $tval){
22
- echo '<span style="color: #999; font-style: italic;">' . $tkey . ':</span> ' . $tval . ' ';
23
- }
24
- echo '<br />-----------------------------------------------------------------------------------------<br />';
25
- }
26
-
27
- ?>
28
-
29
- <div class="diffFooter">&copy;&nbsp;2011 to <?php echo date('Y'); ?> Wordfence &mdash; Visit <a
30
- href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.</div>
31
- </body>
32
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/diffResult.php CHANGED
@@ -4,29 +4,29 @@
4
  <head>
5
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
  <link rel='stylesheet' id='wordfence-main-style-css' href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/diff.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>' type='text/css' media='all' />
 
7
  <body>
8
- <h1>Wordfence: Viewing File Differences</h1>
9
  <p style="width: 800px; font-size: 16px; font-family: Verdana;">
10
- The two panels below show a before and after view of a file on your system that has been modified.
11
- The left panel shows the original file before modification. The right panel shows your version
12
- of the file that has been modified.
13
- Use this view to determine if a file has been modified by an attacker or if this is a change
14
- that you or another trusted person made.
15
- If you are happy with the modifications you see here, then you should choose to
16
- ignore this file the next time Wordfence scans your system.
17
  </p>
18
  <table border="0" style="margin: 0 0 20px 0;" class="summary">
19
- <tr><td>Filename:</td><td><?php echo wp_kses($_GET['file'], array()); ?></td></tr>
20
- <tr><td>File type:</td><td><?php
21
  $cType = $_GET['cType'];
22
  if($cType == 'core'){
23
- echo "WordPress Core File</td></tr>";
24
  } else if($cType == 'theme'){
25
- echo "Theme File</td></tr><tr><td>Theme Name:</td><td>" . wp_kses($_GET['cName'], array()) . "</td></tr><tr><td>Theme Version:</td><td>" . wp_kses($_GET['cVersion'], array()) . "</td></tr>";
 
 
 
26
  } else if($cType == 'plugin'){
27
- echo "Plugin File</td></tr><tr><td>Plugin Name:</td><td>" . wp_kses($_GET['cName'], array()) . "</td></tr><tr><td>Plugin Version:</td><td>" . wp_kses($_GET['cVersion'], array()) . "</td></tr>";
 
 
28
  } else {
29
- echo "Unknown Type</td></tr>";
30
  }
31
  ?>
32
  </table>
@@ -35,12 +35,12 @@
35
  if($diffResult){
36
  echo $diffResult;
37
  } else {
38
- echo "<br />There are no differences between the original file and the file in the repository.";
39
  }
40
 
41
  ?>
42
 
43
 
44
- <div class="diffFooter">&copy;&nbsp;2011 to <?php echo date('Y'); ?> Wordfence &mdash; Visit <a href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.</div>
45
  </body>
46
- </html>
4
  <head>
5
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
  <link rel='stylesheet' id='wordfence-main-style-css' href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/diff.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>' type='text/css' media='all' />
7
+ </head>
8
  <body>
9
+ <h1><?php esc_html_e('Wordfence: Viewing File Differences', 'wordfence') ?></h1>
10
  <p style="width: 800px; font-size: 16px; font-family: Verdana;">
11
+ <?php esc_html_e('The two panels below show a before and after view of a file on your system that has been modified. The left panel shows the original file before modification. The right panel shows your version of the file that has been modified. Use this view to determine if a file has been modified by an attacker or if this is a change that you or another trusted person made. If you are happy with the modifications you see here, then you should choose to ignore this file the next time Wordfence scans your system.', 'wordfence') ?>
 
 
 
 
 
 
12
  </p>
13
  <table border="0" style="margin: 0 0 20px 0;" class="summary">
14
+ <tr><td><?php esc_html_e('Filename:', 'wordfence') ?></td><td><?php echo wp_kses($_GET['file'], array()); ?></td></tr>
15
+ <tr><td><?php esc_html_e('File type:', 'wordfence') ?></td><td><?php
16
  $cType = $_GET['cType'];
17
  if($cType == 'core'){
18
+ esc_html_e('WordPress Core File', 'wordfence') . "</td></tr>";
19
  } else if($cType == 'theme'){
20
+ echo esc_html__('Theme File', 'wordfence') . "</td></tr><tr><td>" .
21
+ esc_html__('Theme Name:', 'wordfence')
22
+ . "</td><td>" . wp_kses($_GET['cName'], array()) . "</td></tr><tr><td>" .
23
+ esc_html__('Theme Version:', 'wordfence') . "</td><td>" . wp_kses($_GET['cVersion'], array()) . "</td></tr>";
24
  } else if($cType == 'plugin'){
25
+ echo esc_html__('Plugin File', 'wordfence') . "</td></tr><tr><td>" .
26
+ esc_html__('Plugin Name:', 'wordfence') . "</td><td>" . wp_kses($_GET['cName'], array()) . "</td></tr><tr><td>" .
27
+ esc_html__('Plugin Version:', 'wordfence') . "</td><td>" . wp_kses($_GET['cVersion'], array()) . "</td></tr>";
28
  } else {
29
+ echo esc_html__('Unknown Type', 'wordfence') . "</td></tr>";
30
  }
31
  ?>
32
  </table>
35
  if($diffResult){
36
  echo $diffResult;
37
  } else {
38
+ echo "<br />" . esc_html__('There are no differences between the original file and the file in the repository.', 'wordfence');
39
  }
40
 
41
  ?>
42
 
43
 
44
+ <div class="diffFooter"><?php echo wp_kses(sprintf(__('&copy;&nbsp;%1$d to %2$d Wordfence &mdash; Visit <a href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.', 'wordfence'), date_i18n('Y', WORDFENCE_EPOCH), date_i18n('Y')), array('a'=>array('href'=>array()))) ?></div>
45
  </body>
46
+ </html>
lib/email_genericAlert.php CHANGED
@@ -1,13 +1,17 @@
1
  <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
- <?php printf(__('This email was sent from your website "%s" by the Wordfence plugin at %s', 'wordfence'), $blogName, $date); ?>
 
 
3
 
4
- <?php printf(__('The Wordfence administrative URL for this site is: %s', 'wordfence'), wfUtils::wpAdminURL('admin.php?page=Wordfence')); ?>
 
 
5
 
6
  <?php echo $alertMsg; ?>
7
  <?php if($IPMsg){ echo "\n$IPMsg\n"; } ?>
8
 
9
  <?php if(! $isPaid){ ?>
10
- <?php _e('NOTE: You are using the free version of Wordfence. Upgrade today:
11
  - Receive real-time Firewall and Scan engine rule updates for protection as threats emerge
12
  - Real-time IP Blocklist blocks the most malicious IPs from accessing your site
13
  - Country blocking
@@ -21,9 +25,12 @@ https://www.wordfence.com/zz1/wordfence-signup/', 'wordfence'); ?>
21
  <?php } ?>
22
 
23
  --
24
- <?php printf(__("To change your alert options for Wordfence, visit:\n%s", 'wordfence'), $myOptionsURL); ?>
25
-
26
- <?php printf(__("To see current Wordfence alerts, visit:\n%s", 'wordfence'), $myHomeURL); ?>
27
 
 
 
 
28
 
29
 
1
  <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
+ <?php printf(
3
+ /* translators: 1. Blog name/title. 2. Date. */
4
+ __('This email was sent from your website "%1$s" by the Wordfence plugin at %2$s', 'wordfence'), $blogName, $date); ?>
5
 
6
+ <?php printf(
7
+ /* translators: URL to the WordPress admin panel. */
8
+ __('The Wordfence administrative URL for this site is: %s', 'wordfence'), wfUtils::wpAdminURL('admin.php?page=Wordfence')); ?>
9
 
10
  <?php echo $alertMsg; ?>
11
  <?php if($IPMsg){ echo "\n$IPMsg\n"; } ?>
12
 
13
  <?php if(! $isPaid){ ?>
14
+ <?php esc_html_e('NOTE: You are using the free version of Wordfence. Upgrade today:
15
  - Receive real-time Firewall and Scan engine rule updates for protection as threats emerge
16
  - Real-time IP Blocklist blocks the most malicious IPs from accessing your site
17
  - Country blocking
25
  <?php } ?>
26
 
27
  --
28
+ <?php printf(
29
+ /* translators: URL to the WordPress admin panel. */
30
+ __("To change your alert options for Wordfence, visit:\n%s", 'wordfence'), $myOptionsURL); ?>
31
 
32
+ <?php printf(
33
+ /* translators: URL to the WordPress admin panel. */
34
+ __("To see current Wordfence alerts, visit:\n%s", 'wordfence'), $myHomeURL); ?>
35
 
36
 
lib/email_newIssues.php CHANGED
@@ -1,30 +1,59 @@
1
  <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
  <?php $scanOptions = $scanController->scanOptions(); ?>
3
- <p><?php printf(__('This email was sent from your website "%s" by the Wordfence plugin.', 'wordfence'), esc_html(get_bloginfo('name', 'raw'))); ?></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- <p><?php printf(__('Wordfence found the following new issues on "%s"%s.', 'wordfence'), esc_html(get_bloginfo('name', 'raw')), count($previousIssues) ? sprintf(__(' (%d existing %s also found again)', 'wordfence'), count($previousIssues), count($previousIssues) == 1 ? __('issue was', 'wordfence') : __('issues were', 'wordfence')) : ''); ?></p>
6
 
7
- <p><?php printf(__('Alert generated at %s', 'wordfence'), esc_html(wfUtils::localHumanDate())); ?></p>
 
 
8
 
9
  <br>
10
 
11
- <p><?php printf(__('See the details of these scan results on your site at: %s', 'wordfence'), wfUtils::wpAdminURL('admin.php?page=WordfenceScan')); ?></p>
 
 
12
 
13
  <?php if ($scanOptions['scansEnabled_highSense']): ?>
14
  <div style="margin: 12px 0;padding: 8px; background-color: #ffffe0; border: 1px solid #ffd975; border-width: 1px 1px 1px 10px;">
15
- <em><?php _e('HIGH SENSITIVITY scanning is enabled, it may produce false positives', 'wordfence'); ?></em>
16
  </div>
17
  <?php endif ?>
18
 
19
  <?php if (wfConfig::get('betaThreatDefenseFeed')): ?>
20
  <div style="margin: 12px 0;padding: 8px; background-color: #ffffe0; border: 1px solid #ffd975; border-width: 1px 1px 1px 10px;">
21
- <?php _e('Beta scan signatures are currently enabled. These signatures have not been fully tested yet and may cause false positives or scan stability issues on some sites.', 'wordfence'); echo ' '; _e('The Beta option can be turned off at the bottom of the Diagnostics page.', 'wordfence'); ?>
22
  </div>
23
  <?php endif; ?>
24
 
25
  <?php if ($timeLimitReached): ?>
26
  <div style="margin: 12px 0;padding: 8px; background-color: #ffffe0; border: 1px solid #ffd975; border-width: 1px 1px 1px 10px;">
27
- <em><?php printf(__('The scan was terminated early because it reached the time limit for scans. If you would like to allow your scans to run longer, you can customize the limit on the options page: <a href="%s">%s</a> or read more about scan options to improve scan speed here: <a href="%s">%s</a>', 'wordfence'), esc_attr(wfUtils::wpAdminURL('admin.php?page=WordfenceScan&subpage=scan_options#wf-scanner-options-performance')), esc_attr(wfUtils::wpAdminURL('admin.php?page=WordfenceScan&subpage=scan_options')), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_TIME_LIMIT), esc_html(wfSupportController::supportURL(wfSupportController::ITEM_SCAN_TIME_LIMIT))); ?></em>
 
 
28
  </div>
29
  <?php endif ?>
30
 
@@ -46,27 +75,27 @@ foreach ($severitySections as $severityLevel => $severityLabel):
46
 
47
  foreach($issues as $i){ if($i['severity'] == $severityLevel){ ?>
48
  <?php if (!$hasIssuesAtSeverity): $hasIssuesAtSeverity = true; ?>
49
- <p><?php echo $severityLabel ?></p>
50
  <?php endif ?>
51
  <p>* <?php echo htmlspecialchars($i['shortMsg']) ?></p>
52
  <?php
53
  if ((isset($i['tmplData']['wpRemoved']) && $i['tmplData']['wpRemoved']) || (isset($i['tmplData']['abandoned']) && $i['tmplData']['abandoned'])) {
54
  if (isset($i['tmplData']['vulnerable']) && $i['tmplData']['vulnerable']) {
55
- echo '<p><strong>' . __('Plugin contains an unpatched security vulnerability.', 'wordfence') . '</strong>';
56
  if (isset($i['tmplData']['vulnerabilityLink'])) {
57
- echo ' <a href="' . $i['tmplData']['vulnerabilityLink'] . '" target="_blank" rel="nofollow noreferrer noopener">' . __('Vulnerability Information', 'wordfence') . '</a>';
58
  }
59
  echo '</p>';
60
  }
61
  }
62
  if ($i['type'] == 'coreUnknown') {
63
- echo '<p>' . __('The core files scan has not run because this version is not currently indexed by Wordfence. New WordPress versions may take up to a day to be indexed.', 'wordfence') . '</p>';
64
  }
65
  else if ($i['type'] == 'wafStatus') {
66
- echo '<p>' . __('Firewall issues may be caused by file permission changes or other technical problems.', 'wordfence') . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_WAF_DISABLED) . '" target="_blank" rel="nofollow noreferrer noopener">' . __('More Details and Instructions', 'wordfence') . '</a></p>';
67
  }
68
  else if ($i['type'] == 'skippedPaths') {
69
- echo '<p>' . __('Scanning additional paths is optional and is not always necessary.', 'wordfence') . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_SKIPPED_PATHS) . '" target="_blank" rel="nofollow noreferrer noopener">' . __('Learn More', 'wordfence') . '</a></p>';
70
  }
71
 
72
  $showWPParagraph = !empty($i['tmplData']['vulnerable']) || isset($i['tmplData']['wpURL']);
@@ -74,9 +103,9 @@ foreach ($severitySections as $severityLevel => $severityLabel):
74
  echo '<p>';
75
  }
76
  if (!empty($i['tmplData']['vulnerable'])) {
77
- echo '<strong>' . __('Update includes security-related fixes.', 'wordfence') . '</strong>';
78
  if (isset($i['tmplData']['vulnerabilityLink'])) {
79
- echo ' <a href="' . $i['tmplData']['vulnerabilityLink'] . '" target="_blank" rel="nofollow noreferrer noopener">' . __('Vulnerability Information', 'wordfence') . '</a>';
80
  }
81
  }
82
  if (isset($i['tmplData']['wpURL'])) {
@@ -92,7 +121,7 @@ if (!empty($i['tmplData']['badURL'])):
92
  $api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
93
  $url = set_url_scheme($api->getTextImageURL($i['tmplData']['badURL']), 'https');
94
  ?>
95
- <p><img src="<?php echo esc_url($url) ?>" alt="The malicious URL matched" /></p>
96
  <?php endif ?>
97
 
98
  <?php } } ?>
@@ -101,11 +130,11 @@ if (!empty($i['tmplData']['badURL'])):
101
  <?php
102
  $sentences = array();
103
  if (count($previousIssues)) {
104
- $sentences[] = sprintf(count($previousIssues) == 1 ? __('%d existing issue was found again and is not shown.', 'wordfence') : __('%d existing issues were found again and are not shown.', 'wordfence'), count($previousIssues));
105
  }
106
  if ($issuesNotShown > 0) {
107
- $sentences[] = sprintf(($issuesNotShown == 1 ? __('%d issue was omitted from this email due to length limits.', 'wordfence') : __('%d issues were omitted from this email due to length limits.', 'wordfence')), $issuesNotShown);
108
- $sentences[] = __('View every issue:', 'wordfence') . sprintf(' <a href="%s">%s</a>', esc_attr(wfUtils::wpAdminURL('admin.php?page=WordfenceScan')), esc_html(wfUtils::wpAdminURL('admin.php?page=WordfenceScan')));
109
  }
110
 
111
  if (count($sentences)) {
@@ -114,21 +143,20 @@ if (count($sentences)) {
114
  ?>
115
 
116
  <?php if(! $isPaid){ ?>
117
- <p><?php _e('NOTE: You are using the free version of Wordfence. Upgrade today:', 'wordfence'); ?></p>
118
 
119
  <ul>
120
- <li><?php _e('Receive real-time Firewall and Scan engine rule updates for protection as threats emerge', 'wordfence'); ?></li>
121
- <li><?php _e('Real-time IP Blocklist blocks the most malicious IPs from accessing your site', 'wordfence'); ?></li>
122
- <li><?php _e('Country blocking', 'wordfence'); ?></li>
123
- <li><?php _e('IP reputation monitoring', 'wordfence'); ?></li>
124
- <li><?php _e('Schedule scans to run more frequently and at optimal times', 'wordfence'); ?></li>
125
- <li><?php _e('Access to Premium Support', 'wordfence'); ?></li>
126
- <li><?php _e('Discounts for multi-year and multi-license purchases', 'wordfence'); ?></li>
127
  </ul>
128
 
129
- <p><?php _e('Click here to upgrade to Wordfence Premium:', 'wordfence'); ?><br><a href="https://www.wordfence.com/zz2/wordfence-signup/">https://www.wordfence.com/zz2/wordfence-signup/</a></p>
130
  <?php } ?>
131
 
132
  <p><!-- ##UNSUBSCRIBE## --></p>
133
 
134
-
1
  <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
  <?php $scanOptions = $scanController->scanOptions(); ?>
3
+ <p><?php echo esc_html(sprintf(
4
+ /* translators: URL to the site's homepage. */
5
+ __('This email was sent from your website "%s" by the Wordfence plugin.', 'wordfence'), get_bloginfo('name', 'raw'))); ?></p>
6
+
7
+ <p><?php
8
+
9
+ if (count($previousIssues) > 0) {
10
+ printf(
11
+ /* translators: 1. URL to the site's homepage. 2. Number of scan results. */
12
+ _n('Wordfence found the following new issues on "%1$s" (%2$d existing issue was also found again).',
13
+ 'Wordfence found the following new issues on "%1$s" (%2$d existing issues were also found again).',
14
+ count($previousIssues),
15
+ 'wordfence'),
16
+ esc_html(get_bloginfo('name', 'raw')),
17
+ count($previousIssues)
18
+ );
19
+ } else {
20
+ echo esc_html(sprintf(
21
+ /* translators: 1. URL to the site's homepage. */
22
+ __('Wordfence found the following new issues on "%1$s".', 'wordfence'),
23
+ get_bloginfo('name', 'raw')
24
+ ));
25
+ }
26
+
27
 
28
+ ?></p>
29
 
30
+ <p><?php echo esc_html(sprintf(
31
+ /* translators: Localized date. */
32
+ __('Alert generated at %s', 'wordfence'), wfUtils::localHumanDate())); ?></p>
33
 
34
  <br>
35
 
36
+ <p><?php echo esc_html(sprintf(
37
+ /* translators: URL to WordPress admin panel. */
38
+ __('See the details of these scan results on your site at: %s', 'wordfence'), wfUtils::wpAdminURL('admin.php?page=WordfenceScan'))); ?></p>
39
 
40
  <?php if ($scanOptions['scansEnabled_highSense']): ?>
41
  <div style="margin: 12px 0;padding: 8px; background-color: #ffffe0; border: 1px solid #ffd975; border-width: 1px 1px 1px 10px;">
42
+ <em><?php esc_html_e('HIGH SENSITIVITY scanning is enabled, it may produce false positives', 'wordfence'); ?></em>
43
  </div>
44
  <?php endif ?>
45
 
46
  <?php if (wfConfig::get('betaThreatDefenseFeed')): ?>
47
  <div style="margin: 12px 0;padding: 8px; background-color: #ffffe0; border: 1px solid #ffd975; border-width: 1px 1px 1px 10px;">
48
+ <?php esc_html_e('Beta scan signatures are currently enabled. These signatures have not been fully tested yet and may cause false positives or scan stability issues on some sites.', 'wordfence'); echo ' '; esc_html_e('The Beta option can be turned off at the bottom of the Diagnostics page.', 'wordfence'); ?>
49
  </div>
50
  <?php endif; ?>
51
 
52
  <?php if ($timeLimitReached): ?>
53
  <div style="margin: 12px 0;padding: 8px; background-color: #ffffe0; border: 1px solid #ffd975; border-width: 1px 1px 1px 10px;">
54
+ <em><?php echo wp_kses(sprintf(
55
+ /* translators: 1. URL to WordPress admin panel. 2. URL to WordPress admin panel. 3. URL to Wordfence support page. 4. URL to Wordfence support page. */
56
+ __('The scan was terminated early because it reached the time limit for scans. If you would like to allow your scans to run longer, you can customize the limit on the options page: <a href="%1$s">%2$s</a> or read more about scan options to improve scan speed here: <a href="%3$s">%4$s</a>', 'wordfence'), esc_attr(wfUtils::wpAdminURL('admin.php?page=WordfenceScan&subpage=scan_options#wf-scanner-options-performance')), esc_attr(wfUtils::wpAdminURL('admin.php?page=WordfenceScan&subpage=scan_options')), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_TIME_LIMIT), esc_html(wfSupportController::supportURL(wfSupportController::ITEM_SCAN_TIME_LIMIT))), array('a'=>array('href'=>array()))); ?></em>
57
  </div>
58
  <?php endif ?>
59
 
75
 
76
  foreach($issues as $i){ if($i['severity'] == $severityLevel){ ?>
77
  <?php if (!$hasIssuesAtSeverity): $hasIssuesAtSeverity = true; ?>
78
+ <p><?php echo esc_html($severityLabel) ?></p>
79
  <?php endif ?>
80
  <p>* <?php echo htmlspecialchars($i['shortMsg']) ?></p>
81
  <?php
82
  if ((isset($i['tmplData']['wpRemoved']) && $i['tmplData']['wpRemoved']) || (isset($i['tmplData']['abandoned']) && $i['tmplData']['abandoned'])) {
83
  if (isset($i['tmplData']['vulnerable']) && $i['tmplData']['vulnerable']) {
84
+ echo '<p><strong>' . esc_html__('Plugin contains an unpatched security vulnerability.', 'wordfence') . '</strong>';
85
  if (isset($i['tmplData']['vulnerabilityLink'])) {
86
+ echo ' <a href="' . $i['tmplData']['vulnerabilityLink'] . '" target="_blank" rel="nofollow noreferrer noopener">' . esc_html__('Vulnerability Information', 'wordfence') . '</a>';
87
  }
88
  echo '</p>';
89
  }
90
  }
91
  if ($i['type'] == 'coreUnknown') {
92
+ echo '<p>' . esc_html__('The core files scan has not run because this version is not currently indexed by Wordfence. New WordPress versions may take up to a day to be indexed.', 'wordfence') . '</p>';
93
  }
94
  else if ($i['type'] == 'wafStatus') {
95
+ echo '<p>' . esc_html__('Firewall issues may be caused by file permission changes or other technical problems.', 'wordfence') . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_WAF_DISABLED) . '" target="_blank" rel="nofollow noreferrer noopener">' . esc_html__('More Details and Instructions', 'wordfence') . '</a></p>';
96
  }
97
  else if ($i['type'] == 'skippedPaths') {
98
+ echo '<p>' . esc_html__('Scanning additional paths is optional and is not always necessary.', 'wordfence') . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_SKIPPED_PATHS) . '" target="_blank" rel="nofollow noreferrer noopener">' . esc_html__('Learn More', 'wordfence') . '</a></p>';
99
  }
100
 
101
  $showWPParagraph = !empty($i['tmplData']['vulnerable']) || isset($i['tmplData']['wpURL']);
103
  echo '<p>';
104
  }
105
  if (!empty($i['tmplData']['vulnerable'])) {
106
+ echo '<strong>' . esc_html__('Update includes security-related fixes.', 'wordfence') . '</strong>';
107
  if (isset($i['tmplData']['vulnerabilityLink'])) {
108
+ echo ' <a href="' . $i['tmplData']['vulnerabilityLink'] . '" target="_blank" rel="nofollow noreferrer noopener">' . esc_html__('Vulnerability Information', 'wordfence') . '</a>';
109
  }
110
  }
111
  if (isset($i['tmplData']['wpURL'])) {
121
  $api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
122
  $url = set_url_scheme($api->getTextImageURL($i['tmplData']['badURL']), 'https');
123
  ?>
124
+ <p><img src="<?php echo esc_url($url) ?>" alt="<?php esc_html_e('The malicious URL matched', 'wordfence') ?>" /></p>
125
  <?php endif ?>
126
 
127
  <?php } } ?>
130
  <?php
131
  $sentences = array();
132
  if (count($previousIssues)) {
133
+ $sentences[] = sprintf(/* translators: Number of scan results */_n('%d existing issue was found again and is not shown.', '%d existing issues were found again and are not shown.', count($previousIssues), 'wordfence'), count($previousIssues));
134
  }
135
  if ($issuesNotShown > 0) {
136
+ $sentences[] = sprintf(/* translators: Number of scan results */ _n('%d issue was omitted from this email due to length limits.', '%d issues were omitted from this email due to length limits.', $issuesNotShown, 'wordfence'), $issuesNotShown);
137
+ $sentences[] = esc_html__('View every issue:', 'wordfence') . sprintf(' <a href="%s">%s</a>', esc_attr(wfUtils::wpAdminURL('admin.php?page=WordfenceScan')), esc_html(wfUtils::wpAdminURL('admin.php?page=WordfenceScan')));
138
  }
139
 
140
  if (count($sentences)) {
143
  ?>
144
 
145
  <?php if(! $isPaid){ ?>
146
+ <p><?php esc_html_e('NOTE: You are using the free version of Wordfence. Upgrade today:', 'wordfence'); ?></p>
147
 
148
  <ul>
149
+ <li><?php esc_html_e('Receive real-time Firewall and Scan engine rule updates for protection as threats emerge', 'wordfence'); ?></li>
150
+ <li><?php esc_html_e('Real-time IP Blocklist blocks the most malicious IPs from accessing your site', 'wordfence'); ?></li>
151
+ <li><?php esc_html_e('Country blocking', 'wordfence'); ?></li>
152
+ <li><?php esc_html_e('IP reputation monitoring', 'wordfence'); ?></li>
153
+ <li><?php esc_html_e('Schedule scans to run more frequently and at optimal times', 'wordfence'); ?></li>
154
+ <li><?php esc_html_e('Access to Premium Support', 'wordfence'); ?></li>
155
+ <li><?php esc_html_e('Discounts for multi-year and multi-license purchases', 'wordfence'); ?></li>
156
  </ul>
157
 
158
+ <p><?php esc_html_e('Click here to upgrade to Wordfence Premium:', 'wordfence'); ?><br><a href="https://www.wordfence.com/zz2/wordfence-signup/">https://www.wordfence.com/zz2/wordfence-signup/</a></p>
159
  <?php } ?>
160
 
161
  <p><!-- ##UNSUBSCRIBE## --></p>
162
 
 
lib/email_unlockRequest.php CHANGED
@@ -1,18 +1,22 @@
1
  <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
- <?php printf(__('Either you or someone else at IP address <b>%s</b> requested instructions to regain access to the website <a href="%s"><b>%s</b></a>.', 'wordfence'), esc_html($IP), esc_attr(wfUtils::getSiteBaseURL()), esc_html($siteName)); ?>
 
 
3
  <br><br>
4
- <?php printf(__('Request was generated at: %s', 'wordfence'), wfUtils::localHumanDate()); ?>
 
 
5
  <br><br>
6
- <?php _e('If you did not request these instructions then you can safely ignore them.', 'wordfence'); ?><br>
7
- <?php _e('These instructions <b>will be valid for 30 minutes</b> from the time they were sent.', 'wordfence'); ?>
8
  <ul>
9
  <li>
10
- <a href="<?php echo $unlockHref; ?>&func=unlockMyIP"><?php _e('Click here to unlock your ability to sign-in and to access to the site.', 'wordfence'); ?></a> <?php _e('Do this if you simply need to regain access because you were accidentally locked out. If you received an "Insecure Password" message before getting locked out, you may also need to reset your password.', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD); ?>"><?php _e('Learn More', 'wordfence'); ?></a>
11
  </li>
12
  <li>
13
- <a href="<?php echo $unlockHref; ?>&func=unlockAllIPs"><?php _e('Click here to unblock all IP addresses.', 'wordfence'); ?></a> <?php _e('Do this if you still can\'t regain access using the link above. It causes everyone who is blocked or locked out to be able to access your site again.', 'wordfence'); ?>
14
  </li>
15
  <li>
16
- <a href="<?php echo $unlockHref; ?>&func=disableRules"><?php _e('Click here to unlock all IP addresses and disable the Wordfence Firewall and Wordfence login security for all users', 'wordfence'); ?></a>. <?php _e('Do this if you keep getting locked out or blocked and can\'t access your site. You can re-enable login security and the firewall once you sign-in to the site by visiting the Wordfence Firewall menu, clicking and then turning on the firewall and login security options. If you use country blocking, you will also need to choose which countries to block.', 'wordfence'); ?>
17
  </li>
18
- </ul>
1
  <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
+ <?php echo wp_kses(sprintf(
3
+ /* translators: 1. IP address. 2. Site URL. 3. Site name. */
4
+ __('Either you or someone else at IP address <b>%1$s</b> requested instructions to regain access to the website <a href="%2$s"><b>%3$s</b></a>.', 'wordfence'), esc_html($IP), esc_attr(wfUtils::getSiteBaseURL()), esc_html($siteName)), array('a'=>array('href'=>array()), 'b'=>array())); ?>
5
  <br><br>
6
+ <?php printf(
7
+ /* translators: Localized date. */
8
+ __('Request was generated at: %s', 'wordfence'), wfUtils::localHumanDate()); ?>
9
  <br><br>
10
+ <?php esc_html_e('If you did not request these instructions then you can safely ignore them.', 'wordfence'); ?><br>
11
+ <?php echo wp_kses(__('These instructions <b>will be valid for 30 minutes</b> from the time they were sent.', 'wordfence'), array('b'=>array())); ?>
12
  <ul>
13
  <li>
14
+ <a href="<?php echo $unlockHref; ?>&func=unlockMyIP"><?php esc_html_e('Click here to unlock your ability to sign-in and to access to the site.', 'wordfence'); ?></a> <?php esc_html_e('Do this if you simply need to regain access because you were accidentally locked out. If you received an "Insecure Password" message before getting locked out, you may also need to reset your password.', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD); ?>"><?php esc_html_e('Learn More', 'wordfence'); ?></a>
15
  </li>
16
  <li>
17
+ <a href="<?php echo $unlockHref; ?>&func=unlockAllIPs"><?php esc_html_e('Click here to unblock all IP addresses.', 'wordfence'); ?></a> <?php esc_html_e('Do this if you still can\'t regain access using the link above. It causes everyone who is blocked or locked out to be able to access your site again.', 'wordfence'); ?>
18
  </li>
19
  <li>
20
+ <a href="<?php echo $unlockHref; ?>&func=disableRules"><?php esc_html_e('Click here to unlock all IP addresses and disable the Wordfence Firewall and Wordfence login security for all users', 'wordfence'); ?></a>. <?php esc_html_e('Do this if you keep getting locked out or blocked and can\'t access your site. You can re-enable login security and the firewall once you sign-in to the site by visiting the Wordfence Firewall menu, clicking and then turning on the firewall and login security options. If you use country blocking, you will also need to choose which countries to block.', 'wordfence'); ?>
21
  </li>
22
+ </ul>
lib/email_unsubscribeRequest.php CHANGED
@@ -1,8 +1,14 @@
1
  <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
- <?php printf(__('Either you or someone at IP address <b>%s</b> requested an alert unsubscribe link for the website <a href="%s"><b>%s</b></a>.', 'wordfence'), esc_html($IP), esc_attr($siteURL), esc_html($siteName)); ?>
 
 
3
  <br><br>
4
- <?php printf(__('Request was generated at: %s', 'wordfence'), wfUtils::localHumanDate()); ?>
 
 
5
  <br><br>
6
- <?php _e('If you did not request this, you can safely ignore it.', 'wordfence'); ?>
7
  <br><br>
8
- <?php printf(__('<a href="%s" target="_blank">Click here</a> to stop receiving security alerts.', 'wordfence'), wfUtils::getSiteBaseURL() . '?_wfsf=removeAlertEmail&jwt=' . $jwt); ?>
 
 
1
  <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
+ <?php echo wp_kses(sprintf(
3
+ /* translators: 1. IP address. 2. Site URL. 3. Site name. */
4
+ __('Either you or someone at IP address <b>%1$s</b> requested an alert unsubscribe link for the website <a href="%2$s"><b>%3$s</b></a>.', 'wordfence'), esc_html($IP), esc_attr($siteURL), esc_html($siteName)), array('a'=>array('href'=>array()), 'b'=>array())); ?>
5
  <br><br>
6
+ <?php echo esc_html(sprintf(
7
+ /* translators: Localized date. */
8
+ __('Request was generated at: %s', 'wordfence'), wfUtils::localHumanDate())); ?>
9
  <br><br>
10
+ <?php esc_html_e('If you did not request this, you can safely ignore it.', 'wordfence'); ?>
11
  <br><br>
12
+ <?php echo wp_kses(sprintf(
13
+ /* translators: URL to WordPress admin panel. */
14
+ __('<a href="%s" target="_blank">Click here</a> to stop receiving security alerts.', 'wordfence'), wfUtils::getSiteBaseURL() . '?_wfsf=removeAlertEmail&jwt=' . $jwt), array('a'=>array('href'=>array(), 'target'=>array()))); ?>
lib/live_activity.php CHANGED
@@ -2,11 +2,11 @@
2
  <div class="wf-live-activity" data-mode="auto">
3
  <div class="wf-live-activity-inner">
4
  <div class="wf-live-activity-content">
5
- <div class="wf-live-activity-title">Wordfence Live Activity:</div>
6
  <div class="wf-live-activity-message"></div>
7
  </div>
8
  <?php if (wfConfig::get('liveActivityPauseEnabled')): ?>
9
- <div class="wf-live-activity-state"><p>Live Updates Paused &mdash; Click inside window to resume</p></div>
10
  <?php endif; ?>
11
  </div>
12
  </div>
2
  <div class="wf-live-activity" data-mode="auto">
3
  <div class="wf-live-activity-inner">
4
  <div class="wf-live-activity-content">
5
+ <div class="wf-live-activity-title"><?php esc_html_e('Wordfence Live Activity:', 'wordfence') ?></div>
6
  <div class="wf-live-activity-message"></div>
7
  </div>
8
  <?php if (wfConfig::get('liveActivityPauseEnabled')): ?>
9
+ <div class="wf-live-activity-state"><p><?php esc_html_e('Live Updates Paused &mdash; Click inside window to resume') ?></p></div>
10
  <?php endif; ?>
11
  </div>
12
  </div>
lib/menu_dashboard.php CHANGED
@@ -23,7 +23,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
23
  echo wfView::create('common/section-title', array(
24
  'title' => __('Wordfence Dashboard', 'wordfence'),
25
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_DASHBOARD),
26
- 'helpLabelHTML' => __('Learn more<span class="wf-hidden-xs"> about the Dashboard</span>', 'wordfence'),
27
  'showIcon' => true,
28
  ))->render();
29
  ?>
@@ -101,11 +101,21 @@ else if (wfConfig::get('touppPromptNeeded')) {
101
  'linkNewWindow' => true,
102
  ))->render();
103
  ?>
 
 
 
 
 
 
 
 
 
 
104
  <?php elseif (wfConfig::get('keyType') == wfAPI::KEY_TYPE_FREE || wfConfig::get('keyType') === false): ?>
105
  <div>
106
- <p><h3><?php _e('Premium Protection Disabled', 'wordfence'); ?></h3></p>
107
- <p><?php printf(__('As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by an additional %d firewall rules and malware signatures. Upgrade to Premium today to improve your protection.', 'wordfence'), ($d->tdfPremium - $d->tdfCommunity)); ?></p>
108
- <p><a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="https://www.wordfence.com/gnl1dashboardUpgrade/wordfence-signup/#premium-order-form" target="_blank" rel="noopener noreferrer"><?php _e('Upgrade to Premium', 'wordfence'); ?></a>&nbsp;&nbsp;<a class="wf-btn wf-btn-callout-subtle wf-btn-default" href="https://www.wordfence.com/gnl1dashboardLearn/wordfence-signup/" target="_blank" rel="noopener noreferrer"><?php _e('Learn More', 'wordfence'); ?></a></p>
109
  </div>
110
  <?php elseif (wfConfig::get('keyExpDays') < 30 && (wfConfig::get('premiumAutoRenew', null) === '0' || wfConfig::get('premiumAutoRenew', null) === 0)): ?>
111
  <?php
@@ -136,19 +146,21 @@ else if (wfConfig::get('touppPromptNeeded')) {
136
  if (isset($title)) {
137
  $days = floor(((int) wfConfig::get('premiumNextRenew') - time()) / 86400);
138
  if ($days <= 0) {
139
- $days = __('today', 'wordfence');
140
  }
141
  else if ($days == 1) {
142
- $days = __('tomorrow', 'wordfence');
143
  }
144
  else {
145
- $days = sprintf(__('in %d days', 'wordfence'), $days);
 
 
146
  }
147
 
148
  echo wfView::create('dashboard/status-payment-expiring', array(
149
  'id' => 'wf-premium-alert',
150
  'title' => $title,
151
- 'subtitle' => sprintf(__('License renews %s', 'wordfence'), $days),
152
  'link' => 'https://www.wordfence.com/gnl1renewExpiring/manage-wordfence-api-keys/',
153
  'linkLabel' => __('Update Payment Method', 'wordfence'),
154
  'linkNewWindow' => true,
@@ -157,19 +169,19 @@ else if (wfConfig::get('touppPromptNeeded')) {
157
  else {
158
  $days = floor(((int) wfConfig::get('premiumNextRenew') - time()) / 86400);
159
  if ($days == 0) {
160
- $days = __('today', 'wordfence');
161
  }
162
  else if ($days == 1) {
163
- $days = __('in 1 day', 'wordfence');
164
  }
165
  else {
166
- $days = sprintf(__('in %d days', 'wordfence'), $days);
167
  }
168
 
169
  echo wfView::create('dashboard/status-renewing', array(
170
  'id' => 'wf-premium-alert',
171
  'title' => __('Premium License Expiring', 'wordfence'),
172
- 'subtitle' => sprintf(__('License renews %s', 'wordfence'), $days),
173
  'link' => 'https://www.wordfence.com/gnl1reviewExpiring/manage-wordfence-api-keys/',
174
  'linkLabel' => __('Review Payment Method', 'wordfence'),
175
  'linkNewWindow' => true,
@@ -179,7 +191,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
179
  <?php elseif (wfConfig::get('keyType') == wfAPI::KEY_TYPE_PAID_CURRENT): ?>
180
  <div class="wf-block-labeled-value wf-protection-status wf-protection-status-<?php echo esc_attr($firewall->ruleMode()); ?>">
181
  <div class="wf-block-labeled-value-value"><i class="wf-fa wf-fa-check" aria-hidden="true"></i></div>
182
- <div class="wf-block-labeled-value-label"><?php _e('Wordfence Premium Enabled', 'wordfence'); ?></div>
183
  </div>
184
  <?php endif; ?>
185
  </li>
@@ -279,48 +291,48 @@ else if (wfConfig::get('touppPromptNeeded')) {
279
 
280
  <script type="text/x-jquery-template" id="wfNewTour1">
281
  <div>
282
- <h3><?php _e('This is your Dashboard', 'wordfence'); ?></h3>
283
- <p><?php _e('The Wordfence Dashboard provides valuable insights into the current state of your site\'s security. You\'ll find useful data summarized here as well as important status updates and notifications.', 'wordfence'); ?></p>
284
  <div class="wf-pointer-footer">
285
  <ul class="wf-tour-pagination">
286
  <li class="wf-active">&bullet;</li>
287
  <li>&bullet;</li>
288
  <li>&bullet;</li>
289
  </ul>
290
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
291
  </div>
292
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
293
  </div>
294
  </script>
295
  <script type="text/x-jquery-template" id="wfNewTour2">
296
  <div>
297
- <h3><?php _e('Easily Monitor Your Wordfence Protection', 'wordfence'); ?></h3>
298
- <p><?php _e('Each feature contains a status that reminds you what\'s enabled, disabled or needs attention. The Notifications section will highlight actions you need to take.', 'wordfence'); ?></p>
299
  <div class="wf-pointer-footer">
300
  <ul class="wf-tour-pagination">
301
  <li>&bullet;</li>
302
  <li class="wf-active">&bullet;</li>
303
  <li>&bullet;</li>
304
  </ul>
305
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
306
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
307
  </div>
308
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
309
  </div>
310
  </script>
311
  <script type="text/x-jquery-template" id="wfNewTour3">
312
  <div>
313
- <h3><?php _e('Global Wordfence Options', 'wordfence'); ?></h3>
314
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
315
- <p><?php _e('You\'ll find this icon throughout the plugin. Clicking it will show you the options and features for each section of Wordfence. From the dashboard, you can find the <strong>Global Options</strong> for Wordfence such as alerts, automatic updates, and managing your site\'s Premium License.', 'wordfence'); ?></p>
316
  <div class="wf-pointer-footer">
317
  <ul class="wf-tour-pagination">
318
  <li>&bullet;</li>
319
  <li>&bullet;</li>
320
  <li class="wf-active">&bullet;</li>
321
  </ul>
322
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
323
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Got it', 'wordfence'); ?></a></div>
324
  </div>
325
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
326
  </div>
@@ -354,9 +366,11 @@ else if (wfConfig::get('touppPromptNeeded')) {
354
 
355
  <script type="text/x-jquery-template" id="wfUpgradeTour1">
356
  <div>
357
- <h3><?php printf(__('You have successfully updated to Wordfence %s', 'wordfence'), WORDFENCE_VERSION); ?></h3>
358
- <p><?php _e('This update includes a number of significant interface changes. We\'d like to walk you through some of them, but you can bypass the tour for a section at any time by closing the dialogs.', 'wordfence'); ?></p>
359
- <p><?php _e('We welcome your feedback and comments at <a href="mailto:feedback@wordfence.com">feedback@wordfence.com</a>. For a deeper dive on all of the changes, <a href="https://www.wordfence.com/blog/2018/01/introducing-wordfence-7/" target="_blank" rel="noopener noreferrer">click here</a>.', 'wordfence'); ?></p>
 
 
360
  <div class="wf-pointer-footer">
361
  <ul class="wf-tour-pagination">
362
  <li class="wf-active">&bullet;</li>
@@ -364,15 +378,15 @@ else if (wfConfig::get('touppPromptNeeded')) {
364
  <li>&bullet;</li>
365
  <li>&bullet;</li>
366
  </ul>
367
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
368
  </div>
369
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
370
  </div>
371
  </script>
372
  <script type="text/x-jquery-template" id="wfUpgradeTour2">
373
  <div>
374
- <h3><?php _e('Monitor Your Wordfence Protection', 'wordfence'); ?></h3>
375
- <p><?php _e('Each feature contains a status percentage reminding you at a high level of what\'s enabled, disabled, or needing your attention. The Notifications section highlights actions you need to take.', 'wordfence'); ?></p>
376
  <div class="wf-pointer-footer">
377
  <ul class="wf-tour-pagination">
378
  <li>&bullet;</li>
@@ -380,17 +394,17 @@ else if (wfConfig::get('touppPromptNeeded')) {
380
  <li>&bullet;</li>
381
  <li>&bullet;</li>
382
  </ul>
383
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
384
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
385
  </div>
386
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
387
  </div>
388
  </script>
389
  <script type="text/x-jquery-template" id="wfUpgradeTour3">
390
  <div>
391
- <h3><?php _e('Global Wordfence Options', 'wordfence'); ?></h3>
392
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
393
- <p><?php _e('Manage your Wordfence license, see alerts and automatic plugin updates, and import/export your settings.', 'wordfence'); ?></p>
394
  <div class="wf-pointer-footer">
395
  <ul class="wf-tour-pagination">
396
  <li>&bullet;</li>
@@ -398,16 +412,16 @@ else if (wfConfig::get('touppPromptNeeded')) {
398
  <li class="wf-active">&bullet;</li>
399
  <li>&bullet;</li>
400
  </ul>
401
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
402
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
403
  </div>
404
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
405
  </div>
406
  </script>
407
  <script type="text/x-jquery-template" id="wfUpgradeTour4">
408
  <div>
409
- <h3><?php _e('Updated Navigation', 'wordfence'); ?></h3>
410
- <p><?php _e('The main navigation no longer includes an <strong>Options</strong> link. Options are now accessed via the <strong>Options</strong> link on each feature\'s main page. Live Traffic is now located in the Tools section, and blocking is found under the Firewall. Shortcuts to add a <strong>Blocking</strong> link back to the main navigation are available under Blocking options.', 'wordfence'); ?></p>
411
  <div class="wf-pointer-footer">
412
  <ul class="wf-tour-pagination">
413
  <li>&bullet;</li>
@@ -415,8 +429,8 @@ else if (wfConfig::get('touppPromptNeeded')) {
415
  <li>&bullet;</li>
416
  <li class="wf-active">&bullet;</li>
417
  </ul>
418
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
419
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Got it', 'wordfence'); ?></a></div>
420
  </div>
421
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
422
  </div>
@@ -457,7 +471,7 @@ if ($recordAll && !$hostSetting && !wfUtils::truthyToBoolean(wfConfig::get('swit
457
  <?php
458
  echo wfView::create('common/modal-prompt', array(
459
  'title' => __('Recommended Settings Change', 'wordfence'),
460
- 'messageHTML' => '<p>' . __('Greetings! The default configuration for Wordfence Live Traffic has changed. The new default saves only logins and blocked requests, while this site is currently recording all traffic. Would you like to change to the new default?', 'wordfence') . '</p>' . (!wfRateLimit::identicalHumanBotRateLimits() ? '<p>' . __('Rate limiting based on type of request (human vs crawler) may be less accurate because this prevents loading the extra JavaScript used for that identification.', 'wordfence') . '</p>' : ''),
461
  'primaryButton' => array('id' => 'wf-livetrafficmigrate-yes', 'label' => __('Yes Please', 'wordfence'), 'link' => '#', 'type' => 'wf-btn-primary'),
462
  'secondaryButtons' => array(
463
  array('id' => 'wf-livetrafficmigrate-no', 'label' => __('No Thanks', 'wordfence'), 'link' => '#', 'type' => 'wf-btn-default'),
@@ -466,4 +480,4 @@ if ($recordAll && !$hostSetting && !wfUtils::truthyToBoolean(wfConfig::get('swit
466
  ))->render();
467
  ?>
468
  </script>
469
- <?php endif; ?>
23
  echo wfView::create('common/section-title', array(
24
  'title' => __('Wordfence Dashboard', 'wordfence'),
25
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_DASHBOARD),
26
+ 'helpLabelHTML' => wp_kses(__('Learn more<span class="wf-hidden-xs"> about the Dashboard</span>', 'wordfence'), array('span'=>array('class'=>array()))),
27
  'showIcon' => true,
28
  ))->render();
29
  ?>
101
  'linkNewWindow' => true,
102
  ))->render();
103
  ?>
104
+ <?php elseif (wfConfig::get('keyType') == wfAPI::KEY_TYPE_PAID_DELETED): ?>
105
+ <?php
106
+ echo wfView::create('common/status-critical', array(
107
+ 'id' => 'wf-premium-alert',
108
+ 'title' => __('Premium Protection Disabled', 'wordfence'),
109
+ 'subtitleHtml' => wp_kses(__('The license you were using has been removed from your account. Please reach out to <a href="mailto:billing@wordfence.com">billing@wordfence.com</a> or create a Premium support case at <a href="https://support.wordfence.com/support/tickets" target="_blank">https://support.wordfence.com/support/tickets</a> for more information. Our staff is happy to help.', 'wordfence'), array('a'=>array('href'=>array(), 'target'=>array()))),
110
+ 'link' => null,
111
+ 'linkLabel' => null
112
+ ))->render();
113
+ ?>
114
  <?php elseif (wfConfig::get('keyType') == wfAPI::KEY_TYPE_FREE || wfConfig::get('keyType') === false): ?>
115
  <div>
116
+ <p><h3><?php esc_html_e('Premium Protection Disabled', 'wordfence'); ?></h3></p>
117
+ <p><?php esc_html_e('As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by additional firewall rules and malware signatures. Upgrade to Premium today to improve your protection.', 'wordfence'); ?></p>
118
+ <p><a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="https://www.wordfence.com/gnl1dashboardUpgrade/wordfence-signup/#premium-order-form" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Upgrade to Premium', 'wordfence'); ?></a>&nbsp;&nbsp;<a class="wf-btn wf-btn-callout-subtle wf-btn-default" href="https://www.wordfence.com/gnl1dashboardLearn/wordfence-signup/" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Learn More', 'wordfence'); ?></a></p>
119
  </div>
120
  <?php elseif (wfConfig::get('keyExpDays') < 30 && (wfConfig::get('premiumAutoRenew', null) === '0' || wfConfig::get('premiumAutoRenew', null) === 0)): ?>
121
  <?php
146
  if (isset($title)) {
147
  $days = floor(((int) wfConfig::get('premiumNextRenew') - time()) / 86400);
148
  if ($days <= 0) {
149
+ $subtitle = __('License renews today', 'wordfence');
150
  }
151
  else if ($days == 1) {
152
+ $subtitle = __('License renews tomorrow', 'wordfence');
153
  }
154
  else {
155
+ $subtitle = sprintf(
156
+ /* translators: Number of days */
157
+ __('License renews in %d days', 'wordfence'), $days);
158
  }
159
 
160
  echo wfView::create('dashboard/status-payment-expiring', array(
161
  'id' => 'wf-premium-alert',
162
  'title' => $title,
163
+ 'subtitle' => $subtitle,
164
  'link' => 'https://www.wordfence.com/gnl1renewExpiring/manage-wordfence-api-keys/',
165
  'linkLabel' => __('Update Payment Method', 'wordfence'),
166
  'linkNewWindow' => true,
169
  else {
170
  $days = floor(((int) wfConfig::get('premiumNextRenew') - time()) / 86400);
171
  if ($days == 0) {
172
+ $subtitle = __('License renews today', 'wordfence');
173
  }
174
  else if ($days == 1) {
175
+ $subtitle = __('License renews in 1 day', 'wordfence');
176
  }
177
  else {
178
+ $subtitle = sprintf(__('License renews in %d days', 'wordfence'), $days);
179
  }
180
 
181
  echo wfView::create('dashboard/status-renewing', array(
182
  'id' => 'wf-premium-alert',
183
  'title' => __('Premium License Expiring', 'wordfence'),
184
+ 'subtitle' => $subtitle,
185
  'link' => 'https://www.wordfence.com/gnl1reviewExpiring/manage-wordfence-api-keys/',
186
  'linkLabel' => __('Review Payment Method', 'wordfence'),
187
  'linkNewWindow' => true,
191
  <?php elseif (wfConfig::get('keyType') == wfAPI::KEY_TYPE_PAID_CURRENT): ?>
192
  <div class="wf-block-labeled-value wf-protection-status wf-protection-status-<?php echo esc_attr($firewall->ruleMode()); ?>">
193
  <div class="wf-block-labeled-value-value"><i class="wf-fa wf-fa-check" aria-hidden="true"></i></div>
194
+ <div class="wf-block-labeled-value-label"><?php esc_html_e('Wordfence Premium Enabled', 'wordfence'); ?></div>
195
  </div>
196
  <?php endif; ?>
197
  </li>
291
 
292
  <script type="text/x-jquery-template" id="wfNewTour1">
293
  <div>
294
+ <h3><?php esc_html_e('This is your Dashboard', 'wordfence'); ?></h3>
295
+ <p><?php esc_html_e('The Wordfence Dashboard provides valuable insights into the current state of your site\'s security. You\'ll find useful data summarized here as well as important status updates and notifications.', 'wordfence'); ?></p>
296
  <div class="wf-pointer-footer">
297
  <ul class="wf-tour-pagination">
298
  <li class="wf-active">&bullet;</li>
299
  <li>&bullet;</li>
300
  <li>&bullet;</li>
301
  </ul>
302
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
303
  </div>
304
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
305
  </div>
306
  </script>
307
  <script type="text/x-jquery-template" id="wfNewTour2">
308
  <div>
309
+ <h3><?php esc_html_e('Easily Monitor Your Wordfence Protection', 'wordfence'); ?></h3>
310
+ <p><?php esc_html_e('Each feature contains a status that reminds you what\'s enabled, disabled or needs attention. The Notifications section will highlight actions you need to take.', 'wordfence'); ?></p>
311
  <div class="wf-pointer-footer">
312
  <ul class="wf-tour-pagination">
313
  <li>&bullet;</li>
314
  <li class="wf-active">&bullet;</li>
315
  <li>&bullet;</li>
316
  </ul>
317
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
318
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
319
  </div>
320
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
321
  </div>
322
  </script>
323
  <script type="text/x-jquery-template" id="wfNewTour3">
324
  <div>
325
+ <h3><?php esc_html_e('Global Wordfence Options', 'wordfence'); ?></h3>
326
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
327
+ <p><?php echo wp_kses(__('You\'ll find this icon throughout the plugin. Clicking it will show you the options and features for each section of Wordfence. From the dashboard, you can find the <strong>Global Options</strong> for Wordfence such as alerts, automatic updates, and managing your site\'s Premium License.', 'wordfence'), array('strong'=>array())); ?></p>
328
  <div class="wf-pointer-footer">
329
  <ul class="wf-tour-pagination">
330
  <li>&bullet;</li>
331
  <li>&bullet;</li>
332
  <li class="wf-active">&bullet;</li>
333
  </ul>
334
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
335
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Got it', 'wordfence'); ?></a></div>
336
  </div>
337
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
338
  </div>
366
 
367
  <script type="text/x-jquery-template" id="wfUpgradeTour1">
368
  <div>
369
+ <h3><?php printf(
370
+ /* translators: Wordfence version. */
371
+ esc_html__('You have successfully updated to Wordfence %s', 'wordfence'), WORDFENCE_VERSION); ?></h3>
372
+ <p><?php esc_html_e('This update includes a number of significant interface changes. We\'d like to walk you through some of them, but you can bypass the tour for a section at any time by closing the dialogs.', 'wordfence'); ?></p>
373
+ <p><?php echo wp_kses(__('We welcome your feedback and comments at <a href="mailto:feedback@wordfence.com">feedback@wordfence.com</a>. For a deeper dive on all of the changes, <a href="https://www.wordfence.com/blog/2018/01/introducing-wordfence-7/" target="_blank" rel="noopener noreferrer">click here</a>.', 'wordfence'), array('a'=>array('href'=>array(), 'target'=>array()))); ?></p>
374
  <div class="wf-pointer-footer">
375
  <ul class="wf-tour-pagination">
376
  <li class="wf-active">&bullet;</li>
378
  <li>&bullet;</li>
379
  <li>&bullet;</li>
380
  </ul>
381
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
382
  </div>
383
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
384
  </div>
385
  </script>
386
  <script type="text/x-jquery-template" id="wfUpgradeTour2">
387
  <div>
388
+ <h3><?php esc_html_e('Monitor Your Wordfence Protection', 'wordfence'); ?></h3>
389
+ <p><?php esc_html_e('Each feature contains a status percentage reminding you at a high level of what\'s enabled, disabled, or needing your attention. The Notifications section highlights actions you need to take.', 'wordfence'); ?></p>
390
  <div class="wf-pointer-footer">
391
  <ul class="wf-tour-pagination">
392
  <li>&bullet;</li>
394
  <li>&bullet;</li>
395
  <li>&bullet;</li>
396
  </ul>
397
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
398
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
399
  </div>
400
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
401
  </div>
402
  </script>
403
  <script type="text/x-jquery-template" id="wfUpgradeTour3">
404
  <div>
405
+ <h3><?php esc_html_e('Global Wordfence Options', 'wordfence'); ?></h3>
406
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
407
+ <p><?php esc_html_e('Manage your Wordfence license, see alerts and automatic plugin updates, and import/export your settings.', 'wordfence'); ?></p>
408
  <div class="wf-pointer-footer">
409
  <ul class="wf-tour-pagination">
410
  <li>&bullet;</li>
412
  <li class="wf-active">&bullet;</li>
413
  <li>&bullet;</li>
414
  </ul>
415
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
416
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
417
  </div>
418
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
419
  </div>
420
  </script>
421
  <script type="text/x-jquery-template" id="wfUpgradeTour4">
422
  <div>
423
+ <h3><?php esc_html_e('Updated Navigation', 'wordfence'); ?></h3>
424
+ <p><?php echo wp_kses(__('The main navigation no longer includes an <strong>Options</strong> link. Options are now accessed via the <strong>Options</strong> link on each feature\'s main page. Live Traffic is now located in the Tools section, and blocking is found under the Firewall. Shortcuts to add a <strong>Blocking</strong> link back to the main navigation are available under Blocking options.', 'wordfence'), array('strong'=>array())); ?></p>
425
  <div class="wf-pointer-footer">
426
  <ul class="wf-tour-pagination">
427
  <li>&bullet;</li>
429
  <li>&bullet;</li>
430
  <li class="wf-active">&bullet;</li>
431
  </ul>
432
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
433
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Got it', 'wordfence'); ?></a></div>
434
  </div>
435
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
436
  </div>
471
  <?php
472
  echo wfView::create('common/modal-prompt', array(
473
  'title' => __('Recommended Settings Change', 'wordfence'),
474
+ 'messageHTML' => '<p>' . esc_html__('Greetings! The default configuration for Wordfence Live Traffic has changed. The new default saves only logins and blocked requests, while this site is currently recording all traffic. Would you like to change to the new default?', 'wordfence') . '</p>' . (!wfRateLimit::identicalHumanBotRateLimits() ? '<p>' . __('Rate limiting based on type of request (human vs crawler) may be less accurate because this prevents loading the extra JavaScript used for that identification.', 'wordfence') . '</p>' : ''),
475
  'primaryButton' => array('id' => 'wf-livetrafficmigrate-yes', 'label' => __('Yes Please', 'wordfence'), 'link' => '#', 'type' => 'wf-btn-primary'),
476
  'secondaryButtons' => array(
477
  array('id' => 'wf-livetrafficmigrate-no', 'label' => __('No Thanks', 'wordfence'), 'link' => '#', 'type' => 'wf-btn-default'),
480
  ))->render();
481
  ?>
482
  </script>
483
+ <?php endif; ?>
lib/menu_dashboard_options.php CHANGED
@@ -45,7 +45,7 @@ $d = new wfDashboard();
45
  <?php
46
  echo wfView::create('options/block-controls', array(
47
  'backLink' => $dashboardURL,
48
- 'backLabelHTML' => __('Back<span class="wf-hidden-xs"> to Dashboard</span>', 'wordfence'),
49
  'restoreDefaultsSection' => wfConfig::OPTIONS_TYPE_GLOBAL,
50
  'restoreDefaultsMessage' => __('Are you sure you want to restore the default global settings? This will undo any custom changes you have made to the options on this page. Your configured license key and alert emails will not be changed.', 'wordfence'),
51
  ))->render();
@@ -78,7 +78,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
78
  echo wfView::create('common/section-title', array(
79
  'title' => __('Wordfence Global Options', 'wordfence'),
80
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_DASHBOARD_OPTIONS),
81
- 'helpLabelHTML' => __('Learn more<span class="wf-hidden-xs"> about Global Options</span>', 'wordfence'),
82
  'showIcon' => true,
83
  ))->render();
84
  ?>
@@ -145,11 +145,21 @@ else if (wfConfig::get('touppPromptNeeded')) {
145
  'linkNewWindow' => true,
146
  ))->render();
147
  ?>
 
 
 
 
 
 
 
 
 
 
148
  <?php elseif (wfConfig::get('keyType') == wfAPI::KEY_TYPE_FREE || wfConfig::get('keyType') === false): ?>
149
  <div>
150
- <p><h3><?php _e('Premium Protection Disabled', 'wordfence'); ?></h3></p>
151
- <p><?php printf(__('As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by an additional %d firewall rules and malware signatures. Upgrade to Premium today to improve your protection.', 'wordfence'), ($d->tdfPremium - $d->tdfCommunity)); ?></p>
152
- <p><a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="https://www.wordfence.com/gnl1dashboardUpgrade/wordfence-signup/#premium-order-form" target="_blank" rel="noopener noreferrer"><?php _e('Upgrade to Premium', 'wordfence'); ?></a>&nbsp;&nbsp;<a class="wf-btn wf-btn-callout-subtle wf-btn-default" href="https://www.wordfence.com/gnl1dashboardLearn/wordfence-signup/" target="_blank" rel="noopener noreferrer"><?php _e('Learn More', 'wordfence'); ?></a></p>
153
  </div>
154
  <?php elseif (wfConfig::get('keyExpDays') < 30 && (wfConfig::get('premiumAutoRenew', null) === '0' || wfConfig::get('premiumAutoRenew', null) === 0)): ?>
155
  <?php
@@ -186,7 +196,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
186
  $days = __('tomorrow', 'wordfence');
187
  }
188
  else {
189
- $days = sprintf(__('in %d days', 'wordfence'), $days);
190
  }
191
 
192
  echo wfView::create('dashboard/status-payment-expiring', array(
@@ -223,7 +233,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
223
  <?php elseif (wfConfig::get('keyType') == wfAPI::KEY_TYPE_PAID_CURRENT): ?>
224
  <div class="wf-block-labeled-value wf-protection-status wf-protection-status-<?php echo esc_attr($firewall->ruleMode()); ?>">
225
  <div class="wf-block-labeled-value-value"><i class="wf-fa wf-fa-check" aria-hidden="true"></i></div>
226
- <div class="wf-block-labeled-value-label"><?php _e('Wordfence Premium Enabled', 'wordfence'); ?></div>
227
  </div>
228
  <?php endif; ?>
229
  </li>
@@ -265,7 +275,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
265
  <div class="wf-block-header">
266
  <div class="wf-block-header-content">
267
  <div class="wf-block-title">
268
- <strong><?php _e('Import/Export Options', 'wordfence'); ?></strong>
269
  </div>
270
  </div>
271
  </div>
@@ -273,9 +283,9 @@ else if (wfConfig::get('touppPromptNeeded')) {
273
  <ul class="wf-block-list">
274
  <li>
275
  <ul class="wf-flex-horizontal wf-flex-vertical-xs wf-flex-full-width wf-add-top wf-add-bottom">
276
- <li><?php _e('Importing and exporting of options has moved to the Tools page', 'wordfence'); ?></li>
277
  <li class="wf-right wf-left-xs wf-padding-add-top-xs-small">
278
- <a href="<?php echo esc_url(network_admin_url('admin.php?page=WordfenceTools&subpage=importexport')); ?>" class="wf-btn wf-btn-primary wf-btn-callout-subtle" id="wf-export-options"><?php _e('Import/Export Options', 'wordfence'); ?></a>
279
  </li>
280
  </ul>
281
  </li>
@@ -288,4 +298,4 @@ else if (wfConfig::get('touppPromptNeeded')) {
288
  </div> <!-- end content block -->
289
  </div> <!-- end row -->
290
  </div> <!-- end container -->
291
- </div>
45
  <?php
46
  echo wfView::create('options/block-controls', array(
47
  'backLink' => $dashboardURL,
48
+ 'backLabelHTML' => wp_kses(__('Back<span class="wf-hidden-xs"> to Dashboard</span>', 'wordfence'), array('span'=>array('class'=>array()))),
49
  'restoreDefaultsSection' => wfConfig::OPTIONS_TYPE_GLOBAL,
50
  'restoreDefaultsMessage' => __('Are you sure you want to restore the default global settings? This will undo any custom changes you have made to the options on this page. Your configured license key and alert emails will not be changed.', 'wordfence'),
51
  ))->render();
78
  echo wfView::create('common/section-title', array(
79
  'title' => __('Wordfence Global Options', 'wordfence'),
80
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_DASHBOARD_OPTIONS),
81
+ 'helpLabelHTML' => wp_kses(__('Learn more<span class="wf-hidden-xs"> about Global Options</span>', 'wordfence'), array('span'=>array('class'=>array()))),
82
  'showIcon' => true,
83
  ))->render();
84
  ?>
145
  'linkNewWindow' => true,
146
  ))->render();
147
  ?>
148
+ <?php elseif (wfConfig::get('keyType') == wfAPI::KEY_TYPE_PAID_DELETED): ?>
149
+ <?php
150
+ echo wfView::create('common/status-critical', array(
151
+ 'id' => 'wf-premium-alert',
152
+ 'title' => __('Premium Protection Disabled', 'wordfence'),
153
+ 'subtitleHtml' => __('The license you were using has been removed from your account. Please reach out to <a href="mailto:billing@wordfence.com">billing@wordfence.com</a> or create a Premium support case at <a href="https://support.wordfence.com/support/tickets" target="_blank">https://support.wordfence.com/support/tickets</a> for more information. Our staff is happy to help.', 'wordfence'),
154
+ 'link' => null,
155
+ 'linkLabel' => null
156
+ ))->render();
157
+ ?>
158
  <?php elseif (wfConfig::get('keyType') == wfAPI::KEY_TYPE_FREE || wfConfig::get('keyType') === false): ?>
159
  <div>
160
+ <p><h3><?php esc_html_e('Premium Protection Disabled', 'wordfence'); ?></h3></p>
161
+ <p><?php esc_html_e('As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by additional firewall rules and malware signatures. Upgrade to Premium today to improve your protection.', 'wordfence'); ?></p>
162
+ <p><a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="https://www.wordfence.com/gnl1dashboardUpgrade/wordfence-signup/#premium-order-form" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Upgrade to Premium', 'wordfence'); ?></a>&nbsp;&nbsp;<a class="wf-btn wf-btn-callout-subtle wf-btn-default" href="https://www.wordfence.com/gnl1dashboardLearn/wordfence-signup/" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Learn More', 'wordfence'); ?></a></p>
163
  </div>
164
  <?php elseif (wfConfig::get('keyExpDays') < 30 && (wfConfig::get('premiumAutoRenew', null) === '0' || wfConfig::get('premiumAutoRenew', null) === 0)): ?>
165
  <?php
196
  $days = __('tomorrow', 'wordfence');
197
  }
198
  else {
199
+ $days = sprintf(/* translators: Number of days */ __('in %d days', 'wordfence'), $days);
200
  }
201
 
202
  echo wfView::create('dashboard/status-payment-expiring', array(
233
  <?php elseif (wfConfig::get('keyType') == wfAPI::KEY_TYPE_PAID_CURRENT): ?>
234
  <div class="wf-block-labeled-value wf-protection-status wf-protection-status-<?php echo esc_attr($firewall->ruleMode()); ?>">
235
  <div class="wf-block-labeled-value-value"><i class="wf-fa wf-fa-check" aria-hidden="true"></i></div>
236
+ <div class="wf-block-labeled-value-label"><?php esc_html_e('Wordfence Premium Enabled', 'wordfence'); ?></div>
237
  </div>
238
  <?php endif; ?>
239
  </li>
275
  <div class="wf-block-header">
276
  <div class="wf-block-header-content">
277
  <div class="wf-block-title">
278
+ <strong><?php esc_html_e('Import/Export Options', 'wordfence'); ?></strong>
279
  </div>
280
  </div>
281
  </div>
283
  <ul class="wf-block-list">
284
  <li>
285
  <ul class="wf-flex-horizontal wf-flex-vertical-xs wf-flex-full-width wf-add-top wf-add-bottom">
286
+ <li><?php esc_html_e('Importing and exporting of options has moved to the Tools page', 'wordfence'); ?></li>
287
  <li class="wf-right wf-left-xs wf-padding-add-top-xs-small">
288
+ <a href="<?php echo esc_url(network_admin_url('admin.php?page=WordfenceTools&subpage=importexport')); ?>" class="wf-btn wf-btn-primary wf-btn-callout-subtle" id="wf-export-options"><?php esc_html_e('Import/Export Options', 'wordfence'); ?></a>
289
  </li>
290
  </ul>
291
  </li>
298
  </div> <!-- end content block -->
299
  </div> <!-- end row -->
300
  </div> <!-- end container -->
301
+ </div>
lib/menu_firewall.php CHANGED
@@ -30,7 +30,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
30
  'title' => __('Firewall', 'wordfence'),
31
  'headerID' => 'wf-section-firewall',
32
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF),
33
- 'helpLabelHTML' => __('Learn more<span class="wf-hidden-xs"> about the Firewall</span>', 'wordfence'),
34
  ))->render();
35
  require(dirname(__FILE__) . '/menu_firewall_waf.php');
36
  ?>
@@ -41,7 +41,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
41
  'title' => __('Blocking', 'wordfence'),
42
  'headerID' => 'wf-section-blocking',
43
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_BLOCKING),
44
- 'helpLabelHTML' => __('Learn more<span class="wf-hidden-xs"> about Blocking</span>', 'wordfence'),
45
  ))->render();
46
  require(dirname(__FILE__) . '/menu_firewall_blocking.php');
47
  ?>
@@ -49,4 +49,4 @@ else if (wfConfig::get('touppPromptNeeded')) {
49
  </div> <!-- end content block -->
50
  </div> <!-- end row -->
51
  </div> <!-- end container -->
52
- </div>
30
  'title' => __('Firewall', 'wordfence'),
31
  'headerID' => 'wf-section-firewall',
32
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF),
33
+ 'helpLabelHTML' => wp_kses(__('Learn more<span class="wf-hidden-xs"> about the Firewall</span>', 'wordfence'), array('span'=>array('class'=>array()))),
34
  ))->render();
35
  require(dirname(__FILE__) . '/menu_firewall_waf.php');
36
  ?>
41
  'title' => __('Blocking', 'wordfence'),
42
  'headerID' => 'wf-section-blocking',
43
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_BLOCKING),
44
+ 'helpLabelHTML' => wp_kses(__('Learn more<span class="wf-hidden-xs"> about Blocking</span>', 'wordfence'), array('span'=>array('class'=>array()))),
45
  ))->render();
46
  require(dirname(__FILE__) . '/menu_firewall_blocking.php');
47
  ?>
49
  </div> <!-- end content block -->
50
  </div> <!-- end row -->
51
  </div> <!-- end container -->
52
+ </div>
lib/menu_firewall_blocking.php CHANGED
@@ -22,20 +22,22 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
22
  <div class="wf-block wf-always-active">
23
  <?php if (!wfConfig::get('firewallEnabled')): ?>
24
  <ul class="wf-block-banner">
25
- <li><?php _e('<strong>Note:</strong> Blocking is disabled when the option "Enable Rate Limiting and Advanced Blocking" is off.', 'wordfence'); ?></li>
26
- <li><a href="#" class="wf-btn wf-btn-default" id="wf-blocking-enable"><?php _e('Turn On', 'wordfence'); ?></a></li>
27
  </ul>
28
  <?php endif; ?>
29
  <?php if (version_compare(phpversion(), '5.4') < 0 && wfConfig::get('isPaid') && wfBlock::hasCountryBlock()): ?>
30
  <ul class="wf-block-banner">
31
- <li><?php printf(__('<strong>Note:</strong> The GeoIP database that is required for country blocking has been updated to a new format. This new format requires sites to run PHP 5.4 or newer, and this site is on PHP %s. To ensure country blocking continues functioning, please update PHP.', 'wordfence'), wfUtils::cleanPHPVersion()); ?></li>
32
- <li><a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_GEOIP_UPDATE); ?>" class="wf-btn wf-btn-default" target="_blank" rel="noopener noreferrer"><?php _e('More Information', 'wordfence'); ?></a></li>
 
 
33
  </ul>
34
  <?php endif; ?>
35
  <div class="wf-block-header">
36
  <div class="wf-block-header-content">
37
  <div class="wf-block-title">
38
- <strong id="wf-block-parameters-title" data-new-title="<?php esc_attr_e('Create a Blocking Rule', 'wordfence'); ?>" data-edit-title="<?php esc_attr_e('Edit Blocking Rule', 'wordfence'); ?>"><?php _e('Create a Blocking Rule', 'wordfence'); ?></strong>
39
  </div>
40
  </div>
41
  </div>
@@ -114,47 +116,47 @@ echo wfView::create('blocking/block-list', array(
114
 
115
  <script type="text/x-jquery-template" id="wfBlockingNewTour1">
116
  <div>
117
- <h3><?php _e('Blocking', 'wordfence'); ?></h3>
118
- <p><?php _e('Wordfence lets you take control of protecting your site with powerful blocking features. Block traffic based on IP, IP range, hostname, browser, or referrer. Country blocking is available for Premium customers.', 'wordfence'); ?></p>
119
  <div class="wf-pointer-footer">
120
  <ul class="wf-tour-pagination">
121
  <li class="wf-active">&bullet;</li>
122
  <li>&bullet;</li>
123
  <li>&bullet;</li>
124
  </ul>
125
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
126
  </div>
127
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
128
  </div>
129
  </script>
130
  <script type="text/x-jquery-template" id="wfBlockingNewTour2">
131
  <div>
132
- <h3><?php _e('Blocking Builder', 'wordfence'); ?></h3>
133
- <p><?php _e('All of your blocking rules are in one central location. Choose the Block Type, then enter the details for the rule. Once it has been added, you\'ll see it saved as a rule for your site.', 'wordfence'); ?></p>
134
  <div class="wf-pointer-footer">
135
  <ul class="wf-tour-pagination">
136
  <li>&bullet;</li>
137
  <li class="wf-active">&bullet;</li>
138
  <li>&bullet;</li>
139
  </ul>
140
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
141
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
142
  </div>
143
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
144
  </div>
145
  </script>
146
  <script type="text/x-jquery-template" id="wfBlockingNewTour3">
147
  <div>
148
- <h3><?php _e('Manage Blocking Rules', 'wordfence'); ?></h3>
149
- <p><?php _e('Here\'s where you\'ll see all the blocking rules you\'ve created. You can also manage them as well as remove or modify them from this table.', 'wordfence'); ?></p>
150
  <div class="wf-pointer-footer">
151
  <ul class="wf-tour-pagination">
152
  <li>&bullet;</li>
153
  <li>&bullet;</li>
154
  <li class="wf-active">&bullet;</li>
155
  </ul>
156
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
157
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Got it', 'wordfence'); ?></a></div>
158
  </div>
159
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
160
  </div>
@@ -199,31 +201,31 @@ echo wfView::create('blocking/block-list', array(
199
 
200
  <script type="text/x-jquery-template" id="wfBlockingUpgradeTour1">
201
  <div>
202
- <h3><?php _e('Blocking Builder', 'wordfence'); ?></h3>
203
- <p><?php _e('All of the blocking rules you create are now in one central location. Simply choose the block type and enter the details for the rule you want to create. Premium users have access to advanced country blocking options, found via the <strong>Options</strong> link.', 'wordfence'); ?></p>
204
  <div class="wf-pointer-footer">
205
  <ul class="wf-tour-pagination">
206
  <li class="wf-active">&bullet;</li>
207
  <li>&bullet;</li>
208
  </ul>
209
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
210
  </div>
211
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
212
  </div>
213
  </script>
214
  <script type="text/x-jquery-template" id="wfBlockingUpgradeTour2">
215
  <div>
216
- <h3><?php _e('Manage Blocking Rules', 'wordfence'); ?></h3>
217
- <p><?php _e('All blocking rules you create will show here. You can manage them as well as remove or modify them from the same location.', 'wordfence'); ?></p>
218
  <div class="wf-pointer-footer">
219
  <ul class="wf-tour-pagination">
220
  <li>&bullet;</li>
221
  <li class="wf-active">&bullet;</li>
222
  </ul>
223
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
224
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Got it', 'wordfence'); ?></a></div>
225
  </div>
226
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
227
  </div>
228
  </script>
229
- <?php endif; ?>
22
  <div class="wf-block wf-always-active">
23
  <?php if (!wfConfig::get('firewallEnabled')): ?>
24
  <ul class="wf-block-banner">
25
+ <li><?php echo wp_kses(__('<strong>Note:</strong> Blocking is disabled when the option "Enable Rate Limiting and Advanced Blocking" is off.', 'wordfence'), array('strong'=>array())); ?></li>
26
+ <li><a href="#" class="wf-btn wf-btn-default" id="wf-blocking-enable"><?php esc_html_e('Turn On', 'wordfence'); ?></a></li>
27
  </ul>
28
  <?php endif; ?>
29
  <?php if (version_compare(phpversion(), '5.4') < 0 && wfConfig::get('isPaid') && wfBlock::hasCountryBlock()): ?>
30
  <ul class="wf-block-banner">
31
+ <li><?php echo esc_html(sprintf(
32
+ /* translators: PHP version. */
33
+ __('<strong>Note:</strong> The GeoIP database that is required for country blocking has been updated to a new format. This new format requires sites to run PHP 5.4 or newer, and this site is on PHP %s. To ensure country blocking continues functioning, please update PHP.', 'wordfence'), wfUtils::cleanPHPVersion())); ?></li>
34
+ <li><a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_GEOIP_UPDATE); ?>" class="wf-btn wf-btn-default" target="_blank" rel="noopener noreferrer"><?php esc_html_e('More Information', 'wordfence'); ?></a></li>
35
  </ul>
36
  <?php endif; ?>
37
  <div class="wf-block-header">
38
  <div class="wf-block-header-content">
39
  <div class="wf-block-title">
40
+ <strong id="wf-block-parameters-title" data-new-title="<?php esc_attr_e('Create a Blocking Rule', 'wordfence'); ?>" data-edit-title="<?php esc_attr_e('Edit Blocking Rule', 'wordfence'); ?>"><?php esc_html_e('Create a Blocking Rule', 'wordfence'); ?></strong>
41
  </div>
42
  </div>
43
  </div>
116
 
117
  <script type="text/x-jquery-template" id="wfBlockingNewTour1">
118
  <div>
119
+ <h3><?php esc_html_e('Blocking', 'wordfence'); ?></h3>
120
+ <p><?php esc_html_e('Wordfence lets you take control of protecting your site with powerful blocking features. Block traffic based on IP, IP range, hostname, browser, or referrer. Country blocking is available for Premium customers.', 'wordfence'); ?></p>
121
  <div class="wf-pointer-footer">
122
  <ul class="wf-tour-pagination">
123
  <li class="wf-active">&bullet;</li>
124
  <li>&bullet;</li>
125
  <li>&bullet;</li>
126
  </ul>
127
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
128
  </div>
129
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
130
  </div>
131
  </script>
132
  <script type="text/x-jquery-template" id="wfBlockingNewTour2">
133
  <div>
134
+ <h3><?php esc_html_e('Blocking Builder', 'wordfence'); ?></h3>
135
+ <p><?php esc_html_e('All of your blocking rules are in one central location. Choose the Block Type, then enter the details for the rule. Once it has been added, you\'ll see it saved as a rule for your site.', 'wordfence'); ?></p>
136
  <div class="wf-pointer-footer">
137
  <ul class="wf-tour-pagination">
138
  <li>&bullet;</li>
139
  <li class="wf-active">&bullet;</li>
140
  <li>&bullet;</li>
141
  </ul>
142
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
143
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
144
  </div>
145
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
146
  </div>
147
  </script>
148
  <script type="text/x-jquery-template" id="wfBlockingNewTour3">
149
  <div>
150
+ <h3><?php esc_html_e('Manage Blocking Rules', 'wordfence'); ?></h3>
151
+ <p><?php esc_html_e('Here\'s where you\'ll see all the blocking rules you\'ve created. You can also manage them as well as remove or modify them from this table.', 'wordfence'); ?></p>
152
  <div class="wf-pointer-footer">
153
  <ul class="wf-tour-pagination">
154
  <li>&bullet;</li>
155
  <li>&bullet;</li>
156
  <li class="wf-active">&bullet;</li>
157
  </ul>
158
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
159
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Got it', 'wordfence'); ?></a></div>
160
  </div>
161
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
162
  </div>
201
 
202
  <script type="text/x-jquery-template" id="wfBlockingUpgradeTour1">
203
  <div>
204
+ <h3><?php esc_html_e('Blocking Builder', 'wordfence'); ?></h3>
205
+ <p><?php echo wp_kses(__('All of the blocking rules you create are now in one central location. Simply choose the block type and enter the details for the rule you want to create. Premium users have access to advanced country blocking options, found via the <strong>Options</strong> link.', 'wordfence'), array('strong'=>array())); ?></p>
206
  <div class="wf-pointer-footer">
207
  <ul class="wf-tour-pagination">
208
  <li class="wf-active">&bullet;</li>
209
  <li>&bullet;</li>
210
  </ul>
211
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
212
  </div>
213
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
214
  </div>
215
  </script>
216
  <script type="text/x-jquery-template" id="wfBlockingUpgradeTour2">
217
  <div>
218
+ <h3><?php esc_html_e('Manage Blocking Rules', 'wordfence'); ?></h3>
219
+ <p><?php esc_html_e('All blocking rules you create will show here. You can manage them as well as remove or modify them from the same location.', 'wordfence'); ?></p>
220
  <div class="wf-pointer-footer">
221
  <ul class="wf-tour-pagination">
222
  <li>&bullet;</li>
223
  <li class="wf-active">&bullet;</li>
224
  </ul>
225
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
226
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Got it', 'wordfence'); ?></a></div>
227
  </div>
228
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
229
  </div>
230
  </script>
231
+ <?php endif; ?>
lib/menu_firewall_blocking_options.php CHANGED
@@ -46,7 +46,9 @@ if (isset($_GET['source']) && wfPage::isValidPage($_GET['source'])) {
46
  <?php
47
  echo wfView::create('options/block-controls', array(
48
  'backLink' => $backPage->url(),
49
- 'backLabelHTML' => sprintf(__('<span class="wf-hidden-xs">Back to </span>%s', 'wordfence'), $backPage->label()),
 
 
50
  'restoreDefaultsSection' => wfConfig::OPTIONS_TYPE_BLOCKING,
51
  'restoreDefaultsMessage' => __('Are you sure you want to restore the default Blocking settings? This will undo any custom changes you have made to the options on this page. Any existing blocks will be preserved.', 'wordfence'),
52
  ))->render();
@@ -89,7 +91,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
89
  echo wfView::create('common/section-title', array(
90
  'title' => __('Blocking Options', 'wordfence'),
91
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_BLOCKING),
92
- 'helpLabelHTML' => __('Learn more<span class="wf-hidden-xs"> about Blocking</span>', 'wordfence'),
93
  'showIcon' => true,
94
  ))->render();
95
  ?>
@@ -99,7 +101,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
99
  <div class="wf-block-header">
100
  <div class="wf-block-header-content">
101
  <div class="wf-block-title">
102
- <strong><?php _e('General', 'wordfence'); ?></strong>
103
  </div>
104
  <div class="wf-block-header-action"></div>
105
  </div>
@@ -132,4 +134,4 @@ else if (wfConfig::get('touppPromptNeeded')) {
132
  </div> <!-- end content block -->
133
  </div> <!-- end row -->
134
  </div> <!-- end container -->
135
- </div>
46
  <?php
47
  echo wfView::create('options/block-controls', array(
48
  'backLink' => $backPage->url(),
49
+ 'backLabelHTML' => wp_kses(sprintf(
50
+ /* translators: Page title/label. */
51
+ __('<span class="wf-hidden-xs">Back to </span>%s', 'wordfence'), $backPage->label()), array('span'=>array('class'=>array()))),
52
  'restoreDefaultsSection' => wfConfig::OPTIONS_TYPE_BLOCKING,
53
  'restoreDefaultsMessage' => __('Are you sure you want to restore the default Blocking settings? This will undo any custom changes you have made to the options on this page. Any existing blocks will be preserved.', 'wordfence'),
54
  ))->render();
91
  echo wfView::create('common/section-title', array(
92
  'title' => __('Blocking Options', 'wordfence'),
93
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_BLOCKING),
94
+ 'helpLabelHTML' => wp_kses(__('Learn more<span class="wf-hidden-xs"> about Blocking</span>', 'wordfence'), array('span'=>array('class'=>array()))),
95
  'showIcon' => true,
96
  ))->render();
97
  ?>
101
  <div class="wf-block-header">
102
  <div class="wf-block-header-content">
103
  <div class="wf-block-title">
104
+ <strong><?php esc_html_e('General', 'wordfence'); ?></strong>
105
  </div>
106
  <div class="wf-block-header-action"></div>
107
  </div>
134
  </div> <!-- end content block -->
135
  </div> <!-- end row -->
136
  </div> <!-- end container -->
137
+ </div>
lib/menu_firewall_waf.php CHANGED
@@ -243,8 +243,8 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_optio
243
 
244
  <script type="text/x-jquery-template" id="wfWAFNewTour1">
245
  <div>
246
- <h3><?php _e('The Wordfence firewall protects your sites from attackers', 'wordfence'); ?></h3>
247
- <p><?php _e('This is where you can monitor the work Wordfence is doing to protect your site and also where you can manage the options to optimize the firewall\'s configuration.', 'wordfence'); ?></p>
248
  <div class="wf-pointer-footer">
249
  <ul class="wf-tour-pagination">
250
  <li class="wf-active">&bullet;</li>
@@ -252,15 +252,15 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_optio
252
  <li>&bullet;</li>
253
  <li>&bullet;</li>
254
  </ul>
255
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
256
  </div>
257
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
258
  </div>
259
  </script>
260
  <script type="text/x-jquery-template" id="wfWAFNewTour2">
261
  <div>
262
- <h3><?php _e('Web Application Firewall (WAF)', 'wordfence'); ?></h3>
263
- <p><?php _e('The Wordfence Web Application Firewall blocks known and emerging attacks using firewall rules. When you first install the WAF, it will be in learning mode. This allows Wordfence to learn about your site so that we can understand how to protect it and how to allow normal visitors through the firewall. We recommend you let Wordfence learn for a week before you enable the firewall.', 'wordfence'); ?></p>
264
  <div class="wf-pointer-footer">
265
  <ul class="wf-tour-pagination">
266
  <li>&bullet;</li>
@@ -268,16 +268,16 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_optio
268
  <li>&bullet;</li>
269
  <li>&bullet;</li>
270
  </ul>
271
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
272
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
273
  </div>
274
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
275
  </div>
276
  </script>
277
  <script type="text/x-jquery-template" id="wfWAFNewTour3">
278
  <div>
279
- <h3><?php _e('Brute Force Protection', 'wordfence'); ?></h3>
280
- <p><?php _e('Wordfence protects your site from password-guessing attacks by locking out attackers and helping you avoid weak passwords.', 'wordfence'); ?></p>
281
  <div class="wf-pointer-footer">
282
  <ul class="wf-tour-pagination">
283
  <li>&bullet;</li>
@@ -285,17 +285,17 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_optio
285
  <li class="wf-active">&bullet;</li>
286
  <li>&bullet;</li>
287
  </ul>
288
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
289
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
290
  </div>
291
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
292
  </div>
293
  </script>
294
  <script type="text/x-jquery-template" id="wfWAFNewTour4">
295
  <div>
296
- <h3><?php _e('Firewall Options', 'wordfence'); ?></h3>
297
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
298
- <p><?php _e('Set up the way you want the firewall to protect your site including the web application firewall, brute force protection, rate limiting, and blocking.', 'wordfence'); ?></p>
299
  <div class="wf-pointer-footer">
300
  <ul class="wf-tour-pagination">
301
  <li>&bullet;</li>
@@ -303,8 +303,8 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_optio
303
  <li>&bullet;</li>
304
  <li class="wf-active">&bullet;</li>
305
  </ul>
306
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
307
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Got it', 'wordfence'); ?></a></div>
308
  </div>
309
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
310
  </div>
@@ -344,14 +344,14 @@ $wafRemoveURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_optio
344
 
345
  <script type="text/x-jquery-template" id="wfWAFUpgradeTour1">
346
  <div>
347
- <h3><?php _e('Firewall Options', 'wordfence'); ?></h3>
348
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
349
- <p><?php _e('All of the Firewall settings are now located here. This includes configuration options for the web application firewall, brute force protection, rate limiting, allowlisted URLs, and blocking.', 'wordfence'); ?></p>
350
  <div class="wf-pointer-footer">
351
  <ul class="wf-tour-pagination">
352
  <li class="wf-active">&bullet;</li>
353
  </ul>
354
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Got it', 'wordfence'); ?></a></div>
355
  </div>
356
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
357
  </div>
243
 
244
  <script type="text/x-jquery-template" id="wfWAFNewTour1">
245
  <div>
246
+ <h3><?php esc_html_e('The Wordfence firewall protects your sites from attackers', 'wordfence'); ?></h3>
247
+ <p><?php esc_html_e('This is where you can monitor the work Wordfence is doing to protect your site and also where you can manage the options to optimize the firewall\'s configuration.', 'wordfence'); ?></p>
248
  <div class="wf-pointer-footer">
249
  <ul class="wf-tour-pagination">
250
  <li class="wf-active">&bullet;</li>
252
  <li>&bullet;</li>
253
  <li>&bullet;</li>
254
  </ul>
255
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
256
  </div>
257
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
258
  </div>
259
  </script>
260
  <script type="text/x-jquery-template" id="wfWAFNewTour2">
261
  <div>
262
+ <h3><?php esc_html_e('Web Application Firewall (WAF)', 'wordfence'); ?></h3>
263
+ <p><?php esc_html_e('The Wordfence Web Application Firewall blocks known and emerging attacks using firewall rules. When you first install the WAF, it will be in learning mode. This allows Wordfence to learn about your site so that we can understand how to protect it and how to allow normal visitors through the firewall. We recommend you let Wordfence learn for a week before you enable the firewall.', 'wordfence'); ?></p>
264
  <div class="wf-pointer-footer">
265
  <ul class="wf-tour-pagination">
266
  <li>&bullet;</li>
268
  <li>&bullet;</li>
269
  <li>&bullet;</li>
270
  </ul>
271
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
272
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
273
  </div>
274
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
275
  </div>
276
  </script>
277
  <script type="text/x-jquery-template" id="wfWAFNewTour3">
278
  <div>
279
+ <h3><?php esc_html_e('Brute Force Protection', 'wordfence'); ?></h3>
280
+ <p><?php esc_html_e('Wordfence protects your site from password-guessing attacks by locking out attackers and helping you avoid weak passwords.', 'wordfence'); ?></p>
281
  <div class="wf-pointer-footer">
282
  <ul class="wf-tour-pagination">
283
  <li>&bullet;</li>
285
  <li class="wf-active">&bullet;</li>
286
  <li>&bullet;</li>
287
  </ul>
288
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
289
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
290
  </div>
291
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
292
  </div>
293
  </script>
294
  <script type="text/x-jquery-template" id="wfWAFNewTour4">
295
  <div>
296
+ <h3><?php esc_html_e('Firewall Options', 'wordfence'); ?></h3>
297
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
298
+ <p><?php esc_html_e('Set up the way you want the firewall to protect your site including the web application firewall, brute force protection, rate limiting, and blocking.', 'wordfence'); ?></p>
299
  <div class="wf-pointer-footer">
300
  <ul class="wf-tour-pagination">
301
  <li>&bullet;</li>
303
  <li>&bullet;</li>
304
  <li class="wf-active">&bullet;</li>
305
  </ul>
306
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
307
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Got it', 'wordfence'); ?></a></div>
308
  </div>
309
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
310
  </div>
344
 
345
  <script type="text/x-jquery-template" id="wfWAFUpgradeTour1">
346
  <div>
347
+ <h3><?php esc_html_e('Firewall Options', 'wordfence'); ?></h3>
348
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
349
+ <p><?php esc_html_e('All of the Firewall settings are now located here. This includes configuration options for the web application firewall, brute force protection, rate limiting, allowlisted URLs, and blocking.', 'wordfence'); ?></p>
350
  <div class="wf-pointer-footer">
351
  <ul class="wf-tour-pagination">
352
  <li class="wf-active">&bullet;</li>
353
  </ul>
354
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Got it', 'wordfence'); ?></a></div>
355
  </div>
356
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
357
  </div>
lib/menu_firewall_waf_options.php CHANGED
@@ -75,7 +75,7 @@ if (isset($_GET['source']) && wfPage::isValidPage($_GET['source'])) {
75
  <?php
76
  echo wfView::create('options/block-controls', array(
77
  'backLink' => $backPage->url(),
78
- 'backLabelHTML' => sprintf(__('<span class="wf-hidden-xs">Back to </span>%s', 'wordfence'), $backPage->label()),
79
  'restoreDefaultsSection' => wfConfig::OPTIONS_TYPE_FIREWALL,
80
  'restoreDefaultsMessage' => __('Are you sure you want to restore the default Firewall settings? This will undo any custom changes you have made to the options on this page. If you have manually disabled any rules or added any custom allowlisted URLs, those changes will not be overwritten.', 'wordfence'),
81
  ))->render();
@@ -121,7 +121,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
121
  echo wfView::create('common/section-title', array(
122
  'title' => __('Firewall Options', 'wordfence'),
123
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF),
124
- 'helpLabelHTML' => __('Learn more<span class="wf-hidden-xs"> about the Firewall</span>', 'wordfence'),
125
  'showIcon' => true,
126
  ))->render();
127
  ?>
75
  <?php
76
  echo wfView::create('options/block-controls', array(
77
  'backLink' => $backPage->url(),
78
+ 'backLabelHTML' => wp_kses(sprintf(__('<span class="wf-hidden-xs">Back to </span>%s', 'wordfence'), $backPage->label()), array('span'=>array('class'=>array()))),
79
  'restoreDefaultsSection' => wfConfig::OPTIONS_TYPE_FIREWALL,
80
  'restoreDefaultsMessage' => __('Are you sure you want to restore the default Firewall settings? This will undo any custom changes you have made to the options on this page. If you have manually disabled any rules or added any custom allowlisted URLs, those changes will not be overwritten.', 'wordfence'),
81
  ))->render();
121
  echo wfView::create('common/section-title', array(
122
  'title' => __('Firewall Options', 'wordfence'),
123
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF),
124
+ 'helpLabelHTML' => wp_kses(__('Learn more<span class="wf-hidden-xs"> about the Firewall</span>', 'wordfence'), array('span'=>array('class'=>array()))),
125
  'showIcon' => true,
126
  ))->render();
127
  ?>
lib/menu_options.php CHANGED
@@ -93,9 +93,9 @@ if (isset($_GET['source']) && wfPage::isValidPage($_GET['source'])) {
93
  'wf-option-alertOn-loginLockout' => __('Alert when someone is locked out from login', 'wordfence'),
94
  'wf-option-alertOn-lostPasswdForm' => __('Alert when the "lost password" form is used for a valid user', 'wordfence'),
95
  'wf-option-alertOn-adminLogin' => __('Alert me when someone with administrator access signs in', 'wordfence'),
96
- 'wf-option-alertOn-firstAdminLoginOnly' => __('Only alert me when that administrator signs in from a new device or location', 'wordfence'),
97
  'wf-option-alertOn-nonAdminLogin' => __('Alert me when a non-admin user signs in', 'wordfence'),
98
- 'wf-option-alertOn-firstNonAdminLoginOnly' => __('Only alert me when that user signs in from a new device or location', 'wordfence'),
99
  'wf-option-wafAlertOnAttacks' => __('Alert me when there\'s a large increase in attacks detected on my site', 'wordfence'),
100
  'wf-option-alert-maxHourly' => __('Maximum email alerts to send per hour', 'wordfence'),
101
  'wf-option-email-summary-enabled' => __('Enable email summary', 'wordfence'),
@@ -265,7 +265,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
265
  ))->render();
266
  ?>
267
 
268
- <p><?php _e('These options are also available throughout the plugin pages, in the relevant sections. This page is provided for easier setup for experienced Wordfence users.', 'wordfence'); ?></p>
269
 
270
  <?php
271
  echo wfView::create('common/section-subtitle', array(
@@ -402,7 +402,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
402
  <div class="wf-block-header">
403
  <div class="wf-block-header-content">
404
  <div class="wf-block-title">
405
- <strong><?php _e('Import/Export Options', 'wordfence'); ?></strong>
406
  </div>
407
  </div>
408
  </div>
@@ -410,9 +410,9 @@ else if (wfConfig::get('touppPromptNeeded')) {
410
  <ul class="wf-block-list">
411
  <li>
412
  <ul class="wf-flex-horizontal wf-flex-vertical-xs wf-flex-full-width wf-add-top wf-add-bottom">
413
- <li><?php _e('Importing and exporting of options is available on the Tools page', 'wordfence'); ?></li>
414
  <li class="wf-right wf-left-xs wf-padding-add-top-xs-small">
415
- <a href="<?php echo esc_url(network_admin_url('admin.php?page=WordfenceTools&subpage=importexport')); ?>" class="wf-btn wf-btn-primary wf-btn-callout-subtle" id="wf-export-options"><?php _e('Import/Export Options', 'wordfence'); ?></a>
416
  </li>
417
  </ul>
418
  <input type="hidden" id="wf-option-exportOptions">
93
  'wf-option-alertOn-loginLockout' => __('Alert when someone is locked out from login', 'wordfence'),
94
  'wf-option-alertOn-lostPasswdForm' => __('Alert when the "lost password" form is used for a valid user', 'wordfence'),
95
  'wf-option-alertOn-adminLogin' => __('Alert me when someone with administrator access signs in', 'wordfence'),
96
+ 'wf-option-alertOn-firstAdminLoginOnly' => __('Only alert me when that administrator signs in from a new device', 'wordfence'),
97
  'wf-option-alertOn-nonAdminLogin' => __('Alert me when a non-admin user signs in', 'wordfence'),
98
+ 'wf-option-alertOn-firstNonAdminLoginOnly' => __('Only alert me when that user signs in from a new device', 'wordfence'),
99
  'wf-option-wafAlertOnAttacks' => __('Alert me when there\'s a large increase in attacks detected on my site', 'wordfence'),
100
  'wf-option-alert-maxHourly' => __('Maximum email alerts to send per hour', 'wordfence'),
101
  'wf-option-email-summary-enabled' => __('Enable email summary', 'wordfence'),
265
  ))->render();
266
  ?>
267
 
268
+ <p><?php esc_html_e('These options are also available throughout the plugin pages, in the relevant sections. This page is provided for easier setup for experienced Wordfence users.', 'wordfence'); ?></p>
269
 
270
  <?php
271
  echo wfView::create('common/section-subtitle', array(
402
  <div class="wf-block-header">
403
  <div class="wf-block-header-content">
404
  <div class="wf-block-title">
405
+ <strong><?php esc_html_e('Import/Export Options', 'wordfence'); ?></strong>
406
  </div>
407
  </div>
408
  </div>
410
  <ul class="wf-block-list">
411
  <li>
412
  <ul class="wf-flex-horizontal wf-flex-vertical-xs wf-flex-full-width wf-add-top wf-add-bottom">
413
+ <li><?php esc_html_e('Importing and exporting of options is available on the Tools page', 'wordfence'); ?></li>
414
  <li class="wf-right wf-left-xs wf-padding-add-top-xs-small">
415
+ <a href="<?php echo esc_url(network_admin_url('admin.php?page=WordfenceTools&subpage=importexport')); ?>" class="wf-btn wf-btn-primary wf-btn-callout-subtle" id="wf-export-options"><?php esc_html_e('Import/Export Options', 'wordfence'); ?></a>
416
  </li>
417
  </ul>
418
  <input type="hidden" id="wf-option-exportOptions">
lib/menu_scanner.php CHANGED
@@ -7,7 +7,7 @@ $dashboard = new wfDashboard();
7
  <?php if (wfConfig::get('liveActivityPauseEnabled')): ?>
8
  <div id="wfLiveTrafficOverlayAnchor"></div>
9
  <div id="wfLiveTrafficDisabledMessage">
10
- <h2>Status Updates Paused<br /><small>Click inside window to resume</small></h2>
11
  </div>
12
  <?php endif; ?>
13
  <?php
@@ -31,7 +31,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
31
  'title' => __('Scan', 'wordfence'),
32
  'headerID' => 'wf-section-scan',
33
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN),
34
- 'helpLabelHTML' => __('Learn more<span class="wf-hidden-xs"> about the Scanner</span>', 'wordfence'),
35
  'showIcon' => true,
36
  ))->render();
37
  ?>
@@ -116,8 +116,8 @@ else if (wfConfig::get('touppPromptNeeded')) {
116
  <div class="wf-block wf-active">
117
  <?php if (wfConfig::get('betaThreatDefenseFeed')): ?>
118
  <ul class="wf-block-banner">
119
- <li><?php _e('Beta scan signatures are currently enabled. These signatures have not been fully tested yet and may cause false positives or scan stability issues on some sites.', 'wordfence'); ?></li>
120
- <li><a href="#" class="wf-btn wf-btn-default" id="wf-beta-disable"><?php _e('Turn Off Beta Signatures', 'wordfence'); ?></a></li>
121
  </ul>
122
  <?php endif; ?>
123
  <div class="wf-block-content">
@@ -210,8 +210,10 @@ else if (wfConfig::get('touppPromptNeeded')) {
210
  <?php
211
  echo wfView::create('common/modal-prompt', array(
212
  'title' => __('Are you sure you want to delete?', 'wordfence'),
213
- 'messageHTML' => '<p class="wf-callout-warning"><i class="wf-fa wf-fa-exclamation-triangle" aria-hidden="true"></i> ' . __('<strong>WARNING:</strong> If you delete the wrong file, it could cause your WordPress website to stop functioning, and you will probably have to restore from a backup.', 'wordfence') . '</p>' .
214
- '<p>' . sprintf(__('Do not delete files on your system unless you\'re ABSOLUTELY sure you know what you\'re doing. If you delete the wrong file it could cause your WordPress website to stop functioning and you will probably have to restore from backups. If you\'re unsure, Cancel and work with your hosting provider to clean your system of infected files. If you\'d like to learn more, <a href="%s" target="_blank" rel="noopener noreferrer">click here for our help article</a>.', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_BULK_DELETE_WARNING)) . '</p>',
 
 
215
  'primaryButton' => array('id' => 'wf-scanner-prompt-cancel', 'label' => __('Cancel', 'wordfence'), 'link' => '#', 'type' => 'wf-btn-default'),
216
  'secondaryButtons' => array(array('id' => 'wf-scanner-prompt-confirm', 'label' => __('Delete Files', 'wordfence'), 'link' => '#', 'type' => 'wf-btn-danger')),
217
  ))->render();
@@ -300,48 +302,48 @@ if (wfOnboardingController::willShowNewTour(wfOnboardingController::TOUR_SCAN)):
300
 
301
  <script type="text/x-jquery-template" id="wfNewTour1">
302
  <div>
303
- <h3><?php _e('Scan', 'wordfence'); ?></h3>
304
- <p><?php _e('A Wordfence scan looks for malware, malicious URLs, and patterns of infections by examining all of the files, posts, and comments on your WordPress website. It also checks your server and monitors your site\'s online reputation.', 'wordfence'); ?></p>
305
  <div class="wf-pointer-footer">
306
  <ul class="wf-tour-pagination">
307
  <li class="wf-active">&bullet;</li>
308
  <li>&bullet;</li>
309
  <li>&bullet;</li>
310
  </ul>
311
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
312
  </div>
313
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
314
  </div>
315
  </script>
316
  <script type="text/x-jquery-template" id="wfNewTour2">
317
  <div>
318
- <h3><?php _e('Manage Scan Settings', 'wordfence'); ?></h3>
319
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
320
- <p><?php _e('Set up the way you want the scan to monitor your site security including custom scan configurations and scheduling.', 'wordfence'); ?></p>
321
  <div class="wf-pointer-footer">
322
  <ul class="wf-tour-pagination">
323
  <li>&bullet;</li>
324
  <li class="wf-active">&bullet;</li>
325
  <li>&bullet;</li>
326
  </ul>
327
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
328
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
329
  </div>
330
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
331
  </div>
332
  </script>
333
  <script type="text/x-jquery-template" id="wfNewTour3">
334
  <div>
335
- <h3><?php _e('Start Your First Scan', 'wordfence'); ?></h3>
336
- <p><?php _e('By default, Wordfence will scan your site daily. Start your first scan now to see if your site has any security issues that need to be addressed. From here you can run manual scans any time you like.', 'wordfence'); ?></p>
337
  <div class="wf-pointer-footer">
338
  <ul class="wf-tour-pagination">
339
  <li>&bullet;</li>
340
  <li>&bullet;</li>
341
  <li class="wf-active">&bullet;</li>
342
  </ul>
343
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
344
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Got it', 'wordfence'); ?></a></div>
345
  </div>
346
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
347
  </div>
@@ -369,30 +371,30 @@ if (wfOnboardingController::willShowNewTour(wfOnboardingController::TOUR_SCAN)):
369
 
370
  <script type="text/x-jquery-template" id="wfUpgradeTour1">
371
  <div>
372
- <h3><?php _e('Scan Options &amp; Settings', 'wordfence'); ?></h3>
373
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
374
- <p class="wf-center"><?php _e('All of your scan options, including scheduling, are now located here.', 'wordfence'); ?></p>
375
  <div class="wf-pointer-footer">
376
  <ul class="wf-tour-pagination">
377
  <li class="wf-active">&bullet;</li>
378
  <li>&bullet;</li>
379
  </ul>
380
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Next', 'wordfence'); ?></a></div>
381
  </div>
382
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
383
  </div>
384
  </script>
385
  <script type="text/x-jquery-template" id="wfUpgradeTour2">
386
  <div>
387
- <h3><?php _e('Scan Progress and Activity', 'wordfence'); ?></h3>
388
- <p><?php _e('Track each scan stage as Wordfence scans your entire site. Along the way you can see the activity log one line at a time or expand the activity log for a more detailed view. Clicking on scan results will reveal detailed scan findings.', 'wordfence'); ?></p>
389
  <div class="wf-pointer-footer">
390
  <ul class="wf-tour-pagination">
391
  <li>&bullet;</li>
392
  <li class="wf-active">&bullet;</li>
393
  </ul>
394
- <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php _e('Previous', 'wordfence'); ?></a></div>
395
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Got it', 'wordfence'); ?></a></div>
396
  </div>
397
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
398
  </div>
7
  <?php if (wfConfig::get('liveActivityPauseEnabled')): ?>
8
  <div id="wfLiveTrafficOverlayAnchor"></div>
9
  <div id="wfLiveTrafficDisabledMessage">
10
+ <h2><?php echo wp_kses(__('Status Updates Paused<br /><small>Click inside window to resume</small>', 'wordfence'), array('small'=>array(), 'br'=>array())); ?></h2>
11
  </div>
12
  <?php endif; ?>
13
  <?php
31
  'title' => __('Scan', 'wordfence'),
32
  'headerID' => 'wf-section-scan',
33
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN),
34
+ 'helpLabelHTML' => wp_kses(__('Learn more<span class="wf-hidden-xs"> about the Scanner</span>', 'wordfence'), array('span'=>array('class'=>array()))),
35
  'showIcon' => true,
36
  ))->render();
37
  ?>
116
  <div class="wf-block wf-active">
117
  <?php if (wfConfig::get('betaThreatDefenseFeed')): ?>
118
  <ul class="wf-block-banner">
119
+ <li><?php esc_html_e('Beta scan signatures are currently enabled. These signatures have not been fully tested yet and may cause false positives or scan stability issues on some sites.', 'wordfence'); ?></li>
120
+ <li><a href="#" class="wf-btn wf-btn-default" id="wf-beta-disable"><?php esc_html_e('Turn Off Beta Signatures', 'wordfence'); ?></a></li>
121
  </ul>
122
  <?php endif; ?>
123
  <div class="wf-block-content">
210
  <?php
211
  echo wfView::create('common/modal-prompt', array(
212
  'title' => __('Are you sure you want to delete?', 'wordfence'),
213
+ 'messageHTML' => '<p class="wf-callout-warning"><i class="wf-fa wf-fa-exclamation-triangle" aria-hidden="true"></i> ' . wp_kses(__('<strong>WARNING:</strong> If you delete the wrong file, it could cause your WordPress website to stop functioning, and you will probably have to restore from a backup.', 'wordfence'), array('strong'=>array())) . '</p>' .
214
+ '<p>' . wp_kses(sprintf(
215
+ /* translators: Support URL. */
216
+ __('Do not delete files on your system unless you\'re ABSOLUTELY sure you know what you\'re doing. If you delete the wrong file it could cause your WordPress website to stop functioning and you will probably have to restore from backups. If you\'re unsure, Cancel and work with your hosting provider to clean your system of infected files. If you\'d like to learn more, <a href="%s" target="_blank" rel="noopener noreferrer">click here for our help article</a>.', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_BULK_DELETE_WARNING)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))) . '</p>',
217
  'primaryButton' => array('id' => 'wf-scanner-prompt-cancel', 'label' => __('Cancel', 'wordfence'), 'link' => '#', 'type' => 'wf-btn-default'),
218
  'secondaryButtons' => array(array('id' => 'wf-scanner-prompt-confirm', 'label' => __('Delete Files', 'wordfence'), 'link' => '#', 'type' => 'wf-btn-danger')),
219
  ))->render();
302
 
303
  <script type="text/x-jquery-template" id="wfNewTour1">
304
  <div>
305
+ <h3><?php esc_html_e('Scan', 'wordfence'); ?></h3>
306
+ <p><?php esc_html_e('A Wordfence scan looks for malware, malicious URLs, and patterns of infections by examining all of the files, posts, and comments on your WordPress website. It also checks your server and monitors your site\'s online reputation.', 'wordfence'); ?></p>
307
  <div class="wf-pointer-footer">
308
  <ul class="wf-tour-pagination">
309
  <li class="wf-active">&bullet;</li>
310
  <li>&bullet;</li>
311
  <li>&bullet;</li>
312
  </ul>
313
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
314
  </div>
315
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
316
  </div>
317
  </script>
318
  <script type="text/x-jquery-template" id="wfNewTour2">
319
  <div>
320
+ <h3><?php esc_html_e('Manage Scan Settings', 'wordfence'); ?></h3>
321
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
322
+ <p><?php esc_html_e('Set up the way you want the scan to monitor your site security including custom scan configurations and scheduling.', 'wordfence'); ?></p>
323
  <div class="wf-pointer-footer">
324
  <ul class="wf-tour-pagination">
325
  <li>&bullet;</li>
326
  <li class="wf-active">&bullet;</li>
327
  <li>&bullet;</li>
328
  </ul>
329
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
330
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
331
  </div>
332
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
333
  </div>
334
  </script>
335
  <script type="text/x-jquery-template" id="wfNewTour3">
336
  <div>
337
+ <h3><?php esc_html_e('Start Your First Scan', 'wordfence'); ?></h3>
338
+ <p><?php esc_html_e('By default, Wordfence will scan your site daily. Start your first scan now to see if your site has any security issues that need to be addressed. From here you can run manual scans any time you like.', 'wordfence'); ?></p>
339
  <div class="wf-pointer-footer">
340
  <ul class="wf-tour-pagination">
341
  <li>&bullet;</li>
342
  <li>&bullet;</li>
343
  <li class="wf-active">&bullet;</li>
344
  </ul>
345
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
346
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Got it', 'wordfence'); ?></a></div>
347
  </div>
348
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
349
  </div>
371
 
372
  <script type="text/x-jquery-template" id="wfUpgradeTour1">
373
  <div>
374
+ <h3><?php esc_html_e('Scan Options &amp; Settings', 'wordfence'); ?></h3>
375
  <p class="wf-center"><svg viewBox="0 0 100.11 100.11" class="wf-icon"><path d="M99.59,41.42a2.06,2.06,0,0,0-1.37-.82L86.3,38.78a39.34,39.34,0,0,0-2.67-6.39q1.17-1.63,3.52-4.6t3.32-4.33A2.52,2.52,0,0,0,91,22a2.1,2.1,0,0,0-.46-1.43Q88.18,17.2,79.78,9.45a2.52,2.52,0,0,0-1.63-.65,2.12,2.12,0,0,0-1.57.59l-9.25,7a40.09,40.09,0,0,0-5.87-2.41L59.64,2a1.92,1.92,0,0,0-.75-1.4A2.46,2.46,0,0,0,57.29,0H42.82a2.19,2.19,0,0,0-2.34,1.82,106,106,0,0,0-1.89,12.12,37.62,37.62,0,0,0-5.93,2.48l-9-7A2.78,2.78,0,0,0,22,8.8q-1.44,0-6.16,4.66a64.88,64.88,0,0,0-6.42,7A2.75,2.75,0,0,0,8.8,22a2.44,2.44,0,0,0,.65,1.56q4.37,5.28,7,9a32.38,32.38,0,0,0-2.54,6L1.76,40.34a2,2,0,0,0-1.24.85A2.5,2.5,0,0,0,0,42.69V57.16a2.44,2.44,0,0,0,.52,1.53,2,2,0,0,0,1.37.82l11.93,1.76a31.91,31.91,0,0,0,2.67,6.45Q15.31,69.35,13,72.31T9.65,76.65a2.54,2.54,0,0,0-.07,3q2.54,3.52,10.75,11a2.25,2.25,0,0,0,1.63.71,2.35,2.35,0,0,0,1.63-.59l9.19-7a40.54,40.54,0,0,0,5.87,2.41l1.82,12a1.92,1.92,0,0,0,.75,1.4,2.45,2.45,0,0,0,1.6.55H57.29a2.2,2.2,0,0,0,2.35-1.82,107.41,107.41,0,0,0,1.89-12.12,37.19,37.19,0,0,0,5.93-2.48l9,7a3.18,3.18,0,0,0,1.69.59q1.43,0,6.13-4.62a65.86,65.86,0,0,0,6.45-7,2.16,2.16,0,0,0,.59-1.5,2.51,2.51,0,0,0-.65-1.63q-4.69-5.74-7-9a41.57,41.57,0,0,0,2.54-5.93l12.06-1.82a2,2,0,0,0,1.3-.85,2.52,2.52,0,0,0,.52-1.5V43a2.46,2.46,0,0,0-.52-1.53ZM61.85,61.86a16.08,16.08,0,0,1-11.8,4.89A16.69,16.69,0,0,1,33.37,50.06,16.69,16.69,0,0,1,50.06,33.37,16.69,16.69,0,0,1,66.74,50.06a16.08,16.08,0,0,1-4.89,11.8Zm0,0"></path></svg></p>
376
+ <p class="wf-center"><?php esc_html_e('All of your scan options, including scheduling, are now located here.', 'wordfence'); ?></p>
377
  <div class="wf-pointer-footer">
378
  <ul class="wf-tour-pagination">
379
  <li class="wf-active">&bullet;</li>
380
  <li>&bullet;</li>
381
  </ul>
382
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Next', 'wordfence'); ?></a></div>
383
  </div>
384
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
385
  </div>
386
  </script>
387
  <script type="text/x-jquery-template" id="wfUpgradeTour2">
388
  <div>
389
+ <h3><?php esc_html_e('Scan Progress and Activity', 'wordfence'); ?></h3>
390
+ <p><?php esc_html_e('Track each scan stage as Wordfence scans your entire site. Along the way you can see the activity log one line at a time or expand the activity log for a more detailed view. Clicking on scan results will reveal detailed scan findings.', 'wordfence'); ?></p>
391
  <div class="wf-pointer-footer">
392
  <ul class="wf-tour-pagination">
393
  <li>&bullet;</li>
394
  <li class="wf-active">&bullet;</li>
395
  </ul>
396
+ <div id="wf-tour-previous"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-default"><?php esc_html_e('Previous', 'wordfence'); ?></a></div>
397
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Got it', 'wordfence'); ?></a></div>
398
  </div>
399
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
400
  </div>
lib/menu_scanner_credentials.php CHANGED
@@ -63,7 +63,9 @@ switch ($action) {
63
  //else - outputs credentials form
64
  }
65
  else {
66
- echo '<p>' . sprintf(__('Security token has expired. Click <a href="%s">here</a> to return to the scan page.', 'wordfence'), esc_url($scanURL)) . '</p>';
 
 
67
  }
68
  ?>
69
  </div>
@@ -74,4 +76,4 @@ switch ($action) {
74
  </div> <!-- end content block -->
75
  </div> <!-- end row -->
76
  </div> <!-- end container -->
77
- </div>
63
  //else - outputs credentials form
64
  }
65
  else {
66
+ echo '<p>' . wp_kses(sprintf(
67
+ /* translators: URL to the WordPress admin panel. */
68
+ __('Security token has expired. Click <a href="%s">here</a> to return to the scan page.', 'wordfence'), esc_url($scanURL)), array('a'=>array('href'=>array()))) . '</p>';
69
  }
70
  ?>
71
  </div>
76
  </div> <!-- end content block -->
77
  </div> <!-- end row -->
78
  </div> <!-- end container -->
79
+ </div>
lib/menu_scanner_options.php CHANGED
@@ -63,7 +63,7 @@ if (isset($_GET['source']) && wfPage::isValidPage($_GET['source'])) {
63
  <?php
64
  echo wfView::create('options/block-controls', array(
65
  'backLink' => $backPage->url(),
66
- 'backLabelHTML' => sprintf(__('<span class="wf-hidden-xs">Back to </span>%s', 'wordfence'), $backPage->label()),
67
  'restoreDefaultsSection' => wfConfig::OPTIONS_TYPE_SCANNER,
68
  'restoreDefaultsMessage' => __('Are you sure you want to restore the default Scan settings? This will undo any custom changes you have made to the options on this page.', 'wordfence'),
69
  ))->render();
@@ -96,7 +96,7 @@ else if (wfConfig::get('touppPromptNeeded')) {
96
  echo wfView::create('common/section-title', array(
97
  'title' => __('Scan Options and Scheduling', 'wordfence'),
98
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN),
99
- 'helpLabelHTML' => __('Learn more<span class="wf-hidden-xs"> about Scanning</span>', 'wordfence'),
100
  'showIcon' => true,
101
  ))->render();
102
  ?>
@@ -209,4 +209,4 @@ else if (wfConfig::get('touppPromptNeeded')) {
209
  });
210
  });
211
  })(jQuery);
212
- </script>
63
  <?php
64
  echo wfView::create('options/block-controls', array(
65
  'backLink' => $backPage->url(),
66
+ 'backLabelHTML' => wp_kses(sprintf(__('<span class="wf-hidden-xs">Back to </span>%s', 'wordfence'), $backPage->label()), array('span'=>array('class'=>array()))),
67
  'restoreDefaultsSection' => wfConfig::OPTIONS_TYPE_SCANNER,
68
  'restoreDefaultsMessage' => __('Are you sure you want to restore the default Scan settings? This will undo any custom changes you have made to the options on this page.', 'wordfence'),
69
  ))->render();
96
  echo wfView::create('common/section-title', array(
97
  'title' => __('Scan Options and Scheduling', 'wordfence'),
98
  'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN),
99
+ 'helpLabelHTML' => wp_kses(__('Learn more<span class="wf-hidden-xs"> about Scanning</span>', 'wordfence'), array('span'=>array('classes'=>array()))),
100
  'showIcon' => true,
101
  ))->render();
102
  ?>
209
  });
210
  });
211
  })(jQuery);
212
+ </script>
lib/menu_support.php CHANGED
@@ -28,19 +28,19 @@ $support = @json_decode(wfConfig::get('supportContent'), true);
28
  <li>
29
  <ul class="wf-block-list wf-block-list-horizontal">
30
  <li class="wf-flex-vertical">
31
- <h3><?php _e('Free Support', 'wordfence'); ?></h3>
32
- <p class="wf-center"><?php _e('Support for free customers is available via our forums page on wordpress.org. The majority of requests <strong>receive an answer within a few days.</strong>', 'wordfence'); ?></p>
33
- <p><a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FREE); ?>" target="_blank" rel="noopener noreferrer" class="wf-btn wf-btn-default wf-btn-callout-subtle"><?php _e('Go to Support Forums', 'wordfence'); ?></a></p>
34
  </li>
35
  <li class="wf-flex-vertical">
36
  <?php if (wfConfig::get('isPaid')): ?>
37
- <h3><?php _e('Premium Support', 'wordfence'); ?></h3>
38
- <p class="wf-center"><?php _e('Our senior support engineers <strong>respond to Premium tickets within a few hours</strong> on average and have a direct line to our QA and development teams.', 'wordfence'); ?></p>
39
- <p><a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_PREMIUM); ?>" target="_blank" rel="noopener noreferrer" class="wf-btn wf-btn-primary wf-btn-callout-subtle"><?php _e('Go to Premium Support', 'wordfence'); ?></a></p>
40
  <?php else: ?>
41
- <h3><?php _e('Upgrade Now to Access Premium Support', 'wordfence'); ?></h3>
42
- <p class="wf-center"><?php _e('Our senior support engineers <strong>respond to Premium tickets within a few hours</strong> on average and have a direct line to our QA and development teams.', 'wordfence'); ?></p>
43
- <p><a href="https://www.wordfence.com/gnl1supportUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wf-btn wf-btn-primary wf-btn-callout-subtle"><?php _e('Upgrade to Premium', 'wordfence'); ?></a></p>
44
  <?php endif; ?>
45
  </li>
46
  </ul>
@@ -56,7 +56,7 @@ $support = @json_decode(wfConfig::get('supportContent'), true);
56
  <div class="wf-block-header">
57
  <div class="wf-block-header-content">
58
  <div class="wf-block-title">
59
- <strong><?php _e('GDPR Information', 'wordfence'); ?></strong>
60
  </div>
61
  <div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('support-gdpr') ? 'true' : 'false'); ?>" tabindex="0"></div></div>
62
  </div>
@@ -67,8 +67,8 @@ $support = @json_decode(wfConfig::get('supportContent'), true);
67
  <ul class="wf-option wf-option-static">
68
  <li class="wf-option-title">
69
  <ul class="wf-flex-vertical wf-flex-align-left">
70
- <li><?php _e('General Data Protection Regulation', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_GDPR); ?>" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i></a></li>
71
- <li class="wf-option-subtitle"><?php _e('The GDPR is a set of rules that provides more control over EU personal data. Defiant has updated its terms of use, privacy policies, and software, as well as made available a data processing agreement to meet GDPR compliance.', 'wordfence'); ?></li>
72
  </ul>
73
  </li>
74
  </ul>
@@ -77,8 +77,10 @@ $support = @json_decode(wfConfig::get('supportContent'), true);
77
  <ul class="wf-option wf-option-static">
78
  <li class="wf-option-title">
79
  <ul class="wf-flex-vertical wf-flex-align-left">
80
- <li><?php _e('Data Processing Agreement', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_GDPR_DPA); ?>" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i></a></li>
81
- <li class="wf-option-subtitle"><?php printf(__('If you qualify as a data controller under the GDPR and need a data processing agreement, it can be <a href="%s" target="_blank" rel="noopener noreferrer">found here</a>.', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_GDPR_DPA)); ?></li>
 
 
82
  </ul>
83
  </li>
84
  </ul>
@@ -87,8 +89,8 @@ $support = @json_decode(wfConfig::get('supportContent'), true);
87
  <ul class="wf-option wf-option-static">
88
  <li class="wf-option-title">
89
  <ul class="wf-flex-vertical wf-flex-align-left">
90
- <li><?php _e('Agreement to New Terms and Privacy Policies', 'wordfence'); ?></li>
91
- <li class="wf-option-subtitle"><?php _e('To continue using Defiant products and services including the Wordfence plugin, all customers must review and agree to the updated terms and privacy policies. These changes reflect our commitment to follow data protection best practices and regulations. The Wordfence interface will remain disabled until these terms are agreed to.', 'wordfence'); ?></li>
92
  </ul>
93
  </li>
94
  </ul>
@@ -101,7 +103,7 @@ $support = @json_decode(wfConfig::get('supportContent'), true);
101
  <?php if (isset($support['all'])): ?>
102
  <div class="wf-row">
103
  <div class="wf-col-xs-12 wf-col-sm-9 wf-col-sm-half-padding-right wf-add-top">
104
- <h3 class="wf-no-top"><?php _e('All Documentation', 'wordfence'); ?></h3>
105
  </div>
106
  </div>
107
  <div class="wf-row">
@@ -109,7 +111,7 @@ $support = @json_decode(wfConfig::get('supportContent'), true);
109
  <div class="wf-block wf-active">
110
  <div class="wf-block-content">
111
  <div class="wf-support-top-block">
112
- <h4><?php _e('Top Topics and Questions', 'wordfence'); ?></h4>
113
  <ol>
114
  <?php
115
  if (isset($support['top'])):
@@ -157,9 +159,9 @@ $support = @json_decode(wfConfig::get('supportContent'), true);
157
  <div class="wf-block wf-active">
158
  <div class="wf-block-content">
159
  <div class="wf-support-missing-block">
160
- <h4><?php _e('Documentation', 'wordfence'); ?></h4>
161
- <p><?php _e('Documentation about Wordfence may be found on our website by clicking the button below or by clicking the <i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i> links on any of the plugin\'s pages.', 'wordfence'); ?></p>
162
- <p class="wf-no-bottom"><a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_INDEX); ?>" target="_blank" rel="noopener noreferrer" class="wf-btn wf-btn-default wf-btn-callout-subtle"><?php _e('View Documentation', 'wordfence'); ?></a></p>
163
  </div>
164
  </div>
165
  </div>
@@ -264,7 +266,7 @@ $support = @json_decode(wfConfig::get('supportContent'), true);
264
  $.wfcolorbox.resize();
265
  });*/
266
 
267
- var html = '<div class="wf-modal wf-modal-success"><div class="wf-model-success-wrapper"><div class="wf-modal-header"><div class="wf-modal-header-content"><div class="wf-modal-title"><?php _e('Premium License Installed', 'wordfence'); ?></div></div></div><div class="wf-modal-content"><?php _e('Congratulations! Wordfence Premium is now active on your website. Please note that some Premium features are not enabled by default.', 'wordfence'); ?></div></div><div class="wf-modal-footer"><ul class="wf-onboarding-flex-horizontal wf-onboarding-flex-align-right wf-onboarding-full-width"><li><a href="<?php echo esc_url(network_admin_url('admin.php?page=Wordfence')); ?>" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Continue', 'wordfence'); ?></a></li></ul></div></div>';
268
  $.wfcolorbox({
269
  width: (wordfenceExt.isSmallScreen ? '300px' : '500px'),
270
  html: html,
28
  <li>
29
  <ul class="wf-block-list wf-block-list-horizontal">
30
  <li class="wf-flex-vertical">
31
+ <h3><?php esc_html_e('Free Support', 'wordfence'); ?></h3>
32
+ <p class="wf-center"><?php echo wp_kses(__('Support for free customers is available via our forums page on wordpress.org. The majority of requests <strong>receive an answer within a few days.</strong>', 'wordfence'), array('strong'=>array())); ?></p>
33
+ <p><a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FREE); ?>" target="_blank" rel="noopener noreferrer" class="wf-btn wf-btn-default wf-btn-callout-subtle"><?php esc_html_e('Go to Support Forums', 'wordfence'); ?></a></p>
34
  </li>
35
  <li class="wf-flex-vertical">
36
  <?php if (wfConfig::get('isPaid')): ?>
37
+ <h3><?php esc_html_e('Premium Support', 'wordfence'); ?></h3>
38
+ <p class="wf-center"><?php echo wp_kses(__('Our senior support engineers <strong>respond to Premium tickets within a few hours</strong> on average and have a direct line to our QA and development teams.', 'wordfence'), array('strong'=>array())); ?></p>
39
+ <p><a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_PREMIUM); ?>" target="_blank" rel="noopener noreferrer" class="wf-btn wf-btn-primary wf-btn-callout-subtle"><?php esc_html_e('Go to Premium Support', 'wordfence'); ?></a></p>
40
  <?php else: ?>
41
+ <h3><?php esc_html_e('Upgrade Now to Access Premium Support', 'wordfence'); ?></h3>
42
+ <p class="wf-center"><?php echo wp_kses(__('Our senior support engineers <strong>respond to Premium tickets within a few hours</strong> on average and have a direct line to our QA and development teams.', 'wordfence'), array('strong'=>array())); ?></p>
43
+ <p><a href="https://www.wordfence.com/gnl1supportUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wf-btn wf-btn-primary wf-btn-callout-subtle"><?php esc_html_e('Upgrade to Premium', 'wordfence'); ?></a></p>
44
  <?php endif; ?>
45
  </li>
46
  </ul>
56
  <div class="wf-block-header">
57
  <div class="wf-block-header-content">
58
  <div class="wf-block-title">
59
+ <strong><?php esc_html_e('GDPR Information', 'wordfence'); ?></strong>
60
  </div>
61
  <div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('support-gdpr') ? 'true' : 'false'); ?>" tabindex="0"></div></div>
62
  </div>
67
  <ul class="wf-option wf-option-static">
68
  <li class="wf-option-title">
69
  <ul class="wf-flex-vertical wf-flex-align-left">
70
+ <li><?php esc_html_e('General Data Protection Regulation', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_GDPR); ?>" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i></a></li>
71
+ <li class="wf-option-subtitle"><?php esc_html_e('The GDPR is a set of rules that provides more control over EU personal data. Defiant has updated its terms of use, privacy policies, and software, as well as made available a data processing agreement to meet GDPR compliance.', 'wordfence'); ?></li>
72
  </ul>
73
  </li>
74
  </ul>
77
  <ul class="wf-option wf-option-static">
78
  <li class="wf-option-title">
79
  <ul class="wf-flex-vertical wf-flex-align-left">
80
+ <li><?php esc_html_e('Data Processing Agreement', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_GDPR_DPA); ?>" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i></a></li>
81
+ <li class="wf-option-subtitle"><?php echo wp_kses(sprintf(
82
+ /* translators: URL to support page. */
83
+ __('If you qualify as a data controller under the GDPR and need a data processing agreement, it can be <a href="%s" target="_blank" rel="noopener noreferrer">found here</a>.', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_GDPR_DPA)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))); ?></li>
84
  </ul>
85
  </li>
86
  </ul>
89
  <ul class="wf-option wf-option-static">
90
  <li class="wf-option-title">
91
  <ul class="wf-flex-vertical wf-flex-align-left">
92
+ <li><?php esc_html_e('Agreement to New Terms and Privacy Policies', 'wordfence'); ?></li>
93
+ <li class="wf-option-subtitle"><?php esc_html_e('To continue using Defiant products and services including the Wordfence plugin, all customers must review and agree to the updated terms and privacy policies. These changes reflect our commitment to follow data protection best practices and regulations. The Wordfence interface will remain disabled until these terms are agreed to.', 'wordfence'); ?></li>
94
  </ul>
95
  </li>
96
  </ul>
103
  <?php if (isset($support['all'])): ?>
104
  <div class="wf-row">
105
  <div class="wf-col-xs-12 wf-col-sm-9 wf-col-sm-half-padding-right wf-add-top">
106
+ <h3 class="wf-no-top"><?php esc_html_e('All Documentation', 'wordfence'); ?></h3>
107
  </div>
108
  </div>
109
  <div class="wf-row">
111
  <div class="wf-block wf-active">
112
  <div class="wf-block-content">
113
  <div class="wf-support-top-block">
114
+ <h4><?php esc_html_e('Top Topics and Questions', 'wordfence'); ?></h4>
115
  <ol>
116
  <?php
117
  if (isset($support['top'])):
159
  <div class="wf-block wf-active">
160
  <div class="wf-block-content">
161
  <div class="wf-support-missing-block">
162
+ <h4><?php esc_html_e('Documentation', 'wordfence'); ?></h4>
163
+ <p><?php echo wp_kses(__('Documentation about Wordfence may be found on our website by clicking the button below or by clicking the <i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i> links on any of the plugin\'s pages.', 'wordfence'), array('i'=>array('class'=>array(), 'aria-hidden'=>array()))); ?></p>
164
+ <p class="wf-no-bottom"><a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_INDEX); ?>" target="_blank" rel="noopener noreferrer" class="wf-btn wf-btn-default wf-btn-callout-subtle"><?php esc_html_e('View Documentation', 'wordfence'); ?></a></p>
165
  </div>
166
  </div>
167
  </div>
266
  $.wfcolorbox.resize();
267
  });*/
268
 
269
+ var html = '<div class="wf-modal wf-modal-success"><div class="wf-model-success-wrapper"><div class="wf-modal-header"><div class="wf-modal-header-content"><div class="wf-modal-title"><?php esc_html_e('Premium License Installed', 'wordfence'); ?></div></div></div><div class="wf-modal-content"><?php esc_html_e('Congratulations! Wordfence Premium is now active on your website. Please note that some Premium features are not enabled by default.', 'wordfence'); ?></div></div><div class="wf-modal-footer"><ul class="wf-onboarding-flex-horizontal wf-onboarding-flex-align-right wf-onboarding-full-width"><li><a href="<?php echo esc_url(network_admin_url('admin.php?page=Wordfence')); ?>" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Continue', 'wordfence'); ?></a></li></ul></div></div>';
270
  $.wfcolorbox({
271
  width: (wordfenceExt.isSmallScreen ? '300px' : '500px'),
272
  html: html,
lib/menu_tools_diagnostic.php CHANGED
@@ -31,11 +31,11 @@ if (!isset($sendingDiagnosticEmail)) {
31
  <div class="wf-diagnostics-wrapper">
32
  <div class="wf-flex-row">
33
  <div class="wf-flex-row-1">
34
- <?php _e('This page shows information that can be used for troubleshooting conflicts, configuration issues, or compatibility with other plugins, themes, or a host\'s environment.', 'wordfence') ?>
35
  </div>
36
  <div class="wf-flex-row-0 wf-padding-add-left">
37
  <div id="sendByEmailThanks" class="hidden">
38
- <h3><?php _e('Thanks for sending your diagnostic page over email', 'wordfence'); ?></h3>
39
  </div>
40
  <div id="sendByEmailDiv" class="wf-add-bottom">
41
  <span class="wf-nowrap">
@@ -50,21 +50,21 @@ if (!isset($sendingDiagnosticEmail)) {
50
  <div class="wf-block-header">
51
  <div class="wf-block-header-content">
52
  <div class="wf-block-title">
53
- <strong><?php echo esc_html(__('Send Report by Email', 'wordfence')) ?></strong>
54
  </div>
55
  </div>
56
  </div>
57
  <div class="wf-block-content wf-clearfix">
58
  <ul class="wf-block-list">
59
  <li>
60
- <div><?php _e('Email address:', 'wordfence'); ?></div>
61
  <div style="width: 40%">
62
  <p><input class="wf-input-text" type="email" id="_email" value="wftest@wordfence.com"/>
63
  </p>
64
  </div>
65
  </li>
66
  <li>
67
- <div><?php _e('Ticket Number/Forum Username:', 'wordfence'); ?></div>
68
  <div style="width: 40%">
69
  <p><input class="wf-input-text" type="text" id="_ticketnumber" required/></p>
70
  </div>
@@ -119,7 +119,7 @@ if (!isset($sendingDiagnosticEmail)) {
119
  <div class="wf-result-error"><?php echo nl2br(esc_html($result['message'])); ?></div>
120
  <?php endif ?>
121
  <?php if (isset($result['detail']) && !empty($result['detail'])): ?>
122
- <p><strong><?php _e('Additional Detail', 'wordfence'); ?></strong><br><?php echo nl2br(esc_html($result['detail'])); ?></p>
123
  <?php endif; ?>
124
  </td>
125
  </tr>
@@ -162,7 +162,7 @@ if (!isset($sendingDiagnosticEmail)) {
162
  <div class="wf-result-error"><?php echo nl2br(esc_html($result['message'])); ?></div>
163
  <?php endif ?>
164
  <?php if (isset($result['detail']) && !empty($result['detail'])): ?>
165
- <p><a href="#" onclick="jQuery('#wf-diagnostics-detail-<?php echo esc_attr($key); ?>').show(); jQuery(this).hide(); return false;"><?php _e('View Additional Detail', 'wordfence'); ?></a></p>
166
  <pre class="wf-pre wf-split-word" id="wf-diagnostics-detail-<?php echo esc_attr($key); ?>" style="max-width: 600px; display: none;"><?php echo esc_html($result['detail']); ?></pre>
167
  <?php endif; ?>
168
  </div>
@@ -183,8 +183,8 @@ if (!isset($sendingDiagnosticEmail)) {
183
  <div class="wf-block-header">
184
  <div class="wf-block-header-content">
185
  <div class="wf-block-title">
186
- <strong><?php _e('IP Detection', 'wordfence') ?></strong>
187
- <span class="wf-text-small"><?php _e('Methods of detecting a visitor\'s IP address.', 'wordfence') ?></span>
188
  </div>
189
  <div class="wf-block-header-action">
190
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-client-ip') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -196,9 +196,9 @@ if (!isset($sendingDiagnosticEmail)) {
196
  <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
197
  <tbody class="thead">
198
  <tr>
199
- <th><?php _e('IPs', 'wordfence'); ?></th>
200
- <th><?php _e('Value', 'wordfence'); ?></th>
201
- <th><?php _e('Used', 'wordfence'); ?></th>
202
  </tr>
203
  </tbody>
204
  <tbody>
@@ -223,16 +223,16 @@ if (!isset($sendingDiagnosticEmail)) {
223
  }
224
  ?></td>
225
  <?php if ($currentServerVarForIP && $currentServerVarForIP === $variable): ?>
226
- <td class="wf-result-success"><?php _e('In use', 'wordfence'); ?></td>
227
  <?php elseif ($howGet === $variable): ?>
228
- <td class="wf-result-error"><?php _e('Configured but not valid', 'wordfence'); ?></td>
229
  <?php else: ?>
230
  <td></td>
231
  <?php endif ?>
232
  </tr>
233
  <?php endforeach ?>
234
  <tr>
235
- <td><?php _e('Trusted Proxies', 'wordfence'); ?></td>
236
  <td><?php echo esc_html(implode(', ', explode("\n", wfConfig::get('howGetIPs_trusted_proxies', '')))); ?></td>
237
  <td></td>
238
  </tr>
@@ -246,8 +246,8 @@ if (!isset($sendingDiagnosticEmail)) {
246
  <div class="wf-block-header">
247
  <div class="wf-block-header-content">
248
  <div class="wf-block-title">
249
- <strong><?php _e('WordPress Settings', 'wordfence') ?></strong>
250
- <span class="wf-text-small"><?php _e('WordPress version and internal settings/constants.', 'wordfence') ?></span>
251
  </div>
252
  <div class="wf-block-header-action">
253
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-constants') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -273,14 +273,14 @@ if (!isset($sendingDiagnosticEmail)) {
273
  'DB_COLLATE' => __('Database collation', 'wordfence'),
274
  'WP_SITEURL' => __('Explicitly set site URL', 'wordfence'),
275
  'WP_HOME' => __('Explicitly set blog URL', 'wordfence'),
276
- 'WP_CONTENT_DIR' => array('description' => __('"wp-content" folder is in default location', 'wordfence'), 'value' => (realpath(WP_CONTENT_DIR) === realpath(ABSPATH . 'wp-content') ? __('Yes', 'wordfence') : sprintf(__('No: %s', 'wordfence'), WP_CONTENT_DIR))),
277
  'WP_CONTENT_URL' => __('URL to the "wp-content" folder', 'wordfence'),
278
- 'WP_PLUGIN_DIR' => array('description' => __('"plugins" folder is in default location', 'wordfence'), 'value' => (realpath(WP_PLUGIN_DIR) === realpath(ABSPATH . 'wp-content/plugins') ? __('Yes', 'wordfence') : sprintf(__('No: %s', 'wordfence'), WP_PLUGIN_DIR))),
279
- 'WP_LANG_DIR' => array('description' => __('"languages" folder is in default location', 'wordfence'), 'value' => (realpath(WP_LANG_DIR) === realpath(ABSPATH . 'wp-content/languages') ? __('Yes', 'wordfence') : sprintf(__('No: %s', 'wordfence'), WP_LANG_DIR))),
280
  'WPLANG' => __('Language choice', 'wordfence'),
281
  'UPLOADS' => __('Custom upload folder location', 'wordfence'),
282
- 'TEMPLATEPATH' => array('description' => __('Theme template folder override', 'wordfence'), 'value' => (defined('TEMPLATEPATH') && realpath(get_template_directory()) !== realpath(TEMPLATEPATH) ? sprintf(__('Overridden: %s', 'wordfence'), TEMPLATEPATH) : __('(not set)', 'wordfence'))),
283
- 'STYLESHEETPATH' => array('description' => __('Theme stylesheet folder override', 'wordfence'), 'value' => (defined('STYLESHEETPATH') && realpath(get_stylesheet_directory()) !== realpath(STYLESHEETPATH) ? sprintf(__('Overridden: %s', 'wordfence'), STYLESHEETPATH) : __('(not set)', 'wordfence'))),
284
  'AUTOSAVE_INTERVAL' => __('Post editing automatic saving interval', 'wordfence'),
285
  'WP_POST_REVISIONS' => array('description' => __('Post revisions saved by WordPress', 'wordfence'), 'value' => is_numeric($postRevisions) ? $postRevisions : ($postRevisions ? __('Unlimited', 'wordfence') : __('None', 'wordfence'))),
286
  'COOKIE_DOMAIN' => __('WordPress cookie domain', 'wordfence'),
@@ -293,8 +293,8 @@ if (!isset($sendingDiagnosticEmail)) {
293
  'WP_MEMORY_LIMIT' => __('WordPress memory limit', 'wordfence'),
294
  'WP_MAX_MEMORY_LIMIT' => __('Administrative memory limit', 'wordfence'),
295
  'WP_CACHE' => array('description' => __('Built-in caching', 'wordfence'), 'value' => (defined('WP_CACHE') && WP_CACHE ? __('Enabled', 'wordfence') : __('Disabled', 'wordfence'))),
296
- 'CUSTOM_USER_TABLE' => array('description' => __('Custom "users" table', 'wordfence'), 'value' => (defined('CUSTOM_USER_TABLE') ? sprintf(__('Set: %s', 'wordfence'), CUSTOM_USER_TABLE) : __('(not set)', 'wordfence'))),
297
- 'CUSTOM_USER_META_TABLE' => array('description' => __('Custom "usermeta" table', 'wordfence'), 'value' => (defined('CUSTOM_USER_META_TABLE') ? sprintf(__('Set: %s', 'wordfence'), CUSTOM_USER_META_TABLE) : __('(not set)', 'wordfence'))),
298
  'FS_CHMOD_DIR' => array('description' => __('Overridden permissions for a new folder', 'wordfence'), 'value' => defined('FS_CHMOD_DIR') ? decoct(FS_CHMOD_DIR) : __('(not set)', 'wordfence')),
299
  'FS_CHMOD_FILE' => array('description' => __('Overridden permissions for a new file', 'wordfence'), 'value' => defined('FS_CHMOD_FILE') ? decoct(FS_CHMOD_FILE) : __('(not set)', 'wordfence')),
300
  'ALTERNATE_WP_CRON' => array('description' => __('Alternate WP cron', 'wordfence'), 'value' => (defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON ? __('Enabled', 'wordfence') : __('Disabled', 'wordfence'))),
@@ -354,8 +354,8 @@ if (!isset($sendingDiagnosticEmail)) {
354
  <div class="wf-block-header">
355
  <div class="wf-block-header-content">
356
  <div class="wf-block-title">
357
- <strong><?php _e('WordPress Plugins', 'wordfence') ?></strong>
358
- <span class="wf-text-small"><?php _e('Status of installed plugins.', 'wordfence') ?></span>
359
  </div>
360
  <div class="wf-block-header-action">
361
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-plugins') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -379,15 +379,15 @@ if (!isset($sendingDiagnosticEmail)) {
379
  <td>
380
  <strong><?php echo esc_html($pluginData['Name']); ?> (<?php echo esc_html($slug); ?>)</strong>
381
  <?php if (!empty($pluginData['Version'])): ?>
382
- - <?php printf(__('Version %s', 'wordfence'), esc_html($pluginData['Version'])); ?>
383
  <?php endif ?>
384
  </td>
385
  <?php if (array_key_exists(trailingslashit(WP_PLUGIN_DIR) . $plugin, $activeNetworkPlugins)): ?>
386
- <td class="wf-result-success"><?php _e('Network Activated', 'wordfence'); ?></td>
387
  <?php elseif (array_key_exists($plugin, $activePlugins)): ?>
388
- <td class="wf-result-success"><?php _e('Active', 'wordfence'); ?></td>
389
  <?php else: ?>
390
- <td class="wf-result-inactive"><?php _e('Inactive', 'wordfence'); ?></td>
391
  <?php endif ?>
392
  </tr>
393
  <?php endforeach ?>
@@ -399,8 +399,8 @@ if (!isset($sendingDiagnosticEmail)) {
399
  <div class="wf-block-header">
400
  <div class="wf-block-header-content">
401
  <div class="wf-block-title">
402
- <strong><?php _e('Must-Use WordPress Plugins', 'wordfence') ?></strong>
403
- <span class="wf-text-small"><?php _e('WordPress "mu-plugins" that are always active, including those provided by hosts.', 'wordfence') ?></span>
404
  </div>
405
  <div class="wf-block-header-action">
406
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-mu-wordpress-plugins') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -425,17 +425,17 @@ if (!isset($sendingDiagnosticEmail)) {
425
  <td>
426
  <strong><?php echo esc_html($pluginData['Name']) ?> (<?php echo esc_html($slug); ?>)</strong>
427
  <?php if (!empty($pluginData['Version'])): ?>
428
- - <?php printf(__('Version %s', 'wordfence'), esc_html($pluginData['Version'])); ?>
429
  <?php endif ?>
430
  </td>
431
- <td class="wf-result-success"><?php _e('Active', 'wordfence'); ?></td>
432
  </tr>
433
  <?php endforeach ?>
434
  </tbody>
435
  <?php else: ?>
436
  <tbody>
437
  <tr>
438
- <td><?php _e('No MU-Plugins', 'wordfence'); ?></td>
439
  </tr>
440
  </tbody>
441
 
@@ -447,8 +447,8 @@ if (!isset($sendingDiagnosticEmail)) {
447
  <div class="wf-block-header">
448
  <div class="wf-block-header-content">
449
  <div class="wf-block-title">
450
- <strong><?php _e('Drop-In WordPress Plugins', 'wordfence') ?></strong>
451
- <span class="wf-text-small"><?php _e('WordPress "drop-in" plugins that are active.', 'wordfence') ?></span>
452
  </div>
453
  <div class="wf-block-header-action">
454
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-dropin-wordpress-plugins') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -484,9 +484,9 @@ if (!isset($sendingDiagnosticEmail)) {
484
  <strong><?php echo esc_html($data[0]) ?> (<?php echo esc_html($file); ?>)</strong>
485
  </td>
486
  <?php if ($active): ?>
487
- <td class="wf-result-success"><?php _e('Active', 'wordfence'); ?></td>
488
  <?php else: ?>
489
- <td class="wf-result-inactive"><?php _e('Inactive', 'wordfence'); ?></td>
490
  <?php endif; ?>
491
  </tr>
492
  <?php endforeach ?>
@@ -498,8 +498,8 @@ if (!isset($sendingDiagnosticEmail)) {
498
  <div class="wf-block-header">
499
  <div class="wf-block-header-content">
500
  <div class="wf-block-title">
501
- <strong><?php _e('Themes', 'wordfence') ?></strong>
502
- <span class="wf-text-small"><?php _e('Status of installed themes.', 'wordfence') ?></span>
503
  </div>
504
  <div class="wf-block-header-action">
505
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-themes') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -524,12 +524,12 @@ if (!isset($sendingDiagnosticEmail)) {
524
  <td>
525
  <strong><?php echo esc_html($themeData['Name']) ?> (<?php echo esc_html($slug); ?>)</strong>
526
  <?php if (!empty($themeData['Version'])): ?>
527
- - <?php printf(__('Version %s', 'wordfence'), esc_html($themeData['Version'])); ?>
528
  <?php endif ?>
529
  <?php if ($currentTheme instanceof WP_Theme && $theme === $currentTheme->get_stylesheet()): ?>
530
- <td class="wf-result-success"><?php _e('Active', 'wordfence'); ?></td>
531
  <?php else: ?>
532
- <td class="wf-result-inactive"><?php _e('Inactive', 'wordfence'); ?></td>
533
  <?php endif ?>
534
  </tr>
535
  <?php endforeach ?>
@@ -537,7 +537,7 @@ if (!isset($sendingDiagnosticEmail)) {
537
  <?php else: ?>
538
  <tbody>
539
  <tr>
540
- <td><?php _e('No Themes', 'wordfence'); ?></td>
541
  </tr>
542
  </tbody>
543
 
@@ -549,8 +549,8 @@ if (!isset($sendingDiagnosticEmail)) {
549
  <div class="wf-block-header">
550
  <div class="wf-block-header-content">
551
  <div class="wf-block-title">
552
- <strong><?php _e('Cron Jobs', 'wordfence') ?></strong>
553
- <span class="wf-text-small"><?php _e('List of WordPress cron jobs scheduled by WordPress, plugins, or themes.', 'wordfence') ?></span>
554
  </div>
555
  <div class="wf-block-header-action">
556
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-cron-jobs') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -570,7 +570,7 @@ if (!isset($sendingDiagnosticEmail)) {
570
  $overdue = ((time() - 1800) > $timestamp);
571
  ?>
572
  <tr<?php echo $overdue ? ' class="wf-overdue-cron"' : ''; ?>>
573
- <td><?php echo esc_html(date('r', $timestamp)) . ($overdue ? ' <strong>(' . __('Overdue', 'wordfence') . ')</strong>' : '') ?></td>
574
  <td><?php echo esc_html($cron_job) ?></td>
575
  </tr>
576
  <?php
@@ -602,8 +602,8 @@ if (!isset($sendingDiagnosticEmail)) {
602
  <div class="wf-block-header">
603
  <div class="wf-block-header-content">
604
  <div class="wf-block-title">
605
- <strong><?php _e('Database Tables', 'wordfence') ?></strong>
606
- <span class="wf-text-small"><?php _e('Database table names, sizes, timestamps, and other metadata.', 'wordfence') ?></span>
607
  </div>
608
  <div class="wf-block-header-action">
609
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-database-tables') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -613,10 +613,10 @@ if (!isset($sendingDiagnosticEmail)) {
613
  <div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
614
  <ul class="wf-block-list wf-padding-add-left-large wf-padding-add-right-large">
615
  <li style="border-bottom: 1px solid #e2e2e2;">
616
- <div style="width: 75%; min-width: 300px;"><?php _e('Wordfence Table Check', 'wordfence'); ?></div>
617
  <div class="wf-right">
618
  <?php if ($total > 250): ?>
619
- <div class="wf-result-info"><?php _e('Unable to verify - table count too high', 'wordfence'); ?></div>
620
  <?php else:
621
  $hasAll = true;
622
  $schemaTables = wfSchema::tableList();
@@ -645,9 +645,11 @@ if (!isset($sendingDiagnosticEmail)) {
645
  }
646
 
647
  if ($hasAll): ?>
648
- <div class="wf-result-success"><?php _e('All Tables Exist', 'wordfence'); ?></div>
649
  <?php else: ?>
650
- <div class="wf-result-error"><?php printf(__('Tables missing (prefix %s, %s): %s', 'wordfence'), wfDB::networkPrefix(), wfSchema::usingLowercase() ? __('lowercase', 'wordfence') : __('regular case', 'wordfence'), implode(', ', $missingTables)); ?></div>
 
 
651
  <?php endif; ?>
652
  <?php endif; ?>
653
  </div>
@@ -693,7 +695,7 @@ if (!isset($sendingDiagnosticEmail)) {
693
  if ($count >= 250 && $total > $count) {
694
  ?>
695
  <tr>
696
- <td colspan="<?php echo $databaseCols; ?>"><?php printf(__('and %d more', 'wordfence'), $total - $count); ?></td>
697
  </tr>
698
  <?php
699
  break;
@@ -712,8 +714,8 @@ if (!isset($sendingDiagnosticEmail)) {
712
  <div class="wf-block-header">
713
  <div class="wf-block-header-content">
714
  <div class="wf-block-title">
715
- <strong><?php _e('Log Files', 'wordfence') ?></strong>
716
- <span class="wf-text-small"><?php _e('PHP error logs generated by your site, if enabled by your host.', 'wordfence') ?></span>
717
  </div>
718
  <div class="wf-block-header-action">
719
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-log-files') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -725,8 +727,8 @@ if (!isset($sendingDiagnosticEmail)) {
725
  <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
726
  <tbody class="thead thead-subhead" style="font-size: 85%">
727
  <tr>
728
- <th><?php _e('File', 'wordfence'); ?></th>
729
- <th><?php _e('Download', 'wordfence'); ?></th>
730
  </tr>
731
  </tbody>
732
  <tbody style="font-size: 85%">
@@ -734,7 +736,7 @@ if (!isset($sendingDiagnosticEmail)) {
734
  $errorLogs = wfErrorLogHandler::getErrorLogs();
735
  if (count($errorLogs) < 1): ?>
736
  <tr>
737
- <td colspan="2"><em><?php _e('No log files found.', 'wordfence'); ?></em></td>
738
  </tr>
739
  <?php else:
740
  foreach ($errorLogs as $log => $readable): ?>
@@ -764,8 +766,8 @@ if (!isset($sendingDiagnosticEmail)) {
764
  }
765
  ?>
766
  <tr>
767
- <td style="width: 100%"><?php echo esc_html($shortLog); if (!empty($metadata)) { echo ' (' . implode(', ', $metadata) . ')'; } ?></td>
768
- <td style="white-space: nowrap; text-align: right;"><?php echo($readable ? '<a href="#" data-logfile="' . esc_attr($log) . '" class="downloadLogFile" target="_blank" rel="noopener noreferrer">' . __('Download', 'wordfence') . '</a>' : '<em>' . __('Requires downloading from the server directly', 'wordfence') . '</em>'); ?></td>
769
  </tr>
770
  <?php endforeach;
771
  endif; ?>
@@ -779,12 +781,12 @@ if (!isset($sendingDiagnosticEmail)) {
779
 
780
  <?php
781
  if (!empty($inEmail)) {
782
- echo '<h1>' . __('Scan Issues', 'wordfence') . "</h1>\n";
783
  $issues = wfIssues::shared()->getIssues(0, 50, 0, 50);
784
  $issueCounts = array_merge(array('new' => 0, 'ignoreP' => 0, 'ignoreC' => 0), wfIssues::shared()->getIssueCounts());
785
  $issueTypes = wfIssues::validIssueTypes();
786
 
787
- echo '<h2>' . sprintf(__('New Issues (%d total)', 'wordfence'), $issueCounts['new']) . "</h2>\n";
788
  if (isset($issues['new']) && count($issues['new'])) {
789
  foreach ($issues['new'] as $i) {
790
  if (!in_array($i['type'], $issueTypes)) {
@@ -805,7 +807,7 @@ if (!isset($sendingDiagnosticEmail)) {
805
  }
806
  }
807
  else {
808
- echo '<h1>' . __('No New Issues', 'wordfence') . "</h1>\n";
809
  }
810
  }
811
  ?>
@@ -820,8 +822,8 @@ if (!isset($sendingDiagnosticEmail)) {
820
  <div class="wf-block-header">
821
  <div class="wf-block-header-content">
822
  <div class="wf-block-title">
823
- <strong><?php _e('Other Tests', 'wordfence') ?></strong>
824
- <span class="wf-text-small"><?php _e('System configuration, memory test, send test email from this server.', 'wordfence') ?></span>
825
  </div>
826
  <div class="wf-block-header-action">
827
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-other-tests') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -832,33 +834,33 @@ if (!isset($sendingDiagnosticEmail)) {
832
  <ul class="wf-block-list">
833
  <li>
834
  <span>
835
- <a href="<?php echo wfUtils::siteURLRelative(); ?>?_wfsf=sysinfo&nonce=<?php echo wp_create_nonce('wp-ajax'); ?>" target="_blank" rel="noopener noreferrer"><?php _e('Click to view your system\'s configuration in a new window', 'wordfence'); ?></a>
836
  <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_SYSTEM_CONFIGURATION); ?>" target="_blank" rel="noopener noreferrer" class="wfhelp wf-inline-help"></a>
837
  </span>
838
  </li>
839
  <li>
840
  <span>
841
- <a href="<?php echo wfUtils::siteURLRelative(); ?>?_wfsf=testmem&nonce=<?php echo wp_create_nonce('wp-ajax'); ?>" target="_blank" rel="noopener noreferrer"><?php _e('Test your WordPress host\'s available memory', 'wordfence'); ?></a>
842
  <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_TEST_MEMORY); ?>" target="_blank" rel="noopener noreferrer" class="wfhelp wf-inline-help"></a>
843
  </span>
844
  </li>
845
  <li>
846
  <span>
847
- <?php _e('Send a test email from this WordPress server to an email address:', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_TEST_EMAIL); ?>" target="_blank" rel="noopener noreferrer" class="wfhelp wf-inline-help"></a>
848
  <input type="text" id="testEmailDest" value="" size="20" maxlength="255" class="wfConfigElem"/>
849
  <input class="wf-btn wf-btn-default wf-btn-sm" type="button" value="<?php esc_attr_e('Send Test Email', 'wordfence'); ?>" onclick="WFAD.sendTestEmail(jQuery('#testEmailDest').val());"/>
850
  </span>
851
  </li>
852
  <li>
853
  <span>
854
- <?php _e('Send a test activity report email:', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_TEST_ACTIVITY_REPORT); ?>" target="_blank" rel="noopener noreferrer" class="wfhelp wf-inline-help"></a>
855
  <input type="email" id="email_summary_email_address_debug" value="" size="20" maxlength="255" class="wfConfigElem"/>
856
  <input class="wf-btn wf-btn-default wf-btn-sm" type="button" value="<?php esc_attr_e('Send Test Activity Report', 'wordfence'); ?>" onclick="WFAD.ajax('wordfence_email_summary_email_address_debug', {email: jQuery('#email_summary_email_address_debug').val()});"/>
857
  </span>
858
  </li>
859
  <li>
860
  <span>
861
- <?php _e('Clear all Wordfence Central connection data', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_REMOVE_CENTRAL_DATA); ?>" target="_blank" rel="noopener noreferrer" class="wfhelp wf-inline-help"></a>
862
  <input class="wf-btn wf-btn-default wf-btn-sm" type="button" value="<?php esc_attr_e('Clear Connection Data', 'wordfence'); ?>" onclick="WFAD.ajax('wordfence_wfcentral_disconnect', {}, function() { WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), 'Successfully romved data', 'All associated Wordfence Central data has been removed from the database.'); });"/>
863
  </span>
864
  </li>
@@ -871,7 +873,7 @@ if (!isset($sendingDiagnosticEmail)) {
871
  <div class="wf-block-header">
872
  <div class="wf-block-header-content">
873
  <div class="wf-block-title">
874
- <strong><?php _e('Debugging Options', 'wordfence') ?></strong>
875
  </div>
876
  <div class="wf-block-header-action">
877
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-debugging-options') ? 'true' : 'false'); ?>" tabindex="0"></div>
@@ -941,6 +943,18 @@ if (!isset($sendingDiagnosticEmail)) {
941
  ))->render();
942
  ?>
943
  </li>
 
 
 
 
 
 
 
 
 
 
 
 
944
  <li>
945
  <p>
946
  <a id="wf-restore-defaults" class="wf-btn wf-btn-default wf-btn-callout-subtle" href="#" data-restore-defaults-section="<?php echo esc_attr(wfConfig::OPTIONS_TYPE_DIAGNOSTICS); ?>"><?php esc_html_e('Restore Defaults', 'wordfence'); ?></a>
@@ -965,7 +979,7 @@ if (!isset($sendingDiagnosticEmail)) {
965
  'title' => __('Confirm Restore Defaults', 'wordfence'),
966
  'message' => __('Are you sure you want to restore the default Diagnostics settings? This will undo any custom changes you have made to the options on this page.', 'wordfence'),
967
  'primaryButton' => array('id' => 'wf-restore-defaults-prompt-cancel', 'label' => __('Cancel', 'wordfence'), 'link' => '#'),
968
- 'secondaryButtons' => array(array('id' => 'wf-restore-defaults-prompt-confirm', 'labelHTML' => __('Restore<span class="wf-hidden-xs"> Defaults</span>', 'wordfence'), 'link' => '#')),
969
  ))->render();
970
  ?>
971
  </script>
31
  <div class="wf-diagnostics-wrapper">
32
  <div class="wf-flex-row">
33
  <div class="wf-flex-row-1">
34
+ <?php esc_html_e('This page shows information that can be used for troubleshooting conflicts, configuration issues, or compatibility with other plugins, themes, or a host\'s environment.', 'wordfence') ?>
35
  </div>
36
  <div class="wf-flex-row-0 wf-padding-add-left">
37
  <div id="sendByEmailThanks" class="hidden">
38
+ <h3><?php esc_html_e('Thanks for sending your diagnostic page over email', 'wordfence'); ?></h3>
39
  </div>
40
  <div id="sendByEmailDiv" class="wf-add-bottom">
41
  <span class="wf-nowrap">
50
  <div class="wf-block-header">
51
  <div class="wf-block-header-content">
52
  <div class="wf-block-title">
53
+ <strong><?php esc_html_e('Send Report by Email', 'wordfence') ?></strong>
54
  </div>
55
  </div>
56
  </div>
57
  <div class="wf-block-content wf-clearfix">
58
  <ul class="wf-block-list">
59
  <li>
60
+ <div><?php esc_html_e('Email address:', 'wordfence'); ?></div>
61
  <div style="width: 40%">
62
  <p><input class="wf-input-text" type="email" id="_email" value="wftest@wordfence.com"/>
63
  </p>
64
  </div>
65
  </li>
66
  <li>
67
+ <div><?php esc_html_e('Ticket Number/Forum Username:', 'wordfence'); ?></div>
68
  <div style="width: 40%">
69
  <p><input class="wf-input-text" type="text" id="_ticketnumber" required/></p>
70
  </div>
119
  <div class="wf-result-error"><?php echo nl2br(esc_html($result['message'])); ?></div>
120
  <?php endif ?>
121
  <?php if (isset($result['detail']) && !empty($result['detail'])): ?>
122
+ <p><strong><?php esc_html_e('Additional Detail', 'wordfence'); ?></strong><br><?php echo nl2br(esc_html($result['detail'])); ?></p>
123
  <?php endif; ?>
124
  </td>
125
  </tr>
162
  <div class="wf-result-error"><?php echo nl2br(esc_html($result['message'])); ?></div>
163
  <?php endif ?>
164
  <?php if (isset($result['detail']) && !empty($result['detail'])): ?>
165
+ <p><a href="#" onclick="jQuery('#wf-diagnostics-detail-<?php echo esc_attr($key); ?>').show(); jQuery(this).hide(); return false;"><?php esc_html_e('View Additional Detail', 'wordfence'); ?></a></p>
166
  <pre class="wf-pre wf-split-word" id="wf-diagnostics-detail-<?php echo esc_attr($key); ?>" style="max-width: 600px; display: none;"><?php echo esc_html($result['detail']); ?></pre>
167
  <?php endif; ?>
168
  </div>
183
  <div class="wf-block-header">
184
  <div class="wf-block-header-content">
185
  <div class="wf-block-title">
186
+ <strong><?php esc_html_e('IP Detection', 'wordfence') ?></strong>
187
+ <span class="wf-text-small"><?php esc_html_e('Methods of detecting a visitor\'s IP address.', 'wordfence') ?></span>
188
  </div>
189
  <div class="wf-block-header-action">
190
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-client-ip') ? 'true' : 'false'); ?>" tabindex="0"></div>
196
  <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
197
  <tbody class="thead">
198
  <tr>
199
+ <th><?php esc_html_e('IPs', 'wordfence'); ?></th>
200
+ <th><?php esc_html_e('Value', 'wordfence'); ?></th>
201
+ <th><?php esc_html_e('Used', 'wordfence'); ?></th>
202
  </tr>
203
  </tbody>
204
  <tbody>
223
  }
224
  ?></td>
225
  <?php if ($currentServerVarForIP && $currentServerVarForIP === $variable): ?>
226
+ <td class="wf-result-success"><?php esc_html_e('In use', 'wordfence'); ?></td>
227
  <?php elseif ($howGet === $variable): ?>
228
+ <td class="wf-result-error"><?php esc_html_e('Configured but not valid', 'wordfence'); ?></td>
229
  <?php else: ?>
230
  <td></td>
231
  <?php endif ?>
232
  </tr>
233
  <?php endforeach ?>
234
  <tr>
235
+ <td><?php esc_html_e('Trusted Proxies', 'wordfence'); ?></td>
236
  <td><?php echo esc_html(implode(', ', explode("\n", wfConfig::get('howGetIPs_trusted_proxies', '')))); ?></td>
237
  <td></td>
238
  </tr>
246
  <div class="wf-block-header">
247
  <div class="wf-block-header-content">
248
  <div class="wf-block-title">
249
+ <strong><?php esc_html_e('WordPress Settings', 'wordfence') ?></strong>
250
+ <span class="wf-text-small"><?php esc_html_e('WordPress version and internal settings/constants.', 'wordfence') ?></span>
251
  </div>
252
  <div class="wf-block-header-action">
253
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-constants') ? 'true' : 'false'); ?>" tabindex="0"></div>
273
  'DB_COLLATE' => __('Database collation', 'wordfence'),
274
  'WP_SITEURL' => __('Explicitly set site URL', 'wordfence'),
275
  'WP_HOME' => __('Explicitly set blog URL', 'wordfence'),
276
+ 'WP_CONTENT_DIR' => array('description' => __('"wp-content" folder is in default location', 'wordfence'), 'value' => (realpath(WP_CONTENT_DIR) === realpath(ABSPATH . 'wp-content') ? __('Yes', 'wordfence') : sprintf(/* translators: WordPress content directory. */ __('No: %s', 'wordfence'), WP_CONTENT_DIR))),
277
  'WP_CONTENT_URL' => __('URL to the "wp-content" folder', 'wordfence'),
278
+ 'WP_PLUGIN_DIR' => array('description' => __('"plugins" folder is in default location', 'wordfence'), 'value' => (realpath(WP_PLUGIN_DIR) === realpath(ABSPATH . 'wp-content/plugins') ? __('Yes', 'wordfence') : sprintf(/* translators: WordPress plugins directory. */ __('No: %s', 'wordfence'), WP_PLUGIN_DIR))),
279
+ 'WP_LANG_DIR' => array('description' => __('"languages" folder is in default location', 'wordfence'), 'value' => (realpath(WP_LANG_DIR) === realpath(ABSPATH . 'wp-content/languages') ? __('Yes', 'wordfence') : sprintf(/* translators: WordPress languages directory. */ __('No: %s', 'wordfence'), WP_LANG_DIR))),
280
  'WPLANG' => __('Language choice', 'wordfence'),
281
  'UPLOADS' => __('Custom upload folder location', 'wordfence'),
282
+ 'TEMPLATEPATH' => array('description' => __('Theme template folder override', 'wordfence'), 'value' => (defined('TEMPLATEPATH') && realpath(get_template_directory()) !== realpath(TEMPLATEPATH) ? sprintf(/* translators: WordPress theme template directory. */ __('Overridden: %s', 'wordfence'), TEMPLATEPATH) : __('(not set)', 'wordfence'))),
283
+ 'STYLESHEETPATH' => array('description' => __('Theme stylesheet folder override', 'wordfence'), 'value' => (defined('STYLESHEETPATH') && realpath(get_stylesheet_directory()) !== realpath(STYLESHEETPATH) ? sprintf(/* translators: WordPress theme stylesheet directory. */ __('Overridden: %s', 'wordfence'), STYLESHEETPATH) : __('(not set)', 'wordfence'))),
284
  'AUTOSAVE_INTERVAL' => __('Post editing automatic saving interval', 'wordfence'),
285
  'WP_POST_REVISIONS' => array('description' => __('Post revisions saved by WordPress', 'wordfence'), 'value' => is_numeric($postRevisions) ? $postRevisions : ($postRevisions ? __('Unlimited', 'wordfence') : __('None', 'wordfence'))),
286
  'COOKIE_DOMAIN' => __('WordPress cookie domain', 'wordfence'),
293
  'WP_MEMORY_LIMIT' => __('WordPress memory limit', 'wordfence'),
294
  'WP_MAX_MEMORY_LIMIT' => __('Administrative memory limit', 'wordfence'),
295
  'WP_CACHE' => array('description' => __('Built-in caching', 'wordfence'), 'value' => (defined('WP_CACHE') && WP_CACHE ? __('Enabled', 'wordfence') : __('Disabled', 'wordfence'))),
296
+ 'CUSTOM_USER_TABLE' => array('description' => __('Custom "users" table', 'wordfence'), 'value' => (defined('CUSTOM_USER_TABLE') ? sprintf(/* translators: WordPress custom user table. */ __('Set: %s', 'wordfence'), CUSTOM_USER_TABLE) : __('(not set)', 'wordfence'))),
297
+ 'CUSTOM_USER_META_TABLE' => array('description' => __('Custom "usermeta" table', 'wordfence'), 'value' => (defined('CUSTOM_USER_META_TABLE') ? sprintf(/* translators: WordPress custom user meta table. */ __('Set: %s', 'wordfence'), CUSTOM_USER_META_TABLE) : __('(not set)', 'wordfence'))),
298
  'FS_CHMOD_DIR' => array('description' => __('Overridden permissions for a new folder', 'wordfence'), 'value' => defined('FS_CHMOD_DIR') ? decoct(FS_CHMOD_DIR) : __('(not set)', 'wordfence')),
299
  'FS_CHMOD_FILE' => array('description' => __('Overridden permissions for a new file', 'wordfence'), 'value' => defined('FS_CHMOD_FILE') ? decoct(FS_CHMOD_FILE) : __('(not set)', 'wordfence')),
300
  'ALTERNATE_WP_CRON' => array('description' => __('Alternate WP cron', 'wordfence'), 'value' => (defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON ? __('Enabled', 'wordfence') : __('Disabled', 'wordfence'))),
354
  <div class="wf-block-header">
355
  <div class="wf-block-header-content">
356
  <div class="wf-block-title">
357
+ <strong><?php esc_html_e('WordPress Plugins', 'wordfence') ?></strong>
358
+ <span class="wf-text-small"><?php esc_html_e('Status of installed plugins.', 'wordfence') ?></span>
359
  </div>
360
  <div class="wf-block-header-action">
361
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-plugins') ? 'true' : 'false'); ?>" tabindex="0"></div>
379
  <td>
380
  <strong><?php echo esc_html($pluginData['Name']); ?> (<?php echo esc_html($slug); ?>)</strong>
381
  <?php if (!empty($pluginData['Version'])): ?>
382
+ - <?php echo esc_html(sprintf(__('Version %s', 'wordfence'), $pluginData['Version'])); ?>
383
  <?php endif ?>
384
  </td>
385
  <?php if (array_key_exists(trailingslashit(WP_PLUGIN_DIR) . $plugin, $activeNetworkPlugins)): ?>
386
+ <td class="wf-result-success"><?php esc_html_e('Network Activated', 'wordfence'); ?></td>
387
  <?php elseif (array_key_exists($plugin, $activePlugins)): ?>
388
+ <td class="wf-result-success"><?php esc_html_e('Active', 'wordfence'); ?></td>
389
  <?php else: ?>
390
+ <td class="wf-result-inactive"><?php esc_html_e('Inactive', 'wordfence'); ?></td>
391
  <?php endif ?>
392
  </tr>
393
  <?php endforeach ?>
399
  <div class="wf-block-header">
400
  <div class="wf-block-header-content">
401
  <div class="wf-block-title">
402
+ <strong><?php esc_html_e('Must-Use WordPress Plugins', 'wordfence') ?></strong>
403
+ <span class="wf-text-small"><?php esc_html_e('WordPress "mu-plugins" that are always active, including those provided by hosts.', 'wordfence') ?></span>
404
  </div>
405
  <div class="wf-block-header-action">
406
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-mu-wordpress-plugins') ? 'true' : 'false'); ?>" tabindex="0"></div>
425
  <td>
426
  <strong><?php echo esc_html($pluginData['Name']) ?> (<?php echo esc_html($slug); ?>)</strong>
427
  <?php if (!empty($pluginData['Version'])): ?>
428
+ - <?php echo esc_html(sprintf(/* translators: Plugin version. */ __('Version %s', 'wordfence'), $pluginData['Version'])); ?>
429
  <?php endif ?>
430
  </td>
431
+ <td class="wf-result-success"><?php esc_html_e('Active', 'wordfence'); ?></td>
432
  </tr>
433
  <?php endforeach ?>
434
  </tbody>
435
  <?php else: ?>
436
  <tbody>
437
  <tr>
438
+ <td><?php esc_html_e('No MU-Plugins', 'wordfence'); ?></td>
439
  </tr>
440
  </tbody>
441
 
447
  <div class="wf-block-header">
448
  <div class="wf-block-header-content">
449
  <div class="wf-block-title">
450
+ <strong><?php esc_html_e('Drop-In WordPress Plugins', 'wordfence') ?></strong>
451
+ <span class="wf-text-small"><?php esc_html_e('WordPress "drop-in" plugins that are active.', 'wordfence') ?></span>
452
  </div>
453
  <div class="wf-block-header-action">
454
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-dropin-wordpress-plugins') ? 'true' : 'false'); ?>" tabindex="0"></div>
484
  <strong><?php echo esc_html($data[0]) ?> (<?php echo esc_html($file); ?>)</strong>
485
  </td>
486
  <?php if ($active): ?>
487
+ <td class="wf-result-success"><?php esc_html_e('Active', 'wordfence'); ?></td>
488
  <?php else: ?>
489
+ <td class="wf-result-inactive"><?php esc_html_e('Inactive', 'wordfence'); ?></td>
490
  <?php endif; ?>
491
  </tr>
492
  <?php endforeach ?>
498
  <div class="wf-block-header">
499
  <div class="wf-block-header-content">
500
  <div class="wf-block-title">
501
+ <strong><?php esc_html_e('Themes', 'wordfence') ?></strong>
502
+ <span class="wf-text-small"><?php esc_html_e('Status of installed themes.', 'wordfence') ?></span>
503
  </div>
504
  <div class="wf-block-header-action">
505
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-themes') ? 'true' : 'false'); ?>" tabindex="0"></div>
524
  <td>
525
  <strong><?php echo esc_html($themeData['Name']) ?> (<?php echo esc_html($slug); ?>)</strong>
526
  <?php if (!empty($themeData['Version'])): ?>
527
+ - <?php echo esc_html(sprintf(/* translators: Theme version. */ __('Version %s', 'wordfence'), $themeData['Version'])); ?>
528
  <?php endif ?>
529
  <?php if ($currentTheme instanceof WP_Theme && $theme === $currentTheme->get_stylesheet()): ?>
530
+ <td class="wf-result-success"><?php esc_html_e('Active', 'wordfence'); ?></td>
531
  <?php else: ?>
532
+ <td class="wf-result-inactive"><?php esc_html_e('Inactive', 'wordfence'); ?></td>
533
  <?php endif ?>
534
  </tr>
535
  <?php endforeach ?>
537
  <?php else: ?>
538
  <tbody>
539
  <tr>
540
+ <td><?php esc_html_e('No Themes', 'wordfence'); ?></td>
541
  </tr>
542
  </tbody>
543
 
549
  <div class="wf-block-header">
550
  <div class="wf-block-header-content">
551
  <div class="wf-block-title">
552
+ <strong><?php esc_html_e('Cron Jobs', 'wordfence') ?></strong>
553
+ <span class="wf-text-small"><?php esc_html_e('List of WordPress cron jobs scheduled by WordPress, plugins, or themes.', 'wordfence') ?></span>
554
  </div>
555
  <div class="wf-block-header-action">
556
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-cron-jobs') ? 'true' : 'false'); ?>" tabindex="0"></div>
570
  $overdue = ((time() - 1800) > $timestamp);
571
  ?>
572
  <tr<?php echo $overdue ? ' class="wf-overdue-cron"' : ''; ?>>
573
+ <td><?php echo esc_html(date('r', $timestamp)) . ($overdue ? ' <strong>(' . esc_html__('Overdue', 'wordfence') . ')</strong>' : '') ?></td>
574
  <td><?php echo esc_html($cron_job) ?></td>
575
  </tr>
576
  <?php
602
  <div class="wf-block-header">
603
  <div class="wf-block-header-content">
604
  <div class="wf-block-title">
605
+ <strong><?php esc_html_e('Database Tables', 'wordfence') ?></strong>
606
+ <span class="wf-text-small"><?php esc_html_e('Database table names, sizes, timestamps, and other metadata.', 'wordfence') ?></span>
607
  </div>
608
  <div class="wf-block-header-action">
609
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-database-tables') ? 'true' : 'false'); ?>" tabindex="0"></div>
613
  <div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
614
  <ul class="wf-block-list wf-padding-add-left-large wf-padding-add-right-large">
615
  <li style="border-bottom: 1px solid #e2e2e2;">
616
+ <div style="width: 75%; min-width: 300px;"><?php esc_html_e('Wordfence Table Check', 'wordfence'); ?></div>
617
  <div class="wf-right">
618
  <?php if ($total > 250): ?>
619
+ <div class="wf-result-info"><?php esc_html_e('Unable to verify - table count too high', 'wordfence'); ?></div>
620
  <?php else:
621
  $hasAll = true;
622
  $schemaTables = wfSchema::tableList();
645
  }
646
 
647
  if ($hasAll): ?>
648
+ <div class="wf-result-success"><?php esc_html_e('All Tables Exist', 'wordfence'); ?></div>
649
  <?php else: ?>
650
+ <div class="wf-result-error"><?php echo esc_html(sprintf(
651
+ /* translators: 1. WordPress table prefix. 2. Wordfence table case. 3. List of database tables. */
652
+ __('Tables missing (prefix %1$s, %2$s): %3$s', 'wordfence'), wfDB::networkPrefix(), wfSchema::usingLowercase() ? __('lowercase', 'wordfence') : __('regular case', 'wordfence'), implode(', ', $missingTables))); ?></div>
653
  <?php endif; ?>
654
  <?php endif; ?>
655
  </div>
695
  if ($count >= 250 && $total > $count) {
696
  ?>
697
  <tr>
698
+ <td colspan="<?php echo $databaseCols; ?>"><?php echo esc_html(sprintf(/* translators: Row/record count. */ __('and %d more', 'wordfence'), $total - $count)); ?></td>
699
  </tr>
700
  <?php
701
  break;
714
  <div class="wf-block-header">
715
  <div class="wf-block-header-content">
716
  <div class="wf-block-title">
717
+ <strong><?php esc_html_e('Log Files', 'wordfence') ?></strong>
718
+ <span class="wf-text-small"><?php esc_html_e('PHP error logs generated by your site, if enabled by your host.', 'wordfence') ?></span>
719
  </div>
720
  <div class="wf-block-header-action">
721
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-log-files') ? 'true' : 'false'); ?>" tabindex="0"></div>
727
  <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
728
  <tbody class="thead thead-subhead" style="font-size: 85%">
729
  <tr>
730
+ <th><?php esc_html_e('File', 'wordfence'); ?></th>
731
+ <th><?php esc_html_e('Download', 'wordfence'); ?></th>
732
  </tr>
733
  </tbody>
734
  <tbody style="font-size: 85%">
736
  $errorLogs = wfErrorLogHandler::getErrorLogs();
737
  if (count($errorLogs) < 1): ?>
738
  <tr>
739
+ <td colspan="2"><em><?php esc_html_e('No log files found.', 'wordfence'); ?></em></td>
740
  </tr>
741
  <?php else:
742
  foreach ($errorLogs as $log => $readable): ?>
766
  }
767
  ?>
768
  <tr>
769
+ <td style="width: 100%"><?php echo esc_html($shortLog); if (!empty($metadata)) { echo ' (' . esc_html(implode(', ', $metadata)) . ')'; } ?></td>
770
+ <td style="white-space: nowrap; text-align: right;"><?php echo($readable ? '<a href="#" data-logfile="' . esc_attr($log) . '" class="downloadLogFile" target="_blank" rel="noopener noreferrer">' . esc_html__('Download', 'wordfence') . '</a>' : '<em>' . esc_html__('Requires downloading from the server directly', 'wordfence') . '</em>'); ?></td>
771
  </tr>
772
  <?php endforeach;
773
  endif; ?>
781
 
782
  <?php
783
  if (!empty($inEmail)) {
784
+ echo '<h1>' . esc_html__('Scan Issues', 'wordfence') . "</h1>\n";
785
  $issues = wfIssues::shared()->getIssues(0, 50, 0, 50);
786
  $issueCounts = array_merge(array('new' => 0, 'ignoreP' => 0, 'ignoreC' => 0), wfIssues::shared()->getIssueCounts());
787
  $issueTypes = wfIssues::validIssueTypes();
788
 
789
+ echo '<h2>' . esc_html(sprintf(/* translators: Number of scan issues. */ __('New Issues (%d total)', 'wordfence'), $issueCounts['new'])) . "</h2>\n";
790
  if (isset($issues['new']) && count($issues['new'])) {
791
  foreach ($issues['new'] as $i) {
792
  if (!in_array($i['type'], $issueTypes)) {
807
  }
808
  }
809
  else {
810
+ echo '<h1>' . esc_html__('No New Issues', 'wordfence') . "</h1>\n";
811
  }
812
  }
813
  ?>
822
  <div class="wf-block-header">
823
  <div class="wf-block-header-content">
824
  <div class="wf-block-title">
825
+ <strong><?php esc_html_e('Other Tests', 'wordfence') ?></strong>
826
+ <span class="wf-text-small"><?php esc_html_e('System configuration, memory test, send test email from this server.', 'wordfence') ?></span>
827
  </div>
828
  <div class="wf-block-header-action">
829
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-other-tests') ? 'true' : 'false'); ?>" tabindex="0"></div>
834
  <ul class="wf-block-list">
835
  <li>
836
  <span>
837
+ <a href="<?php echo wfUtils::siteURLRelative(); ?>?_wfsf=sysinfo&nonce=<?php echo wp_create_nonce('wp-ajax'); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Click to view your system\'s configuration in a new window', 'wordfence'); ?></a>
838
  <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_SYSTEM_CONFIGURATION); ?>" target="_blank" rel="noopener noreferrer" class="wfhelp wf-inline-help"></a>
839
  </span>
840
  </li>
841
  <li>
842
  <span>
843
+ <a href="<?php echo wfUtils::siteURLRelative(); ?>?_wfsf=testmem&nonce=<?php echo wp_create_nonce('wp-ajax'); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Test your WordPress host\'s available memory', 'wordfence'); ?></a>
844
  <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_TEST_MEMORY); ?>" target="_blank" rel="noopener noreferrer" class="wfhelp wf-inline-help"></a>
845
  </span>
846
  </li>
847
  <li>
848
  <span>
849
+ <?php esc_html_e('Send a test email from this WordPress server to an email address:', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_TEST_EMAIL); ?>" target="_blank" rel="noopener noreferrer" class="wfhelp wf-inline-help"></a>
850
  <input type="text" id="testEmailDest" value="" size="20" maxlength="255" class="wfConfigElem"/>
851
  <input class="wf-btn wf-btn-default wf-btn-sm" type="button" value="<?php esc_attr_e('Send Test Email', 'wordfence'); ?>" onclick="WFAD.sendTestEmail(jQuery('#testEmailDest').val());"/>
852
  </span>
853
  </li>
854
  <li>
855
  <span>
856
+ <?php esc_html_e('Send a test activity report email:', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_TEST_ACTIVITY_REPORT); ?>" target="_blank" rel="noopener noreferrer" class="wfhelp wf-inline-help"></a>
857
  <input type="email" id="email_summary_email_address_debug" value="" size="20" maxlength="255" class="wfConfigElem"/>
858
  <input class="wf-btn wf-btn-default wf-btn-sm" type="button" value="<?php esc_attr_e('Send Test Activity Report', 'wordfence'); ?>" onclick="WFAD.ajax('wordfence_email_summary_email_address_debug', {email: jQuery('#email_summary_email_address_debug').val()});"/>
859
  </span>
860
  </li>
861
  <li>
862
  <span>
863
+ <?php esc_html_e('Clear all Wordfence Central connection data', 'wordfence'); ?> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_DIAGNOSTICS_REMOVE_CENTRAL_DATA); ?>" target="_blank" rel="noopener noreferrer" class="wfhelp wf-inline-help"></a>
864
  <input class="wf-btn wf-btn-default wf-btn-sm" type="button" value="<?php esc_attr_e('Clear Connection Data', 'wordfence'); ?>" onclick="WFAD.ajax('wordfence_wfcentral_disconnect', {}, function() { WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), 'Successfully romved data', 'All associated Wordfence Central data has been removed from the database.'); });"/>
865
  </span>
866
  </li>
873
  <div class="wf-block-header">
874
  <div class="wf-block-header-content">
875
  <div class="wf-block-title">
876
+ <strong><?php esc_html_e('Debugging Options', 'wordfence') ?></strong>
877
  </div>
878
  <div class="wf-block-header-action">
879
  <div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive('wf-diagnostics-debugging-options') ? 'true' : 'false'); ?>" tabindex="0"></div>
943
  ))->render();
944
  ?>
945
  </li>
946
+ <li>
947
+ <?php
948
+ echo wfView::create('options/option-toggled', array(
949
+ 'optionName' => 'wordfenceI18n',
950
+ 'enabledValue' => 1,
951
+ 'disabledValue' => 0,
952
+ 'value' => $w->get('wordfenceI18n') ? 1 : 0,
953
+ 'title' => 'Enable Wordfence translations',
954
+ 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_DIAGNOSTICS_OPTION_WORDFENCE_TRANSLATIONS),
955
+ ))->render();
956
+ ?>
957
+ </li>
958
  <li>
959
  <p>
960
  <a id="wf-restore-defaults" class="wf-btn wf-btn-default wf-btn-callout-subtle" href="#" data-restore-defaults-section="<?php echo esc_attr(wfConfig::OPTIONS_TYPE_DIAGNOSTICS); ?>"><?php esc_html_e('Restore Defaults', 'wordfence'); ?></a>
979
  'title' => __('Confirm Restore Defaults', 'wordfence'),
980
  'message' => __('Are you sure you want to restore the default Diagnostics settings? This will undo any custom changes you have made to the options on this page.', 'wordfence'),
981
  'primaryButton' => array('id' => 'wf-restore-defaults-prompt-cancel', 'label' => __('Cancel', 'wordfence'), 'link' => '#'),
982
+ 'secondaryButtons' => array(array('id' => 'wf-restore-defaults-prompt-confirm', 'labelHTML' => wp_kses(__('Restore<span class="wf-hidden-xs"> Defaults</span>', 'wordfence'), array('span'=>array('class'=>array()))), 'link' => '#')),
983
  ))->render();
984
  ?>
985
  </script>
lib/menu_tools_importExport.php CHANGED
@@ -10,12 +10,14 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
10
  </script>
11
  <div id="wf-tools-importexport">
12
  <div class="wf-section-title">
13
- <h2><?php _e('Import/Export Options', 'wordfence') ?></h2>
14
- <span><?php printf(__('<a href="%s" target="_blank" rel="noopener noreferrer" class="wf-help-link">Learn more<span class="wf-hidden-xs"> about importing and exporting options</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_TOOLS_IMPORT_EXPORT)); ?>
 
 
15
  <i class="wf-fa wf-fa-external-link" aria-hidden="true"></i></span>
16
  </div>
17
 
18
- <p><?php _e("To clone one site's configuration to another, use the import/export tools below.", 'wordfence') ?></p>
19
 
20
  <?php
21
  echo wfView::create('dashboard/options-group-import', array(
@@ -23,4 +25,4 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
23
  'collapseable' => false,
24
  ))->render();
25
  ?>
26
- </div>
10
  </script>
11
  <div id="wf-tools-importexport">
12
  <div class="wf-section-title">
13
+ <h2><?php esc_html_e('Import/Export Options', 'wordfence') ?></h2>
14
+ <span><?php echo wp_kses(sprintf(
15
+ /* translators: URL to support page. */
16
+ __('<a href="%s" target="_blank" rel="noopener noreferrer" class="wf-help-link">Learn more<span class="wf-hidden-xs"> about importing and exporting options</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_TOOLS_IMPORT_EXPORT)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array(), 'class'=>array()), 'span'=>array('class'=>array()))); ?>
17
  <i class="wf-fa wf-fa-external-link" aria-hidden="true"></i></span>
18
  </div>
19
 
20
+ <p><?php esc_html_e("To clone one site's configuration to another, use the import/export tools below.", 'wordfence') ?></p>
21
 
22
  <?php
23
  echo wfView::create('dashboard/options-group-import', array(
25
  'collapseable' => false,
26
  ))->render();
27
  ?>
28
+ </div>
lib/menu_tools_livetraffic.php CHANGED
@@ -38,21 +38,23 @@ $w = new wfConfig();
38
  })(jQuery);
39
  </script>
40
  <div class="wf-section-title">
41
- <h2><?php _e('Live Traffic', 'wordfence') ?></h2>
42
- <span><?php printf(__('<a href="%s" target="_blank" rel="noopener noreferrer" class="wf-help-link">Learn more<span class="wf-hidden-xs"> about Live Traffic</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_TOOLS_LIVE_TRAFFIC)); ?>
 
 
43
  <i class="wf-fa wf-fa-external-link" aria-hidden="true"></i></span>
44
  </div>
45
 
46
  <?php if (wfConfig::liveTrafficEnabled() && wfConfig::get('liveActivityPauseEnabled')): ?>
47
  <div id="wfLiveTrafficOverlayAnchor"></div>
48
  <div id="wfLiveTrafficDisabledMessage">
49
- <h2><?php _e('Live Updates Paused', 'wordfence') ?><br/>
50
- <small><?php _e('Click inside window to resume', 'wordfence') ?></small>
51
  </h2>
52
  </div>
53
  <?php endif ?>
54
 
55
- <p><?php _e("Wordfence Live Traffic shows you what is happening on your site in real-time, including user logins, hack attempts, and requests that were blocked by the Wordfence Firewall. You can choose to log security-related traffic only or all traffic. Traffic is logged directly on the server, which means it includes visits that don't execute JavaScript. Google and other JavaScript-based analytics packages typically only show visits from browsers that are operated by a human, while Live Traffic can show visits from crawlers like Google and Bing.", 'wordfence') ?></p>
56
 
57
  <div class="wordfenceModeElem" id="wordfenceMode_liveTraffic"></div>
58
 
@@ -68,17 +70,21 @@ $overridden = false;
68
  if (!wfConfig::liveTrafficEnabled($overridden)):
69
  ?>
70
  <div id="wordfenceLiveActivitySecurityOnly"><p>
71
- <strong><?php _e('Traffic logging mode: Security-related traffic only', 'wordfence') ?><?php
72
  if ($overridden) {
73
- printf(__(' (host setting <a href="%s" class="wfhelp" target="_blank" rel="noopener noreferrer"></a>)', 'wordfence'), wfSupportController::supportURL(wfSupportController::ITEM_TOOLS_LIVE_TRAFFIC_OPTION_ENABLE));
74
- } ?>.</strong> <?php _e('Login and firewall activity will appear below.', 'wordfence') ?></p>
 
 
75
  </div>
76
  <?php else: ?>
77
  <div id="wordfenceLiveActivityAll"><p>
78
- <strong><?php _e('Traffic logging mode: All traffic', 'wordfence') ?><?php
79
  if ($overridden) {
80
- printf(__(' (host setting <a href="%s" class="wfhelp" target="_blank" rel="noopener noreferrer"></a>)', 'wordfence'), wfSupportController::supportURL(wfSupportController::ITEM_TOOLS_LIVE_TRAFFIC_OPTION_ENABLE));
81
- } ?>.</strong> <?php _e('Regular traffic and security-related traffic will appear below.', 'wordfence') ?></p>
 
 
82
  </div>
83
  <?php endif; ?>
84
 
@@ -91,10 +97,10 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
91
  <div class="<?php echo wfStyle::contentClasses(); ?>">
92
  <div id="wf-live-traffic-legend">
93
  <ul>
94
- <li class="wfHuman"><?php _e('Human', 'wordfence') ?></li>
95
- <li class="wfBot"><?php _e('Bot', 'wordfence') ?></li>
96
- <li class="wfNotice"><?php _e('Warning', 'wordfence') ?></li>
97
- <li class="wfBlocked"><?php _e('Blocked', 'wordfence') ?></li>
98
  </ul>
99
  </div>
100
  <div class="wf-row wf-add-bottom-small">
@@ -108,14 +114,14 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
108
  &nbsp;&nbsp;
109
  <input id="wf-live-traffic-filter-show-advanced" class="wf-option-checkbox" data-bind="checked: showAdvancedFilters" type="checkbox">
110
  <label for="wf-live-traffic-filter-show-advanced">
111
- <?php _e('Show Advanced Filters', 'wordfence') ?>
112
  </label>
113
  </li>
114
  <li class="wf-live-traffic-show-expanded">
115
  <ul class="wf-option wf-option-toggled-boolean-switch wf-option-no-spacing" data-option="liveTraf_displayExpandedRecords" data-enabled-value="1" data-disabled-value="0" data-original-value="<?php echo wfConfig::get('liveTraf_displayExpandedRecords') ? 1 : 0; ?>">
116
  <li class="wf-boolean-switch<?php echo wfConfig::get('liveTraf_displayExpandedRecords') ? ' wf-active' : ''; ?>"><a href="#" class="wf-boolean-switch-handle"></a></li>
117
  <li class="wf-option-title wf-padding-add-left wf-no-right wf-padding-no-right">
118
- <?php echo __('Expand All Results', 'wordfence'); ?>
119
  </li>
120
  </ul>
121
  </li>
@@ -143,8 +149,8 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
143
  </span>
144
 
145
  <span data-bind="if: selectedFilterParamOptionValue() && selectedFilterParamOptionValue().type() == 'bool'">
146
- <label>Yes <input data-bind="checked: value" type="radio" value="1"></label>
147
- <label>No <input data-bind="checked: value" type="radio" value="0"></label>
148
  </span>
149
  </div>
150
  </div>
@@ -157,28 +163,28 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
157
  <div>
158
  <div class="wf-pad-small">
159
  <button type="button" class="wf-btn wf-btn-default" data-bind="click: addFilter">
160
- Add Filter
161
  </button>
162
  </div>
163
  </div>
164
  </div>
165
  <div class="wf-form wf-form-horizontal">
166
  <div class="wf-form-group">
167
- <label for="wf-live-traffic-from" class="wf-col-sm-2">From:&nbsp;</label>
168
  <div class="wf-col-sm-10">
169
  <input placeholder="Start date" id="wf-live-traffic-from" type="text" class="wf-datetime" data-bind="value: startDate, datetimepicker: null, datepickerOptions: { timeFormat: 'hh:mm tt z' }">
170
- <button data-bind="click: startDate('')" class="wf-btn wf-btn-default wf-btn-sm" type="button">Clear</button>
171
  </div>
172
  </div>
173
  <div class="wf-form-group">
174
- <label for="wf-live-traffic-to" class="wf-col-sm-2">To:&nbsp;</label>
175
  <div class="wf-col-sm-10">
176
  <input placeholder="End date" id="wf-live-traffic-to" type="text" class="wf-datetime" data-bind="value: endDate, datetimepicker: null, datepickerOptions: { timeFormat: 'hh:mm tt z' }">
177
- <button data-bind="click: endDate('')" class="wf-btn wf-btn-default wf-btn-sm" type="button">Clear</button>
178
  </div>
179
  </div>
180
  <div class="wf-form-group">
181
- <label for="wf-live-traffic-group-by" class="wf-col-sm-2">Group&nbsp;By:&nbsp;</label>
182
  <div class="wf-col-sm-10">
183
  <select id="wf-live-traffic-group-by" name="groupby" class="wf-lt-advanced-filters-groupby" data-bind="options: filterGroupByOptions, optionsText: filterGroupByOptionsText, value: groupBy, optionsCaption: 'None'"></select>
184
  </div>
@@ -203,12 +209,12 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
203
  target="_blank" rel="noopener noreferrer"></a>
204
  </div>
205
  <div data-bind="if: !loc()">
206
- An unknown location at IP
207
  <span data-bind="text: IP" target="_blank" rel="noopener noreferrer"></span>
208
  </div>
209
 
210
  <div>
211
- <strong>IP:</strong>
212
  <span data-bind="text: IP" target="_blank" rel="noopener noreferrer"></span>
213
  </div>
214
  <div>
@@ -217,56 +223,56 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
217
  <!-- /ko -->
218
  <!-- ko if: $root.groupBy().param() == 'type' -->
219
  <div>
220
- <strong>Type:</strong>
221
- <span data-bind="if: jsRun() == '1'">Human</span>
222
- <span data-bind="if: jsRun() == '0'">Bot</span>
223
  </div>
224
  <!-- /ko -->
225
  <!-- ko if: $root.groupBy().param() == 'user_login' -->
226
  <div>
227
- <strong>Username:</strong>
228
  <span data-bind="text: username()"></span>
229
  </div>
230
  <!-- /ko -->
231
  <!-- ko if: $root.groupBy().param() == 'statusCode' -->
232
  <div>
233
- <strong>HTTP Response Code:</strong>
234
  <span data-bind="text: statusCode()"></span>
235
  </div>
236
  <!-- /ko -->
237
  <!-- ko if: $root.groupBy().param() == 'action' -->
238
  <div>
239
- <strong>Firewall Response:</strong>
240
  <span data-bind="text: firewallAction()"></span>
241
  </div>
242
  <!-- /ko -->
243
  <!-- ko if: $root.groupBy().param() == 'url' -->
244
  <div>
245
- <strong>URL:</strong>
246
  <span data-bind="text: displayURL()"></span>
247
  </div>
248
  <!-- /ko -->
249
  <div>
250
- <strong>Last Hit:</strong> <span
251
- data-bind="attr: { 'data-timestamp': ctime, text: 'Last hit was ' + ctime() + ' ago.' }"
252
  class="wfTimeAgo wfTimeAgo-timestamp"></span>
253
  </div>
254
  <!-- ko if: $root.groupBy().param() == 'ip' -->
255
  <div class="wf-add-top-small">
256
  <span data-bind="if: blocked()">
257
- <a class="wf-btn wf-btn-default wf-btn-sm" data-bind="click: unblockIP">Unblock IP</a>
258
  </span>
259
  <span data-bind="if: rangeBlocked()">
260
- <a class="wf-btn wf-btn-default wf-btn-sm" data-bind="click: unblockNetwork">Unblock range</a>
261
  </span>
262
  <span data-bind="if: !blocked() && !rangeBlocked()">
263
- <a class="wf-btn wf-btn-default wf-btn-sm" data-bind="click: blockIP">Block IP</a>
264
  </span>
265
  </div>
266
  <!-- /ko -->
267
  </div>
268
  <div class="wf-flex-row-0 wf-padding-add-left">
269
- <span class="wf-filtered-traffic-hits" data-bind="text: hitCount"></span> hits
270
  </div>
271
  </li>
272
 
@@ -277,14 +283,14 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
277
  <table class="wf-striped-table">
278
  <thead>
279
  <tr>
280
- <th>Type</th>
281
- <th>Location</th>
282
- <th>Page Visited</th>
283
- <th>Time</th>
284
- <th>IP Address</th>
285
- <th>Hostname</th>
286
- <th>Response</th>
287
- <th>View</th>
288
  </tr>
289
  </thead>
290
  <tbody id="wf-lt-listings" class="wf-filtered-traffic" data-bind="foreach: listings">
@@ -298,7 +304,7 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
298
  <span class="wf-padding-add-left-small" data-bind="text: (loc().city ? loc().city + ', ' : '') + (loc().region ? loc().region + ', ' : '') + loc().countryName"></span>
299
  </span>
300
  <span class="wf-flex-horizontal" data-bind="if: !loc()">
301
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 64.22 64.37" class="wf-flag wf-flag-unspecified"><path d="M64,28.21a30.32,30.32,0,0,0-5.8-14.73A31.6,31.6,0,0,0,37.43.56C35.7.26,33.94.18,32.2,0h-.35C30.22.18,28.58.3,27,.55A32.14,32.14,0,0,0,.2,35.61,31.4,31.4,0,0,0,10.4,55.87a31.24,31.24,0,0,0,25,8.33,30.5,30.5,0,0,0,18.94-8.79C62,47.94,65.15,38.8,64,28.21ZM57.21,44.68a23.94,23.94,0,0,1-2.3-5.08c-.66-2.45-2.27-.08-2.4,1.52s-1.2,2.8-3.33.4-2.54-1.87-3.2-1.87-1.87,1.6-1.6,9.07c.19,5.33,2.29,6.18,3.67,6.56a27.16,27.16,0,0,1-8.78,4A27.55,27.55,0,0,1,7.85,45.13C2.27,34.4,5,22.26,10.67,15.57c.15,1.21.3,2.29.43,3.37a27.63,27.63,0,0,1-.52,8.79,4.39,4.39,0,0,0,.08,1.94,1.3,1.3,0,0,0,.94.76c.27,0,.75-.41.86-.73a8.27,8.27,0,0,0,.27-1.86c0-.44,0-.89.07-1.58a10.67,10.67,0,0,1,1.06.86c.7.7,1.4,1.4,2,2.15a2.11,2.11,0,0,1,.56,1.21,3.44,3.44,0,0,0,.83,2.13,12.21,12.21,0,0,1,1.07,2.57c.14.37.17.78.33,1.13a2,2,0,0,0,1.8,1.32c1,.07,1.32.44,1.46,1.43l-.74.08c-1.17.11-1.75.65-1.71,1.83a8.43,8.43,0,0,0,2.69,6c.48.45,1,.87,1.46,1.33a3.35,3.35,0,0,1,.92,3.75,12.18,12.18,0,0,0-.69,2.09,6,6,0,0,0,.06,2.23c.18.75.1,2.37.86,2.24,1.36-.24,2.14,0,2.25-1.49a1.22,1.22,0,0,0-.08-.6c-.4-1.42,1.42-5.47,2.52-6.2a27.11,27.11,0,0,0,2.73-2,3.6,3.6,0,0,0,1.26-4,3.22,3.22,0,0,1,1.14-3.59,4.54,4.54,0,0,0,1.71-3.65c-.08-1.53-1.07-2.63-2.37-2.47a9.21,9.21,0,0,0-1.87.59,20.62,20.62,0,0,1-2.72.9c-1.31.23-2.11-.62-2.69-1.66-.47-.83-.63-.9-1.44-.38s-1.37.89-2.08,1.28S22,35.58,21.45,35a5.79,5.79,0,0,0-1.24-.88c-.31-.19-.73-.24-1-.48s-.8-.8-.75-1.15a1.69,1.69,0,0,1,.95-1.1,14.36,14.36,0,0,1,2.29-.51,7.33,7.33,0,0,0,1.22-.33c.52-.21.5-.56.1-.89a3.26,3.26,0,0,0-.69-.37l-3.52-1.39a4.74,4.74,0,0,1-.84-.43c-.74-.49-.83-1-.16-1.61,2.64-2.33,5.72-3,8.45.08.84,1,1.42,2.16,2.22,3.16a12.5,12.5,0,0,0,2.15,2.15,1.62,1.62,0,0,0,1.44.09,1.15,1.15,0,0,0,.29-1.56,8.43,8.43,0,0,0-.86-1.41,5.16,5.16,0,0,1,1.59-7.52,4.38,4.38,0,0,0,2.53-2.58c-.58.16-1,.26-1.42.39-2.3.71-.7-1,.36-1.31.65-.18-.58-.67-.58-.67s.82-.28,1.69-.65a6.85,6.85,0,0,0,1.7-.94,3.79,3.79,0,0,0,.66-1.17l-.16-.18-1.83.24c-1,.11-1.27-.09-1.37-1.14a1,1,0,0,0-1.48-.73c-.45.25-.85.61-1.29.9-1,.66-1.78.39-2.19-.75-.23-.68-.57-.81-1.19-.42-.31.18-.58.47-.89.64a11.53,11.53,0,0,1-1.62.79c-.55.19-1.21.33-1.58-.27a1.25,1.25,0,0,1,.46-1.68A14.78,14.78,0,0,1,27,10c1-.56,2.07-1,3-1.65a1.78,1.78,0,0,0,.79-2.07.88.88,0,0,0-1.37-.65c-.56.28-1.06.72-1.63,1a2.81,2.81,0,0,1-1.41.08c-.17,0-.35-.49-.35-.76s.31-.43.51-.46c1.4-.22,2.81-.41,4.22-.57a.76.76,0,0,1,.58.25,6.84,6.84,0,0,0,3.6,2.15c1.15.34,1.31.18,1.47-1,1.48-.34,3-1,4.46-.09A14.4,14.4,0,0,1,43.14,8c.18.17.07.7,0,1s-.36.87-.48,1.33a1.2,1.2,0,0,0,1.26,1.56c.29,0,.57-.07.86-.08.85,0,1.14.28,1.07,1.13-.11,1.21.09,1.35,1.31,1.15a2.07,2.07,0,0,1,1.67.64c1.14.86,2,.54,2.33-.86,0-.16,0-.32.06-.47.14-.63.49-.79.92-.35.9,1,1.74,2,2.66,3a3,3,0,0,0-.8,3.07,5.19,5.19,0,0,1-.55,3.27A24.63,24.63,0,0,0,52.2,25.5c-.45,1.57.06,2.3,1.66,2.65s1.78.64,1.84,2.14a4.85,4.85,0,0,0,2.92,4.35c.4.19.82.34,1.23.51a25.22,25.22,0,0,1-2.64,9.53Z"/></svg> <span class="wf-padding-add-left-small">Unspecified</span>
302
  </span>
303
  </td>
304
  <td>
@@ -332,7 +338,7 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
332
  <div data-bind="text: typeText"></div>
333
  </div>
334
  <div class="wf-live-traffic-activity-detail">
335
- <h2>Activity Detail</h2>
336
  <div>
337
  <span data-bind="if: action() != 'loginOK' && action() != 'loginFailValidUsername' && action() != 'loginFailInvalidUsername' && user()">
338
  <span data-bind="attr: {'data-userid': user().ID}" class="wfAvatar"></span>
@@ -347,57 +353,75 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
347
  target="_blank" rel="noopener noreferrer"></a>
348
  </span>
349
  <span data-bind="if: !loc()">
350
- <span data-bind="text: action() != 'loginOK' && action() != 'loginFailValidUsername' && action() != 'loginFailInvalidUsername' && user() ? 'at an' : 'An'"></span> unknown location at IP
351
- <a data-bind="text: IP, attr: { href: WFAD.makeIPTrafLink(IP()) }"
352
- target="_blank" rel="noopener noreferrer"></a>
 
 
 
 
 
 
 
353
  </span>
354
  <span data-bind="if: referer()">
355
  <span data-bind="if: extReferer()">
356
- arrived from <a data-bind="text: LiveTrafficViewModel.truncateText(referer(), 100), attr: { title: referer, href: referer }"
357
- target="_blank" rel="noopener noreferrer"
358
- class="wf-split-word-xs"></a> and
359
  </span>
360
  <span data-bind="if: !extReferer()">
361
- left <a data-bind="text: LiveTrafficViewModel.truncateText(referer(), 100), attr: { title: referer, href: referer }"
362
- target="_blank" rel="noopener noreferrer"
363
- class="wf-split-word-xs"></a> and
364
  </span>
365
  </span>
366
  <span data-bind="if: statusCode() == 404">
367
- tried to access a <span style="color: #F00;">non-existent page</span>
 
 
368
  </span>
369
 
370
  <span data-bind="if: statusCode() == 200 && !action()">
371
- visited
 
 
372
  </span>
373
  <span data-bind="if: (statusCode() == 301 || statusCode() == 302) && !action()">
374
- was redirected when visiting
 
 
375
  </span>
376
  <span data-bind="if: (statusCode() == 301 || statusCode() == 302) && action() && firewallAction()">
377
- was <span data-bind="text: firewallAction"></span> at
 
 
378
  </span>
379
  <span data-bind="if: ((statusCode() == 403 || statusCode() == 503) && action() != 'loginFailValidUsername' && action() != 'loginFailInvalidUsername')">
380
- was <span data-bind="text: firewallAction" style="color: #F00;"></span> at
 
 
381
  </span>
382
 
383
  <span data-bind="if: action() == 'loginOK'">
384
- logged in successfully as "<strong data-bind="text: username"></strong>".
 
 
385
  </span>
386
  <span data-bind="if: action() == 'logout'">
387
- logged out successfully.
388
  </span>
389
  <span data-bind="if: action() == 'lostPassword'">
390
- requested a password reset.
391
  </span>
392
  <span data-bind="if: action() == 'loginFailValidUsername'">
393
- attempted a <span style="color: #F00;">failed login</span> as "<strong data-bind="text: username"></strong>".
394
  </span>
395
  <span data-bind="if: action() == 'loginFailInvalidUsername'">
396
- attempted a <span style="color: #F00;">failed login</span> using an invalid username "<strong
397
- data-bind="text: username"></strong>".
398
  </span>
399
  <span data-bind="if: action() == 'user:passwordReset'">
400
- changed their password.
401
  </span>
402
  <a class="wf-lt-url wf-split-word-xs"
403
  data-bind="text: displayURL, attr: { href: URL, title: URL }"
@@ -408,61 +432,62 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
408
  class="wfTimeAgo-timestamp"></span>&nbsp;&nbsp;
409
  </div>
410
  <div>
411
- <strong>IP:</strong> <span data-bind="text: IP"></span>
412
  <span class="wfReverseLookup">
413
  <span data-bind="text: IP" style="display:none;"></span>
414
  </span>
415
  <span data-bind="if: blocked()">
416
  <a class="wf-btn wf-btn-default wf-btn-sm wf-block-ip-btn"
417
  data-bind="click: unblockIP">
418
- Unblock IP
419
  </a>
420
  </span>
421
  <span data-bind="if: rangeBlocked()">
422
  <a class="wf-btn wf-btn-default wf-btn-sm wf-block-ip-btn"
423
- data-bind="click: unblockNetwork">Unblock range
424
  </a>
425
  </span>
426
  <span data-bind="if: !blocked() && !rangeBlocked()">
427
  <a class="wf-btn wf-btn-default wf-btn-sm wf-block-ip-btn"
428
  data-bind="click: blockIP">
429
- Block IP
430
  </a>
431
  </span>
432
  </div>
433
  <div data-bind="visible: (jQuery.inArray(parseInt(statusCode(), 10), [403, 503, 404]) !== -1 || action() == 'loginFailValidUsername' || action() == 'loginFailInvalidUsername')">
434
- <strong>Human/Bot:</strong> <span data-bind="text: (jsRun() === '1' ? 'Human' : 'Bot')"></span>
435
  </div>
436
  <div class="wf-split-word" data-bind="text: UA"></div>
437
  <div class="wf-live-traffic-actions">
438
  <span data-bind="if: blocked()">
439
  <a class="wf-btn wf-btn-default wf-btn-sm"
440
  data-bind="click: unblockIP">
441
- Unblock IP
442
  </a>
443
  </span>
444
  <span data-bind="if: rangeBlocked()">
445
  <a class="wf-btn wf-btn-default wf-btn-sm"
446
- data-bind="click: unblockNetwork">Unblock range
 
447
  </a>
448
  </span>
449
  <span data-bind="if: !blocked() && !rangeBlocked()">
450
  <a class="wf-btn wf-btn-default wf-btn-sm"
451
  data-bind="click: blockIP">
452
- Block IP
453
  </a>
454
  </span>
455
  <a class="wf-btn wf-btn-default wf-btn-sm" data-bind="click: showWhoisOverlay"
456
- target="_blank" rel="noopener noreferrer">Run Whois</a>
457
  <a class="wf-btn wf-btn-default wf-btn-sm"
458
  data-bind="click: showRecentTraffic" target="_blank" rel="noopener noreferrer">
459
- <span class="wf-hidden-xs"><?php _e('See recent traffic', 'wordfence'); ?></span><span class="wf-visible-xs"><?php _e('Recent', 'wordfence'); ?></span>
460
  </a>
461
  <span data-bind="if: action() == 'blocked:waf'">
462
  <a class="wf-btn wf-btn-default wf-btn-sm"
463
  data-bind="click: function () { $root.whitelistWAFParamKey(actionData().path, actionData().paramKey, actionData().failedRules) }"
464
- title="If this is a false positive, you can exclude this parameter from being filtered by the firewall">
465
- Add Param to Firewall Allowlist
466
  </a>
467
  <?php if (WFWAF_DEBUG): ?>
468
  <a class="wf-btn wf-btn-default wf-btn-sm"
@@ -480,7 +505,7 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
480
  </table>
481
  </div>
482
  <div class="wf-live-traffic-none" data-bind="if: listings().length == 0">
483
- No requests to report yet.
484
  </div>
485
  </div>
486
  </div>
@@ -543,13 +568,13 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
543
 
544
  <script type="text/x-jquery-template" id="wfNewTour1">
545
  <div>
546
- <h3><?php _e('Live Traffic', 'wordfence'); ?></h3>
547
- <p><?php _e('Live traffic defaults to a summary view of all security-related traffic. Details are viewable by clicking anywhere within the summary record. To switch to the expanded view, click the <strong>Expand All Records</strong> switch.', 'wordfence'); ?></p>
548
  <div class="wf-pointer-footer">
549
  <ul class="wf-tour-pagination">
550
  <li class="wf-active">&bullet;</li>
551
  </ul>
552
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Got it', 'wordfence'); ?></a></div>
553
  </div>
554
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
555
  </div>
@@ -574,15 +599,15 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
574
 
575
  <script type="text/x-jquery-template" id="wfUpgradeTour1">
576
  <div>
577
- <h3><?php _e('Live Traffic', 'wordfence'); ?></h3>
578
- <p><?php _e('Live traffic now defaults to a summary view. Details are viewable by clicking anywhere within the summary record. To switch to the expanded view, click the <strong>Expand All Records</strong> switch. New installations will only log security-related traffic by default, though your previous setting has been preserved.', 'wordfence'); ?></p>
579
  <div class="wf-pointer-footer">
580
  <ul class="wf-tour-pagination">
581
  <li class="wf-active">&bullet;</li>
582
  </ul>
583
- <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php _e('Got it', 'wordfence'); ?></a></div>
584
  </div>
585
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
586
  </div>
587
  </script>
588
- <?php endif; ?>
38
  })(jQuery);
39
  </script>
40
  <div class="wf-section-title">
41
+ <h2><?php esc_html_e('Live Traffic', 'wordfence') ?></h2>
42
+ <span><?php echo wp_kses(sprintf(
43
+ /* translators: URL to support page. */
44
+ __('<a href="%s" target="_blank" rel="noopener noreferrer" class="wf-help-link">Learn more<span class="wf-hidden-xs"> about Live Traffic</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_TOOLS_LIVE_TRAFFIC)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array(), 'class'=>array()))); ?>
45
  <i class="wf-fa wf-fa-external-link" aria-hidden="true"></i></span>
46
  </div>
47
 
48
  <?php if (wfConfig::liveTrafficEnabled() && wfConfig::get('liveActivityPauseEnabled')): ?>
49
  <div id="wfLiveTrafficOverlayAnchor"></div>
50
  <div id="wfLiveTrafficDisabledMessage">
51
+ <h2><?php esc_html_e('Live Updates Paused', 'wordfence') ?><br/>
52
+ <small><?php esc_html_e('Click inside window to resume', 'wordfence') ?></small>
53
  </h2>
54
  </div>
55
  <?php endif ?>
56
 
57
+ <p><?php esc_html_e("Wordfence Live Traffic shows you what is happening on your site in real-time, including user logins, hack attempts, and requests that were blocked by the Wordfence Firewall. You can choose to log security-related traffic only or all traffic. Traffic is logged directly on the server, which means it includes visits that don't execute JavaScript. Google and other JavaScript-based analytics packages typically only show visits from browsers that are operated by a human, while Live Traffic can show visits from crawlers like Google and Bing.", 'wordfence') ?></p>
58
 
59
  <div class="wordfenceModeElem" id="wordfenceMode_liveTraffic"></div>
60
 
70
  if (!wfConfig::liveTrafficEnabled($overridden)):
71
  ?>
72
  <div id="wordfenceLiveActivitySecurityOnly"><p>
73
+ <strong><?php esc_html_e('Traffic logging mode: Security-related traffic only', 'wordfence') ?><?php
74
  if ($overridden) {
75
+ echo wp_kses(sprintf(
76
+ /* translators: URL to support page. */
77
+ __(' (host setting <a href="%s" class="wfhelp" target="_blank" rel="noopener noreferrer"></a>)', 'wordfence'), wfSupportController::supportURL(wfSupportController::ITEM_TOOLS_LIVE_TRAFFIC_OPTION_ENABLE)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array(), 'class'=>array())));
78
+ } ?>.</strong> <?php esc_html_e('Login and firewall activity will appear below.', 'wordfence') ?></p>
79
  </div>
80
  <?php else: ?>
81
  <div id="wordfenceLiveActivityAll"><p>
82
+ <strong><?php esc_html_e('Traffic logging mode: All traffic', 'wordfence') ?><?php
83
  if ($overridden) {
84
+ echo wp_kses(sprintf(
85
+ /* translators: URL to support page. */
86
+ __(' (host setting <a href="%s" class="wfhelp" target="_blank" rel="noopener noreferrer"></a>)', 'wordfence'), wfSupportController::supportURL(wfSupportController::ITEM_TOOLS_LIVE_TRAFFIC_OPTION_ENABLE)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array(), 'class'=>array())));
87
+ } ?>.</strong> <?php esc_html_e('Regular traffic and security-related traffic will appear below.', 'wordfence') ?></p>
88
  </div>
89
  <?php endif; ?>
90
 
97
  <div class="<?php echo wfStyle::contentClasses(); ?>">
98
  <div id="wf-live-traffic-legend">
99
  <ul>
100
+ <li class="wfHuman"><?php esc_html_e('Human', 'wordfence') ?></li>
101
+ <li class="wfBot"><?php esc_html_e('Bot', 'wordfence') ?></li>
102
+ <li class="wfNotice"><?php esc_html_e('Warning', 'wordfence') ?></li>
103
+ <li class="wfBlocked"><?php esc_html_e('Blocked', 'wordfence') ?></li>
104
  </ul>
105
  </div>
106
  <div class="wf-row wf-add-bottom-small">
114
  &nbsp;&nbsp;
115
  <input id="wf-live-traffic-filter-show-advanced" class="wf-option-checkbox" data-bind="checked: showAdvancedFilters" type="checkbox">
116
  <label for="wf-live-traffic-filter-show-advanced">
117
+ <?php esc_html_e('Show Advanced Filters', 'wordfence') ?>
118
  </label>
119
  </li>
120
  <li class="wf-live-traffic-show-expanded">
121
  <ul class="wf-option wf-option-toggled-boolean-switch wf-option-no-spacing" data-option="liveTraf_displayExpandedRecords" data-enabled-value="1" data-disabled-value="0" data-original-value="<?php echo wfConfig::get('liveTraf_displayExpandedRecords') ? 1 : 0; ?>">
122
  <li class="wf-boolean-switch<?php echo wfConfig::get('liveTraf_displayExpandedRecords') ? ' wf-active' : ''; ?>"><a href="#" class="wf-boolean-switch-handle"></a></li>
123
  <li class="wf-option-title wf-padding-add-left wf-no-right wf-padding-no-right">
124
+ <?php esc_html_e('Expand All Results', 'wordfence'); ?>
125
  </li>
126
  </ul>
127
  </li>
149
  </span>
150
 
151
  <span data-bind="if: selectedFilterParamOptionValue() && selectedFilterParamOptionValue().type() == 'bool'">
152
+ <label><?php esc_html_e('Yes', 'wordfence') ?> <input data-bind="checked: value" type="radio" value="1"></label>
153
+ <label><?php esc_html_e('No', 'wordfence') ?> <input data-bind="checked: value" type="radio" value="0"></label>
154
  </span>
155
  </div>
156
  </div>
163
  <div>
164
  <div class="wf-pad-small">
165
  <button type="button" class="wf-btn wf-btn-default" data-bind="click: addFilter">
166
+ <?php esc_html_e('Add Filter', 'wordfence') ?>
167
  </button>
168
  </div>
169
  </div>
170
  </div>
171
  <div class="wf-form wf-form-horizontal">
172
  <div class="wf-form-group">
173
+ <label for="wf-live-traffic-from" class="wf-col-sm-2"><?php esc_html_e('From:', 'wordfence') ?>&nbsp;</label>
174
  <div class="wf-col-sm-10">
175
  <input placeholder="Start date" id="wf-live-traffic-from" type="text" class="wf-datetime" data-bind="value: startDate, datetimepicker: null, datepickerOptions: { timeFormat: 'hh:mm tt z' }">
176
+ <button data-bind="click: startDate('')" class="wf-btn wf-btn-default wf-btn-sm" type="button"><?php esc_html_e('Clear', 'wordfence') ?></button>
177
  </div>
178
  </div>
179
  <div class="wf-form-group">
180
+ <label for="wf-live-traffic-to" class="wf-col-sm-2"><?php esc_html_e('To:', 'wordfence')?>&nbsp;</label>
181
  <div class="wf-col-sm-10">
182
  <input placeholder="End date" id="wf-live-traffic-to" type="text" class="wf-datetime" data-bind="value: endDate, datetimepicker: null, datepickerOptions: { timeFormat: 'hh:mm tt z' }">
183
+ <button data-bind="click: endDate('')" class="wf-btn wf-btn-default wf-btn-sm" type="button"><?php esc_html_e('Clear', 'wordfence') ?></button>
184
  </div>
185
  </div>
186
  <div class="wf-form-group">
187
+ <label for="wf-live-traffic-group-by" class="wf-col-sm-2"><?php esc_html_e('Group By:', 'wordfence') ?>&nbsp;</label>
188
  <div class="wf-col-sm-10">
189
  <select id="wf-live-traffic-group-by" name="groupby" class="wf-lt-advanced-filters-groupby" data-bind="options: filterGroupByOptions, optionsText: filterGroupByOptionsText, value: groupBy, optionsCaption: 'None'"></select>
190
  </div>
209
  target="_blank" rel="noopener noreferrer"></a>
210
  </div>
211
  <div data-bind="if: !loc()">
212
+ <?php esc_html_e('An unknown location at IP', 'wordfence') ?>
213
  <span data-bind="text: IP" target="_blank" rel="noopener noreferrer"></span>
214
  </div>
215
 
216
  <div>
217
+ <strong><?php esc_html_e('IP:', 'wordfence') ?></strong>
218
  <span data-bind="text: IP" target="_blank" rel="noopener noreferrer"></span>
219
  </div>
220
  <div>
223
  <!-- /ko -->
224
  <!-- ko if: $root.groupBy().param() == 'type' -->
225
  <div>
226
+ <strong><?php esc_html_e('Type:', 'wordfence') ?></strong>
227
+ <span data-bind="if: jsRun() == '1'"><?php esc_html_e('Human', 'wordfence') ?></span>
228
+ <span data-bind="if: jsRun() == '0'"><?php esc_html_e('Bot', 'wordfence') ?></span>
229
  </div>
230
  <!-- /ko -->
231
  <!-- ko if: $root.groupBy().param() == 'user_login' -->
232
  <div>
233
+ <strong><?php esc_html_e('Username:', 'wordfence') ?></strong>
234
  <span data-bind="text: username()"></span>
235
  </div>
236
  <!-- /ko -->
237
  <!-- ko if: $root.groupBy().param() == 'statusCode' -->
238
  <div>
239
+ <strong><?php esc_html_e('HTTP Response Code:', 'wordfence') ?></strong>
240
  <span data-bind="text: statusCode()"></span>
241
  </div>
242
  <!-- /ko -->
243
  <!-- ko if: $root.groupBy().param() == 'action' -->
244
  <div>
245
+ <strong><?php esc_html_e('Firewall Response:', 'wordfence') ?></strong>
246
  <span data-bind="text: firewallAction()"></span>
247
  </div>
248
  <!-- /ko -->
249
  <!-- ko if: $root.groupBy().param() == 'url' -->
250
  <div>
251
+ <strong><?php esc_html_e('URL:', 'wordfence') ?></strong>
252
  <span data-bind="text: displayURL()"></span>
253
  </div>
254
  <!-- /ko -->
255
  <div>
256
+ <strong><?php esc_html_e('Last Hit:', 'wordfence') ?></strong> <span
257
+ data-bind="attr: { 'data-timestamp': ctime, text: <?php echo esc_attr(sprintf(json_encode(/* translators: Time ago. */ __('Last hit was %s ago.', 'wordfence')), '"+ ctime() + "')) ?> }"
258
  class="wfTimeAgo wfTimeAgo-timestamp"></span>
259
  </div>
260
  <!-- ko if: $root.groupBy().param() == 'ip' -->
261
  <div class="wf-add-top-small">
262
  <span data-bind="if: blocked()">
263
+ <a class="wf-btn wf-btn-default wf-btn-sm" data-bind="click: unblockIP"><?php esc_html_e('Unblock IP', 'wordfence') ?></a>
264
  </span>
265
  <span data-bind="if: rangeBlocked()">
266
+ <a class="wf-btn wf-btn-default wf-btn-sm" data-bind="click: unblockNetwork"><?php esc_html_e('Unblock range', 'wordfence') ?></a>
267
  </span>
268
  <span data-bind="if: !blocked() && !rangeBlocked()">
269
+ <a class="wf-btn wf-btn-default wf-btn-sm" data-bind="click: blockIP"><?php esc_html_e('Block IP', 'wordfence') ?></a>
270
  </span>
271
  </div>
272
  <!-- /ko -->
273
  </div>
274
  <div class="wf-flex-row-0 wf-padding-add-left">
275
+ <?php echo sprintf(/* translators: Number of HTTP requests. */ esc_html__('%s hits', 'wordfence'), '<span class="wf-filtered-traffic-hits" data-bind="text: hitCount"></span>') ?>
276
  </div>
277
  </li>
278
 
283
  <table class="wf-striped-table">
284
  <thead>
285
  <tr>
286
+ <th><?php esc_html_e('Type', 'wordfence') ?></th>
287
+ <th><?php esc_html_e('Location', 'wordfence') ?></th>
288
+ <th><?php esc_html_e('Page Visited', 'wordfence') ?></th>
289
+ <th><?php esc_html_e('Time', 'wordfence') ?></th>
290
+ <th><?php esc_html_e('IP Address', 'wordfence') ?></th>
291
+ <th><?php esc_html_e('Hostname', 'wordfence') ?></th>
292
+ <th><?php esc_html_e('Response', 'wordfence') ?></th>
293
+ <th><?php esc_html_e('View', 'wordfence') ?></th>
294
  </tr>
295
  </thead>
296
  <tbody id="wf-lt-listings" class="wf-filtered-traffic" data-bind="foreach: listings">
304
  <span class="wf-padding-add-left-small" data-bind="text: (loc().city ? loc().city + ', ' : '') + (loc().region ? loc().region + ', ' : '') + loc().countryName"></span>
305
  </span>
306
  <span class="wf-flex-horizontal" data-bind="if: !loc()">
307
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 64.22 64.37" class="wf-flag wf-flag-unspecified"><path d="M64,28.21a30.32,30.32,0,0,0-5.8-14.73A31.6,31.6,0,0,0,37.43.56C35.7.26,33.94.18,32.2,0h-.35C30.22.18,28.58.3,27,.55A32.14,32.14,0,0,0,.2,35.61,31.4,31.4,0,0,0,10.4,55.87a31.24,31.24,0,0,0,25,8.33,30.5,30.5,0,0,0,18.94-8.79C62,47.94,65.15,38.8,64,28.21ZM57.21,44.68a23.94,23.94,0,0,1-2.3-5.08c-.66-2.45-2.27-.08-2.4,1.52s-1.2,2.8-3.33.4-2.54-1.87-3.2-1.87-1.87,1.6-1.6,9.07c.19,5.33,2.29,6.18,3.67,6.56a27.16,27.16,0,0,1-8.78,4A27.55,27.55,0,0,1,7.85,45.13C2.27,34.4,5,22.26,10.67,15.57c.15,1.21.3,2.29.43,3.37a27.63,27.63,0,0,1-.52,8.79,4.39,4.39,0,0,0,.08,1.94,1.3,1.3,0,0,0,.94.76c.27,0,.75-.41.86-.73a8.27,8.27,0,0,0,.27-1.86c0-.44,0-.89.07-1.58a10.67,10.67,0,0,1,1.06.86c.7.7,1.4,1.4,2,2.15a2.11,2.11,0,0,1,.56,1.21,3.44,3.44,0,0,0,.83,2.13,12.21,12.21,0,0,1,1.07,2.57c.14.37.17.78.33,1.13a2,2,0,0,0,1.8,1.32c1,.07,1.32.44,1.46,1.43l-.74.08c-1.17.11-1.75.65-1.71,1.83a8.43,8.43,0,0,0,2.69,6c.48.45,1,.87,1.46,1.33a3.35,3.35,0,0,1,.92,3.75,12.18,12.18,0,0,0-.69,2.09,6,6,0,0,0,.06,2.23c.18.75.1,2.37.86,2.24,1.36-.24,2.14,0,2.25-1.49a1.22,1.22,0,0,0-.08-.6c-.4-1.42,1.42-5.47,2.52-6.2a27.11,27.11,0,0,0,2.73-2,3.6,3.6,0,0,0,1.26-4,3.22,3.22,0,0,1,1.14-3.59,4.54,4.54,0,0,0,1.71-3.65c-.08-1.53-1.07-2.63-2.37-2.47a9.21,9.21,0,0,0-1.87.59,20.62,20.62,0,0,1-2.72.9c-1.31.23-2.11-.62-2.69-1.66-.47-.83-.63-.9-1.44-.38s-1.37.89-2.08,1.28S22,35.58,21.45,35a5.79,5.79,0,0,0-1.24-.88c-.31-.19-.73-.24-1-.48s-.8-.8-.75-1.15a1.69,1.69,0,0,1,.95-1.1,14.36,14.36,0,0,1,2.29-.51,7.33,7.33,0,0,0,1.22-.33c.52-.21.5-.56.1-.89a3.26,3.26,0,0,0-.69-.37l-3.52-1.39a4.74,4.74,0,0,1-.84-.43c-.74-.49-.83-1-.16-1.61,2.64-2.33,5.72-3,8.45.08.84,1,1.42,2.16,2.22,3.16a12.5,12.5,0,0,0,2.15,2.15,1.62,1.62,0,0,0,1.44.09,1.15,1.15,0,0,0,.29-1.56,8.43,8.43,0,0,0-.86-1.41,5.16,5.16,0,0,1,1.59-7.52,4.38,4.38,0,0,0,2.53-2.58c-.58.16-1,.26-1.42.39-2.3.71-.7-1,.36-1.31.65-.18-.58-.67-.58-.67s.82-.28,1.69-.65a6.85,6.85,0,0,0,1.7-.94,3.79,3.79,0,0,0,.66-1.17l-.16-.18-1.83.24c-1,.11-1.27-.09-1.37-1.14a1,1,0,0,0-1.48-.73c-.45.25-.85.61-1.29.9-1,.66-1.78.39-2.19-.75-.23-.68-.57-.81-1.19-.42-.31.18-.58.47-.89.64a11.53,11.53,0,0,1-1.62.79c-.55.19-1.21.33-1.58-.27a1.25,1.25,0,0,1,.46-1.68A14.78,14.78,0,0,1,27,10c1-.56,2.07-1,3-1.65a1.78,1.78,0,0,0,.79-2.07.88.88,0,0,0-1.37-.65c-.56.28-1.06.72-1.63,1a2.81,2.81,0,0,1-1.41.08c-.17,0-.35-.49-.35-.76s.31-.43.51-.46c1.4-.22,2.81-.41,4.22-.57a.76.76,0,0,1,.58.25,6.84,6.84,0,0,0,3.6,2.15c1.15.34,1.31.18,1.47-1,1.48-.34,3-1,4.46-.09A14.4,14.4,0,0,1,43.14,8c.18.17.07.7,0,1s-.36.87-.48,1.33a1.2,1.2,0,0,0,1.26,1.56c.29,0,.57-.07.86-.08.85,0,1.14.28,1.07,1.13-.11,1.21.09,1.35,1.31,1.15a2.07,2.07,0,0,1,1.67.64c1.14.86,2,.54,2.33-.86,0-.16,0-.32.06-.47.14-.63.49-.79.92-.35.9,1,1.74,2,2.66,3a3,3,0,0,0-.8,3.07,5.19,5.19,0,0,1-.55,3.27A24.63,24.63,0,0,0,52.2,25.5c-.45,1.57.06,2.3,1.66,2.65s1.78.64,1.84,2.14a4.85,4.85,0,0,0,2.92,4.35c.4.19.82.34,1.23.51a25.22,25.22,0,0,1-2.64,9.53Z"/></svg> <span class="wf-padding-add-left-small"><?php esc_html_e('Unspecified', 'wordfence') ?></span>
308
  </span>
309
  </td>
310
  <td>
338
  <div data-bind="text: typeText"></div>
339
  </div>
340
  <div class="wf-live-traffic-activity-detail">
341
+ <h2><?php esc_html_e('Activity Detail', 'wordfence') ?></h2>
342
  <div>
343
  <span data-bind="if: action() != 'loginOK' && action() != 'loginFailValidUsername' && action() != 'loginFailInvalidUsername' && user()">
344
  <span data-bind="attr: {'data-userid': user().ID}" class="wfAvatar"></span>
353
  target="_blank" rel="noopener noreferrer"></a>
354
  </span>
355
  <span data-bind="if: !loc()">
356
+ <span data-bind="if: action() != 'loginOK' && action() != 'loginFailValidUsername' && action() != 'loginFailInvalidUsername' && user()">
357
+ <?php echo wp_kses(sprintf(
358
+ /* translators: 1. User agent. 2. IP address */
359
+ __('%1$s at an unknown location at IP %2$s', 'wordfence'), '', '<a data-bind="text: IP, attr: { href: WFAD.makeIPTrafLink(IP()) }" target="_blank" rel="noopener noreferrer"></a>'), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array(), 'data-bind'=>array()))) ?>
360
+ </span>
361
+ <span data-bind="if: !(action() != 'loginOK' && action() != 'loginFailValidUsername' && action() != 'loginFailInvalidUsername' && user())">
362
+ <?php echo wp_kses(sprintf(
363
+ /* translators: IP address */
364
+ __('An unknown location at IP %s', 'wordfence'), '<a data-bind="text: IP, attr: { href: WFAD.makeIPTrafLink(IP()) }" target="_blank" rel="noopener noreferrer"></a>'), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array(), 'data-bind'=>array()))) ?>
365
+ </span>
366
  </span>
367
  <span data-bind="if: referer()">
368
  <span data-bind="if: extReferer()">
369
+ <?php echo wp_kses(sprintf(
370
+ /* translators: 1. User agent. 2. HTTP referer. 3. Server response. */
371
+ __('%1$s arrived from %2$s and %3$s', 'wordfence'), '', '<a data-bind="text: LiveTrafficViewModel.truncateText(referer(), 100), attr: { title: referer, href: referer }" target="_blank" rel="noopener noreferrer" class="wf-split-word-xs"></a>', ''), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array(), 'class'=>array(), 'data-bind'=>array()))) ?>
372
  </span>
373
  <span data-bind="if: !extReferer()">
374
+ <?php echo wp_kses(sprintf(
375
+ /* translators: 1. User agent. 2. HTTP referer. 3. Server response. */
376
+ __('%1$s left %2$s and %3$s', 'wordfence'), '', '<a data-bind="text: LiveTrafficViewModel.truncateText(referer(), 100), attr: { title: referer, href: referer }" target="_blank" rel="noopener noreferrer" class="wf-split-word-xs"></a>', ''), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array(), 'class'=>array(), 'data-bind'=>array()))) ?>
377
  </span>
378
  </span>
379
  <span data-bind="if: statusCode() == 404">
380
+ <?php echo wp_kses(sprintf(
381
+ /* translators: User agent. */
382
+ __('%s tried to access a <span style="color: #F00;">non-existent page</span>', 'wordfence'), ''), array('span'=>array('style'=>array()))) ?>
383
  </span>
384
 
385
  <span data-bind="if: statusCode() == 200 && !action()">
386
+ <?php echo esc_html(sprintf(
387
+ /* translators: 1. User agent. 2. URL of page visited. */
388
+ __('%1$s visited %2$s', 'wordfence'), '', '')) ?>
389
  </span>
390
  <span data-bind="if: (statusCode() == 301 || statusCode() == 302) && !action()">
391
+ <?php echo esc_html(sprintf(
392
+ /* translators: 1. User agent. 2. URL of page visited. */
393
+ __('%1$s was redirected when visiting %2$s', 'wordfence'), '', '')) ?>
394
  </span>
395
  <span data-bind="if: (statusCode() == 301 || statusCode() == 302) && action() && firewallAction()">
396
+ <?php echo wp_kses(sprintf(
397
+ /* translators: 1. User agent. 2. Firewall action (blocked, rate limited, etc). 3. Time ago. */
398
+ __('%1$s was %2$s at %3$s', 'wordfence'), '', '<span data-bind="text: firewallAction"></span>', ''), array('span'=>array('data-bind'=>array()))) ?>
399
  </span>
400
  <span data-bind="if: ((statusCode() == 403 || statusCode() == 503) && action() != 'loginFailValidUsername' && action() != 'loginFailInvalidUsername')">
401
+ <?php printf(
402
+ /* translators: 1. User agent. 2. Firewall action (blocked, rate limited, etc). 3. Time ago. */
403
+ esc_html(__('%1$s was %2$s at %3$s', 'wordfence')), '', '<span data-bind="text: firewallAction" style="color: #F00;"></span>', '') ?>
404
  </span>
405
 
406
  <span data-bind="if: action() == 'loginOK'">
407
+ <?php echo wp_kses(sprintf(
408
+ /* translators: 1. User agent. 2. WordPress username. */
409
+ __('%1$s logged in successfully as "%2$s".', 'wordfence'), '', '<strong data-bind="text: username"></strong>'), array('strong'=>array('data-bind'=>array()))) ?>
410
  </span>
411
  <span data-bind="if: action() == 'logout'">
412
+ <?php echo esc_html(sprintf(/* translators: WordPress username. */ __('%s logged out successfully.', 'wordfence'), '')) ?>
413
  </span>
414
  <span data-bind="if: action() == 'lostPassword'">
415
+ <?php echo esc_html(sprintf(/* translators: WordPress username. */__('%s requested a password reset.', 'wordfence'), '')) ?>
416
  </span>
417
  <span data-bind="if: action() == 'loginFailValidUsername'">
418
+ <?php echo wp_kses(sprintf(/* translators: 1. User agent. 2. WordPress username. */ __('%1$s attempted a <span style="color: #F00;">failed login</span> as "%2$s".', 'wordfence'), '', '<strong data-bind="text: username"></strong>'), array('span'=>array('style'=>array()), 'strong'=>array('data-bind'=>array()))) ?>
419
  </span>
420
  <span data-bind="if: action() == 'loginFailInvalidUsername'">
421
+ <?php echo wp_kses(sprintf(/* translators: 1. User agent. 2. WordPress username. */ __('%1$s attempted a <span style="color: #F00;">failed login</span> using an invalid username "%2$s".', 'wordfence'), '', '<strong data-bind="text: username"></strong>'), array('span'=>array('style'=>array()), 'strong'=>array('data-bind'=>array()))) ?>
 
422
  </span>
423
  <span data-bind="if: action() == 'user:passwordReset'">
424
+ <?php echo esc_html(sprintf(/* translators: WordPress username. */ __('%s changed their password.', 'wordfence'), '')) ?>
425
  </span>
426
  <a class="wf-lt-url wf-split-word-xs"
427
  data-bind="text: displayURL, attr: { href: URL, title: URL }"
432
  class="wfTimeAgo-timestamp"></span>&nbsp;&nbsp;
433
  </div>
434
  <div>
435
+ <strong><?php esc_html_e('IP:', 'wordfence') ?></strong> <span data-bind="text: IP"></span>
436
  <span class="wfReverseLookup">
437
  <span data-bind="text: IP" style="display:none;"></span>
438
  </span>
439
  <span data-bind="if: blocked()">
440
  <a class="wf-btn wf-btn-default wf-btn-sm wf-block-ip-btn"
441
  data-bind="click: unblockIP">
442
+ <?php esc_html_e('Unblock IP', 'wordfence') ?>
443
  </a>
444
  </span>
445
  <span data-bind="if: rangeBlocked()">
446
  <a class="wf-btn wf-btn-default wf-btn-sm wf-block-ip-btn"
447
+ data-bind="click: unblockNetwork"><?php esc_html_e('Unblock range', 'wordfence') ?>
448
  </a>
449
  </span>
450
  <span data-bind="if: !blocked() && !rangeBlocked()">
451
  <a class="wf-btn wf-btn-default wf-btn-sm wf-block-ip-btn"
452
  data-bind="click: blockIP">
453
+ <?php esc_html_e('Block IP', 'wordfence') ?>
454
  </a>
455
  </span>
456
  </div>
457
  <div data-bind="visible: (jQuery.inArray(parseInt(statusCode(), 10), [403, 503, 404]) !== -1 || action() == 'loginFailValidUsername' || action() == 'loginFailInvalidUsername')">
458
+ <strong><?php esc_html_e('Human/Bot:', 'wordfence') ?></strong> <span data-bind="text: (jsRun() === '1' ? <?php echo esc_attr(json_encode(__('Human', 'wordfence'))) ?> : <?php echo esc_attr(json_encode(__('Bot', 'wordfence'))) ?>)"></span>
459
  </div>
460
  <div class="wf-split-word" data-bind="text: UA"></div>
461
  <div class="wf-live-traffic-actions">
462
  <span data-bind="if: blocked()">
463
  <a class="wf-btn wf-btn-default wf-btn-sm"
464
  data-bind="click: unblockIP">
465
+ <?php esc_html_e('Unblock IP', 'wordfence') ?>
466
  </a>
467
  </span>
468
  <span data-bind="if: rangeBlocked()">
469
  <a class="wf-btn wf-btn-default wf-btn-sm"
470
+ data-bind="click: unblockNetwork">
471
+ <?php esc_html_e('Unblock range', 'wordfence') ?>
472
  </a>
473
  </span>
474
  <span data-bind="if: !blocked() && !rangeBlocked()">
475
  <a class="wf-btn wf-btn-default wf-btn-sm"
476
  data-bind="click: blockIP">
477
+ <?php esc_html_e('Block IP', 'wordfence') ?>
478
  </a>
479
  </span>
480
  <a class="wf-btn wf-btn-default wf-btn-sm" data-bind="click: showWhoisOverlay"
481
+ target="_blank" rel="noopener noreferrer"><?php esc_html_e('Run Whois', 'wordfence') ?></a>
482
  <a class="wf-btn wf-btn-default wf-btn-sm"
483
  data-bind="click: showRecentTraffic" target="_blank" rel="noopener noreferrer">
484
+ <span class="wf-hidden-xs"><?php esc_html_e('See recent traffic', 'wordfence'); ?></span><span class="wf-visible-xs"><?php esc_html_e('Recent', 'wordfence'); ?></span>
485
  </a>
486
  <span data-bind="if: action() == 'blocked:waf'">
487
  <a class="wf-btn wf-btn-default wf-btn-sm"
488
  data-bind="click: function () { $root.whitelistWAFParamKey(actionData().path, actionData().paramKey, actionData().failedRules) }"
489
+ title="<?php esc_attr_e('If this is a false positive, you can exclude this parameter from being filtered by the firewall', 'wordfence') ?>">
490
+ <?php esc_html_e('Add Param to Firewall Allowlist', 'wordfence') ?>
491
  </a>
492
  <?php if (WFWAF_DEBUG): ?>
493
  <a class="wf-btn wf-btn-default wf-btn-sm"
505
  </table>
506
  </div>
507
  <div class="wf-live-traffic-none" data-bind="if: listings().length == 0">
508
+ <?php esc_html_e('No requests to report yet.', 'wordfence') ?>
509
  </div>
510
  </div>
511
  </div>
568
 
569
  <script type="text/x-jquery-template" id="wfNewTour1">
570
  <div>
571
+ <h3><?php esc_html_e('Live Traffic', 'wordfence'); ?></h3>
572
+ <p><?php echo wp_kses(__('Live traffic defaults to a summary view of all security-related traffic. Details are viewable by clicking anywhere within the summary record. To switch to the expanded view, click the <strong>Expand All Records</strong> switch.', 'wordfence'), array('strong'=>array())); ?></p>
573
  <div class="wf-pointer-footer">
574
  <ul class="wf-tour-pagination">
575
  <li class="wf-active">&bullet;</li>
576
  </ul>
577
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Got it', 'wordfence'); ?></a></div>
578
  </div>
579
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
580
  </div>
599
 
600
  <script type="text/x-jquery-template" id="wfUpgradeTour1">
601
  <div>
602
+ <h3><?php esc_html_e('Live Traffic', 'wordfence'); ?></h3>
603
+ <p><?php echo wp_kses(__('Live traffic now defaults to a summary view. Details are viewable by clicking anywhere within the summary record. To switch to the expanded view, click the <strong>Expand All Records</strong> switch. New installations will only log security-related traffic by default, though your previous setting has been preserved.', 'wordfence'), array('strong'=>array())); ?></p>
604
  <div class="wf-pointer-footer">
605
  <ul class="wf-tour-pagination">
606
  <li class="wf-active">&bullet;</li>
607
  </ul>
608
+ <div id="wf-tour-continue"><a href="#" class="wf-onboarding-btn wf-onboarding-btn-primary"><?php esc_html_e('Got it', 'wordfence'); ?></a></div>
609
  </div>
610
  <div id="wf-tour-close"><a href="#"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div>
611
  </div>
612
  </script>
613
+ <?php endif; ?>
lib/menu_tools_twoFactor.php CHANGED
@@ -13,7 +13,7 @@ else {
13
  echo wfView::create('common/section-title', array(
14
  'title' => __('Two-Factor Authentication', 'wordfence'),
15
  'helpLink' => $helpLink,
16
- 'helpLabelHTML' => __('Learn more<span class="wf-hidden-xs"> about Two-Factor Authentication</span>', 'wordfence'),
17
  ))->render();
18
  ?>
19
 
@@ -32,15 +32,15 @@ echo wfView::create('common/section-title', array(
32
  <div class="wf-row">
33
  <div class="wf-col-xs-12">
34
  <div id="wordfenceTwoFactorLegacy">
35
- <p><strong><?php _e('2FA Mode: Legacy', 'wordfence') ?>.</strong> <?php _e('Two-factor authentication is using legacy support, which enables SMS-based codes but is less compatible. An improved interface and use by non-administrators is available by activating the new login security module.', 'wordfence'); ?></p>
36
- <p><a id="wf-migrate2fanew-start" class="wf-btn wf-btn-default wf-btn-sm wf-dismiss-link" href="#"><?php _e('Switch to New 2FA', 'wordfence'); ?></a></p>
37
  </div>
38
  </div>
39
  </div>
40
  <?php if (!wfConfig::get('isPaid')): ?>
41
  <div class="wf-premium-callout wf-add-bottom">
42
- <h3><?php _e("Take Login Security to the next level with Two-Factor Authentication", 'wordfence') ?></h3>
43
- <p><?php _e('Used by banks, government agencies, and military worldwide, two-factor authentication is one of the most secure forms of remote system authentication available. With it enabled, an attacker needs to know your username, password, <em>and</em> have control of your phone to log into your site. Upgrade to Premium now to enable this powerful feature.', 'wordfence') ?></p>
44
 
45
  <p class="wf-nowrap">
46
  <img id="wf-two-factor-img1" src="<?php echo wfUtils::getBaseURL() . 'images/2fa1.svg' ?>" alt="">
@@ -48,7 +48,7 @@ echo wfView::create('common/section-title', array(
48
  </p>
49
 
50
  <p class="center">
51
- <a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/gnl1twoFac1/wordfence-signup/" target="_blank" rel="noopener noreferrer"><?php _e('Upgrade to Premium', 'wordfence') ?></a>
52
  </p>
53
  </div>
54
 
@@ -56,7 +56,7 @@ echo wfView::create('common/section-title', array(
56
  <div class="wf-row">
57
  <div class="wf-col-xs-12 wf-flex-row">
58
  <div class="wf-flex-row-1">
59
- <p><?php _e('With Two-Factor Authentication enabled, an attacker needs to know your username, password <em>and</em> have control of your phone to log in to your site. We recommend you enable Two-Factor Authentication for all Administrator level accounts.', 'wordfence') ?></p>
60
  </div>
61
  <div class="wf-flex-row-0 wf-padding-add-left">
62
  <?php
@@ -75,14 +75,14 @@ echo wfView::create('common/section-title', array(
75
  <div class="wf-block wf-active">
76
  <?php if (!wfConfig::get('loginSecurityEnabled')): ?>
77
  <ul class="wf-block-banner">
78
- <li><?php _e('<strong>Note:</strong> Two-Factor Authentication is disabled when the option "Enable Brute Force Protection" is off.', 'wordfence'); ?></li>
79
- <li><a href="#" class="wf-btn wf-btn-default" id="wf-2fa-enable"><?php _e('Turn On', 'wordfence'); ?></a></li>
80
  </ul>
81
  <?php endif; ?>
82
  <div class="wf-block-header">
83
  <div class="wf-block-header-content">
84
  <div class="wf-block-title">
85
- <strong><?php _e('Enable Two-Factor Authentication', 'wordfence') ?></strong>
86
  </div>
87
  </div>
88
  </div>
@@ -101,7 +101,7 @@ echo wfView::create('common/section-title', array(
101
  <input class="wf-option-radio" type="radio" name="wf2faMode" id="wf2faMode-authenticator" value="authenticator" checked>
102
  <label for="wf2faMode-authenticator">&nbsp;&nbsp;</label>
103
  </li>
104
- <li class="wf-option-title"><?php _e('Use authenticator app', 'wordfence') ?></li>
105
  </ul>
106
  </li>
107
  <li>
@@ -110,7 +110,7 @@ echo wfView::create('common/section-title', array(
110
  <input class="wf-option-radio" type="radio" name="wf2faMode" id="wf2faMode-phone" value="phone">
111
  <label for="wf2faMode-phone">&nbsp;&nbsp;</label>
112
  </li>
113
- <li class="wf-option-title"><?php _e('Send code to a phone number:', 'wordfence') ?>&nbsp;&nbsp;</li>
114
  <li class="wf-option-text">
115
  <input class="wf-form-control" type="text" value="" id="wfPhone" placeholder="<?php echo esc_attr(__('+1 (000) 000 0000', 'wordfence')) ?>">
116
  </li>
@@ -131,7 +131,7 @@ echo wfView::create('common/section-title', array(
131
  </div>
132
  <div class="wf-row">
133
  <div class="wf-col-xs-12">
134
- <h2><?php _e('Two-Factor Authentication Users', 'wordfence') ?></h2>
135
 
136
  <div id="wfTwoFacUsers"></div>
137
  </div>
@@ -172,10 +172,10 @@ echo wfView::create('common/section-title', array(
172
  <table class="wf-striped-table wf-table-twofactor">
173
  <thead>
174
  <tr>
175
- <th>User</th>
176
- <th>Mode</th>
177
- <th>Status</th>
178
- <th class="wf-center">Delete</th>
179
  </tr>
180
  </thead>
181
  <tbody>
@@ -183,17 +183,17 @@ echo wfView::create('common/section-title', array(
183
  <tr id="twoFactorUser-${user.userID}">
184
  <td style="white-space: nowrap;">${user.username}</td>
185
  {{if user.mode == 'phone'}}
186
- <td style="white-space: nowrap;"><?php printf(__('Phone (%s)', 'wordfence'), '${user.phone}') ?></td>
187
  {{else}}
188
- <td style="white-space: nowrap;"><?php _e('Authenticator', 'wordfence') ?></td>
189
  {{/if}}
190
  <td style="white-space: nowrap;">
191
  {{if user.status == 'activated'}}
192
- <span style="color: #0A0;"><?php _e('Cellphone Sign-in Enabled', 'wordfence') ?></span>
193
  {{else}}
194
  <div class="wf-form-inline">
195
  <div class="wf-form-group">
196
- <label class="wf-plain wf-hidden-xs" style="margin: 0;" for="wfActivate-${user.userID}"><?php _e('Enter activation code:', 'wordfence') ?></label>
197
  <input class="wf-form-control" type="text" id="wfActivate-${user.userID}" size="6" placeholder="<?php esc_attr_e('Code', 'wordfence') ?>">
198
  </div>
199
  <input class="wf-btn wf-btn-default" type="button" value="<?php esc_attr_e('Activate', 'wordfence') ?>" onclick="WFAD.twoFacActivate('${user.userID}', jQuery('#wfActivate-${user.userID}').val());">
@@ -207,7 +207,7 @@ echo wfView::create('common/section-title', array(
207
  {{/each}}
208
  {{if (users.length == 0)}}
209
  <tr id="twoFactorUser-none">
210
- <td colspan="4"><?php _e('No users currently have cellphone sign-in enabled.', 'wordfence') ?></td>
211
  </tr>
212
  {{/if}}
213
  </tbody>
@@ -218,9 +218,9 @@ echo wfView::create('common/section-title', array(
218
  <div class="wf-row">
219
  <div class="wf-col-xs-12">
220
  <div id="wordfenceTwoFactorModern">
221
- <p><strong><?php _e('2FA Mode: Normal', 'wordfence') ?>.</strong> <?php _e('Legacy support for SMS-based two-factor authentication is being phased out, as it is less secure than using a modern authenticator app.', 'wordfence') ?></p>
222
- <p><?php _e('If you have a conflict with the new 2FA method, you can temporarily switch back to the Legacy version.', 'wordfence'); ?></p>
223
- <p><a id="wf-migrate2faold-start" class="wf-btn wf-btn-default wf-btn-sm wf-dismiss-link" href="#"><?php _e('Revert to Legacy 2FA', 'wordfence'); ?></a></p>
224
  </div>
225
  </div>
226
  </div>
13
  echo wfView::create('common/section-title', array(
14
  'title' => __('Two-Factor Authentication', 'wordfence'),
15
  'helpLink' => $helpLink,
16
+ 'helpLabelHTML' => wp_kses(__('Learn more<span class="wf-hidden-xs"> about Two-Factor Authentication</span>', 'wordfence'), array('span'=>array('class'=>array()))),
17
  ))->render();
18
  ?>
19
 
32
  <div class="wf-row">
33
  <div class="wf-col-xs-12">
34
  <div id="wordfenceTwoFactorLegacy">
35
+ <p><strong><?php esc_html_e('2FA Mode: Legacy', 'wordfence') ?>.</strong> <?php esc_html_e('Two-factor authentication is using legacy support, which enables SMS-based codes but is less compatible. An improved interface and use by non-administrators is available by activating the new login security module.', 'wordfence'); ?></p>
36
+ <p><a id="wf-migrate2fanew-start" class="wf-btn wf-btn-default wf-btn-sm wf-dismiss-link" href="#"><?php esc_html_e('Switch to New 2FA', 'wordfence'); ?></a></p>
37
  </div>
38
  </div>
39
  </div>
40
  <?php if (!wfConfig::get('isPaid')): ?>
41
  <div class="wf-premium-callout wf-add-bottom">
42
+ <h3><?php esc_html_e("Take Login Security to the next level with Two-Factor Authentication", 'wordfence') ?></h3>
43
+ <p><?php echo wp_kses(__('Used by banks, government agencies, and military worldwide, two-factor authentication is one of the most secure forms of remote system authentication available. With it enabled, an attacker needs to know your username, password, <em>and</em> have control of your phone to log into your site. Upgrade to Premium now to enable this powerful feature.', 'wordfence'), array('em'=>array())) ?></p>
44
 
45
  <p class="wf-nowrap">
46
  <img id="wf-two-factor-img1" src="<?php echo wfUtils::getBaseURL() . 'images/2fa1.svg' ?>" alt="">
48
  </p>
49
 
50
  <p class="center">
51
+ <a class="wf-btn wf-btn-primary wf-btn-callout" href="https://www.wordfence.com/gnl1twoFac1/wordfence-signup/" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Upgrade to Premium', 'wordfence') ?></a>
52
  </p>
53
  </div>
54
 
56
  <div class="wf-row">
57
  <div class="wf-col-xs-12 wf-flex-row">
58
  <div class="wf-flex-row-1">
59
+ <p><?php echo wp_kses(__('With Two-Factor Authentication enabled, an attacker needs to know your username, password <em>and</em> have control of your phone to log in to your site. We recommend you enable Two-Factor Authentication for all Administrator level accounts.', 'wordfence'), array('em'=>array())) ?></p>
60
  </div>
61
  <div class="wf-flex-row-0 wf-padding-add-left">
62
  <?php
75
  <div class="wf-block wf-active">
76
  <?php if (!wfConfig::get('loginSecurityEnabled')): ?>
77
  <ul class="wf-block-banner">
78
+ <li><?php echo wp_kses(__('<strong>Note:</strong> Two-Factor Authentication is disabled when the option "Enable Brute Force Protection" is off.', 'wordfence'), array('strong'=>array())); ?></li>
79
+ <li><a href="#" class="wf-btn wf-btn-default" id="wf-2fa-enable"><?php esc_html_e('Turn On', 'wordfence'); ?></a></li>
80
  </ul>
81
  <?php endif; ?>
82
  <div class="wf-block-header">
83
  <div class="wf-block-header-content">
84
  <div class="wf-block-title">
85
+ <strong><?php esc_html_e('Enable Two-Factor Authentication', 'wordfence') ?></strong>
86
  </div>
87
  </div>
88
  </div>
101
  <input class="wf-option-radio" type="radio" name="wf2faMode" id="wf2faMode-authenticator" value="authenticator" checked>
102
  <label for="wf2faMode-authenticator">&nbsp;&nbsp;</label>
103
  </li>
104
+ <li class="wf-option-title"><?php esc_html_e('Use authenticator app', 'wordfence') ?></li>
105
  </ul>
106
  </li>
107
  <li>
110
  <input class="wf-option-radio" type="radio" name="wf2faMode" id="wf2faMode-phone" value="phone">
111
  <label for="wf2faMode-phone">&nbsp;&nbsp;</label>
112
  </li>
113
+ <li class="wf-option-title"><?php esc_html_e('Send code to a phone number:', 'wordfence') ?>&nbsp;&nbsp;</li>
114
  <li class="wf-option-text">
115
  <input class="wf-form-control" type="text" value="" id="wfPhone" placeholder="<?php echo esc_attr(__('+1 (000) 000 0000', 'wordfence')) ?>">
116
  </li>
131
  </div>
132
  <div class="wf-row">
133
  <div class="wf-col-xs-12">
134
+ <h2><?php esc_html_e('Two-Factor Authentication Users', 'wordfence') ?></h2>
135
 
136
  <div id="wfTwoFacUsers"></div>
137
  </div>
172
  <table class="wf-striped-table wf-table-twofactor">
173
  <thead>
174
  <tr>
175
+ <th><?php esc_html_e('User', 'wordfence') ?></th>
176
+ <th><?php esc_html_e('Mode', 'wordfence') ?></th>
177
+ <th><?php esc_html_e('Status', 'wordfence') ?></th>
178
+ <th class="wf-center"><?php esc_html_e('Delete', 'wordfence') ?></th>
179
  </tr>
180
  </thead>
181
  <tbody>
183
  <tr id="twoFactorUser-${user.userID}">
184
  <td style="white-space: nowrap;">${user.username}</td>
185
  {{if user.mode == 'phone'}}
186
+ <td style="white-space: nowrap;"><?php echo esc_html(sprintf(/* translators: Phone number. */ __('Phone (%s)', 'wordfence'), '${user.phone}')) ?></td>
187
  {{else}}
188
+ <td style="white-space: nowrap;"><?php esc_html_e('Authenticator', 'wordfence') ?></td>
189
  {{/if}}
190
  <td style="white-space: nowrap;">
191
  {{if user.status == 'activated'}}
192
+ <span style="color: #0A0;"><?php esc_html_e('Cellphone Sign-in Enabled', 'wordfence') ?></span>
193
  {{else}}
194
  <div class="wf-form-inline">
195
  <div class="wf-form-group">
196
+ <label class="wf-plain wf-hidden-xs" style="margin: 0;" for="wfActivate-${user.userID}"><?php esc_html_e('Enter activation code:', 'wordfence') ?></label>
197
  <input class="wf-form-control" type="text" id="wfActivate-${user.userID}" size="6" placeholder="<?php esc_attr_e('Code', 'wordfence') ?>">
198
  </div>
199
  <input class="wf-btn wf-btn-default" type="button" value="<?php esc_attr_e('Activate', 'wordfence') ?>" onclick="WFAD.twoFacActivate('${user.userID}', jQuery('#wfActivate-${user.userID}').val());">
207
  {{/each}}
208
  {{if (users.length == 0)}}
209
  <tr id="twoFactorUser-none">
210
+ <td colspan="4"><?php esc_html_e('No users currently have cellphone sign-in enabled.', 'wordfence') ?></td>
211
  </tr>
212
  {{/if}}
213
  </tbody>
218
  <div class="wf-row">
219
  <div class="wf-col-xs-12">
220
  <div id="wordfenceTwoFactorModern">
221
+ <p><strong><?php esc_html_e('2FA Mode: Normal', 'wordfence') ?>.</strong> <?php esc_html_e('Legacy support for SMS-based two-factor authentication is being phased out, as it is less secure than using a modern authenticator app.', 'wordfence') ?></p>
222
+ <p><?php esc_html_e('If you have a conflict with the new 2FA method, you can temporarily switch back to the Legacy version.', 'wordfence'); ?></p>
223
+ <p><a id="wf-migrate2faold-start" class="wf-btn wf-btn-default wf-btn-sm wf-dismiss-link" href="#"><?php esc_html_e('Revert to Legacy 2FA', 'wordfence'); ?></a></p>
224
  </div>
225
  </div>
226
  </div>
lib/menu_tools_whois.php CHANGED
@@ -13,12 +13,14 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
13
 
14
  <div id="wf-tools-whois">
15
  <div class="wf-section-title">
16
- <h2><?php _e('Whois Lookup', 'wordfence') ?></h2>
17
- <span><?php printf(__('<a href="%s" target="_blank" rel="noopener noreferrer" class="wf-help-link">Learn more<span class="wf-hidden-xs"> about Whois Lookup</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_TOOLS_WHOIS_LOOKUP)); ?>
 
 
18
  <i class="wf-fa wf-fa-external-link" aria-hidden="true"></i></span>
19
  </div>
20
 
21
- <p><?php _e("The whois service gives you a way to look up who owns an IP address or domain name that is visiting your website or is engaging in malicious activity on your website.", 'wordfence') ?></p>
22
 
23
  <div>
24
 
@@ -31,9 +33,11 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
31
  </div>
32
  </div>
33
  <?php if (isset($_GET['wfnetworkblock']) && $_GET['wfnetworkblock']) { ?>
34
- <h2><?php _e('How to block a network', 'wordfence') ?></h2>
35
  <p style="width: 600px;">
36
- <?php printf(__("You've chosen to block the network that <span style=\"color: #F00;\">%s</span> is part of. We've marked the networks we found that this IP address belongs to in red below. Make sure you read all the WHOIS information so that you see all networks this IP belongs to. We recommend blocking the network with the lowest number of addresses. You may find this is listed at the end as part of the 'rWHOIS' query which contacts the local WHOIS server that is run by the network administrator."), esc_html($_GET['whoisval'])) ?>
 
 
37
  </p>
38
  <?php } ?>
39
  <div id="wfrawhtml" class="wf-padding-add-top"></div>
@@ -68,7 +72,7 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
68
  <div class="wf-block-header">
69
  <div class="wf-block-header-content">
70
  <div class="wf-block-title">
71
- <strong><?php _e('Whois Lookup', 'wordfence') ?> <a>${ip}</a></strong>
72
  </div>
73
  </div>
74
  </div>
@@ -88,16 +92,16 @@ if (!defined('WORDFENCE_VERSION')) { exit; }
88
  function whois(ip) {
89
  var val = ip.replace(' ', '');
90
  if (!/\w+/.test(val)) {
91
- WFAD.colorboxModal('300px', "Enter a valid IP or domain", "Please enter a valid IP address or domain name for your whois lookup.");
92
  return;
93
  }
94
  var whoisButton = jQuery('#whoisbutton').attr('disabled', 'disabled')
95
- .attr('value', 'Loading...');
96
  WFAD.ajax('wordfence_whois', {
97
  val: val
98
  }, function(res) {
99
  whoisButton.removeAttr('disabled')
100
- .attr('value', 'Look up IP or Domain');
101
  if (res.ok) {
102
  var whoisHTML = WFAD.completeWhois(res, true);
103
  console.log(whoisHTML);
13
 
14
  <div id="wf-tools-whois">
15
  <div class="wf-section-title">
16
+ <h2><?php esc_html_e('Whois Lookup', 'wordfence') ?></h2>
17
+ <span><?php echo wp_kses(sprintf(
18
+ /* translators: URL to support page. */
19
+ __('<a href="%s" target="_blank" rel="noopener noreferrer" class="wf-help-link">Learn more<span class="wf-hidden-xs"> about Whois Lookup</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_TOOLS_WHOIS_LOOKUP)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array(), 'class'=>array()), 'span'=>array('class'=>array()))); ?>
20
  <i class="wf-fa wf-fa-external-link" aria-hidden="true"></i></span>
21
  </div>
22
 
23
+ <p><?php esc_html_e("The whois service gives you a way to look up who owns an IP address or domain name that is visiting your website or is engaging in malicious activity on your website.", 'wordfence') ?></p>
24
 
25
  <div>
26
 
33
  </div>
34
  </div>
35
  <?php if (isset($_GET['wfnetworkblock']) && $_GET['wfnetworkblock']) { ?>
36
+ <h2><?php esc_html_e('How to block a network', 'wordfence') ?></h2>
37
  <p style="width: 600px;">
38
+ <?php echo wp_kses(sprintf(
39
+ /* translators: Hostname or IP address. */
40
+ __("You've chosen to block the network that <span style=\"color: #F00;\">%s</span> is part of. We've marked the networks we found that this IP address belongs to in red below. Make sure you read all the WHOIS information so that you see all networks this IP belongs to. We recommend blocking the network with the lowest number of addresses. You may find this is listed at the end as part of the 'rWHOIS' query which contacts the local WHOIS server that is run by the network administrator."), esc_html($_GET['whoisval'])), array('span'=>array('style'=>array()))); ?>
41
  </p>
42
  <?php } ?>
43
  <div id="wfrawhtml" class="wf-padding-add-top"></div>
72
  <div class="wf-block-header">
73
  <div class="wf-block-header-content">
74
  <div class="wf-block-title">
75
+ <strong><?php esc_html_e('Whois Lookup', 'wordfence') ?> <a>${ip}</a></strong>
76
  </div>
77
  </div>
78
  </div>
92
  function whois(ip) {
93
  var val = ip.replace(' ', '');
94
  if (!/\w+/.test(val)) {
95
+ WFAD.colorboxModal('300px', <?php echo json_encode(__("Enter a valid IP or domain", 'wordfence')) ?>, <?php echo json_encode(__("Please enter a valid IP address or domain name for your whois lookup.", 'wordfence')) ?>);
96
  return;
97
  }
98
  var whoisButton = jQuery('#whoisbutton').attr('disabled', 'disabled')
99
+ .attr('value', <?php echo json_encode(__('Loading...', 'wordfence')) ?>);
100
  WFAD.ajax('wordfence_whois', {
101
  val: val
102
  }, function(res) {
103
  whoisButton.removeAttr('disabled')
104
+ .attr('value', <?php echo json_encode(__('Look up IP or Domain', 'wordfence')) ?>);
105
  if (res.ok) {
106
  var whoisHTML = WFAD.completeWhois(res, true);
107
  console.log(whoisHTML);
lib/menu_wordfence_central.php CHANGED
@@ -54,16 +54,18 @@ else {
54
  <div class="wf-central-dashboard">
55
  <img class="wf-central-dashboard-logo" src="<?php echo wfUtils::getBaseURL() ?>images/wf-central-logo.svg" alt="Wordfence Central">
56
  <div class="wf-central-dashboard-copy">
57
- <p><strong><?php _e('Wordfence Central', 'wordfence') ?></strong></p>
58
- <p><?php _e('Wordfence Central allows you to manage Wordfence on multiple sites from one location. It makes security monitoring and configuring Wordfence easier.', 'wordfence') ?></p>
59
- <p class="wf-right-lg"><a href="https://www.wordfence.com/central" target="_blank" rel="noopener noreferrer"><strong><?php _e('Visit Wordfence Central', 'wordfence') ?></strong></a></p>
60
  </div>
61
  </div>
62
  </div>
63
  <div class="wf-flex-row-1 wf-block wf-active">
64
- <p><strong><?php _e('Wordfence Central Status', 'wordfence') ?></strong></p>
65
- <p><?php printf(__('Activated - connected by %s on %s', 'wordfence'), esc_html(wfConfig::get('wordfenceCentralConnectEmail')), date_i18n('F j, Y', (int) wfConfig::get('wordfenceCentralConnectTime'))) ?></p>
66
- <p class="wf-right-lg"><a href="<?php echo esc_url($wordfenceURL); ?>"><strong><?php _e('Disconnect This Site', 'wordfence') ?></strong></a></p>
 
 
67
  </div>
68
  </div>
69
  </div>
@@ -72,7 +74,7 @@ else {
72
  <div class="wf-block wf-active">
73
  <div class="wf-block-header">
74
  <div class="wf-block-header-content">
75
- <strong><?php _e('Wordfence Central Installation Process') ?></strong>
76
  </div>
77
  </div>
78
  <div class="wf-block-content">
@@ -102,20 +104,20 @@ else {
102
  </div>
103
  <?php elseif ($partialConnection): ?>
104
  <div class="wf-center-lg">
105
- <p><?php _e('It looks like you\'ve tried to connect this site to Wordfence Central, but the installation did not finish.', 'wordfence') ?></p>
106
  <p>
107
  <a href="<?php echo WORDFENCE_CENTRAL_URL_SEC ?>/sites/connection-issues?complete-setup=<?php echo esc_attr(wfConfig::get('wordfenceCentralSiteID')) ?>"
108
  class="wf-btn wf-btn-primary"
109
- ><?php _e('Resume Installation', 'wordfence') ?></a>
110
- <a href="<?php echo esc_url($wordfenceURL); ?>" class="wf-btn wf-btn-warning"><?php _e('Disconnect Site', 'wordfence') ?></a>
111
  </p>
112
  </div>
113
  <?php else: ?>
114
  <div class="wf-center-lg">
115
- <p><?php _e('Wordfence Central allows you to manage Wordfence on multiple sites from one location. It makes security monitoring and configuring Wordfence easier.', 'wordfence') ?></p>
116
- <p><?php _e('To connect your site your site to Wordfence Central, use the link below:', 'wordfence') ?></p>
117
  <p class="wf-center">
118
- <a href="<?php echo WORDFENCE_CENTRAL_URL_SEC ?>?newsite=<?php echo esc_attr(home_url()) ?>" class="wf-btn wf-btn-primary"><?php _e('Connect Site', 'wordfence') ?></a>
119
  </p>
120
  </div>
121
  <?php endif ?>
@@ -250,4 +252,4 @@ else {
250
  });
251
 
252
  })(jQuery);
253
- </script>
54
  <div class="wf-central-dashboard">
55
  <img class="wf-central-dashboard-logo" src="<?php echo wfUtils::getBaseURL() ?>images/wf-central-logo.svg" alt="Wordfence Central">
56
  <div class="wf-central-dashboard-copy">
57
+ <p><strong><?php esc_html_e('Wordfence Central', 'wordfence') ?></strong></p>
58
+ <p><?php esc_html_e('Wordfence Central allows you to manage Wordfence on multiple sites from one location. It makes security monitoring and configuring Wordfence easier.', 'wordfence') ?></p>
59
+ <p class="wf-right-lg"><a href="https://www.wordfence.com/central" target="_blank" rel="noopener noreferrer"><strong><?php esc_html_e('Visit Wordfence Central', 'wordfence') ?></strong></a></p>
60
  </div>
61
  </div>
62
  </div>
63
  <div class="wf-flex-row-1 wf-block wf-active">
64
+ <p><strong><?php esc_html_e('Wordfence Central Status', 'wordfence') ?></strong></p>
65
+ <p><?php echo esc_html(sprintf(
66
+ /* translators: 1. Email address. 2. Localized date. */
67
+ __('Activated - connected by %1$s on %2$s', 'wordfence'), wfConfig::get('wordfenceCentralConnectEmail')), date_i18n('F j, Y', (int) wfConfig::get('wordfenceCentralConnectTime'))) ?></p>
68
+ <p class="wf-right-lg"><a href="<?php echo esc_url($wordfenceURL); ?>"><strong><?php esc_html_e('Disconnect This Site', 'wordfence') ?></strong></a></p>
69
  </div>
70
  </div>
71
  </div>
74
  <div class="wf-block wf-active">
75
  <div class="wf-block-header">
76
  <div class="wf-block-header-content">
77
+ <strong><?php esc_html_e('Wordfence Central Installation Process', 'wordfence') ?></strong>
78
  </div>
79
  </div>
80
  <div class="wf-block-content">
104
  </div>
105
  <?php elseif ($partialConnection): ?>
106
  <div class="wf-center-lg">
107
+ <p><?php esc_html_e('It looks like you\'ve tried to connect this site to Wordfence Central, but the installation did not finish.', 'wordfence') ?></p>
108
  <p>
109
  <a href="<?php echo WORDFENCE_CENTRAL_URL_SEC ?>/sites/connection-issues?complete-setup=<?php echo esc_attr(wfConfig::get('wordfenceCentralSiteID')) ?>"
110
  class="wf-btn wf-btn-primary"
111
+ ><?php esc_html_e('Resume Installation', 'wordfence') ?></a>
112
+ <a href="<?php echo esc_url($wordfenceURL); ?>" class="wf-btn wf-btn-warning"><?php esc_html_e('Disconnect Site', 'wordfence') ?></a>
113
  </p>
114
  </div>
115
  <?php else: ?>
116
  <div class="wf-center-lg">
117
+ <p><?php esc_html_e('Wordfence Central allows you to manage Wordfence on multiple sites from one location. It makes security monitoring and configuring Wordfence easier.', 'wordfence') ?></p>
118
+ <p><?php esc_html_e('To connect your site your site to Wordfence Central, use the link below:', 'wordfence') ?></p>
119
  <p class="wf-center">
120
+ <a href="<?php echo WORDFENCE_CENTRAL_URL_SEC ?>?newsite=<?php echo esc_attr(home_url()) ?>" class="wf-btn wf-btn-primary"><?php esc_html_e('Connect Site', 'wordfence') ?></a>
121
  </p>
122
  </div>
123
  <?php endif ?>
252
  });
253
 
254
  })(jQuery);
255
+ </script>
lib/rest-api/wfRESTConfigController.php CHANGED
@@ -210,7 +210,9 @@ class wfRESTConfigController extends wfRESTBaseController {
210
  if ($errors !== true) {
211
  if (count($errors) == 1) {
212
  return new WP_Error('rest_set_config_error',
213
- sprintf(__('An error occurred while saving the configuration: %s', 'wordfence'), $errors[0]['error']),
 
 
214
  array('status' => 422));
215
 
216
  } else if (count($errors) > 1) {
@@ -219,7 +221,9 @@ class wfRESTConfigController extends wfRESTBaseController {
219
  $compoundMessage[] = $e['error'];
220
  }
221
  return new WP_Error('rest_set_config_error',
222
- sprintf(__('Errors occurred while saving the configuration: %s', 'wordfence'), implode(', ', $compoundMessage)),
 
 
223
  array('status' => 422));
224
  }
225
 
@@ -238,7 +242,9 @@ class wfRESTConfigController extends wfRESTBaseController {
238
 
239
  } catch (Exception $e) {
240
  return new WP_Error('rest_save_config_error',
241
- sprintf(__('A server error occurred while saving the configuration: %s', 'wordfence'), $e->getMessage()),
 
 
242
  array('status' => 500));
243
  }
244
  }
@@ -247,7 +253,9 @@ class wfRESTConfigController extends wfRESTBaseController {
247
  if ($errors !== true) {
248
  if (count($errors) == 1) {
249
  return new WP_Error('rest_set_config_error',
250
- sprintf(__('An error occurred while saving the configuration: %s', 'wordfence'), $errors[0]['error']),
 
 
251
  array('status' => 422));
252
 
253
  } else if (count($errors) > 1) {
@@ -256,7 +264,9 @@ class wfRESTConfigController extends wfRESTBaseController {
256
  $compoundMessage[] = $e['error'];
257
  }
258
  return new WP_Error('rest_set_config_error',
259
- sprintf(__('Errors occurred while saving the configuration: %s', 'wordfence'), implode(', ', $compoundMessage)),
 
 
260
  array('status' => 422));
261
  }
262
 
@@ -273,7 +283,9 @@ class wfRESTConfigController extends wfRESTBaseController {
273
 
274
  } catch (Exception $e) {
275
  return new WP_Error('rest_save_config_error',
276
- sprintf(__('A server error occurred while saving the configuration: %s', 'wordfence'), $e->getMessage()),
 
 
277
  array('status' => 500));
278
  }
279
  }
210
  if ($errors !== true) {
211
  if (count($errors) == 1) {
212
  return new WP_Error('rest_set_config_error',
213
+ sprintf(
214
+ /* translators: Error message. */
215
+ __('An error occurred while saving the configuration: %s', 'wordfence'), $errors[0]['error']),
216
  array('status' => 422));
217
 
218
  } else if (count($errors) > 1) {
221
  $compoundMessage[] = $e['error'];
222
  }
223
  return new WP_Error('rest_set_config_error',
224
+ sprintf(
225
+ /* translators: Error message. */
226
+ __('Errors occurred while saving the configuration: %s', 'wordfence'), implode(', ', $compoundMessage)),
227
  array('status' => 422));
228
  }
229
 
242
 
243
  } catch (Exception $e) {
244
  return new WP_Error('rest_save_config_error',
245
+ sprintf(
246
+ /* translators: Error message. */
247
+ __('A server error occurred while saving the configuration: %s', 'wordfence'), $e->getMessage()),
248
  array('status' => 500));
249
  }
250
  }
253
  if ($errors !== true) {
254
  if (count($errors) == 1) {
255
  return new WP_Error('rest_set_config_error',
256
+ sprintf(
257
+ /* translators: Error message. */
258
+ __('An error occurred while saving the configuration: %s', 'wordfence'), $errors[0]['error']),
259
  array('status' => 422));
260
 
261
  } else if (count($errors) > 1) {
264
  $compoundMessage[] = $e['error'];
265
  }
266
  return new WP_Error('rest_set_config_error',
267
+ sprintf(
268
+ /* translators: Error message. */
269
+ __('Errors occurred while saving the configuration: %s', 'wordfence'), implode(', ', $compoundMessage)),
270
  array('status' => 422));
271
  }
272
 
283
 
284
  } catch (Exception $e) {
285
  return new WP_Error('rest_save_config_error',
286
+ sprintf(
287
+ /* translators: Error message. */
288
+ __('A server error occurred while saving the configuration: %s', 'wordfence'), $e->getMessage()),
289
  array('status' => 500));
290
  }
291
  }
lib/rest-api/wfRESTScanController.php CHANGED
@@ -81,7 +81,7 @@ class wfRESTScanController extends wfRESTBaseController {
81
  * @return mixed|WP_REST_Response
82
  */
83
  public function startScan($request) {
84
- wordfence::status(1, 'info', sprintf(__('Wordfence scan starting at %s from Wordfence Central', 'wordfence'),
85
  date('l jS \of F Y h:i:s A', current_time('timestamp'))));
86
 
87
  try {
81
  * @return mixed|WP_REST_Response
82
  */
83
  public function startScan($request) {
84
+ wordfence::status(1, 'info', sprintf(/* translators: Localized date. */ __('Wordfence scan starting at %s from Wordfence Central', 'wordfence'),
85
  date('l jS \of F Y h:i:s A', current_time('timestamp'))));
86
 
87
  try {
lib/sysinfo.php CHANGED
@@ -2,7 +2,7 @@
2
  <?php if(! wfUtils::isAdmin()){ exit(); } ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
  <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
4
  <head>
5
- <title>Wordfence System Info</title>
6
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7
  <link rel='stylesheet' id='wordfence-main-style-css' href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/phpinfo.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>' type='text/css' media='all' />
8
  <body>
@@ -17,6 +17,6 @@ $out = preg_replace('/<\/a>/', '', $out);
17
  $out = preg_replace('/<title>[^<]*<\/title>/','', $out);
18
  echo $out;
19
  ?>
20
- <div class="diffFooter">&copy;&nbsp;2011 to <?php echo date('Y'); ?> Wordfence &mdash; Visit <a href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.</div>
21
  </body>
22
- </html>
2
  <?php if(! wfUtils::isAdmin()){ exit(); } ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
  <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
4
  <head>
5
+ <title><?php esc_html_e('Wordfence System Info', 'wordfence') ?></title>
6
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7
  <link rel='stylesheet' id='wordfence-main-style-css' href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/phpinfo.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>' type='text/css' media='all' />
8
  <body>
17
  $out = preg_replace('/<title>[^<]*<\/title>/','', $out);
18
  echo $out;
19
  ?>
20
+ <div class="diffFooter"><?php echo wp_kses(sprintf(__('&copy;&nbsp;%d to %d Wordfence &mdash; Visit <a href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.', 'wordfence'), date_i18n('Y', WORDFENCE_EPOCH), date_i18n('Y')), array('a'=>array('href'=>array()))) ?></div>
21
  </body>
22
+ </html>
lib/unknownFiles.php DELETED
@@ -1,158 +0,0 @@
1
- <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
- <?php if(! wfUtils::isAdmin()){ exit(); } ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
- <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
4
- <head>
5
- <title>Files found that don't belong to WordPress Core or known Themes and Plugins</title>
6
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7
- <link rel='stylesheet' id='wordfence-main-style-css' href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/diff.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>' type='text/css' media='all' />
8
- <body>
9
- <h1>Wordfence: Files found that don't belong to WordPress Core or known Themes and Plugins.</h1>
10
- <?php
11
- $path = ABSPATH;
12
- $fileList = wfConfig::get('lastUnknownFileList');
13
- if($fileList){
14
- ?>
15
- <p style="width: 700px; margin-top: 20px;">
16
- <b>Please note:</b> To use this utility, you must enable scanning of Core, Theme and Plugin files on the Wordfence options page.
17
- <?php if(! wfConfig::get('scansEnabled_themes')){ echo '<span style="color: #F00;">Theme scanning is currently disabled.</span> '; } ?>
18
- <?php if(! wfConfig::get('scansEnabled_plugins')){ echo '<span style="color: #F00;">Plugin scanning is currently disabled.</span> '; } ?>
19
- <?php if( (!wfConfig::get('scansEnabled_plugins')) || (!wfConfig::get('scansEnabled_themes')) ){ echo 'You can visit the Wordfence "options" page to enable theme or plugin scanning.'; } ?>
20
-
21
- If you don't have core, theme and plugin scanning enabled, then the list below will not be very useful because Wordfence won't recognize known core, theme and plugin files.
22
- If you have the option enabled to "Scan files outside your WordPress installation" enabled, then you may find that this list is very long because it will include files in all your directories.
23
- <br /><br />
24
- <b>What is in this list:</b>
25
- When Wordfence does a scan, it separates files on your system into two lists. The first list is files that belong to WordPress Core or a known theme or plugin. The second list is all other files.
26
- <br /><br />
27
- If a <b>file belongs to WordPress Core or a known theme or plugin</b>, we do an integrity check and let you know if it has been modified.
28
- The integrity check we do on known Core, theme and plugin files is a very reliable way to detect compromised files. It is impossible as far as we know for a hacker to fool this scan
29
- because we are comparing your files to known originals on our secure scanning servers. If the file is modified, we let you know with a warning or critical alert in the scan results.
30
- <br /><br />
31
- If the file <b>does not belong to WordPress Core or a known theme or plugin</b>, we scan it for security problems.
32
- We have a pretty good detection rate for this second scan, but for very advanced or sneaky attacks our admin's sometimes prefer to examine these files by hand.
33
- If you would like to look at these non-integrity checked files, we provide you with the list below. You can click on any file to view the contents and see if it has been hacked.
34
- <br /><br />
35
- <b>Files that you will find in this list are:</b>
36
- <ul>
37
- <li>Files belonging to commercial themes that are not in the open source WordPress theme repository</li>
38
- <li>Files belonging to commercial plugins that are not in the open source WordPress repository</li>
39
- <li>Files created by themes or plugins</li>
40
- <li>Files created by you on your WordPress installation by uploading them through WordPress or a utility like FTP or SFTP</li>
41
- <li>Files that a hacker put on your system to create a back-door, distribute spam or for another nefarious purpose.</li>
42
- </ul>
43
- <b>How to use this list to clean your system if it is infected:</b>
44
- <ul>
45
- <li>First sort by most recently modified files by clicking the "Last Modified" column. You may have to click it twice.</li>
46
- <li>Examine recently modified files by clicking them to view the file and check if it is infected. This is often the most reliable way to find an infection.</li>
47
- <li>Then sort by "Full File Path" and look at files that aren't one of your custom themes or plugins.</li>
48
- <li>Note that custom themes and plugins live in the /wp-content/themes/ and /wp-content/plugins directories.</li>
49
- <li>Then start going through your themes and plugins to see if they are infected.</li>
50
- </ul>
51
- </p>
52
- <h2 style="margin-top: 30px;">Files that don't belong to WordPress Core, or to a theme or plugin in the WordPress Repository:</h2>
53
-
54
-
55
- <?php
56
- $files = array();
57
- while(strlen($fileList) > 0){
58
- $filenameLen = unpack('n', substr($fileList, 0, 2));
59
- $filenameLen = $filenameLen[1];
60
- if($filenameLen > 1000 || $filenameLen < 1){
61
- continue;
62
- }
63
- $file = substr($fileList, 2, $filenameLen);
64
- $fileList = substr($fileList, 2 + $filenameLen);
65
- $fullFile = $path . $file;
66
- if(! file_exists($fullFile)){
67
- continue;
68
- }
69
- $fileExt = '';
70
- if(preg_match('/\.([a-zA-Z\d\-]{1,7})$/', $file, $matches)){
71
- $fileExt = strtolower($matches[1]);
72
- }
73
- $isPHP = false;
74
- if(preg_match('/^(?:php|phtml|php\d+)$/', $fileExt)){
75
- $isPHP = true;
76
- }
77
- // http://test3.com/?_wfsf=view&nonce=c1ad72bcbd&file=wp-content%2Fplugins%2Fwordfence%2Flib%2Fmenu_options.php
78
- $viewLink = wfUtils::siteURLRelative() . '?_wfsf=view&nonce=' . wp_create_nonce('wp-ajax') . '&file=' . urlencode($file);
79
- $stat = stat($fullFile);
80
- if(function_exists('posix_getpwuid')){
81
- $owner = posix_getpwuid($stat['uid']);
82
- $owner = $owner['name'];
83
- } else {
84
- $owner = "unknown";
85
- }
86
- if(function_exists('posix_getgrgid')){
87
- $group = posix_getgrgid($stat['gid']);
88
- $group = $group['name'];
89
- } else {
90
- $group = 'unknown';
91
- }
92
- $perms = substr(sprintf('%o', fileperms($fullFile)), -4);
93
- $files[] = array($file, $fullFile, $stat['size'], $stat['mtime'], $viewLink, $owner, $group, $perms);
94
- }
95
- function wfUKFcmp($a, $b){
96
- $idx = $_GET['sort'] ? $_GET['sort'] : 2;
97
- if($_GET['dir'] == 'rev'){
98
- $tmp = $a;
99
- $a = $b;
100
- $b = $tmp;
101
- }
102
- $type = 'num';
103
- if($idx == 1 || $idx == 5 || $idx == 6 || $idx == 7){
104
- $type = 'str';
105
- }
106
-
107
- if($a[$idx] == $b[$idx]){
108
- return 0;
109
- }
110
- if($type == 'num'){
111
- return ($a[$idx] < $b[$idx]) ? -1 : 1;
112
- } else {
113
- return strcmp($a[$idx], $b[$idx]);
114
- }
115
- }
116
- usort($files, 'wfUKFcmp');
117
-
118
- $sortLink = wfUtils::siteURLRelative() . '?_wfsf=unknownFiles&nonce=' . wp_create_nonce('wp-ajax') . '&sort=';
119
- $sortIDX = $_GET['sort'];
120
- if(! $sortIDX){
121
- $sortIDX = 2;
122
- }
123
- $sortDir = $_GET['dir'];
124
- if(! $sortDir){
125
- $sortDir = 'fwd';
126
- }
127
- ?>
128
- <p>
129
- All columns are sortable. Click the heading to sort a column. Click again to sort in reverse direction.<br />
130
- If you are cleaning a hacked site, start by sorting files by most recently modified and view those files first.
131
- </p>
132
- <table border="1" cellpadding="2" cellspacing="0">
133
- <tr>
134
- <th><a href="<?php echo $sortLink; ?>2&dir=<?php echo ($sortIDX == 2 && $sortDir == 'fwd') ? 'rev' : 'fwd'; ?>">File Size in Bytes</a></th>
135
- <th><a href="<?php echo $sortLink; ?>3&dir=<?php echo ($sortIDX == 3 && $sortDir == 'fwd') ? 'rev' : 'fwd'; ?>">Last modified</a></th>
136
- <th><a href="<?php echo $sortLink; ?>5&dir=<?php echo ($sortIDX == 5 && $sortDir == 'fwd') ? 'rev' : 'fwd'; ?>">Owner<a></th>
137
- <th><a href="<?php echo $sortLink; ?>6&dir=<?php echo ($sortIDX == 6 && $sortDir == 'fwd') ? 'rev' : 'fwd'; ?>">Group</a></th>
138
- <th><a href="<?php echo $sortLink; ?>7&dir=<?php echo ($sortIDX == 7 && $sortDir == 'fwd') ? 'rev' : 'fwd'; ?>">Permissions</a></th>
139
- <th><a href="<?php echo $sortLink; ?>1&dir=<?php echo ($sortIDX == 1 && $sortDir == 'fwd') ? 'rev' : 'fwd'; ?>">Full file path</a></th>
140
- </tr>
141
- <?php
142
- for($i = 0; $i < sizeof($files); $i++){
143
- echo '<tr><td>' . wfUtils::formatBytes($files[$i][2]) . '</td><td>' . wfUtils::makeTimeAgo(time() - $files[$i][3]) . ' ago.</td><td>' . $files[$i][5] . '</td><td>' . $files[$i][6] . '</td><td>' . $files[$i][7] . '</td><td><a href="' . $files[$i][4] . '" target="_blank" rel="noopener noreferrer">' . $files[$i][1] . '</a></td></tr>';
144
- }
145
- echo "</table>";
146
- } else {
147
- ?>
148
- <p style="margin: 40px; font-size: 20px;">
149
- You either have not completed a scan recently, or there were no files found on your system that are not in the WordPress official repository for Core files, themes and plugins.
150
- </p>
151
- <?php
152
- }
153
-
154
- ?>
155
-
156
- <div class="diffFooter">&copy;&nbsp;2011 to <?php echo date('Y'); ?> Wordfence &mdash; Visit <a href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.</div>
157
- </body>
158
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/viewFullActivityLog.php CHANGED
@@ -7,8 +7,9 @@
7
  <style type="text/css">
8
 
9
  </style>
 
10
  <body>
11
- <h1>Wordfence Full Activity Log</h1>
12
  <?php
13
  $db = new wfDB();
14
  global $wpdb;
7
  <style type="text/css">
8
 
9
  </style>
10
+ </head>
11
  <body>
12
+ <h1><?php esc_html_e('Wordfence Full Activity Log', 'wordfence') ?></h1>
13
  <?php
14
  $db = new wfDB();
15
  global $wpdb;
lib/wf503.php CHANGED
@@ -2,7 +2,7 @@
2
  <!DOCTYPE html>
3
  <html>
4
  <head>
5
- <title><?php _e('Your access to this site has been limited', 'wordfence'); ?></title>
6
  <style>
7
  html {
8
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
@@ -318,9 +318,9 @@
318
  <body>
319
  <div class="top-accent"></div>
320
  <div class="container">
321
- <h1><?php _e('Your access to this site has been limited by the site owner', 'wordfence'); ?></h1>
322
- <p><?php _e('Your access to this service has been limited. (HTTP response code 503)', 'wordfence'); ?></p>
323
- <p><?php _e('If you think you have been blocked in error, contact the owner of this site for assistance.', 'wordfence'); ?></p>
324
  <?php if (!empty($customText)): ?>
325
  <hr>
326
  <div class="medium"><?php echo $customText; ?></div>
@@ -328,14 +328,14 @@
328
  <hr>
329
  <?php require(dirname(__FILE__) . '/wfUnlockMsg.php'); ?>
330
 
331
- <h2 class="h3"><?php _e('Block Technical Data', 'wordfence') ?></h2>
332
  <table border="0" cellspacing="0" cellpadding="0" class="block-data">
333
  <tr>
334
- <th class="reason"><?php _e('Block Reason', 'wordfence'); ?>:</th>
335
  <td class="reason"><?php echo htmlspecialchars($reason); ?></td>
336
  </tr>
337
  <tr>
338
- <th class="time"><?php _e('Time', 'wordfence'); ?>:</th>
339
  <td class="time"><?php echo htmlspecialchars(gmdate('D, j M Y G:i:s T', wfWAFUtils::normalizedTime())); ?></td>
340
  </tr>
341
  </table>
@@ -351,14 +351,14 @@
351
  ?>
352
  </div>
353
  <div class="about-text">
354
- <h3 class="h4"><?php _e('About Wordfence', 'wordfence'); ?></h3>
355
- <p><?php _e('Wordfence is a security plugin installed on over 3 million WordPress sites. The owner of this site is using Wordfence to manage access to their site.', 'wordfence'); ?></p>
356
- <p><?php _e('You can also read the documentation to learn about Wordfence\'s blocking tools, or visit wordfence.com to learn more about Wordfence.', 'wordfence'); ?></p>
357
  </div>
358
  </div>
359
 
360
- <p class="documentation small"><?php printf(__('Click here to learn more: <a href="%s" target="_blank" rel="noopener noreferrer">Documentation</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_LOCKED_OUT)); ?></p>
361
- <p class="generated small"><em><?php printf(__('Generated by Wordfence at %s', 'wordfence'), gmdate('D, j M Y G:i:s T', wfWAFUtils::normalizedTime())); ?>.<br><?php _e('Your computer\'s time:', 'wordfence'); ?> <script type="application/javascript">document.write(new Date().toUTCString());</script>.</em></p>
362
  </div>
363
  </body>
364
- </html>
2
  <!DOCTYPE html>
3
  <html>
4
  <head>
5
+ <title><?php esc_html_e('Your access to this site has been limited', 'wordfence'); ?></title>
6
  <style>
7
  html {
8
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
318
  <body>
319
  <div class="top-accent"></div>
320
  <div class="container">
321
+ <h1><?php esc_html_e('Your access to this site has been limited by the site owner', 'wordfence'); ?></h1>
322
+ <p><?php esc_html_e('Your access to this service has been limited. (HTTP response code 503)', 'wordfence'); ?></p>
323
+ <p><?php esc_html_e('If you think you have been blocked in error, contact the owner of this site for assistance.', 'wordfence'); ?></p>
324
  <?php if (!empty($customText)): ?>
325
  <hr>
326
  <div class="medium"><?php echo $customText; ?></div>
328
  <hr>
329
  <?php require(dirname(__FILE__) . '/wfUnlockMsg.php'); ?>
330
 
331
+ <h2 class="h3"><?php esc_html_e('Block Technical Data', 'wordfence') ?></h2>
332
  <table border="0" cellspacing="0" cellpadding="0" class="block-data">
333
  <tr>
334
+ <th class="reason"><?php esc_html_e('Block Reason', 'wordfence'); ?>:</th>
335
  <td class="reason"><?php echo htmlspecialchars($reason); ?></td>
336
  </tr>
337
  <tr>
338
+ <th class="time"><?php esc_html_e('Time', 'wordfence'); ?>:</th>
339
  <td class="time"><?php echo htmlspecialchars(gmdate('D, j M Y G:i:s T', wfWAFUtils::normalizedTime())); ?></td>
340
  </tr>
341
  </table>
351
  ?>
352
  </div>
353
  <div class="about-text">
354
+ <h3 class="h4"><?php esc_html_e('About Wordfence', 'wordfence'); ?></h3>
355
+ <p><?php esc_html_e('Wordfence is a security plugin installed on over 3 million WordPress sites. The owner of this site is using Wordfence to manage access to their site.', 'wordfence'); ?></p>
356
+ <p><?php esc_html_e('You can also read the documentation to learn about Wordfence\'s blocking tools, or visit wordfence.com to learn more about Wordfence.', 'wordfence'); ?></p>
357
  </div>
358
  </div>
359
 
360
+ <p class="documentation small"><?php echo wp_kses(sprintf(/* translators: Support URL. */ __('Click here to learn more: <a href="%s" target="_blank" rel="noopener noreferrer">Documentation</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_LOCKED_OUT)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))); ?></p>
361
+ <p class="generated small"><em><?php echo wp_kses(sprintf(/* translators: Localized date. */ __('Generated by Wordfence at %s', 'wordfence'), gmdate('D, j M Y G:i:s T', wfWAFUtils::normalizedTime())), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))); ?>.<br><?php esc_html_e('Your computer\'s time:', 'wordfence'); ?> <script type="application/javascript">document.write(new Date().toUTCString());</script>.</em></p>
362
  </div>
363
  </body>
364
+ </html>
lib/wfAPI.php CHANGED
@@ -6,6 +6,7 @@ class wfAPI {
6
  const KEY_TYPE_FREE = 'free';
7
  const KEY_TYPE_PAID_CURRENT = 'paid-current';
8
  const KEY_TYPE_PAID_EXPIRED = 'paid-expired';
 
9
 
10
  public $lastHTTPStatus = '';
11
  public $lastCurlErrorNo = '';
@@ -27,7 +28,7 @@ class wfAPI {
27
  //Sanity check. Developer should call wfAPI::SSLEnabled() to check if SSL is enabled before forcing SSL and return a user friendly msg if it's not.
28
  if ($forceSSL && (!preg_match('/^https:/i', $apiURL))) {
29
  //User's should never see this message unless we aren't calling SSLEnabled() to check if SSL is enabled before using call() with forceSSL
30
- throw new wfAPICallSSLUnavailableException("SSL is not supported by your web server and is required to use this function. Please ask your hosting provider or site admin to install cURL with openSSL to use this feature.");
31
  }
32
  $json = $this->getURL(rtrim($apiURL, '/') . '/v' . WORDFENCE_API_VERSION . '/?' . $this->makeAPIQueryString() . '&' . self::buildQuery(
33
  array_merge(
@@ -35,7 +36,7 @@ class wfAPI {
35
  $getParams
36
  )), $postParams, $timeout);
37
  if (!$json) {
38
- throw new wfAPICallInvalidResponseException("We received an empty data response from the Wordfence scanning servers when calling the '$action' function.");
39
  }
40
 
41
  $dat = json_decode($json, true);
@@ -69,7 +70,7 @@ class wfAPI {
69
  if (isset($dat['_hasKeyConflict'])) {
70
  $hasKeyConflict = ($dat['_hasKeyConflict'] == 1);
71
  if ($hasKeyConflict) {
72
- new wfNotification(null, wfNotification::PRIORITY_HIGH_CRITICAL, '<a href="' . wfUtils::wpAdminURL('admin.php?page=Wordfence&subpage=global_options') . '">The Wordfence license you\'re using does not match this site\'s address. Premium features are disabled.</a>', 'wfplugin_keyconflict', null, array(array('link' => 'https://www.wordfence.com/manage-wordfence-api-keys/', 'label' => 'Manage Keys')));
73
  wfConfig::set('hasKeyConflict', 1);
74
  }
75
  }
@@ -78,7 +79,8 @@ class wfAPI {
78
  if (isset($dat['_keyNoLongerValid'])) {
79
  $keyNoLongerValid = ($dat['_keyNoLongerValid'] == 1);
80
  if ($keyNoLongerValid) {
81
- wordfence::ajax_downgradeLicense_callback();
 
82
  }
83
  }
84
 
@@ -96,7 +98,7 @@ class wfAPI {
96
  }
97
 
98
  if (!is_array($dat)) {
99
- throw new wfAPICallInvalidResponseException("We received a data structure that is not the expected array when contacting the Wordfence scanning servers and calling the '$action' function.");
100
  }
101
  if (is_array($dat) && isset($dat['errorMsg'])) {
102
  throw new wfAPICallErrorResponseException($dat['errorMsg']);
@@ -105,7 +107,7 @@ class wfAPI {
105
  }
106
 
107
  protected function getURL($url, $postParams = array(), $timeout = 900) {
108
- wordfence::status(4, 'info', "Calling Wordfence API v" . WORDFENCE_API_VERSION . ":" . $url);
109
 
110
  if (!function_exists('wp_remote_post')) {
111
  require_once(ABSPATH . WPINC . 'http.php');
@@ -130,7 +132,13 @@ class wfAPI {
130
 
131
  if (is_wp_error($response)) {
132
  $error_message = $response->get_error_message();
133
- throw new wfAPICallFailedException("There was an " . ($error_message ? '' : 'unknown ') . "error connecting to the Wordfence scanning servers" . ($error_message ? ": $error_message" : '.'));
 
 
 
 
 
 
134
  }
135
 
136
  $dateHeader = @$response['headers']['date'];
@@ -152,7 +160,7 @@ class wfAPI {
152
  }
153
 
154
  if (200 != $this->lastHTTPStatus) {
155
- throw new wfAPICallFailedException("The Wordfence scanning servers are currently unavailable. This may be for maintenance or a temporary outage. If this still occurs in an hour, please contact support. [$this->lastHTTPStatus]");
156
  }
157
 
158
  $content = wp_remote_retrieve_body($response);
@@ -194,6 +202,7 @@ class wfAPI {
194
  'cs' => $cs,
195
  'sv' => (isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : null),
196
  'dv' => wfConfig::get('dbVersion', null),
 
197
  );
198
 
199
  return self::buildQuery(array(
@@ -238,4 +247,4 @@ class wfAPICallInvalidResponseException extends Exception {
238
  }
239
 
240
  class wfAPICallErrorResponseException extends Exception {
241
- }
6
  const KEY_TYPE_FREE = 'free';
7
  const KEY_TYPE_PAID_CURRENT = 'paid-current';
8
  const KEY_TYPE_PAID_EXPIRED = 'paid-expired';
9
+ const KEY_TYPE_PAID_DELETED = 'paid-deleted';
10
 
11
  public $lastHTTPStatus = '';
12
  public $lastCurlErrorNo = '';
28
  //Sanity check. Developer should call wfAPI::SSLEnabled() to check if SSL is enabled before forcing SSL and return a user friendly msg if it's not.
29
  if ($forceSSL && (!preg_match('/^https:/i', $apiURL))) {
30
  //User's should never see this message unless we aren't calling SSLEnabled() to check if SSL is enabled before using call() with forceSSL
31
+ throw new wfAPICallSSLUnavailableException(__("SSL is not supported by your web server and is required to use this function. Please ask your hosting provider or site admin to install cURL with openSSL to use this feature.", 'wordfence'));
32
  }
33
  $json = $this->getURL(rtrim($apiURL, '/') . '/v' . WORDFENCE_API_VERSION . '/?' . $this->makeAPIQueryString() . '&' . self::buildQuery(
34
  array_merge(
36
  $getParams
37
  )), $postParams, $timeout);
38
  if (!$json) {
39
+ throw new wfAPICallInvalidResponseException(sprintf(/* translators: API call/action/endpoint. */__("We received an empty data response from the Wordfence scanning servers when calling the '%s' function.", 'wordfence'), $action));
40
  }
41
 
42
  $dat = json_decode($json, true);
70
  if (isset($dat['_hasKeyConflict'])) {
71
  $hasKeyConflict = ($dat['_hasKeyConflict'] == 1);
72
  if ($hasKeyConflict) {
73
+ new wfNotification(null, wfNotification::PRIORITY_HIGH_CRITICAL, '<a href="' . wfUtils::wpAdminURL('admin.php?page=Wordfence&subpage=global_options') . '">' . esc_html__('The Wordfence license you\'re using does not match this site\'s address. Premium features are disabled.', 'wordfence') . '</a>', 'wfplugin_keyconflict', null, array(array('link' => 'https://www.wordfence.com/manage-wordfence-api-keys/', 'label' => 'Manage Keys')));
74
  wfConfig::set('hasKeyConflict', 1);
75
  }
76
  }
79
  if (isset($dat['_keyNoLongerValid'])) {
80
  $keyNoLongerValid = ($dat['_keyNoLongerValid'] == 1);
81
  if ($keyNoLongerValid) {
82
+ wfConfig::set('keyType', self::KEY_TYPE_PAID_DELETED);
83
+ wfConfig::set('isPaid', '');
84
  }
85
  }
86
 
98
  }
99
 
100
  if (!is_array($dat)) {
101
+ throw new wfAPICallInvalidResponseException(sprintf(/* translators: API call/action/endpoint. */ __("We received a data structure that is not the expected array when contacting the Wordfence scanning servers and calling the '%s' function.", 'wordfence'), $action));
102
  }
103
  if (is_array($dat) && isset($dat['errorMsg'])) {
104
  throw new wfAPICallErrorResponseException($dat['errorMsg']);
107
  }
108
 
109
  protected function getURL($url, $postParams = array(), $timeout = 900) {
110
+ wordfence::status(4, 'info', sprintf(/* translators: API version. */ __("Calling Wordfence API v%s:", 'wordfence'), WORDFENCE_API_VERSION) . $url);
111
 
112
  if (!function_exists('wp_remote_post')) {
113
  require_once(ABSPATH . WPINC . 'http.php');
132
 
133
  if (is_wp_error($response)) {
134
  $error_message = $response->get_error_message();
135
+ if ($error_message) {
136
+ $apiExceptionMessage = sprintf(/* translators: Error message. */ __('There was an error connecting to the Wordfence scanning servers: %s', 'wordfence'), $error_message);
137
+ } else {
138
+ $apiExceptionMessage = __('There was an unknown error connecting to the Wordfence scanning servers.', 'wordfence');
139
+ }
140
+
141
+ throw new wfAPICallFailedException($apiExceptionMessage);
142
  }
143
 
144
  $dateHeader = @$response['headers']['date'];
160
  }
161
 
162
  if (200 != $this->lastHTTPStatus) {
163
+ throw new wfAPICallFailedException(sprintf(/* translators: HTTP status code. */__("The Wordfence scanning servers are currently unavailable. This may be for maintenance or a temporary outage. If this still occurs in an hour, please contact support. [%s]"), $this->lastHTTPStatus));
164
  }
165
 
166
  $content = wp_remote_retrieve_body($response);
202
  'cs' => $cs,
203
  'sv' => (isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : null),
204
  'dv' => wfConfig::get('dbVersion', null),
205
+ 'lang' => get_site_option('WPLANG'),
206
  );
207
 
208
  return self::buildQuery(array(
247
  }
248
 
249
  class wfAPICallErrorResponseException extends Exception {
250
+ }
lib/wfActivityReport.php CHANGED
@@ -504,8 +504,8 @@ SQL
504
  $success = true;
505
  if (is_string($email_addresses)) { $email_addresses = explode(',', $email_addresses); }
506
  foreach ($email_addresses as $email) {
507
- $uniqueContent = str_replace('<!-- ##UNSUBSCRIBE## -->', sprintf(__('No longer an administrator for this site? <a href="%s" target="_blank">Click here</a> to stop receiving security alerts.', 'wordfence'), wfUtils::getSiteBaseURL() . '?_wfsf=removeAlertEmail&jwt=' . wfUtils::generateJWT(array('email' => $email))), $content);
508
- if (!wp_mail($email, 'Wordfence activity for ' . date_i18n(get_option('date_format')) . ' on ' . $shortSiteURL, $uniqueContent, 'Content-Type: text/html')) {
509
  $success = false;
510
  }
511
  }
@@ -581,10 +581,10 @@ SQL
581
  }
582
 
583
  if (isset($actionData['failedRules']) && $actionData['failedRules'] == 'blocked') {
584
- $row->longDescription = "Blocked because the IP is blocklisted";
585
  }
586
  else {
587
- $row->longDescription = "Blocked for " . $row->actionDescription;
588
  }
589
 
590
  $paramKey = base64_decode($actionData['paramKey']);
@@ -596,16 +596,16 @@ SQL
596
  if (preg_match('/([a-z0-9_]+\.[a-z0-9_]+)(?:\[(.+?)\](.*))?/i', $paramKey, $matches)) {
597
  switch ($matches[1]) {
598
  case 'request.queryString':
599
- $row->longDescription = "Blocked for " . $row->actionDescription . ' in query string: ' . $matches[2] . '=' . $paramValue;
600
  break;
601
  case 'request.body':
602
- $row->longDescription = "Blocked for " . $row->actionDescription . ' in POST body: ' . $matches[2] . '=' . $paramValue;
603
  break;
604
  case 'request.cookie':
605
- $row->longDescription = "Blocked for " . $row->actionDescription . ' in cookie: ' . $matches[2] . '=' . $paramValue;
606
  break;
607
  case 'request.fileNames':
608
- $row->longDescription = "Blocked for a " . $row->actionDescription . ' in file: ' . $matches[2] . '=' . $paramValue;
609
  break;
610
  }
611
  }
@@ -749,7 +749,7 @@ class wfActivityReportView extends wfView {
749
  public function displayIP($binaryIP) {
750
  $readableIP = wfUtils::inet_ntop($binaryIP);
751
  $country = wfUtils::countryCode2Name(wfUtils::IP2Country($readableIP));
752
- return "{$readableIP} (" . ($country ? $country : 'Unknown') . ")";
753
  }
754
  }
755
- }
504
  $success = true;
505
  if (is_string($email_addresses)) { $email_addresses = explode(',', $email_addresses); }
506
  foreach ($email_addresses as $email) {
507
+ $uniqueContent = str_replace('<!-- ##UNSUBSCRIBE## -->', sprintf(/* translators: URL to the WordPress admin panel. */ __('No longer an administrator for this site? <a href="%s" target="_blank">Click here</a> to stop receiving security alerts.', 'wordfence'), wfUtils::getSiteBaseURL() . '?_wfsf=removeAlertEmail&jwt=' . wfUtils::generateJWT(array('email' => $email))), $content);
508
+ if (!wp_mail($email, sprintf(/* translators: 1. Site URL. 2. Localized date. */ __('Wordfence activity for %1$s on %2$s', 'wordfence'), date_i18n(get_option('date_format')), $shortSiteURL), $uniqueContent, 'Content-Type: text/html')) {
509
  $success = false;
510
  }
511
  }
581
  }
582
 
583
  if (isset($actionData['failedRules']) && $actionData['failedRules'] == 'blocked') {
584
+ $row->longDescription = __("Blocked because the IP is blocklisted", 'wordfence');
585
  }
586
  else {
587
+ $row->longDescription = sprintf(__("Blocked for %s", 'wordfence'), $row->actionDescription);
588
  }
589
 
590
  $paramKey = base64_decode($actionData['paramKey']);
596
  if (preg_match('/([a-z0-9_]+\.[a-z0-9_]+)(?:\[(.+?)\](.*))?/i', $paramKey, $matches)) {
597
  switch ($matches[1]) {
598
  case 'request.queryString':
599
+ $row->longDescription = sprintf(__('Blocked for %1$s in query string: %2$s = %3$s', 'wordfence'), $row->actionDescription, $matches[2], $paramValue);
600
  break;
601
  case 'request.body':
602
+ $row->longDescription = sprintf(__('Blocked for %1$s in POST body: %2$s = %3$s', 'wordfence'), $row->actionDescription, $matches[2], $paramValue);
603
  break;
604
  case 'request.cookie':
605
+ $row->longDescription = sprintf(__('Blocked for %1$s in cookie: %2$s = %3$s', 'wordfence'), $row->actionDescription, $matches[2], $paramValue);
606
  break;
607
  case 'request.fileNames':
608
+ $row->longDescription = sprintf(__('Blocked for %1$s in file: %2$s = %3$s', 'wordfence'), $row->actionDescription, $matches[2], $paramValue);
609
  break;
610
  }
611
  }
749
  public function displayIP($binaryIP) {
750
  $readableIP = wfUtils::inet_ntop($binaryIP);
751
  $country = wfUtils::countryCode2Name(wfUtils::IP2Country($readableIP));
752
+ return "{$readableIP} (" . ($country ? $country : __('Unknown', 'wordfence')) . ")";
753
  }
754
  }
755
+ }
lib/wfAdminNoticeQueue.php CHANGED
@@ -76,9 +76,11 @@ class wfAdminNoticeQueue {
76
  }
77
 
78
  $notices = self::_notices();
 
79
  foreach ($notices as $nid => $n) {
80
  if ($id == $nid) { //ID match
81
  unset($notices[$nid]);
 
82
  break;
83
  }
84
  else if ($id !== false) {
@@ -89,14 +91,17 @@ class wfAdminNoticeQueue {
89
  if ($users !== false) {
90
  if (isset($n['users']) && wfUtils::sets_equal($users, $n['users'])) {
91
  unset($notices[$nid]);
 
92
  }
93
  }
94
  else {
95
  unset($notices[$nid]);
 
96
  }
97
  }
98
  }
99
- self::_setNotices($notices);
 
100
  }
101
 
102
  public static function hasNotice($category = false, $users = false) {
@@ -172,6 +177,6 @@ class wfAdminNotice {
172
  $severityClass = 'notice-warning';
173
  }
174
 
175
- echo '<div class="wf-admin-notice notice ' . $severityClass . '" data-notice-id="' . esc_attr($this->_id) . '"><p>' . $this->_messageHTML . '</p><p>' . sprintf(__('<a class="wf-btn wf-btn-default wf-btn-sm wf-dismiss-link" href="#" onclick="wordfenceExt.dismissAdminNotice(\'%s\'); return false;">Dismiss</a>', 'wordfence'), esc_attr($this->_id)) . '</p></div>';
176
  }
177
  }
76
  }
77
 
78
  $notices = self::_notices();
79
+ $found = false;
80
  foreach ($notices as $nid => $n) {
81
  if ($id == $nid) { //ID match
82
  unset($notices[$nid]);
83
+ $found=true;
84
  break;
85
  }
86
  else if ($id !== false) {
91
  if ($users !== false) {
92
  if (isset($n['users']) && wfUtils::sets_equal($users, $n['users'])) {
93
  unset($notices[$nid]);
94
+ $found=true;
95
  }
96
  }
97
  else {
98
  unset($notices[$nid]);
99
+ $found=true;
100
  }
101
  }
102
  }
103
+ if($found)
104
+ self::_setNotices($notices);
105
  }
106
 
107
  public static function hasNotice($category = false, $users = false) {
177
  $severityClass = 'notice-warning';
178
  }
179
 
180
+ echo '<div class="wf-admin-notice notice ' . $severityClass . '" data-notice-id="' . esc_attr($this->_id) . '"><p>' . $this->_messageHTML . '</p><p><a class="wf-btn wf-btn-default wf-btn-sm wf-dismiss-link" href="#" onclick="wordfenceExt.dismissAdminNotice(\'' . esc_attr($this->_id) . '\'); return false;">' . esc_html__('Dismiss', 'wordfence') . '</a></p></div>';
181
  }
182
  }
lib/wfAlerts.php CHANGED
@@ -26,12 +26,12 @@ class wfBlockAlert extends wfBaseAlert {
26
 
27
  public function send() {
28
  if (wfConfig::get('alertOn_block')) {
29
- $message = sprintf(__('Wordfence has blocked IP address %s.', 'wordfence'), $this->IP) . "\n";
30
- $message .= sprintf(__('The reason is: "%s".', 'wordfence'), $this->reason);
31
  if ($this->secsToGo > 0) {
32
- $message .= "\n" . sprintf(__('The duration of the block is %s.', 'wordfence'), wfUtils::makeDuration($this->secsToGo, true));
33
  }
34
- wordfence::alert(sprintf(__('Blocking IP %s', 'wordfence'), $this->IP), $message, $this->IP);
35
  }
36
  }
37
 
@@ -50,7 +50,7 @@ class wfAutoUpdatedAlert extends wfBaseAlert {
50
 
51
  public function send() {
52
  if (wfConfig::get('alertOn_update') == '1' && $this->version) {
53
- wordfence::alert(sprintf(__("Wordfence Upgraded to version %s", 'wordfence'), $this->version), sprintf(__("Your Wordfence installation has been upgraded to version %s", 'wordfence'), $this->version), false);
54
  }
55
  }
56
 
@@ -72,7 +72,7 @@ class wfWafDeactivatedAlert extends wfBaseAlert {
72
 
73
  public function send() {
74
  if (wfConfig::get('alertOn_wafDeactivated')) {
75
- wordfence::alert(__('Wordfence WAF Deactivated', 'wordfence'), sprintf(__('A user with username "%s" deactivated the Wordfence Web Application Firewall on your WordPress site.', 'wordfence'), $this->username), $this->IP);
76
  }
77
  }
78
 
@@ -93,7 +93,7 @@ class wfWordfenceDeactivatedAlert extends wfBaseAlert {
93
 
94
  public function send() {
95
  if (wfConfig::get('alertOn_wordfenceDeactivated')) {
96
- wordfence::alert(__("Wordfence Deactivated", 'wordfence'), sprintf(__("A user with username \"%s\" deactivated Wordfence on your WordPress site.", 'wordfence'), $this->username), $this->IP);
97
  }
98
  }
99
 
@@ -115,7 +115,7 @@ class wfLostPasswdFormAlert extends wfBaseAlert {
115
 
116
  public function send() {
117
  if (wfConfig::get('alertOn_lostPasswdForm')) {
118
- wordfence::alert(__("Password recovery attempted", 'wordfence'), sprintf(__("Someone tried to recover the password for user with email address: %s", 'wordfence'), wp_kses($this->user->user_email, array())), $this->IP);
119
  }
120
  }
121
 
@@ -137,9 +137,11 @@ class wfLoginLockoutAlert extends wfBaseAlert {
137
 
138
  public function send() {
139
  if (wfConfig::get('alertOn_loginLockout')) {
140
- $message = sprintf(__('A user with IP addr %s has been locked out from signing in or using the password recovery form for the following reason: %s.', 'wordfence'), $this->IP, $this->reason);
 
 
141
  if (wfBlock::lockoutDuration() > 0) {
142
- $message .= "\n" . sprintf(__('The duration of the lockout is %s.', 'wordfence'), wfUtils::makeDuration(wfBlock::lockoutDuration(), true));
143
  }
144
  wordfence::alert(__('User locked out from signing in', 'wordfence'), $message, $this->IP);
145
  }
@@ -174,7 +176,7 @@ class wfAdminLoginAlert extends wfBaseAlert {
174
  }
175
 
176
  if ($shouldAlert) {
177
- wordfence::alert(__("Admin Login", 'wordfence'), sprintf(__("A user with username \"%s\" who has administrator access signed in to your WordPress site.", 'wordfence'), $this->username), $this->IP);
178
  }
179
  }
180
  }
@@ -208,7 +210,7 @@ class wfNonAdminLoginAlert extends wfBaseAlert {
208
  }
209
 
210
  if ($shouldAlert) {
211
- wordfence::alert(__("User login", 'wordfence'), sprintf(__("A non-admin user with username \"%s\" signed in to your WordPress site.", 'wordfence'), $this->username), $this->IP);
212
  }
213
  }
214
  }
@@ -236,7 +238,9 @@ class wfBreachLoginAlert extends wfBaseAlert {
236
 
237
  public function send() {
238
  if (wfConfig::get('alertOn_breachLogin')) {
239
- wordfence::alert(__('User login blocked for insecure password', 'wordfence'), sprintf(__('A user with username "%s" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%s) to reactivate this account. Learn More: %s', 'wordfence'), $this->username, $this->lostPasswordUrl, $this->supportUrl), $this->IP);
 
 
240
  }
241
  }
242
  }
26
 
27
  public function send() {
28
  if (wfConfig::get('alertOn_block')) {
29
+ $message = sprintf(/* translators: IP address. */ __('Wordfence has blocked IP address %s.', 'wordfence'), $this->IP) . "\n";
30
+ $message .= sprintf(/* translators: Description of firewall action. */ __('The reason is: "%s".', 'wordfence'), $this->reason);
31
  if ($this->secsToGo > 0) {
32
+ $message .= "\n" . sprintf(/* translators: Time until. */ __('The duration of the block is %s.', 'wordfence'), wfUtils::makeDuration($this->secsToGo, true));
33
  }
34
+ wordfence::alert(sprintf(/* translators: IP address. */__('Blocking IP %s', 'wordfence'), $this->IP), $message, $this->IP);
35
  }
36
  }
37
 
50
 
51
  public function send() {
52
  if (wfConfig::get('alertOn_update') == '1' && $this->version) {
53
+ wordfence::alert(sprintf(/* translators: Software version. */ __("Wordfence Upgraded to version %s", 'wordfence'), $this->version), sprintf(/* translators: Software version. */ __("Your Wordfence installation has been upgraded to version %s", 'wordfence'), $this->version), false);
54
  }
55
  }
56
 
72
 
73
  public function send() {
74
  if (wfConfig::get('alertOn_wafDeactivated')) {
75
+ wordfence::alert(__('Wordfence WAF Deactivated', 'wordfence'), sprintf(/* translators: WP username. */__('A user with username "%s" deactivated the Wordfence Web Application Firewall on your WordPress site.', 'wordfence'), $this->username), $this->IP);
76
  }
77
  }
78
 
93
 
94
  public function send() {
95
  if (wfConfig::get('alertOn_wordfenceDeactivated')) {
96
+ wordfence::alert(__("Wordfence Deactivated", 'wordfence'), sprintf(/* translators: WP username. */ __("A user with username \"%s\" deactivated Wordfence on your WordPress site.", 'wordfence'), $this->username), $this->IP);
97
  }
98
  }
99
 
115
 
116
  public function send() {
117
  if (wfConfig::get('alertOn_lostPasswdForm')) {
118
+ wordfence::alert(__("Password recovery attempted", 'wordfence'), sprintf(/* translators: Email address. */__("Someone tried to recover the password for user with email address: %s", 'wordfence'), wp_kses($this->user->user_email, array())), $this->IP);
119
  }
120
  }
121
 
137
 
138
  public function send() {
139
  if (wfConfig::get('alertOn_loginLockout')) {
140
+ $message = sprintf(
141
+ /* translators: 1. IP address. 2. Description of firewall action. */
142
+ __('A user with IP address %1$s has been locked out from signing in or using the password recovery form for the following reason: %2$s.', 'wordfence'), $this->IP, $this->reason);
143
  if (wfBlock::lockoutDuration() > 0) {
144
+ $message .= "\n" . sprintf(/* translators: Time until. */ __('The duration of the lockout is %s.', 'wordfence'), wfUtils::makeDuration(wfBlock::lockoutDuration(), true));
145
  }
146
  wordfence::alert(__('User locked out from signing in', 'wordfence'), $message, $this->IP);
147
  }
176
  }
177
 
178
  if ($shouldAlert) {
179
+ wordfence::alert(__("Admin Login", 'wordfence'), sprintf(/* translators: WP username. */ __("A user with username \"%s\" who has administrator access signed in to your WordPress site.", 'wordfence'), $this->username), $this->IP);
180
  }
181
  }
182
  }
210
  }
211
 
212
  if ($shouldAlert) {
213
+ wordfence::alert(__("User login", 'wordfence'), sprintf(/* translators: WP username. */ __("A non-admin user with username \"%s\" signed in to your WordPress site.", 'wordfence'), $this->username), $this->IP);
214
  }
215
  }
216
  }
238
 
239
  public function send() {
240
  if (wfConfig::get('alertOn_breachLogin')) {
241
+ wordfence::alert(__('User login blocked for insecure password', 'wordfence'), sprintf(
242
+ /* translators: 1. WP username. 2. Reset password URL. 3. Support URL. */
243
+ __('A user with username "%1$s" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%2$s) to reactivate this account. Learn More: %3$s', 'wordfence'), $this->username, $this->lostPasswordUrl, $this->supportUrl), $this->IP);
244
  }
245
  }
246
  }
lib/wfCentralAPI.php CHANGED
@@ -196,7 +196,9 @@ class wfCentralAPIResponse {
196
  public function returnErrorArray() {
197
  return array(
198
  'err' => 1,
199
- 'errorMsg' => sprintf(__('HTTP %d received from Wordfence Central: %s', 'wordfence'),
 
 
200
  $this->getStatusCode(), $this->parseErrorJSON($this->getBody())),
201
  );
202
  }
196
  public function returnErrorArray() {
197
  return array(
198
  'err' => 1,
199
+ 'errorMsg' => sprintf(
200
+ /* translators: 1. HTTP status code. 2. Error message. */
201
+ __('HTTP %1$d received from Wordfence Central: %2$s', 'wordfence'),
202
  $this->getStatusCode(), $this->parseErrorJSON($this->getBody())),
203
  );
204
  }
lib/wfConfig.php CHANGED
@@ -125,6 +125,7 @@ class wfConfig {
125
  'displayTopLevelLiveTraffic' => array('value' => false, 'autoload' => self::AUTOLOAD),
126
  'displayAutomaticBlocks' => array('value' => true, 'autoload' => self::AUTOLOAD),
127
  'allowLegacy2FA' => array('value' => false, 'autoload' => self::AUTOLOAD),
 
128
  ),
129
  //All exportable variable type options
130
  "otherParams" => array(
@@ -476,7 +477,9 @@ class wfConfig {
476
  global $wpdb;
477
 
478
  if (is_array($val)) {
479
- $msg = "wfConfig::set() got an array as second param with key: $key and value: " . var_export($val, true);
 
 
480
  wordfence::status(1, 'error', $msg);
481
  return;
482
  }
@@ -621,7 +624,7 @@ class wfConfig {
621
  $chunk = self::getDB()->querySingle("select val from " . self::table() . " where name=%s", $chunkedValueKey . $i);
622
  self::getDB()->flush(); //clear cache
623
  if (!$chunk) {
624
- wordfence::status(2, 'error', "Error reassembling value for {$key}");
625
  return $default;
626
  }
627
  fwrite($fh, $chunk);
@@ -713,19 +716,25 @@ class wfConfig {
713
  $chunkKey = $chunkedValueKey . $chunks;
714
  $stmt = $dbh->prepare("INSERT IGNORE INTO " . self::table() . " (name, val, autoload) VALUES (?, ?, 'no')");
715
  if ($stmt === false) {
716
- wordfence::status(2, 'error', "Error writing value chunk for {$key} (MySQLi error: [{$dbh->errno}] {$dbh->error})");
 
 
717
  return false;
718
  }
719
  $null = NULL;
720
  $stmt->bind_param("sb", $chunkKey, $null);
721
 
722
  if (!$stmt->send_long_data(1, $dataChunk)) {
723
- wordfence::status(2, 'error', "Error writing value chunk for {$key} (MySQLi error: [{$dbh->errno}] {$dbh->error})");
 
 
724
  return false;
725
  }
726
 
727
  if (!$stmt->execute()) {
728
- wordfence::status(2, 'error', "Error finishing writing value for {$key} (MySQLi error: [{$dbh->errno}] {$dbh->error})");
 
 
729
  return false;
730
  }
731
  }
@@ -733,12 +742,16 @@ class wfConfig {
733
  if (!self::getDB()->queryWrite(sprintf("insert ignore into " . self::table() . " (name, val, autoload) values (%%s, X'%s', 'no')", $dataChunk), $chunkedValueKey . $chunks)) {
734
  if ($useMySQLi) {
735
  $errno = mysqli_errno($wpdb->dbh);
736
- wordfence::status(2, 'error', "Error writing value chunk for {$key} (MySQL error: [$errno] {$wpdb->last_error})");
 
 
737
  }
738
  else if (function_exists('mysql_errno')) {
739
  // phpcs:ignore PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
740
  $errno = mysql_errno($wpdb->dbh);
741
- wordfence::status(2, 'error', "Error writing value chunk for {$key} (MySQL error: [$errno] {$wpdb->last_error})");
 
 
742
  }
743
 
744
  return false;
@@ -748,7 +761,9 @@ class wfConfig {
748
  }
749
 
750
  if (!self::getDB()->queryWrite(sprintf("insert ignore into " . self::table() . " (name, val, autoload) values (%%s, X'%s', 'no')", bin2hex(serialize(array('count' => $chunks)))), $chunkedValueKey . 'header')) {
751
- wordfence::status(2, 'error', "Error writing value header for {$key}");
 
 
752
  return false;
753
  }
754
  }
@@ -759,7 +774,9 @@ class wfConfig {
759
  if ($exists) {
760
  $stmt = $dbh->prepare("UPDATE " . self::table() . " SET val=? WHERE name=?");
761
  if ($stmt === false) {
762
- wordfence::status(2, 'error', "Error writing value for {$key} (MySQLi error: [{$dbh->errno}] {$dbh->error})");
 
 
763
  return false;
764
  }
765
  $null = NULL;
@@ -768,7 +785,9 @@ class wfConfig {
768
  else {
769
  $stmt = $dbh->prepare("INSERT IGNORE INTO " . self::table() . " (val, name, autoload) VALUES (?, ?, ?)");
770
  if ($stmt === false) {
771
- wordfence::status(2, 'error', "Error writing value for {$key} (MySQLi error: [{$dbh->errno}] {$dbh->error})");
 
 
772
  return false;
773
  }
774
  $null = NULL;
@@ -776,12 +795,16 @@ class wfConfig {
776
  }
777
 
778
  if (!$stmt->send_long_data(0, $data)) {
779
- wordfence::status(2, 'error', "Error writing value for {$key} (MySQLi error: [{$dbh->errno}] {$dbh->error})");
 
 
780
  return false;
781
  }
782
 
783
  if (!$stmt->execute()) {
784
- wordfence::status(2, 'error', "Error finishing writing value for {$key} (MySQLi error: [{$dbh->errno}] {$dbh->error})");
 
 
785
  return false;
786
  }
787
  }
@@ -949,7 +972,9 @@ class wfConfig {
949
  $lastEmail = self::get('lastLiteSpdEmail', false);
950
  if( (! $lastEmail) || (time() - (int)$lastEmail > (86400 * 30))){
951
  self::set('lastLiteSpdEmail', time());
952
- wordfence::alert(__("Wordfence Upgrade not run. Please modify your .htaccess", 'wordfence'), sprintf(__("To preserve the integrity of your website we are not running Wordfence auto-update.\n" .
 
 
953
  "You are running the LiteSpeed web server which has been known to cause a problem with Wordfence auto-update.\n" .
954
  "Please go to your website now and make a minor change to your .htaccess to fix this.\n" .
955
  "You can find out how to make this change at:\n" .
@@ -1072,7 +1097,7 @@ Options -ExecCGI
1072
  $uploads_htaccess_has_content = strlen(trim($htaccess_contents)) > 0;
1073
  }
1074
  if (@file_put_contents($uploads_htaccess_file_path, ($uploads_htaccess_has_content ? "\n\n" : "") . self::$_disable_scripts_htaccess, FILE_APPEND | LOCK_EX) === false) {
1075
- throw new wfConfigException("Unable to save the .htaccess file needed to disable script execution in the uploads directory. Please check your permissions on that directory.");
1076
  }
1077
  self::set('disableCodeExecutionUploadsPHP7Migrated', true);
1078
  return true;
@@ -1109,7 +1134,7 @@ Options -ExecCGI
1109
  if (preg_match(self::$_disable_scripts_regex, $htaccess_contents)) {
1110
  $htaccess_contents = preg_replace(self::$_disable_scripts_regex, '', $htaccess_contents);
1111
 
1112
- $error_message = "Unable to remove code execution protections applied to the .htaccess file in the uploads directory. Please check your permissions on that file.";
1113
  if (strlen(trim($htaccess_contents)) === 0) {
1114
  // empty file, remove it
1115
  if (!@unlink($uploads_htaccess_file_path)) {
@@ -1185,7 +1210,9 @@ Options -ExecCGI
1185
  $dirtyRegexes = explode("\n", $value);
1186
  foreach ($dirtyRegexes as $regex) {
1187
  if (@preg_match("/$regex/", "") === false) {
1188
- $errors[] = array('option' => $key, 'error' => sprintf(__('"%s" is not a valid regular expression.', 'wordfence'), esc_html($regex)));
 
 
1189
  }
1190
  }
1191
  $checked = true;
@@ -1749,7 +1776,7 @@ Options -ExecCGI
1749
  wfConfig::set('touppPromptNeeded', true);
1750
  }
1751
  else {
1752
- throw new Exception("The Wordfence server's response did not contain the expected elements.");
1753
  }
1754
  }
1755
  catch (Exception $e) {
@@ -1771,7 +1798,7 @@ Options -ExecCGI
1771
  $ping = true;
1772
  }
1773
  else {
1774
- throw new Exception("The Wordfence server's response did not contain the expected elements.");
1775
  }
1776
  }
1777
  catch (Exception $e) {
@@ -1993,6 +2020,7 @@ Options -ExecCGI
1993
  'startScansRemotely',
1994
  'ssl_verify',
1995
  'betaThreatDefenseFeed',
 
1996
  );
1997
  break;
1998
  case self::OPTIONS_TYPE_ALL:
125
  'displayTopLevelLiveTraffic' => array('value' => false, 'autoload' => self::AUTOLOAD),
126
  'displayAutomaticBlocks' => array('value' => true, 'autoload' => self::AUTOLOAD),
127
  'allowLegacy2FA' => array('value' => false, 'autoload' => self::AUTOLOAD),
128
+ 'wordfenceI18n' => array('value' => true, 'autoload' => self::AUTOLOAD),
129
  ),
130
  //All exportable variable type options
131
  "otherParams" => array(
477
  global $wpdb;
478
 
479
  if (is_array($val)) {
480
+ $msg = sprintf(
481
+ /* translators: 1. Key in key-value store. 2. Value in key-value store. */
482
+ __('wfConfig::set() got an array as second param with key: %1$s and value: %2$s', 'wordfence'), $key, var_export($val, true));
483
  wordfence::status(1, 'error', $msg);
484
  return;
485
  }
624
  $chunk = self::getDB()->querySingle("select val from " . self::table() . " where name=%s", $chunkedValueKey . $i);
625
  self::getDB()->flush(); //clear cache
626
  if (!$chunk) {
627
+ wordfence::status(2, 'error', sprintf(/* translators: Key in key-value store. */ __("Error reassembling value for %s", 'wordfence'), $key));
628
  return $default;
629
  }
630
  fwrite($fh, $chunk);
716
  $chunkKey = $chunkedValueKey . $chunks;
717
  $stmt = $dbh->prepare("INSERT IGNORE INTO " . self::table() . " (name, val, autoload) VALUES (?, ?, 'no')");
718
  if ($stmt === false) {
719
+ wordfence::status(2, 'error', sprintf(
720
+ /* translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message. */
721
+ __('Error writing value chunk for %1$s (MySQLi error: [%2$s] %3$s)', 'wordfence'), $key, $dbh->errno, $dbh->error));
722
  return false;
723
  }
724
  $null = NULL;
725
  $stmt->bind_param("sb", $chunkKey, $null);
726
 
727
  if (!$stmt->send_long_data(1, $dataChunk)) {
728
+ wordfence::status(2, 'error', sprintf(
729
+ /* translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message. */
730
+ __('Error writing value chunk for %1$s (MySQLi error: [%2$s] %3$s)', 'wordfence'), $key, $dbh->errno, $dbh->error));
731
  return false;
732
  }
733
 
734
  if (!$stmt->execute()) {
735
+ wordfence::status(2, 'error', sprintf(
736
+ /* translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message. */
737
+ __('Error writing value chunk for %1$s (MySQLi error: [%2$s] %3$s)', 'wordfence'), $key, $dbh->errno, $dbh->error));
738
  return false;
739
  }
740
  }
742
  if (!self::getDB()->queryWrite(sprintf("insert ignore into " . self::table() . " (name, val, autoload) values (%%s, X'%s', 'no')", $dataChunk), $chunkedValueKey . $chunks)) {
743
  if ($useMySQLi) {
744
  $errno = mysqli_errno($wpdb->dbh);
745
+ wordfence::status(2, 'error', sprintf(
746
+ /* translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message. */
747
+ __('Error writing value chunk for %1$s (MySQLi error: [%2$s] %3$s)', 'wordfence'), $key, $errno, $wpdb->last_error));
748
  }
749
  else if (function_exists('mysql_errno')) {
750
  // phpcs:ignore PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
751
  $errno = mysql_errno($wpdb->dbh);
752
+ wordfence::status(2, 'error', sprintf(
753
+ /* translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message. */
754
+ __('Error writing value chunk for %1$s (MySQLi error: [%2$s] %3$s)', 'wordfence'), $key, $errno, $wpdb->last_error));
755
  }
756
 
757
  return false;
761
  }
762
 
763
  if (!self::getDB()->queryWrite(sprintf("insert ignore into " . self::table() . " (name, val, autoload) values (%%s, X'%s', 'no')", bin2hex(serialize(array('count' => $chunks)))), $chunkedValueKey . 'header')) {
764
+ wordfence::status(2, 'error', sprintf(
765
+ /* translators: Key in key-value store. */
766
+ __("Error writing value header for %s", 'wordfence'), $key));
767
  return false;
768
  }
769
  }
774
  if ($exists) {
775
  $stmt = $dbh->prepare("UPDATE " . self::table() . " SET val=? WHERE name=?");
776
  if ($stmt === false) {
777
+ wordfence::status(2, 'error', sprintf(
778
+ /* translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message. */
779
+ __('Error writing value for %1$s (MySQLi error: [%2$s] %3$s)', 'wordfence'), $key, $dbh->errno, $dbh->error));
780
  return false;
781
  }
782
  $null = NULL;
785
  else {
786
  $stmt = $dbh->prepare("INSERT IGNORE INTO " . self::table() . " (val, name, autoload) VALUES (?, ?, ?)");
787
  if ($stmt === false) {
788
+ wordfence::status(2, 'error', sprintf(
789
+ /* translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message. */
790
+ __('Error writing value for %1$s (MySQLi error: [%2$s] %3$s)', 'wordfence'), $key, $dbh->errno, $dbh->error));
791
  return false;
792
  }
793
  $null = NULL;
795
  }
796
 
797
  if (!$stmt->send_long_data(0, $data)) {
798
+ wordfence::status(2, 'error', sprintf(
799
+ /* translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message. */
800
+ __('Error writing value for %1$s (MySQLi error: [%2$s] %3$s)', 'wordfence'), $key, $dbh->errno, $dbh->error));
801
  return false;
802
  }
803
 
804
  if (!$stmt->execute()) {
805
+ wordfence::status(2, 'error', sprintf(
806
+ /* translators: 1. Key in key-value store. 2. MySQL error number. 3. MySQL error message. */
807
+ __('Error finishing writing value for %1$s (MySQLi error: [%2$s] %3$s)', 'wordfence'), $key, $dbh->errno, $dbh->error));
808
  return false;
809
  }
810
  }
972
  $lastEmail = self::get('lastLiteSpdEmail', false);
973
  if( (! $lastEmail) || (time() - (int)$lastEmail > (86400 * 30))){
974
  self::set('lastLiteSpdEmail', time());
975
+ wordfence::alert(
976
+ /* translators: Support URL. */
977
+ __("Wordfence Upgrade not run. Please modify your .htaccess", 'wordfence'), sprintf(__("To preserve the integrity of your website we are not running Wordfence auto-update.\n" .
978
  "You are running the LiteSpeed web server which has been known to cause a problem with Wordfence auto-update.\n" .
979
  "Please go to your website now and make a minor change to your .htaccess to fix this.\n" .
980
  "You can find out how to make this change at:\n" .
1097
  $uploads_htaccess_has_content = strlen(trim($htaccess_contents)) > 0;
1098
  }
1099
  if (@file_put_contents($uploads_htaccess_file_path, ($uploads_htaccess_has_content ? "\n\n" : "") . self::$_disable_scripts_htaccess, FILE_APPEND | LOCK_EX) === false) {
1100
+ throw new wfConfigException(__("Unable to save the .htaccess file needed to disable script execution in the uploads directory. Please check your permissions on that directory.", 'wordfence'));
1101
  }
1102
  self::set('disableCodeExecutionUploadsPHP7Migrated', true);
1103
  return true;
1134
  if (preg_match(self::$_disable_scripts_regex, $htaccess_contents)) {
1135
  $htaccess_contents = preg_replace(self::$_disable_scripts_regex, '', $htaccess_contents);
1136
 
1137
+ $error_message = __("Unable to remove code execution protections applied to the .htaccess file in the uploads directory. Please check your permissions on that file.", 'wordfence');
1138
  if (strlen(trim($htaccess_contents)) === 0) {
1139
  // empty file, remove it
1140
  if (!@unlink($uploads_htaccess_file_path)) {
1210
  $dirtyRegexes = explode("\n", $value);
1211
  foreach ($dirtyRegexes as $regex) {
1212
  if (@preg_match("/$regex/", "") === false) {
1213
+ $errors[] = array('option' => $key, 'error' => sprintf(
1214
+ /* translators: Regular expression. */
1215
+ __('"%s" is not a valid regular expression.', 'wordfence'), esc_html($regex)));
1216
  }
1217
  }
1218
  $checked = true;
1776
  wfConfig::set('touppPromptNeeded', true);
1777
  }
1778
  else {
1779
+ throw new Exception(__("The Wordfence server's response did not contain the expected elements.", 'wordfence'));
1780
  }
1781
  }
1782
  catch (Exception $e) {
1798
  $ping = true;
1799
  }
1800
  else {
1801
+ throw new Exception(__("The Wordfence server's response did not contain the expected elements.", 'wordfence'));
1802
  }
1803
  }
1804
  catch (Exception $e) {
2020
  'startScansRemotely',
2021
  'ssl_verify',
2022
  'betaThreatDefenseFeed',
2023
+ 'wordfenceI18n',
2024
  );
2025
  break;
2026
  case self::OPTIONS_TYPE_ALL:
lib/wfDiagnostic.php CHANGED
@@ -107,7 +107,7 @@ class wfDiagnostic
107
  'PHP Environment' => array(
108
  'description' => __('PHP version, important PHP extensions.', 'wordfence'),
109
  'tests' => array(
110
- 'phpVersion' => array('raw' => true, 'value' => sprintf(__('PHP version >= PHP 5.6.20<br><em> (<a href="https://wordpress.org/about/requirements/" target="_blank" rel="noopener noreferrer">Minimum version required by WordPress</a>)</em> <a href="%s" target="_blank" rel="noopener noreferrer" class="wfhelp"></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))),
111
  'processOwner' => __('Process Owner', 'wordfence'),
112
  'hasOpenSSL' => __('Checking for OpenSSL support', 'wordfence'),
113
  'openSSLVersion' => __('Checking OpenSSL version', 'wordfence'),
@@ -194,7 +194,7 @@ class wfDiagnostic
194
  }
195
  }
196
 
197
- return array('test' => true, 'infoOnly' => true, 'message' => $overdue ? ($overdue == 1 ? __('1 Job Overdue', 'wordfence') : sprintf(__('%d Jobs Overdue', 'wordfence'), $overdue)) : __('Normal', 'wordfence'));
198
  }
199
 
200
  public function geoIPError() {
@@ -231,7 +231,7 @@ class wfDiagnostic
231
  $unreadable[] = sprintf(__('File "%s" does not exist', 'wordfence'), basename($f));
232
  }
233
  else if (!is_readable($f)) {
234
- $unreadable[] = sprintf(__('File "%s" is unreadable', 'wordfence'), basename($f));
235
  }
236
  }
237
 
@@ -264,10 +264,10 @@ class wfDiagnostic
264
  $unwritable = array();
265
  foreach ($files as $f) {
266
  if (!file_exists($f)) {
267
- $unwritable[] = sprintf(__('File "%s" does not exist', 'wordfence'), basename($f));
268
  }
269
  else if (!is_writable($f)) {
270
- $unwritable[] = sprintf(__('File "%s" is unwritable', 'wordfence'), basename($f));
271
  }
272
  }
273
 
@@ -385,7 +385,7 @@ class wfDiagnostic
385
 
386
  public function wafFilePermissions() {
387
  if (defined('WFWAF_LOG_FILE_MODE')) {
388
- return array('test' => true, 'infoOnly' => true, 'message' => sprintf(__('%s - using constant', 'wordfence'), str_pad(decoct(WFWAF_LOG_FILE_MODE), 4, '0', STR_PAD_LEFT)));
389
  }
390
 
391
  if (defined('WFWAF_LOG_PATH')) {
@@ -398,7 +398,7 @@ class wfDiagnostic
398
  if (($mode & 0020) == 0020) {
399
  $updatedMode = $updatedMode | 0060;
400
  }
401
- return array('test' => true, 'infoOnly' => true, 'message' => sprintf(__('%s - using template', 'wordfence'), str_pad(decoct($updatedMode), 4, '0', STR_PAD_LEFT)));
402
  }
403
  }
404
  }
@@ -634,7 +634,7 @@ class wfDiagnostic
634
  if ($host !== null) {
635
  $ips = wfUtils::resolveDomainName($host);
636
  $ips = implode(', ', $ips);
637
- return array('test' => true, 'message' => sprintf(__('OK - %s', 'wordfence'), $ips));
638
  }
639
  return true;
640
  }
@@ -674,7 +674,7 @@ class wfDiagnostic
674
  if (empty($_SERVER[$howGet])) {
675
  return array(
676
  'test' => false,
677
- 'message' => sprintf(__('We cannot read $_SERVER[%s]', 'wordfence'), $howGet),
678
  );
679
  }
680
  return array(
107
  'PHP Environment' => array(
108
  'description' => __('PHP version, important PHP extensions.', 'wordfence'),
109
  'tests' => array(
110
+ 'phpVersion' => array('raw' => true, 'value' => sprintf(/* translators: Support URL. */ __('PHP version >= PHP 5.6.20<br><em> (<a href="https://wordpress.org/about/requirements/" target="_blank" rel="noopener noreferrer">Minimum version required by WordPress</a>)</em> <a href="%s" target="_blank" rel="noopener noreferrer" class="wfhelp"></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))),
111
  'processOwner' => __('Process Owner', 'wordfence'),
112
  'hasOpenSSL' => __('Checking for OpenSSL support', 'wordfence'),
113
  'openSSLVersion' => __('Checking OpenSSL version', 'wordfence'),
194
  }
195
  }
196
 
197
+ return array('test' => true, 'infoOnly' => true, 'message' => $overdue ? sprintf(/* translators: Number of jobs. */ _n('%d Job Overdue', '%d Jobs Overdue', $overdue, 'wordfence'), $overdue) : __('Normal', 'wordfence'));
198
  }
199
 
200
  public function geoIPError() {
231
  $unreadable[] = sprintf(__('File "%s" does not exist', 'wordfence'), basename($f));
232
  }
233
  else if (!is_readable($f)) {
234
+ $unreadable[] = sprintf(/* translators: File path. */ __('File "%s" is unreadable', 'wordfence'), basename($f));
235
  }
236
  }
237
 
264
  $unwritable = array();
265
  foreach ($files as $f) {
266
  if (!file_exists($f)) {
267
+ $unwritable[] = sprintf(/* translators: File name. */__('File "%s" does not exist', 'wordfence'), basename($f));
268
  }
269
  else if (!is_writable($f)) {
270
+ $unwritable[] = sprintf(/* translators: File name. */__('File "%s" is unwritable', 'wordfence'), basename($f));
271
  }
272
  }
273
 
385
 
386
  public function wafFilePermissions() {
387
  if (defined('WFWAF_LOG_FILE_MODE')) {
388
+ return array('test' => true, 'infoOnly' => true, 'message' => sprintf(/* translators: Unix file permissions in octal (example 0777). */ __('%s - using constant', 'wordfence'), str_pad(decoct(WFWAF_LOG_FILE_MODE), 4, '0', STR_PAD_LEFT)));
389
  }
390
 
391
  if (defined('WFWAF_LOG_PATH')) {
398
  if (($mode & 0020) == 0020) {
399
  $updatedMode = $updatedMode | 0060;
400
  }
401
+ return array('test' => true, 'infoOnly' => true, 'message' => sprintf(/* translators: Unix file permissions in octal (example 0777). */ __('%s - using template', 'wordfence'), str_pad(decoct($updatedMode), 4, '0', STR_PAD_LEFT)));
402
  }
403
  }
404
  }
634
  if ($host !== null) {
635
  $ips = wfUtils::resolveDomainName($host);
636
  $ips = implode(', ', $ips);
637
+ return array('test' => true, 'message' => sprintf('OK - %s', $ips));
638
  }
639
  return true;
640
  }
674
  if (empty($_SERVER[$howGet])) {
675
  return array(
676
  'test' => false,
677
+ 'message' => sprintf(/* translators: PHP super global key. */ __('We cannot read $_SERVER[%s]', 'wordfence'), $howGet),
678
  );
679
  }
680
  return array(
lib/wfIPWhitelist.php CHANGED
@@ -24,7 +24,7 @@ $wfIPWhitelist = array(
24
  ),
25
  'wordfence' => array(
26
  '54.68.32.247', // Central @ AWS
27
- '69.46.36.0/27',
28
- '2605:2400:0104:0100::/56',
29
  ),
30
  );
24
  ),
25
  'wordfence' => array(
26
  '54.68.32.247', // Central @ AWS
27
+ '44.235.211.232',
28
+ '54.71.203.174'
29
  ),
30
  );
lib/wfImportExportController.php CHANGED
@@ -104,14 +104,14 @@ class wfImportExportController {
104
  );
105
  }
106
  else if ($res['err']) {
107
- return array('err' => "An error occurred: " . $res['err']);
108
  }
109
  else {
110
- throw new Exception("Invalid response: " . var_export($res, true));
111
  }
112
  }
113
  catch (Exception $e) {
114
- return array('err' => "An error occurred: " . $e->getMessage());
115
  }
116
  }
117
  }
104
  );
105
  }
106
  else if ($res['err']) {
107
+ return array('err' => sprintf(/* translators: Error message. */ __("An error occurred: %s", 'wordfence'), $res['err']));
108
  }
109
  else {
110
+ throw new Exception(sprintf(/* translators: Error message. */ __("Invalid response: %s", 'wordfence'), var_export($res, true)));
111
  }
112
  }
113
  catch (Exception $e) {
114
+ return array('err' => sprintf(/* translators: Error message. */ __("An error occurred: %s", 'wordfence'), $e->getMessage()));
115
  }
116
  }
117
  }
lib/wfLockedOut.php CHANGED
@@ -7,7 +7,7 @@ header('Status: 503 Service Temporarily Unavailable');
7
  <!DOCTYPE html>
8
  <html>
9
  <head>
10
- <title><?php _e('You are temporarily locked out', 'wordfence'); ?></title>
11
  <style>
12
  html {
13
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
@@ -323,28 +323,28 @@ header('Status: 503 Service Temporarily Unavailable');
323
  <body>
324
  <div class="top-accent"></div>
325
  <div class="container">
326
- <h1><?php _e('Your access to this site has been temporarily limited by the site owner', 'wordfence'); ?></h1>
327
- <p><?php _e('Your access to this service has been temporarily limited. Please try again in a few minutes. (HTTP response code 503)', 'wordfence'); ?></p>
328
- <p><?php _e('If you think you have been blocked in error, contact the owner of this site for assistance.', 'wordfence'); ?></p>
329
  <?php if (!empty($customText)): ?>
330
  <hr>
331
  <div class="medium"><?php echo $customText; ?></div>
332
  <?php endif; ?>
333
  <hr>
334
  <ul>
335
- <li><a href="<?php echo esc_url(site_url()); ?>"><?php _e('Return to the site home page', 'wordfence'); ?></a></li>
336
- <li><a href="<?php echo esc_url(admin_url()); ?>"><?php _e('Attempt to return to the admin login page (you may still be locked out)', 'wordfence'); ?></a></li>
337
  </ul>
338
  <?php require(dirname(__FILE__) . '/wfUnlockMsg.php'); ?>
339
 
340
- <h2 class="h3"><?php _e('Block Technical Data', 'wordfence'); ?></h2>
341
  <table border="0" cellspacing="0" cellpadding="0" class="block-data">
342
  <tr>
343
- <th class="reason"><?php _e('Block Reason:', 'wordfence'); ?></th>
344
- <td class="reason"><?php _e('You have been temporarily locked out of this system. This means that you will not be able to log in for a while.', 'wordfence'); ?></td>
345
  </tr>
346
  <tr>
347
- <th class="time"><?php _e('Time:', 'wordfence'); ?></th>
348
  <td class="time"><?php echo htmlspecialchars(gmdate('D, j M Y G:i:s T', wfWAFUtils::normalizedTime())); ?></td>
349
  </tr>
350
  </table>
@@ -360,15 +360,15 @@ header('Status: 503 Service Temporarily Unavailable');
360
  ?>
361
  </div>
362
  <div class="about-text">
363
- <h3 class="h4"><?php _e('About Wordfence', 'wordfence'); ?></h3>
364
- <p><?php _e('Wordfence is a security plugin installed on over 3 million WordPress sites. The owner of this site is using Wordfence to manage access to their site.', 'wordfence'); ?></p>
365
- <p><?php _e('You can also read the documentation to learn about Wordfence\'s blocking tools, or visit wordfence.com to learn more about Wordfence.', 'wordfence'); ?></p>
366
  </div>
367
  </div>
368
 
369
- <p class="documentation small"><?php printf(__('Click here to learn more: <a href="%s" target="_blank" rel="noopener noreferrer">Documentation</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_LOCKED_OUT)); ?></p>
370
- <p class="generated small"><em><?php printf(__('Generated by Wordfence at %s', 'wordfence'), gmdate('D, j M Y G:i:s T', wfWAFUtils::normalizedTime())); ?>.<br><?php _e('Your computer\'s time:', 'wordfence'); ?> <script type="application/javascript">document.write(new Date().toUTCString());</script>.</em></p>
371
  </div>
372
  </body>
373
  </html>
374
- <?php exit(); ?>
7
  <!DOCTYPE html>
8
  <html>
9
  <head>
10
+ <title><?php esc_html_e('You are temporarily locked out', 'wordfence'); ?></title>
11
  <style>
12
  html {
13
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
323
  <body>
324
  <div class="top-accent"></div>
325
  <div class="container">
326
+ <h1><?php esc_html_e('Your access to this site has been temporarily limited by the site owner', 'wordfence'); ?></h1>
327
+ <p><?php esc_html_e('Your access to this service has been temporarily limited. Please try again in a few minutes. (HTTP response code 503)', 'wordfence'); ?></p>
328
+ <p><?php esc_html_e('If you think you have been blocked in error, contact the owner of this site for assistance.', 'wordfence'); ?></p>
329
  <?php if (!empty($customText)): ?>
330
  <hr>
331
  <div class="medium"><?php echo $customText; ?></div>
332
  <?php endif; ?>
333
  <hr>
334
  <ul>
335
+ <li><a href="<?php echo esc_url(site_url()); ?>"><?php esc_html_e('Return to the site home page', 'wordfence'); ?></a></li>
336
+ <li><a href="<?php echo esc_url(admin_url()); ?>"><?php esc_html_e('Attempt to return to the admin login page (you may still be locked out)', 'wordfence'); ?></a></li>
337
  </ul>
338
  <?php require(dirname(__FILE__) . '/wfUnlockMsg.php'); ?>
339
 
340
+ <h2 class="h3"><?php esc_html_e('Block Technical Data', 'wordfence'); ?></h2>
341
  <table border="0" cellspacing="0" cellpadding="0" class="block-data">
342
  <tr>
343
+ <th class="reason"><?php esc_html_e('Block Reason:', 'wordfence'); ?></th>
344
+ <td class="reason"><?php esc_html_e('You have been temporarily locked out of this system. This means that you will not be able to log in for a while.', 'wordfence'); ?></td>
345
  </tr>
346
  <tr>
347
+ <th class="time"><?php esc_html_e('Time:', 'wordfence'); ?></th>
348
  <td class="time"><?php echo htmlspecialchars(gmdate('D, j M Y G:i:s T', wfWAFUtils::normalizedTime())); ?></td>
349
  </tr>
350
  </table>
360
  ?>
361
  </div>
362
  <div class="about-text">
363
+ <h3 class="h4"><?php esc_html_e('About Wordfence', 'wordfence'); ?></h3>
364
+ <p><?php esc_html_e('Wordfence is a security plugin installed on over 3 million WordPress sites. The owner of this site is using Wordfence to manage access to their site.', 'wordfence'); ?></p>
365
+ <p><?php esc_html_e('You can also read the documentation to learn about Wordfence\'s blocking tools, or visit wordfence.com to learn more about Wordfence.', 'wordfence'); ?></p>
366
  </div>
367
  </div>
368
 
369
+ <p class="documentation small"><?php echo wp_kses(sprintf(__('Click here to learn more: <a href="%s" target="_blank" rel="noopener noreferrer">Documentation</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_LOCKED_OUT)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))); ?></p>
370
+ <p class="generated small"><em><?php esc_html(printf(__('Generated by Wordfence at %s', 'wordfence'), gmdate('D, j M Y G:i:s T', wfWAFUtils::normalizedTime()))); ?>.<br><?php esc_html_e('Your computer\'s time:', 'wordfence'); ?> <script type="application/javascript">document.write(new Date().toUTCString());</script>.</em></p>
371
  </div>
372
  </body>
373
  </html>
374
+ <?php exit(); ?>
lib/wfLog.php CHANGED
@@ -306,7 +306,7 @@ class wfLog {
306
  } else if($type == 'ruser'){
307
  $typeSQL = " and userID > 0 ";
308
  } else {
309
- wordfence::status(1, 'error', "Invalid log type to wfLog: $type");
310
  return false;
311
  }
312
  array_unshift($sqlArgs, "select h.*, u.display_name from {$this->hitsTable} h
@@ -340,7 +340,7 @@ class wfLog {
340
  $results = call_user_func_array(array($this->getDB(), 'querySelect'), $sqlArgs );
341
 
342
  } else {
343
- wordfence::status(1, 'error', "getHits got invalid hitType: $hitType");
344
  return false;
345
  }
346
  $this->processGetHitsResults($type, $results);
@@ -552,7 +552,7 @@ class wfLog {
552
  if ($b->matchRequest($IP, $userAgent, $referrer) !== wfBlock::MATCH_NONE) {
553
  $b->recordBlock();
554
  wfActivityReport::logBlockedIP($IP, null, 'advanced');
555
- $this->currentRequest->actionDescription = 'UA/Referrer/IP Range not allowed';
556
  $this->do503(3600, __("Advanced blocking in effect.", 'wordfence')); //exits
557
  }
558
  }
@@ -579,7 +579,7 @@ class wfLog {
579
  wfConfig::inc('totalCountryBlocked');
580
 
581
  $this->initLogRequest();
582
- $this->getCurrentRequest()->actionDescription = sprintf(__('blocked access via country blocking and redirected to URL (%s)', 'wordfence'), wfConfig::get('cbl_redirURL'));
583
  $this->getCurrentRequest()->statusCode = 503;
584
  if (!$this->getCurrentRequest()->action) {
585
  $this->currentRequest->action = 'blocked:wordfence';
@@ -640,7 +640,7 @@ class wfLog {
640
  'reason' => $reason,
641
  'duration' => $secsToGo,
642
  ), $alertCallback);
643
- wordfence::status(2, 'info', sprintf(__('Blocking IP %s. %s', 'wordfence'), $IP, $reason));
644
  }
645
  else if ($action == 'throttle') { //Rate limited - throttle
646
  $secsToGo = wfBlock::rateLimitThrottleDuration();
@@ -652,7 +652,7 @@ class wfLog {
652
  'reason' => $reason,
653
  'duration' => $secsToGo,
654
  ));
655
- wordfence::status(2, 'info', sprintf(__('Throttling IP %s. %s', 'wordfence'), $IP, $reason));
656
  wfConfig::inc('totalIPsThrottled');
657
  }
658
  $this->do503($secsToGo, $reason, false);
306
  } else if($type == 'ruser'){
307
  $typeSQL = " and userID > 0 ";
308
  } else {
309
+ wordfence::status(1, 'error', sprintf(/* translators: Error message. */ __("Invalid log type to wfLog: %s", 'wordfence'), $type));
310
  return false;
311
  }
312
  array_unshift($sqlArgs, "select h.*, u.display_name from {$this->hitsTable} h
340
  $results = call_user_func_array(array($this->getDB(), 'querySelect'), $sqlArgs );
341
 
342
  } else {
343
+ wordfence::status(1, 'error', sprintf(/* translators: Error message. */ __("getHits got invalid hitType: %s", 'wordfence'), $hitType));
344
  return false;
345
  }
346
  $this->processGetHitsResults($type, $results);
552
  if ($b->matchRequest($IP, $userAgent, $referrer) !== wfBlock::MATCH_NONE) {
553
  $b->recordBlock();
554
  wfActivityReport::logBlockedIP($IP, null, 'advanced');
555
+ $this->currentRequest->actionDescription = __('UA/Referrer/IP Range not allowed', 'wordfence');
556
  $this->do503(3600, __("Advanced blocking in effect.", 'wordfence')); //exits
557
  }
558
  }
579
  wfConfig::inc('totalCountryBlocked');
580
 
581
  $this->initLogRequest();
582
+ $this->getCurrentRequest()->actionDescription = sprintf(/* translators: URL */ __('blocked access via country blocking and redirected to URL (%s)', 'wordfence'), wfConfig::get('cbl_redirURL'));
583
  $this->getCurrentRequest()->statusCode = 503;
584
  if (!$this->getCurrentRequest()->action) {
585
  $this->currentRequest->action = 'blocked:wordfence';
640
  'reason' => $reason,
641
  'duration' => $secsToGo,
642
  ), $alertCallback);
643
+ wordfence::status(2, 'info', sprintf(/* translators: 1. IP address. 2. Description of firewall action. */ __('Blocking IP %1$s. %2$s', 'wordfence'), $IP, $reason));
644
  }
645
  else if ($action == 'throttle') { //Rate limited - throttle
646
  $secsToGo = wfBlock::rateLimitThrottleDuration();
652
  'reason' => $reason,
653
  'duration' => $secsToGo,
654
  ));
655
+ wordfence::status(2, 'info', sprintf(/* translators: 1. IP address. 2. Description of firewall action. */ __('Throttling IP %1$s. %2$s', 'wordfence'), $IP, $reason));
656
  wfConfig::inc('totalIPsThrottled');
657
  }
658
  $this->do503($secsToGo, $reason, false);
lib/wfScan.php CHANGED
@@ -39,50 +39,60 @@ class wfScan {
39
  self::$peakMemAtStart = memory_get_peak_usage(true);
40
  $db = new wfDB();
41
  if($db->errorMsg){
42
- self::errorExit("Could not connect to database to start scan: " . $db->errorMsg);
43
  }
44
  if(! wordfence::wfSchemaExists()){
45
- self::errorExit("Looks like the Wordfence database tables have been deleted. You can fix this by de-activating and re-activating the Wordfence plugin from your Plugins menu.");
46
  }
47
  if( isset( $_GET['test'] ) && $_GET['test'] == '1'){
48
  echo "WFCRONTESTOK:" . wfConfig::get('cronTestID');
49
- self::status(4, 'info', "Cron test received and message printed");
50
  exit();
51
  }
52
 
53
- self::status(4, 'info', "Scan engine received request.");
54
 
55
  /* ----------Starting signature check -------- */
56
- self::status(4, 'info', "Verifying start request signature.");
57
  if (!isset($_GET['signature']) || !wfScanEngine::verifyStartSignature($_GET['signature'], isset($_GET['isFork']) ? wfUtils::truthyToBoolean($_GET['isFork']) : false, isset($_GET['scanMode']) ? $_GET['scanMode'] : '', isset($_GET['cronKey']) ? $_GET['cronKey'] : '', isset($_GET['remote']) ? wfUtils::truthyToBoolean($_GET['remote']) : false)) {
58
  self::errorExit(__('The signature on the request to start a scan is invalid. Please try again.', 'wordfence'));
59
  }
60
 
61
  /* ----------Starting cronkey check -------- */
62
- self::status(4, 'info', "Fetching stored cronkey for comparison.");
63
  $expired = false;
64
  $storedCronKey = self::storedCronKey($expired);
65
  $displayCronKey_received = (isset($_GET['cronKey']) ? (preg_match('/^[a-f0-9]+$/i', $_GET['cronKey']) && strlen($_GET['cronKey']) == 32 ? $_GET['cronKey'] : __('[invalid]', 'wordfence')) : __('[none]', 'wordfence'));
66
  $displayCronKey_stored = (!empty($storedCronKey) && !$expired ? $storedCronKey : __('[none]', 'wordfence'));
67
- self::status(4, 'info', sprintf(__('Checking cronkey: %s (expecting %s)', 'wordfence'), $displayCronKey_received, $displayCronKey_stored));
68
  if (empty($_GET['cronKey'])) {
69
- self::status(4, 'error', "Wordfence scan script accessed directly, or WF did not receive a cronkey.");
70
  echo "If you see this message it means Wordfence is working correctly. You should not access this URL directly. It is part of the Wordfence security plugin and is designed for internal use only.";
71
  exit();
72
  }
73
 
74
  if ($expired) {
75
- self::errorExit("The key used to start a scan expired. The value is: " . $expired . " and split is: " . $storedCronKey . " and time is: " . time());
 
 
76
  } //keys only last 60 seconds and are used within milliseconds of creation
77
 
78
  if (!$storedCronKey) {
79
- wordfence::status(4, 'error', "Wordfence could not find a saved cron key to start the scan so assuming it started and exiting.");
80
  exit();
81
  }
82
 
83
- self::status(4, 'info', "Checking saved cronkey against cronkey param");
84
  if (!hash_equals($storedCronKey, $_GET['cronKey'])) {
85
- self::errorExit("Wordfence could not start a scan because the cron key does not match the saved key. Saved: " . $storedCronKey . " Sent: " . $_GET['cronKey'] . " Current unexploded: " . wfConfig::get('currentCronKey', false));
 
 
 
 
 
 
 
 
86
  }
87
  wfConfig::set('currentCronKey', '');
88
  /* --------- end cronkey check ---------- */
@@ -97,9 +107,9 @@ class wfScan {
97
  $isFork = ($_GET['isFork'] == '1' ? true : false);
98
 
99
  if(! $isFork){
100
- self::status(4, 'info', "Checking if scan is already running");
101
  if(! wfUtils::getScanLock()){
102
- self::errorExit("There is already a scan running.");
103
  }
104
 
105
  wfIssues::updateScanStillRunning();
@@ -108,12 +118,12 @@ class wfScan {
108
  wfConfig::set('lowResourceScanWaitStep', false);
109
 
110
  if ($scanController->useLowResourceScanning()) {
111
- self::status(1, 'info', "Using low resource scanning");
112
  }
113
  }
114
- self::status(4, 'info', "Requesting max memory");
115
  wfUtils::requestMaxMemory();
116
- self::status(4, 'info', "Setting up error handling environment");
117
  set_error_handler('wfScan::error_handler', E_ALL);
118
  register_shutdown_function('wfScan::shutdown');
119
  if(! self::$debugMode){
@@ -121,22 +131,22 @@ class wfScan {
121
  }
122
  @error_reporting(E_ALL);
123
  wfUtils::iniSet('display_errors','On');
124
- self::status(4, 'info', "Setting up scanRunning and starting scan");
125
  try {
126
  if ($isFork) {
127
  $scan = wfConfig::get_ser('wfsd_engine', false, false);
128
  if ($scan) {
129
- self::status(4, 'info', "Got a true deserialized value back from 'wfsd_engine' with type: " . gettype($scan));
130
  wfConfig::set('wfsd_engine', '', wfConfig::DONT_AUTOLOAD);
131
  }
132
  else {
133
- self::status(2, 'error', "Scan can't continue - stored data not found after a fork. Got type: " . gettype($scan));
134
  wfConfig::set('wfsd_engine', '', wfConfig::DONT_AUTOLOAD);
135
  wfConfig::set('lastScanCompleted', __('Scan can\'t continue - stored data not found after a fork.', 'wordfence'));
136
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_FORK_FAILED);
137
  wfUtils::clearScanLock();
138
  self::status(2, 'error', "Scan terminated with error: " . __('Scan can\'t continue - stored data not found after a fork.', 'wordfence'));
139
- self::status(10, 'info', "SUM_KILLED:Previous scan terminated with an error. See below.");
140
  exit();
141
  }
142
  }
@@ -159,7 +169,7 @@ class wfScan {
159
  $scanController->resetSummaryItems();
160
 
161
  if ($scanMode != wfScanner::SCAN_TYPE_QUICK) {
162
- wordfence::status(1, 'info', "Contacting Wordfence to initiate scan");
163
  $wp_version = wfUtils::getWPVersion();
164
  $apiKey = wfConfig::get('apiKey');
165
  $api = new wfAPI($apiKey, $wp_version);
@@ -168,7 +178,7 @@ class wfScan {
168
  if ($scanController->schedulingMode() == wfScanner::SCAN_SCHEDULING_MODE_AUTOMATIC && $isScheduled) {
169
  if (isset($response['defer'])) {
170
  $defer = (int) $response['defer'];
171
- wordfence::status(2, 'info', "Deferring scheduled scan by " . wfUtils::makeDuration($defer));
172
  wfConfig::set('lastScheduledScanStart', 0);
173
  wfConfig::set('lastScanCompleted', 'ok');
174
  wfConfig::set('lastScanFailureType', false);
@@ -189,7 +199,7 @@ class wfScan {
189
  $scan->deleteNewIssues();
190
  }
191
  else {
192
- wordfence::status(1, 'info', "Initiating quick scan");
193
  $scan = new wfScanEngine('', '', $scanMode);
194
  }
195
  }
@@ -199,15 +209,24 @@ class wfScan {
199
  catch (wfScanEngineDurationLimitException $e) { //User error set in wfScanEngine
200
  wfUtils::clearScanLock();
201
  $peakMemory = self::logPeakMemory();
202
- self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
203
- self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
 
 
 
 
204
  exit();
205
  }
206
  catch (wfScanEngineCoreVersionChangeException $e) { //User error set in wfScanEngine
207
  wfUtils::clearScanLock();
208
  $peakMemory = self::logPeakMemory();
209
- self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
210
- self::status(2, 'error', "Scan terminated with message: " . $e->getMessage());
 
 
 
 
 
211
 
212
  $nextScheduledScan = wordfence::getNextScanStartTimestamp();
213
  if ($nextScheduledScan !== false && $nextScheduledScan - time() > 21600 /* 6 hours */) {
@@ -224,8 +243,13 @@ class wfScan {
224
 
225
  wfUtils::clearScanLock();
226
  $peakMemory = self::logPeakMemory();
227
- self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
228
- self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
 
 
 
 
 
229
  exit();
230
  }
231
  catch (wfAPICallFailedException $e) {
@@ -234,8 +258,13 @@ class wfScan {
234
 
235
  wfUtils::clearScanLock();
236
  $peakMemory = self::logPeakMemory();
237
- self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
238
- self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
 
 
 
 
 
239
  exit();
240
  }
241
  catch (wfAPICallInvalidResponseException $e) {
@@ -244,8 +273,13 @@ class wfScan {
244
 
245
  wfUtils::clearScanLock();
246
  $peakMemory = self::logPeakMemory();
247
- self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
248
- self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
 
 
 
 
 
249
  exit();
250
  }
251
  catch (wfAPICallErrorResponseException $e) {
@@ -254,11 +288,18 @@ class wfScan {
254
 
255
  wfUtils::clearScanLock();
256
  $peakMemory = self::logPeakMemory();
257
- self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
258
- self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
 
 
 
 
 
259
 
260
  if (preg_match('/The Wordfence API key you\'re using is already being used by: (\S*?) /', $e->getMessage(), $matches)) {
261
- wordfence::alert(__('Wordfence scan failed because of license site URL conflict', 'wordfence'), sprintf(__(<<<MSG
 
 
262
  The Wordfence scan has failed because the Wordfence API key you're using is already being used by: %s
263
 
264
  If you have changed your blog URL, please sign-in to Wordfence, purchase a new key or reset an existing key, and then enter that key on this site's Wordfence Options page.
@@ -270,8 +311,8 @@ MSG
270
  }
271
  catch (Exception $e) {
272
  wfUtils::clearScanLock();
273
- self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
274
- self::status(10, 'info', "SUM_KILLED:Previous scan terminated with an error. See below.");
275
  exit();
276
  }
277
  wfUtils::clearScanLock();
@@ -308,7 +349,7 @@ MSG
308
  self::logPeakMemory();
309
  }
310
  private static function errorExit($msg){
311
- wordfence::status(1, 'error', "Scan Engine Error: $msg");
312
  exit();
313
  }
314
  private static function status($level, $type, $msg){
39
  self::$peakMemAtStart = memory_get_peak_usage(true);
40
  $db = new wfDB();
41
  if($db->errorMsg){
42
+ self::errorExit(sprintf(/* translators: Error message. */ __("Could not connect to database to start scan: %s", 'wordfence'), $db->errorMsg));
43
  }
44
  if(! wordfence::wfSchemaExists()){
45
+ self::errorExit(__("Looks like the Wordfence database tables have been deleted. You can fix this by de-activating and re-activating the Wordfence plugin from your Plugins menu.", 'wordfence'));
46
  }
47
  if( isset( $_GET['test'] ) && $_GET['test'] == '1'){
48
  echo "WFCRONTESTOK:" . wfConfig::get('cronTestID');
49
+ self::status(4, 'info', __("Cron test received and message printed", 'wordfence'));
50
  exit();
51
  }
52
 
53
+ self::status(4, 'info', __("Scan engine received request.", 'wordfence'));
54
 
55
  /* ----------Starting signature check -------- */
56
+ self::status(4, 'info', __("Verifying start request signature.", 'wordfence'));
57
  if (!isset($_GET['signature']) || !wfScanEngine::verifyStartSignature($_GET['signature'], isset($_GET['isFork']) ? wfUtils::truthyToBoolean($_GET['isFork']) : false, isset($_GET['scanMode']) ? $_GET['scanMode'] : '', isset($_GET['cronKey']) ? $_GET['cronKey'] : '', isset($_GET['remote']) ? wfUtils::truthyToBoolean($_GET['remote']) : false)) {
58
  self::errorExit(__('The signature on the request to start a scan is invalid. Please try again.', 'wordfence'));
59
  }
60
 
61
  /* ----------Starting cronkey check -------- */
62
+ self::status(4, 'info', __("Fetching stored cronkey for comparison.", 'wordfence'));
63
  $expired = false;
64
  $storedCronKey = self::storedCronKey($expired);
65
  $displayCronKey_received = (isset($_GET['cronKey']) ? (preg_match('/^[a-f0-9]+$/i', $_GET['cronKey']) && strlen($_GET['cronKey']) == 32 ? $_GET['cronKey'] : __('[invalid]', 'wordfence')) : __('[none]', 'wordfence'));
66
  $displayCronKey_stored = (!empty($storedCronKey) && !$expired ? $storedCronKey : __('[none]', 'wordfence'));
67
+ self::status(4, 'info', sprintf(/* translators: 1. WordPress nonce. 2. WordPress nonce. */ __('Checking cronkey: %1$s (expecting %2$s)', 'wordfence'), $displayCronKey_received, $displayCronKey_stored));
68
  if (empty($_GET['cronKey'])) {
69
+ self::status(4, 'error', __("Wordfence scan script accessed directly, or WF did not receive a cronkey.", 'wordfence'));
70
  echo "If you see this message it means Wordfence is working correctly. You should not access this URL directly. It is part of the Wordfence security plugin and is designed for internal use only.";
71
  exit();
72
  }
73
 
74
  if ($expired) {
75
+ self::errorExit(sprintf(
76
+ /* translators: 1. Unix timestamp. 2. WordPress nonce. 3. Unix timestamp. */
77
+ __('The key used to start a scan expired. The value is: %1$s and split is: %2$s and time is: %3$d'), $expired, $storedCronKey, time()));
78
  } //keys only last 60 seconds and are used within milliseconds of creation
79
 
80
  if (!$storedCronKey) {
81
+ wordfence::status(4, 'error', __("Wordfence could not find a saved cron key to start the scan so assuming it started and exiting.", 'wordfence'));
82
  exit();
83
  }
84
 
85
+ self::status(4, 'info', __("Checking saved cronkey against cronkey param", 'wordfence'));
86
  if (!hash_equals($storedCronKey, $_GET['cronKey'])) {
87
+ self::errorExit(
88
+ sprintf(
89
+ /* translators: 1. WordPress nonce (used for debugging). 2. WordPress nonce (used for debugging). 3. WordPress nonce (used for debugging). */
90
+ __('Wordfence could not start a scan because the cron key does not match the saved key. Saved: %1$s Sent: %2$s Current unexploded: %3$s', 'wordfence'),
91
+ $storedCronKey,
92
+ $_GET['cronKey'],
93
+ wfConfig::get('currentCronKey', false)
94
+ )
95
+ );
96
  }
97
  wfConfig::set('currentCronKey', '');
98
  /* --------- end cronkey check ---------- */
107
  $isFork = ($_GET['isFork'] == '1' ? true : false);
108
 
109
  if(! $isFork){
110
+ self::status(4, 'info', __("Checking if scan is already running", 'wordfence'));
111
  if(! wfUtils::getScanLock()){
112
+ self::errorExit(__("There is already a scan running.", 'wordfence'));
113
  }
114
 
115
  wfIssues::updateScanStillRunning();
118
  wfConfig::set('lowResourceScanWaitStep', false);
119
 
120
  if ($scanController->useLowResourceScanning()) {
121
+ self::status(1, 'info', __("Using low resource scanning", 'wordfence'));
122
  }
123
  }
124
+ self::status(4, 'info', __("Requesting max memory", 'wordfence'));
125
  wfUtils::requestMaxMemory();
126
+ self::status(4, 'info', __("Setting up error handling environment", 'wordfence'));
127
  set_error_handler('wfScan::error_handler', E_ALL);
128
  register_shutdown_function('wfScan::shutdown');
129
  if(! self::$debugMode){
131
  }
132
  @error_reporting(E_ALL);
133
  wfUtils::iniSet('display_errors','On');
134
+ self::status(4, 'info', __("Setting up scanRunning and starting scan", 'wordfence'));
135
  try {
136
  if ($isFork) {
137
  $scan = wfConfig::get_ser('wfsd_engine', false, false);
138
  if ($scan) {
139
+ self::status(4, 'info', sprintf(/* translators: Error message (used for debugging). */ __("Got a true deserialized value back from 'wfsd_engine' with type: %s", 'wordfence'), gettype($scan)));
140
  wfConfig::set('wfsd_engine', '', wfConfig::DONT_AUTOLOAD);
141
  }
142
  else {
143
+ self::status(2, 'error', sprintf(/* translators: Error message (used for debugging). */ __("Scan can't continue - stored data not found after a fork. Got type: %s", 'wordfence'), gettype($scan)));
144
  wfConfig::set('wfsd_engine', '', wfConfig::DONT_AUTOLOAD);
145
  wfConfig::set('lastScanCompleted', __('Scan can\'t continue - stored data not found after a fork.', 'wordfence'));
146
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_FORK_FAILED);
147
  wfUtils::clearScanLock();
148
  self::status(2, 'error', "Scan terminated with error: " . __('Scan can\'t continue - stored data not found after a fork.', 'wordfence'));
149
+ self::status(10, 'info', "SUM_KILLED:" . __('Previous scan terminated with an error. See below.', 'wordfence'));
150
  exit();
151
  }
152
  }
169
  $scanController->resetSummaryItems();
170
 
171
  if ($scanMode != wfScanner::SCAN_TYPE_QUICK) {
172
+ wordfence::status(1, 'info', __("Contacting Wordfence to initiate scan", 'wordfence'));
173
  $wp_version = wfUtils::getWPVersion();
174
  $apiKey = wfConfig::get('apiKey');
175
  $api = new wfAPI($apiKey, $wp_version);
178
  if ($scanController->schedulingMode() == wfScanner::SCAN_SCHEDULING_MODE_AUTOMATIC && $isScheduled) {
179
  if (isset($response['defer'])) {
180
  $defer = (int) $response['defer'];
181
+ wordfence::status(2, 'info', sprintf(/* translators: Time until. */ __("Deferring scheduled scan by %s"), wfUtils::makeDuration($defer)));
182
  wfConfig::set('lastScheduledScanStart', 0);
183
  wfConfig::set('lastScanCompleted', 'ok');
184
  wfConfig::set('lastScanFailureType', false);
199
  $scan->deleteNewIssues();
200
  }
201
  else {
202
+ wordfence::status(1, 'info', __("Initiating quick scan", 'wordfence'));
203
  $scan = new wfScanEngine('', '', $scanMode);
204
  }
205
  }
209
  catch (wfScanEngineDurationLimitException $e) { //User error set in wfScanEngine
210
  wfUtils::clearScanLock();
211
  $peakMemory = self::logPeakMemory();
212
+ self::status(2, 'info', sprintf(
213
+ __('Wordfence used %1$s of memory for scan. Server peak memory usage was: %2$s', 'wordfence'),
214
+ wfUtils::formatBytes($peakMemory - self::$peakMemAtStart),
215
+ wfUtils::formatBytes($peakMemory)
216
+ ));
217
+ self::status(2, 'error', sprintf(__("Scan terminated with error: %s", 'wordfence'), $e->getMessage()));
218
  exit();
219
  }
220
  catch (wfScanEngineCoreVersionChangeException $e) { //User error set in wfScanEngine
221
  wfUtils::clearScanLock();
222
  $peakMemory = self::logPeakMemory();
223
+ self::status(2, 'info', sprintf(
224
+ /* translators: 1. Bytes of memory. 2. Bytes of memory. */
225
+ __('Wordfence used %1$s of memory for scan. Server peak memory usage was: %2$s', 'wordfence'),
226
+ wfUtils::formatBytes($peakMemory - self::$peakMemAtStart),
227
+ wfUtils::formatBytes($peakMemory)
228
+ ));
229
+ self::status(2, 'error', sprintf(/* translators: Error message. */ __("Scan terminated with error: %s", 'wordfence'), $e->getMessage()));
230
 
231
  $nextScheduledScan = wordfence::getNextScanStartTimestamp();
232
  if ($nextScheduledScan !== false && $nextScheduledScan - time() > 21600 /* 6 hours */) {
243
 
244
  wfUtils::clearScanLock();
245
  $peakMemory = self::logPeakMemory();
246
+ self::status(2, 'info', sprintf(
247
+ /* translators: 1. Bytes of memory. 2. Bytes of memory. */
248
+ __('Wordfence used %1$s of memory for scan. Server peak memory usage was: %2$s', 'wordfence'),
249
+ wfUtils::formatBytes($peakMemory - self::$peakMemAtStart),
250
+ wfUtils::formatBytes($peakMemory)
251
+ ));
252
+ self::status(2, 'error', sprintf(/* translators: Error message. */__("Scan terminated with error: %s", 'wordfence'), $e->getMessage()));
253
  exit();
254
  }
255
  catch (wfAPICallFailedException $e) {
258
 
259
  wfUtils::clearScanLock();
260
  $peakMemory = self::logPeakMemory();
261
+ self::status(2, 'info', sprintf(
262
+ /* translators: 1. Bytes of memory. 2. Bytes of memory. */
263
+ __('Wordfence used %1$s of memory for scan. Server peak memory usage was: %2$s', 'wordfence'),
264
+ wfUtils::formatBytes($peakMemory - self::$peakMemAtStart),
265
+ wfUtils::formatBytes($peakMemory)
266
+ ));
267
+ self::status(2, 'error', sprintf(/* translators: Error message. */ __("Scan terminated with error: %s", 'wordfence'), $e->getMessage()));
268
  exit();
269
  }
270
  catch (wfAPICallInvalidResponseException $e) {
273
 
274
  wfUtils::clearScanLock();
275
  $peakMemory = self::logPeakMemory();
276
+ self::status(2, 'info', sprintf(
277
+ /* translators: 1. Bytes of memory. 2. Bytes of memory. */
278
+ __('Wordfence used %1$s of memory for scan. Server peak memory usage was: %2$s', 'wordfence'),
279
+ wfUtils::formatBytes($peakMemory - self::$peakMemAtStart),
280
+ wfUtils::formatBytes($peakMemory)
281
+ ));
282
+ self::status(2, 'error', sprintf(/* translators: Error message. */ __("Scan terminated with error: %s", 'wordfence'), $e->getMessage()));
283
  exit();
284
  }
285
  catch (wfAPICallErrorResponseException $e) {
288
 
289
  wfUtils::clearScanLock();
290
  $peakMemory = self::logPeakMemory();
291
+ self::status(2, 'info', sprintf(
292
+ /* translators: 1. Bytes of memory. 2. Bytes of memory. */
293
+ __('Wordfence used %1$s of memory for scan. Server peak memory usage was: %2$s', 'wordfence'),
294
+ wfUtils::formatBytes($peakMemory - self::$peakMemAtStart),
295
+ wfUtils::formatBytes($peakMemory)
296
+ ));
297
+ self::status(2, 'error', sprintf(/* translators: Error message. */ __("Scan terminated with error: %s", 'wordfence'), $e->getMessage()));
298
 
299
  if (preg_match('/The Wordfence API key you\'re using is already being used by: (\S*?) /', $e->getMessage(), $matches)) {
300
+ wordfence::alert(__('Wordfence scan failed because of license site URL conflict', 'wordfence'), sprintf(
301
+ /* translators: Site URL. */
302
+ __(<<<MSG
303
  The Wordfence scan has failed because the Wordfence API key you're using is already being used by: %s
304
 
305
  If you have changed your blog URL, please sign-in to Wordfence, purchase a new key or reset an existing key, and then enter that key on this site's Wordfence Options page.
311
  }
312
  catch (Exception $e) {
313
  wfUtils::clearScanLock();
314
+ self::status(2, 'error', sprintf(/* translators: Error message. */ __("Scan terminated with error: %s", 'wordfence'), $e->getMessage()));
315
+ self::status(10, 'info', "SUM_KILLED:" . __('Previous scan terminated with an error. See below.', 'wordfence'));
316
  exit();
317
  }
318
  wfUtils::clearScanLock();
349
  self::logPeakMemory();
350
  }
351
  private static function errorExit($msg){
352
+ wordfence::status(1, 'error', sprintf(/* translators: Error message. */ __('Scan Engine Error: %s', 'wordfence'), $msg));
353
  exit();
354
  }
355
  private static function status($level, $type, $msg){
lib/wfScanEngine.php CHANGED
@@ -6,9 +6,10 @@ require_once(dirname(__FILE__) . '/wordfenceScanner.php');
6
  require_once(dirname(__FILE__) . '/wfIssues.php');
7
  require_once(dirname(__FILE__) . '/wfDB.php');
8
  require_once(dirname(__FILE__) . '/wfUtils.php');
 
9
  class wfScanEngine {
10
  const SCAN_MANUALLY_KILLED = -999;
11
-
12
  public $api = false;
13
  private $dictWords = array();
14
  private $forkRequested = false;
@@ -35,11 +36,11 @@ class wfScanEngine {
35
  private $hoover = false;
36
  private $scanData = array();
37
  private $statusIDX = array(
38
- 'core' => false,
39
- 'plugin' => false,
40
- 'theme' => false,
41
- 'unknown' => false
42
- );
43
  private $userPasswdQueue = "";
44
  private $passwdHasIssues = wfIssues::STATUS_SECURE;
45
  private $suspectedFiles = false; //Files found with the ".suspected" extension
@@ -51,7 +52,7 @@ class wfScanEngine {
51
  private $scanMode = wfScanner::SCAN_TYPE_STANDARD;
52
  private $pluginsCounted = false;
53
  private $themesCounted = false;
54
-
55
  /**
56
  * @var wfScanner
57
  */
@@ -66,9 +67,9 @@ class wfScanEngine {
66
  * @var wfScanKnownFilesLoader
67
  */
68
  private $knownFilesLoader;
69
-
70
  private $metrics = array();
71
-
72
  private $checkHowGetIPsRequestTime = 0;
73
 
74
  public static function testForFullPathDisclosure($url = null, $filePath = null) {
@@ -92,49 +93,48 @@ class wfScanEngine {
92
  return !is_wp_error($response) && ($responseBody = wp_remote_retrieve_body($response)) &&
93
  stripos($responseBody, '<title>Index of') !== false;
94
  }
95
-
96
  public static function refreshScanNotification($issuesInstance = null) {
97
  if ($issuesInstance === null) {
98
  $issuesInstance = new wfIssues();
99
  }
100
-
101
  $message = wfConfig::get('lastScanCompleted', false);
102
  if ($message === false || empty($message)) {
103
  $n = wfNotification::getNotificationForCategory('wfplugin_scan');
104
  if ($n !== null) {
105
  $n->markAsRead();
106
  }
107
- }
108
- else if ($message == 'ok') {
109
  $issueCount = $issuesInstance->getIssueCount();
110
  if ($issueCount) {
111
- new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, "<a href=\"" . wfUtils::wpAdminURL('admin.php?page=WordfenceScan') . "\">{$issueCount} issue" . ($issueCount == 1 ? '' : 's') . ' found in most recent scan</a>', 'wfplugin_scan');
112
- }
113
- else {
 
 
114
  $n = wfNotification::getNotificationForCategory('wfplugin_scan');
115
  if ($n !== null) {
116
  $n->markAsRead();
117
  }
118
  }
119
- }
120
- else {
121
  $failureType = wfConfig::get('lastScanFailureType');
122
  if ($failureType == 'duration') {
123
  new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, '<a href="' . wfUtils::wpAdminURL('admin.php?page=WordfenceScan') . '">Scan aborted due to duration limit</a>', 'wfplugin_scan');
124
- }
125
- else if ($failureType == 'versionchange') {
126
  //No need to create a notification
127
- }
128
- else {
129
  $trimmedError = substr($message, 0, 100) . (strlen($message) > 100 ? '...' : '');
130
  new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, '<a href="' . wfUtils::wpAdminURL('admin.php?page=WordfenceScan') . '">Scan failed: ' . esc_html($trimmedError) . '</a>', 'wfplugin_scan');
131
  }
132
  }
133
  }
134
 
135
- public function __sleep(){ //Same order here as above for properties that are included in serialization
136
  return array('hasher', 'jobList', 'i', 'wp_version', 'apiKey', 'startTime', 'maxExecTime', 'publicScanEnabled', 'fileContentsResults', 'scanner', 'scanQueue', 'hoover', 'scanData', 'statusIDX', 'userPasswdQueue', 'passwdHasIssues', 'suspectedFiles', 'dbScanner', 'knownFilesLoader', 'metrics', 'checkHowGetIPsRequestTime', 'gsbMultisiteBlogOffset', 'updateCheck', 'pluginRepoStatus', 'malwarePrefixesHash', 'coreHashesHash', 'scanMode', 'pluginsCounted', 'themesCounted');
137
  }
 
138
  public function __construct($malwarePrefixesHash = '', $coreHashesHash = '', $scanMode = wfScanner::SCAN_TYPE_STANDARD) {
139
  $this->startTime = time();
140
  $this->recordMetric('scan', 'start', $this->startTime);
@@ -149,7 +149,7 @@ class wfScanEngine {
149
  include(dirname(__FILE__) . '/wfDict.php'); //$dictWords
150
  $this->dictWords = $dictWords;
151
  $this->scanMode = $scanMode;
152
-
153
  $this->scanController = new wfScanner($scanMode);
154
  $jobs = $this->scanController->jobs();
155
  foreach ($jobs as $job) {
@@ -157,36 +157,38 @@ class wfScanEngine {
157
  foreach (array('init', 'main', 'finish') as $op) {
158
  $this->jobList[] = $job . '_' . $op;
159
  }
160
- }
161
- else if (method_exists($this, 'scan_' . $job)) {
162
  $this->jobList[] = $job;
163
  }
164
  }
165
  }
166
-
167
  public function scanController() {
168
  return $this->scanController;
169
  }
170
-
171
  /**
172
  * Deletes all new issues. To only delete specific types, provide an array of issue types.
173
- *
174
  * @param null|array $types
175
  */
176
  public function deleteNewIssues($types = null) {
177
  $this->i->deleteNew($types);
178
  }
179
- public function __wakeup(){
 
180
  $this->cycleStartTime = time();
181
  $this->api = new wfAPI($this->apiKey, $this->wp_version);
182
  include(dirname(__FILE__) . '/wfDict.php'); //$dictWords
183
  $this->dictWords = $dictWords;
184
  $this->scanController = new wfScanner($this->scanMode);
185
  }
 
186
  public function isFullScan() {
187
  return $this->scanMode != wfScanner::SCAN_TYPE_QUICK;
188
  }
189
- public function go(){
 
190
  try {
191
  self::checkForKill();
192
  $this->doScan();
@@ -202,31 +204,29 @@ class wfScanEngine {
202
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
203
  $this->submitMetrics();
204
  }
205
-
206
  wfScanEngine::refreshScanNotification($this->i);
207
 
208
  if (wfCentral::isConnected()) {
209
  wfCentral::updateScanStatus();
210
  }
211
- }
212
- catch (wfScanEngineDurationLimitException $e) {
213
  wfConfig::set('lastScanCompleted', $e->getMessage());
214
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_DURATION_REACHED);
215
  $this->scanController->recordLastScanTime();
216
-
217
  $this->emailNewIssues(true);
218
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
219
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
220
  $this->submitMetrics();
221
-
222
  wfScanEngine::refreshScanNotification($this->i);
223
  throw $e;
224
- }
225
- catch (wfScanEngineCoreVersionChangeException $e) {
226
  wfConfig::set('lastScanCompleted', $e->getMessage());
227
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_VERSION_CHANGE);
228
  $this->scanController->recordLastScanTime();
229
-
230
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
231
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
232
  $this->submitMetrics();
@@ -235,35 +235,34 @@ class wfScanEngine {
235
 
236
  wfScanEngine::refreshScanNotification($this->i);
237
  throw $e;
238
- }
239
- catch (wfScanEngineTestCallbackFailedException $e) {
240
  wfConfig::set('lastScanCompleted', $e->getMessage());
241
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
242
  $this->scanController->recordLastScanTime();
243
-
244
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
245
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
246
  $this->recordMetric('scan', 'failure', $e->getMessage());
247
  $this->submitMetrics();
248
-
249
  wfScanEngine::refreshScanNotification($this->i);
250
  throw $e;
251
- }
252
- catch (Exception $e) {
253
  if ($e->getCode() != wfScanEngine::SCAN_MANUALLY_KILLED) {
254
  wfConfig::set('lastScanCompleted', $e->getMessage());
255
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_GENERAL);
256
  }
257
-
258
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
259
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
260
  $this->recordMetric('scan', 'failure', $e->getMessage());
261
  $this->submitMetrics();
262
-
263
  wfScanEngine::refreshScanNotification($this->i);
264
  throw $e;
265
  }
266
  }
 
267
  public function checkForDurationLimit() {
268
  static $timeLimit = false;
269
  if ($timeLimit === false) {
@@ -272,71 +271,104 @@ class wfScanEngine {
272
  $timeLimit = WORDFENCE_DEFAULT_MAX_SCAN_TIME;
273
  }
274
  }
275
-
276
- if ((time() - $this->startTime) > $timeLimit){
277
- $error = 'The scan time limit of ' . wfUtils::makeDuration($timeLimit) . ' has been exceeded and the scan will be terminated. This limit can be customized on the options page. <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_TIME_LIMIT) . '" target="_blank" rel="noopener noreferrer">Get More Information</a>';
278
- $this->addIssue('timelimit', wfIssues::SEVERITY_HIGH, md5($this->startTime), md5($this->startTime), 'Scan Time Limit Exceeded', $error, array());
279
-
 
 
 
 
 
280
  $this->status(1, 'info', '-------------------');
281
- $this->status(1, 'info', "Scan interrupted. Scanned " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_FILES, 0) . " files, " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_PLUGINS, 0) . " plugins, " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_THEMES, 0) . " themes, " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_POSTS, 0) . " posts, " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_COMMENTS, 0) . " comments and " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, 0) . " URLs in " . wfUtils::makeDuration(time() - $this->startTime, true) . ".");
282
- if($this->i->totalIssues > 0){
283
- $this->status(10, 'info', "SUM_FINAL:Scan interrupted. You have " . $this->i->totalIssues . " new issue" . ($this->i->totalIssues == 1 ? "" : "s") . " to fix. See below.");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  } else {
285
- $this->status(10, 'info', "SUM_FINAL:Scan interrupted. No problems found prior to stopping.");
286
  }
287
  throw new wfScanEngineDurationLimitException($error);
288
  }
289
  }
 
290
  public function checkForCoreVersionChange() {
291
  $startVersion = wfConfig::get('wfScanStartVersion');
292
  $currentVersion = wfUtils::getWPVersion(true);
293
  if (version_compare($startVersion, $currentVersion) != 0) {
294
- throw new wfScanEngineCoreVersionChangeException("Aborting scan because WordPress updated from version {$startVersion} to {$currentVersion}. The scan will be reattempted later.");
 
 
295
  }
296
  }
 
297
  public function shouldFork() {
298
  static $lastCheck = 0;
299
-
300
  if (time() - $this->cycleStartTime > $this->maxExecTime) {
301
  return true;
302
  }
303
-
304
  if ($lastCheck > time() - $this->maxExecTime) {
305
  return false;
306
  }
307
  $lastCheck = time();
308
-
309
  $this->checkForCoreVersionChange();
310
  wfIssues::updateScanStillRunning();
311
  self::checkForKill();
312
  $this->checkForDurationLimit();
313
-
314
  return false;
315
  }
316
- public function forkIfNeeded(){
 
317
  wfIssues::updateScanStillRunning();
318
  $this->checkForCoreVersionChange();
319
  self::checkForKill();
320
  $this->checkForDurationLimit();
321
- if(time() - $this->cycleStartTime > $this->maxExecTime){
322
- wordfence::status(4, 'info', "Forking during hash scan to ensure continuity.");
323
  $this->fork();
324
  }
325
  }
326
- public function fork(){
327
- wordfence::status(4, 'info', "Entered fork()");
328
- if(wfConfig::set_ser('wfsd_engine', $this, true, wfConfig::DONT_AUTOLOAD)){
 
329
  $this->scanController->flushSummaryItems();
330
- wordfence::status(4, 'info', "Calling startScan(true)");
331
  self::startScan(true, $this->scanMode);
332
  } //Otherwise there was an error so don't start another scan.
333
  exit(0);
334
  }
335
- public function emailNewIssues($timeLimitReached = false){
 
336
  if (!wfCentral::pluginAlertingDisabled()) {
337
  $this->i->emailNewIssues($timeLimitReached, $this->scanController);
338
  }
339
  }
 
340
  public function submitMetrics() {
341
  if (wfConfig::get('other_WFNet', true)) {
342
  //Trim down the malware matches if needed to allow the report call to succeed
@@ -352,7 +384,7 @@ class wfScanEngine {
352
  $rules_with_extras++;
353
  }
354
  }
355
-
356
  //Trim additional matches
357
  $overage = $extra_count - WORDFENCE_SCAN_ISSUES_MAX_REPORT;
358
  if ($overage > 0) {
@@ -364,18 +396,19 @@ class wfScanEngine {
364
  $this->metrics['malwareSignature'][$rule] = $sliced;
365
  }
366
  }
367
-
368
  //Trim single matches
369
  if ($count > WORDFENCE_SCAN_ISSUES_MAX_REPORT) {
370
  $sliced = array_slice($this->metrics['malwareSignature'], 0, WORDFENCE_SCAN_ISSUES_MAX_REPORT, true);
371
  $this->metrics['malwareSignature'] = $sliced;
372
  }
373
  }
374
-
375
  $this->api->call('record_scan_metrics', array(), array('metrics' => $this->metrics));
376
  }
377
  }
378
- private function doScan(){
 
379
  if ($this->scanController->useLowResourceScanning()) {
380
  $isFork = ($_GET['isFork'] == '1' ? true : false);
381
  wfConfig::set('lowResourceScanWaitStep', !wfConfig::get('lowResourceScanWaitStep'));
@@ -384,8 +417,8 @@ class wfScanEngine {
384
  $this->fork(); //exits
385
  }
386
  }
387
-
388
- while(sizeof($this->jobList) > 0){
389
  self::checkForKill();
390
  $jobName = $this->jobList[0];
391
  $callback = array($this, 'scan_' . $jobName);
@@ -394,77 +427,116 @@ class wfScanEngine {
394
  }
395
  array_shift($this->jobList); //only shift once we're done because we may pause halfway through a job and need to pick up where we left off
396
  self::checkForKill();
397
- if($this->forkRequested){
398
  $this->fork();
399
  } else {
400
- $this->forkIfNeeded();
401
  }
402
  }
403
-
404
  $this->status(1, 'info', '-------------------');
405
-
406
  $peakMemory = wfScan::logPeakMemory();
407
- $this->status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - wfScan::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
408
-
 
 
 
 
 
409
  if ($this->isFullScan()) {
410
- $this->status(1, 'info', "Scan Complete. Scanned " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_FILES, 0) . " files, " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_PLUGINS, 0) . " plugins, " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_THEMES, 0) . " themes, " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_POSTS, 0) . " posts, " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_COMMENTS, 0) . " comments and " . $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, 0) . " URLs in " . wfUtils::makeDuration(time() - $this->startTime, true) . ".");
411
- }
412
- else {
413
- $this->status(1, 'info', "Quick Scan Complete. Scanned in " . wfUtils::makeDuration(time() - $this->startTime, true) . ".");
 
 
 
 
 
 
 
 
 
 
 
 
 
414
  }
415
-
416
  $ignoredText = '';
417
  if ($this->i->totalIgnoredIssues > 0) {
418
- $ignoredText = ' ' . $this->i->totalIgnoredIssues . ' ignored issue' . ($this->i->totalIgnoredIssues == 1 ? ' was' : 's were') . ' also detected.';
419
- }
420
-
421
- if($this->i->totalIssues > 0){
422
- $this->status(10, 'info', "SUM_FINAL:Scan complete. You have " . $this->i->totalIssues . " new issue" . ($this->i->totalIssues == 1 ? "" : "s") . " to fix.{$ignoredText} See below.");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
423
  } else {
424
- $this->status(10, 'info', "SUM_FINAL:Scan complete. Congratulations, no new problems found.{$ignoredText}");
425
  }
426
  return;
427
  }
428
- public function getCurrentJob(){
 
429
  return $this->jobList[0];
430
  }
 
431
  private function scan_checkSpamIP() {
432
  if ($this->scanController->isPremiumScan()) {
433
- $this->statusIDX['checkSpamIP'] = wfIssues::statusStart("Checking if your site IP is generating spam");
434
  $this->scanController->startStage(wfScanner::STAGE_SPAM_CHECK);
435
  $result = $this->api->call('check_spam_ip', array(), array(
436
  'siteURL' => site_url()
437
- ));
438
  $haveIssues = wfIssues::STATUS_SECURE;
439
- if(!empty($result['haveIssues']) && is_array($result['issues']) ){
440
- foreach($result['issues'] as $issue){
441
  $added = $this->addIssue($issue['type'], wfIssues::SEVERITY_HIGH, $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
442
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
443
- else if ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
444
  }
445
  }
446
  wfIssues::statusEnd($this->statusIDX['checkSpamIP'], $haveIssues);
447
  $this->scanController->completeStage(wfScanner::STAGE_SPAM_CHECK, $haveIssues);
448
- }
449
- else {
450
- wfIssues::statusPaidOnly("Checking if your IP is generating spam is for paid members only");
451
  sleep(2);
452
  }
453
  }
454
-
455
  private function scan_checkGSB_init() {
456
  if ($this->scanController->isPremiumScan()) {
457
- $this->statusIDX['checkGSB'] = wfIssues::statusStart("Checking if your site is on a domain blocklist");
458
  $this->scanController->startStage(wfScanner::STAGE_BLACKLIST_CHECK);
459
- $h = new wordfenceURLHoover($this->apiKey, $this->wp_version);
460
- $h->cleanup();
461
- }
462
- else {
463
- wfIssues::statusPaidOnly("Checking if your site is on a domain blocklist is for paid members only");
464
  sleep(2);
465
  }
466
  }
467
-
468
  private function scan_checkGSB_main() {
469
  if ($this->scanController->isPremiumScan()) {
470
  if (is_multisite()) {
@@ -480,7 +552,7 @@ class wfScanEngine {
480
  $h->hoover($id, $siteURL);
481
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_URLS);
482
  }
483
-
484
  if ($this->shouldFork()) {
485
  $this->gsbMultisiteBlogOffset = $id;
486
  $this->forkIfNeeded();
@@ -489,21 +561,20 @@ class wfScanEngine {
489
  }
490
  }
491
  }
492
-
493
  private function scan_checkGSB_finish() {
494
  if ($this->scanController->isPremiumScan()) {
495
  if (is_multisite()) {
496
  $h = new wordfenceURLHoover($this->apiKey, $this->wp_version, false, true);
497
  $badURLs = $h->getBaddies();
498
  if ($h->errorMsg) {
499
- $this->status(4, 'info', "Error checking domain blocklists: " . $h->errorMsg);
500
  wfIssues::statusEnd($this->statusIDX['checkGSB'], wfIssues::STATUS_FAILED);
501
  $this->scanController->completeStage(wfScanner::STAGE_BLACKLIST_CHECK, wfIssues::STATUS_FAILED);
502
  return;
503
  }
504
  $h->cleanup();
505
- }
506
- else {
507
  $urlsToCheck = array(array(wfUtils::wpHomeURL(), wfUtils::wpSiteURL()));
508
  $badURLs = $this->api->call('check_bad_urls', array(), array('toCheck' => json_encode($urlsToCheck))); //Skipping the separate prefix check since there are just two URLs
509
  $finalResults = array();
@@ -513,14 +584,14 @@ class wfScanEngine {
513
  }
514
  foreach ($badSiteList as $badSite) {
515
  $finalResults[$file][] = array(
516
- 'URL' => $badSite[0],
517
  'badList' => $badSite[1]
518
  );
519
  }
520
  }
521
  $badURLs = $finalResults;
522
  }
523
-
524
  $haveIssues = wfIssues::STATUS_SECURE;
525
  if (is_array($badURLs) && count($badURLs) > 0) {
526
  foreach ($badURLs as $id => $badSiteList) {
@@ -528,74 +599,84 @@ class wfScanEngine {
528
  $url = $badSite['URL'];
529
  $badList = $badSite['badList'];
530
  $data = array('badURL' => $url);
531
-
532
  if ($badList == 'goog-malware-shavar') {
533
  if (is_multisite()) {
534
- $shortMsg = 'The multisite blog with ID ' . intval($id) . ' is listed on Google\'s Safe Browsing malware list.';
535
  $data['multisite'] = intval($id);
 
 
536
  }
537
- else {
538
- $shortMsg = 'Your site is listed on Google\'s Safe Browsing malware list.';
539
- }
540
- $longMsg = "The URL " . esc_html($url) . " is on the malware list. More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=" . urlencode($url) . "&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>.";
541
  $data['gsb'] = $badList;
542
- }
543
- else if ($badList == 'googpub-phish-shavar') {
544
  if (is_multisite()) {
545
- $shortMsg = 'The multisite blog with ID ' . intval($id) . ' is listed on Google\'s Safe Browsing phishing list.';
 
 
546
  $data['multisite'] = intval($id);
 
 
547
  }
548
- else {
549
- $shortMsg = 'Your site is listed on Google\'s Safe Browsing phishing list.';
550
- }
551
- $longMsg = "The URL " . esc_html($url) . " is on the phishing list. More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=" . urlencode($url) . "&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>.";
552
  $data['gsb'] = $badList;
553
- }
554
- else if ($badList == 'wordfence-dbl') {
555
  if (is_multisite()) {
556
- $shortMsg = 'The multisite blog with ID ' . intval($id) . ' is listed on the Wordfence domain blocklist.';
 
 
557
  $data['multisite'] = intval($id);
 
 
558
  }
559
- else {
560
- $shortMsg = 'Your site is listed on the Wordfence domain blocklist.';
561
- }
562
- $longMsg = "The URL " . esc_html($url) . " is on the blocklist.";
563
  $data['gsb'] = $badList;
564
- }
565
- else {
566
  if (is_multisite()) {
567
- $shortMsg = 'The multisite blog with ID ' . intval($id) . ' is listed on a domain blocklist.';
 
 
568
  $data['multisite'] = intval($id);
 
 
569
  }
570
- else {
571
- $shortMsg = 'Your site is listed on a domain blocklist.';
572
- }
573
- $longMsg = "The URL is: " . esc_html($url);
574
  $data['gsb'] = 'unknown';
575
  }
576
-
577
  $added = $this->addIssue('checkGSB', wfIssues::SEVERITY_CRITICAL, 'checkGSB', 'checkGSB' . $url, $shortMsg, $longMsg, $data);
578
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
579
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
580
  }
581
  }
582
  }
583
-
584
  wfIssues::statusEnd($this->statusIDX['checkGSB'], $haveIssues);
585
  $this->scanController->completeStage(wfScanner::STAGE_BLACKLIST_CHECK, $haveIssues);
586
  }
587
  }
588
-
589
  private function scan_checkHowGetIPs_init() {
590
- $this->statusIDX['checkHowGetIPs'] = wfIssues::statusStart("Checking for the most secure way to get IPs");
591
  $this->scanController->startStage(wfScanner::STAGE_SERVER_STATE);
592
  $this->checkHowGetIPsRequestTime = time();
593
  wfUtils::requestDetectProxyCallback();
594
  }
595
-
596
  private function scan_checkHowGetIPs_main() {
597
- if (!defined('WORDFENCE_CHECKHOWGETIPS_TIMEOUT')) { define('WORDFENCE_CHECKHOWGETIPS_TIMEOUT', 30); }
598
-
 
 
599
  $haveIssues = wfIssues::STATUS_SECURE;
600
  $existing = wfConfig::get('howGetIPs', '');
601
  $recommendation = wfConfig::get('detectProxyRecommendation', '');
@@ -604,50 +685,60 @@ class wfScanEngine {
604
  $this->forkIfNeeded();
605
  $recommendation = wfConfig::get('detectProxyRecommendation', '');
606
  }
607
-
608
- if ($recommendation == 'DEFERRED') {
609
  //Do nothing
610
  $haveIssues = wfIssues::STATUS_SKIPPED;
611
- }
612
- else if (empty($recommendation)) {
613
  $haveIssues = wfIssues::STATUS_FAILED;
614
- }
615
- else if ($recommendation == 'UNKNOWN') {
616
- $added = $this->addIssue('checkHowGetIPs', wfIssues::SEVERITY_HIGH, 'checkHowGetIPs', 'checkHowGetIPs' . $recommendation . WORDFENCE_VERSION, "Unable to accurately detect IPs", 'Wordfence was unable to validate a test request to your website. This can happen if your website is behind a proxy that does not use one of the standard ways to convey the IP of the request or it is unreachable publicly. IP blocking and live traffic information may not be accurate. <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_MISCONFIGURED_HOW_GET_IPS) . '" target="_blank" rel="noopener noreferrer">Get More Information</a>', array());
617
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
618
- else if ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC) { $haveIssues = wfIssues::STATUS_IGNORED; }
619
- }
620
- else if (!empty($existing) && $existing != $recommendation) {
 
 
 
 
621
  $extraMsg = '';
622
  if ($recommendation == 'REMOTE_ADDR') {
623
- $extraMsg = ' For maximum security use PHP\'s built in REMOTE_ADDR.';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
624
  }
625
- else if ($recommendation == 'HTTP_X_FORWARDED_FOR') {
626
- $extraMsg = ' This site appears to be behind a front-end proxy, so using the X-Forwarded-For HTTP header will resolve to the correct IPs.';
627
- }
628
- else if ($recommendation == 'HTTP_X_REAL_IP') {
629
- $extraMsg = ' This site appears to be behind a front-end proxy, so using the X-Real-IP HTTP header will resolve to the correct IPs.';
630
- }
631
- else if ($recommendation == 'HTTP_CF_CONNECTING_IP') {
632
- $extraMsg = ' This site appears to be behind Cloudflare, so using the Cloudflare "CF-Connecting-IP" HTTP header will resolve to the correct IPs.';
633
- }
634
-
635
- $added = $this->addIssue('checkHowGetIPs', wfIssues::SEVERITY_HIGH, 'checkHowGetIPs', 'checkHowGetIPs' . $recommendation . WORDFENCE_VERSION, "'How does Wordfence get IPs' is misconfigured", 'A test request to this website was detected on a different value for this setting. IP blocking and live traffic information may not be accurate. <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_MISCONFIGURED_HOW_GET_IPS) . '" target="_blank" rel="noopener noreferrer">Get More Information</a>' . $extraMsg, array('recommendation' => $recommendation));
636
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
637
- else if ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC) { $haveIssues = wfIssues::STATUS_IGNORED; }
638
  }
639
-
640
  wfIssues::statusEnd($this->statusIDX['checkHowGetIPs'], $haveIssues);
641
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
642
  }
643
-
644
  private function scan_checkHowGetIPs_finish() {
645
  /* Do nothing */
646
  }
647
 
648
  private function scan_checkReadableConfig() {
649
  $haveIssues = wfIssues::STATUS_SECURE;
650
- $status = wfIssues::statusStart("Check for publicly accessible configuration files, backup files and logs");
651
  $this->scanController->startStage(wfScanner::STAGE_PUBLIC_FILES);
652
 
653
  $backupFileTests = array(
@@ -678,17 +769,17 @@ class wfScanEngine {
678
  )),
679
  );
680
  $backupFileTests = array_merge($backupFileTests, wfCommonBackupFileTest::createAllForFile('searchreplacedb2.php', wfCommonBackupFileTest::MATCH_REGEX, '/<title>Search and replace DB/i'));
681
-
682
  $userIniFilename = ini_get('user_ini.filename');
683
  if ($userIniFilename && $userIniFilename !== '.user.ini') {
684
- $backupFileTests[] = wfCommonBackupFileTest::createFromRootPath($userIniFilename);
685
  }
686
 
687
 
688
  /** @var wfCommonBackupFileTest $test */
689
  foreach ($backupFileTests as $test) {
690
  $pathFromRoot = (strpos($test->getPath(), ABSPATH) === 0) ? substr($test->getPath(), strlen(ABSPATH)) : $test->getPath();
691
- wordfence::status(4, 'info', "Testing {$pathFromRoot}");
692
  if ($test->fileExists() && $test->isPubliclyAccessible()) {
693
  $key = "configReadable" . bin2hex($test->getUrl());
694
  $added = $this->addIssue(
@@ -696,16 +787,26 @@ class wfScanEngine {
696
  wfIssues::SEVERITY_CRITICAL,
697
  $key,
698
  $key,
699
- 'Publicly accessible config, backup, or log file found: ' . esc_html($pathFromRoot),
700
- '<a href="' . $test->getUrl() . '" target="_blank" rel="noopener noreferrer">' . $test->getUrl() . '</a> is publicly accessible and may expose source code or sensitive information about your site. Files such as this one are commonly checked for by scanners and should be made inaccessible. Alternately, some can be removed if you are certain your site does not need them. Sites using the nginx web server may need manual configuration changes to protect such files. <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_PUBLIC_CONFIG) . '" target="_blank" rel="noopener noreferrer">Learn more</a>',
 
 
 
 
 
 
 
701
  array(
702
  'url' => $test->getUrl(),
703
  'file' => $pathFromRoot,
704
  'canDelete' => true,
705
  )
706
  );
707
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
708
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
709
  }
710
  }
711
 
@@ -720,24 +821,25 @@ class wfScanEngine {
720
  }
721
 
722
  $haveIssues = wfIssues::STATUS_SECURE;
723
- $status = wfIssues::statusStart("Checking if your server discloses the path to the document root");
724
  $testPage = includes_url() . basename($file);
725
 
726
  if (self::testForFullPathDisclosure($testPage, $file)) {
727
- $key = 'wpscan_fullPathDisclosure' . $testPage;
728
  $added = $this->addIssue(
729
  'wpscan_fullPathDisclosure',
730
  wfIssues::SEVERITY_HIGH,
731
  $key,
732
  $key,
733
- 'Web server exposes the document root',
734
- 'Full Path Disclosure (FPD) vulnerabilities enable the attacker to see the path to the webroot/file. e.g.:
735
- /home/user/htdocs/file/. Certain vulnerabilities, such as using the load_file() (within a SQL Injection)
736
- query to view the page source, require the attacker to have the full path to the file they wish to view.',
737
  array('url' => $testPage)
738
  );
739
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
740
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
741
  }
742
 
743
  wfIssues::statusEnd($status, $haveIssues);
@@ -756,70 +858,83 @@ class wfScanEngine {
756
  wfIssues::SEVERITY_HIGH,
757
  'wpscan_directoryListingEnabled',
758
  'wpscan_directoryListingEnabled',
759
- "Directory listing is enabled",
760
- "Directory listing provides an attacker with the complete index of all the resources located inside of the directory. The specific risks and consequences vary depending on which files are listed and accessible, but it is recommended that you disable it unless it is needed.",
761
  array(
762
  'url' => $uploadPaths['baseurl'],
763
  )
764
  );
765
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
766
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
767
  }
768
  wfIssues::statusEnd($this->statusIDX['wpscan_directoryListingEnabled'], $haveIssues);
769
  }
770
 
771
  private function scan_checkSpamvertized() {
772
  if ($this->scanController->isPremiumScan()) {
773
- $this->statusIDX['spamvertizeCheck'] = wfIssues::statusStart("Checking if your site is being Spamvertised");
774
  $this->scanController->startStage(wfScanner::STAGE_SPAMVERTISING_CHECKS);
775
  $result = $this->api->call('spamvertize_check', array(), array(
776
  'siteURL' => site_url()
777
- ));
778
  $haveIssues = wfIssues::STATUS_SECURE;
779
- if($result['haveIssues'] && is_array($result['issues']) ){
780
- foreach($result['issues'] as $issue){
781
  $added = $this->addIssue($issue['type'], wfIssues::SEVERITY_CRITICAL, $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
782
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
783
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
784
  }
785
  }
786
  wfIssues::statusEnd($this->statusIDX['spamvertizeCheck'], $haveIssues);
787
  $this->scanController->completeStage(wfScanner::STAGE_SPAMVERTISING_CHECKS, $haveIssues);
788
- }
789
- else {
790
- wfIssues::statusPaidOnly("Check if your site is being Spamvertized is for paid members only");
791
  sleep(2);
792
  }
793
  }
 
794
  private function _scannedSkippedPaths() {
795
  static $_cache = null;
796
  if ($_cache === null) {
797
  $base_abspath_relative = array('.htaccess', 'index.php', 'license.txt', 'readme.html', 'wp-activate.php', 'wp-admin', 'wp-app.php', 'wp-blog-header.php', 'wp-comments-post.php', 'wp-config-sample.php', 'wp-content', 'wp-cron.php', 'wp-includes', 'wp-links-opml.php', 'wp-load.php', 'wp-login.php', 'wp-mail.php', 'wp-pass.php', 'wp-register.php', 'wp-settings.php', 'wp-signup.php', 'wp-trackback.php', 'xmlrpc.php', '.well-known', 'cgi-bin');
798
  $base_absolute = array();
799
- if (defined('WP_CONTENT_DIR') && strlen(WP_CONTENT_DIR)) { $base_absolute[] = WP_CONTENT_DIR; }
800
- if (defined('WP_PLUGIN_DIR') && strlen(WP_PLUGIN_DIR)) { $base_absolute[] = WP_PLUGIN_DIR; }
801
- if (defined('UPLOADS') && strlen(UPLOADS)) { $base_absolute[] = ABSPATH . UPLOADS; /* UPLOADS is relative to ABSPATH unlike the others */ }
 
 
 
 
 
 
802
  $baseContents = scandir(ABSPATH);
803
  if (!is_array($baseContents)) {
804
- throw new Exception("Wordfence could not read the contents of your base WordPress directory. This usually indicates your permissions are so strict that your web server can't read your WordPress directory.");
805
  }
806
-
807
  $scanOutside = $this->scanController->scanOutsideWordPress();
808
  if ($scanOutside) {
809
  $_cache = array('scanned' => array_merge(array(ABSPATH), $base_absolute), 'skipped' => array());
810
  return $_cache;
811
  }
812
-
813
  $scanned = array();
814
  $skipped = array();
815
  foreach ($baseContents as $file) { //Only include base files less than a meg that are files.
816
- if ($file == '.' || $file == '..') { continue; }
 
 
817
  $fullFile = rtrim(ABSPATH, '/') . '/' . $file;
818
  if (!wfUtils::fileTooBig($fullFile)) { //Silently ignore files that are too large for the purposes of inclusion in the scan issue
819
  if (in_array($file, $base_abspath_relative) || in_array($fullFile, $base_absolute) || (@is_file($fullFile) && @is_readable($fullFile))) {
820
  $scanned[] = realpath($fullFile);
821
- }
822
- else {
823
  $skipped[] = $fullFile;
824
  }
825
  }
@@ -834,11 +949,12 @@ class wfScanEngine {
834
  }
835
  return $_cache;
836
  }
 
837
  private function scan_checkSkippedFiles() {
838
  $haveIssues = wfIssues::STATUS_SECURE;
839
- $status = wfIssues::statusStart("Checking for paths skipped due to scan settings");
840
  $this->scanController->startStage(wfScanner::STAGE_SERVER_STATE);
841
-
842
  $paths = $this->_scannedSkippedPaths();
843
  if (!empty($paths['skipped'])) {
844
  $skippedList = '';
@@ -847,27 +963,25 @@ class wfScanEngine {
847
  if (strpos($fullPath, ABSPATH) === 0) {
848
  $path = '~/' . esc_html(substr($fullPath, strlen(ABSPATH)));
849
  }
850
-
851
  if ($index >= 10) {
852
- $skippedList .= sprintf(__(', and %d more.', 'wordfence'), count($paths['skipped']) - 10);
853
  break;
854
  }
855
-
856
  if (!empty($skippedList)) {
857
  if (count($paths['skipped']) == 2) {
858
  $skippedList .= ' and ';
859
- }
860
- else if ($index == count($paths['skipped']) - 1) {
861
  $skippedList .= ', and ';
862
- }
863
- else {
864
  $skippedList .= ', ';
865
  }
866
  }
867
-
868
  $skippedList .= $path;
869
  }
870
-
871
  $c = count($paths['skipped']);
872
  $key = "skippedPaths";
873
  $added = $this->addIssue(
@@ -875,104 +989,126 @@ class wfScanEngine {
875
  wfIssues::SEVERITY_LOW,
876
  $key,
877
  $key,
878
- sprintf($c == 1 ? __('%d path was skipped for the malware scan due to scan settings', 'wordfence') : __('%d paths were skipped for the malware scan due to scan settings', 'wordfence'), $c),
879
- sprintf($c == 1 ? __('The option "Scan files outside your WordPress installation" is off by default, which means %d path and its file(s) will not be scanned for malware or unauthorized changes. To continue skipping this path, you may ignore this issue. Or to start scanning it, enable the option and subsequent scans will include it. Some paths may not be necessary to scan, so this is optional. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a><br><br>The path skipped is %s', 'wordfence') : __('The option "Scan files outside your WordPress installation" is off by default, which means %d paths and their file(s) will not be scanned for malware or unauthorized changes. To continue skipping these paths, you may ignore this issue. Or to start scanning them, enable the option and subsequent scans will include them. Some paths may not be necessary to scan, so this is optional. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a><br><br>The paths skipped are %s', 'wordfence'), $c, wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_SKIPPED_PATHS), $skippedList),
 
 
 
 
 
 
 
 
 
 
 
880
  array()
881
  );
882
-
883
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
884
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
885
  }
886
-
887
  wfIssues::statusEnd($status, $haveIssues);
888
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
889
  }
890
- private function scan_knownFiles_init(){
 
891
  $paths = $this->_scannedSkippedPaths();
892
  $includeInKnownFilesScan = $paths['scanned'];
893
  if ($this->scanController->scanOutsideWordPress()) {
894
- wordfence::status(2, 'info', "Including files that are outside the WordPress installation in the scan.");
895
  }
896
 
897
- $this->status(2, 'info', "Getting plugin list from WordPress");
898
  $knownFilesPlugins = $this->getPlugins();
899
- $this->status(2, 'info', "Found " . sizeof($knownFilesPlugins) . " plugins");
900
 
901
- $this->status(2, 'info', "Getting theme list from WordPress");
902
  $knownFilesThemes = $this->getThemes();
903
- $this->status(2, 'info', "Found " . sizeof($knownFilesThemes) . " themes");
904
 
905
  $this->hasher = new wordfenceHash(strlen(ABSPATH), ABSPATH, $includeInKnownFilesScan, $knownFilesThemes, $knownFilesPlugins, $this, wfUtils::hex2bin($this->malwarePrefixesHash), $this->coreHashesHash, $this->scanMode);
906
  }
 
907
  private function scan_knownFiles_main() {
908
  $this->hasher->run($this); //Include this so we can call addIssue and ->api->
909
  $this->suspectedFiles = $this->hasher->getSuspectedFiles();
910
  $this->hasher = false;
911
  }
 
912
  private function scan_knownFiles_finish() {
913
  }
 
914
  private function scan_fileContents_init() {
915
  $options = $this->scanController->scanOptions();
916
  if ($options['scansEnabled_fileContents']) {
917
- $this->statusIDX['infect'] = wfIssues::statusStart('Scanning file contents for infections and vulnerabilities');
918
  //This stage is marked as started earlier in the hasher rather than here
 
 
919
  }
920
- else {
921
- wfIssues::statusDisabled("Skipping scan of file contents for infections and vulnerabilities");
922
- }
923
-
924
  if ($options['scansEnabled_fileContentsGSB']) {
925
- $this->statusIDX['GSB'] = wfIssues::statusStart('Scanning file contents for URLs on a domain blocklist');
926
  //This stage is marked as started earlier in the hasher rather than here
 
 
927
  }
928
- else {
929
- wfIssues::statusDisabled("Skipping scan of file contents for URLs on a domain blocklist");
930
- }
931
-
932
  if ($options['scansEnabled_fileContents'] || $options['scansEnabled_fileContentsGSB']) {
933
  $this->scanner = new wordfenceScanner($this->apiKey, $this->wp_version, ABSPATH, $this);
934
- $this->status(2, 'info', "Starting scan of file contents");
935
- }
936
- else {
937
  $this->scanner = false;
938
  }
939
  }
 
940
  private function scan_fileContents_main() {
941
  $options = $this->scanController->scanOptions();
942
  if ($options['scansEnabled_fileContents'] || $options['scansEnabled_fileContentsGSB']) {
943
  $this->fileContentsResults = $this->scanner->scan($this);
944
  }
945
  }
 
946
  private function scan_fileContents_finish() {
947
  $options = $this->scanController->scanOptions();
948
  if ($options['scansEnabled_fileContents'] || $options['scansEnabled_fileContentsGSB']) {
949
- $this->status(2, 'info', "Done file contents scan");
950
- if($this->scanner->errorMsg){
951
  throw new Exception($this->scanner->errorMsg);
952
  }
953
  $this->scanner = null;
954
  $haveIssues = wfIssues::STATUS_SECURE;
955
  $haveIssuesGSB = wfIssues::STATUS_SECURE;
956
- foreach($this->fileContentsResults as $issue){
957
- $this->status(2, 'info', "Adding issue: " . $issue['shortMsg']);
958
  $added = $this->addIssue($issue['type'], $issue['severity'], $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
959
-
960
  if (isset($issue['data']['gsb'])) {
961
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssuesGSB = wfIssues::STATUS_PROBLEM; }
962
- else if ($haveIssuesGSB != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssuesGSB = wfIssues::STATUS_IGNORED; }
963
- }
964
- else {
965
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
966
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
 
 
967
  }
968
  }
969
  $this->fileContentsResults = null;
970
-
971
  if ($options['scansEnabled_fileContents']) {
972
  wfIssues::statusEnd($this->statusIDX['infect'], $haveIssues);
973
  $this->scanController->completeStage(wfScanner::STAGE_MALWARE_SCAN, $haveIssues);
974
  }
975
-
976
  if ($options['scansEnabled_fileContentsGSB']) {
977
  wfIssues::statusEnd($this->statusIDX['GSB'], $haveIssuesGSB);
978
  $this->scanController->completeStage(wfScanner::STAGE_CONTENT_SAFETY, $haveIssuesGSB);
@@ -982,12 +1118,12 @@ class wfScanEngine {
982
 
983
  private function scan_suspectedFiles() {
984
  $haveIssues = wfIssues::STATUS_SECURE;
985
- $status = wfIssues::statusStart("Scanning for publicly accessible quarantined files");
986
  $this->scanController->startStage(wfScanner::STAGE_PUBLIC_FILES);
987
-
988
  if (is_array($this->suspectedFiles) && count($this->suspectedFiles) > 0) {
989
  foreach ($this->suspectedFiles as $file) {
990
- wordfence::status(4, 'info', "Testing accessibility of: $file");
991
  $test = wfPubliclyAccessibleFileTest::createFromRootPath($file);
992
  if ($test->fileExists() && $test->isPubliclyAccessible()) {
993
  $key = "publiclyAccessible" . bin2hex($test->getUrl());
@@ -996,39 +1132,47 @@ class wfScanEngine {
996
  wfIssues::SEVERITY_HIGH,
997
  $key,
998
  $key,
999
- 'Publicly accessible quarantined file found: ' . esc_html($file),
1000
- '<a href="' . $test->getUrl() . '" target="_blank" rel="noopener noreferrer">' . $test->getUrl() . '</a> is publicly accessible and may expose source code or sensitive information about your site. Files such as this one are commonly checked for by scanners and should be removed or made inaccessible.',
 
 
 
 
1001
  array(
1002
  'url' => $test->getUrl(),
1003
  'file' => $file,
1004
  'canDelete' => true,
1005
  )
1006
  );
1007
-
1008
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1009
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
1010
  }
1011
  }
1012
  }
1013
-
1014
  wfIssues::statusEnd($status, $haveIssues);
1015
  $this->scanController->completeStage(wfScanner::STAGE_PUBLIC_FILES, $haveIssues);
1016
  }
1017
 
1018
  private function scan_posts_init() {
1019
- $this->statusIDX['posts'] = wfIssues::statusStart('Scanning posts for URLs on a domain blocklist');
1020
  $this->scanController->startStage(wfScanner::STAGE_CONTENT_SAFETY);
1021
  $blogsToScan = self::getBlogsToScan('posts');
1022
  $this->scanQueue = '';
1023
  $wfdb = new wfDB();
1024
  $this->hoover = new wordfenceURLHoover($this->apiKey, $this->wp_version);
1025
- foreach($blogsToScan as $blog){
1026
  $q1 = $wfdb->querySelect("select ID from " . $blog['table'] . " where post_type IN ('page', 'post') and post_status = 'publish'");
1027
- foreach($q1 as $idRow){
1028
  $this->scanQueue .= pack('LL', $blog['blog_id'], $idRow['ID']);
1029
  }
1030
  }
1031
  }
 
1032
  private function scan_posts_main() {
1033
  global $wpdb;
1034
  $wfdb = new wfDB();
@@ -1038,46 +1182,55 @@ class wfScanEngine {
1038
  $elem = unpack('Lblog/Lpost', $segment);
1039
  $queueSize = strlen($this->scanQueue) / 8;
1040
  if ($queueSize > 0 && $queueSize % 1000 == 0) {
1041
- wordfence::status(2, 'info', "Scanning posts with {$queueSize} left to scan.");
1042
  }
1043
-
1044
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_POSTS);
1045
-
1046
  $blogID = $elem['blog'];
1047
  $postID = $elem['post'];
1048
-
1049
  $blogs = self::getBlogsToScan('posts', $blogID);
1050
  $blog = array_shift($blogs);
1051
-
1052
  $table = wfDB::blogTable('posts', $blogID);
1053
-
1054
  $row = $wfdb->querySingleRec("select ID, post_title, post_type, post_date, post_content from {$table} where ID = %d", $postID);
1055
  $found = $this->hoover->hoover($blogID . '-' . $row['ID'], $row['post_title'] . ' ' . $row['post_content'], wordfenceURLHoover::standardExcludedHosts());
1056
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, $found);
1057
  if (preg_match('/(?:<[\s\n\r\t]*script[\r\s\n\t]+.*>|<[\s\n\r\t]*meta.*refresh)/i', $row['post_title'])) {
1058
- $this->addIssue('postBadTitle', wfIssues::SEVERITY_HIGH, $row['ID'], md5($row['post_title']), "Post title contains suspicious code", "This post contains code that is suspicious. Please check the title of the post and confirm that the code in the title is not malicious.", array(
1059
- 'postID' => $postID,
1060
- 'postTitle' => $row['post_title'],
1061
- 'permalink' => get_permalink($postID),
1062
- 'editPostLink' => get_edit_post_link($postID),
1063
- 'type' => $row['post_type'],
1064
- 'postDate' => $row['post_date'],
1065
- 'isMultisite' => $blog['isMultisite'],
1066
- 'domain' => $blog['domain'],
1067
- 'path' => $blog['path'],
1068
- 'blog_id' => $blog['blog_id']
1069
- ));
 
 
 
 
 
 
 
 
1070
  }
1071
-
1072
  $this->forkIfNeeded();
1073
  }
1074
  }
 
1075
  private function scan_posts_finish() {
1076
  global $wpdb;
1077
  $wfdb = new wfDB();
1078
- $this->status(2, 'info', "Examining URLs found in posts we scanned for dangerous websites");
1079
  $hooverResults = $this->hoover->getBaddies();
1080
- $this->status(2, 'info', "Done examining URLs");
1081
  if ($this->hoover->errorMsg) {
1082
  wfIssues::statusEndErr();
1083
  throw new Exception($this->hoover->errorMsg);
@@ -1095,12 +1248,12 @@ class wfScanEngine {
1095
  if ($result['badList'] != 'goog-malware-shavar' && $result['badList'] != 'googpub-phish-shavar' && $result['badList'] != 'wordfence-dbl') {
1096
  continue; //A list type that may be new and the plugin has not been upgraded yet.
1097
  }
1098
-
1099
  if ($blog === null) {
1100
  $blogs = self::getBlogsToScan('posts', $blogID);
1101
  $blog = array_shift($blogs);
1102
  }
1103
-
1104
  if ($post === null) {
1105
  $post = $wfdb->querySingleRec("select ID, post_title, post_type, post_date, post_content from {$table} where ID = %d", $postID);
1106
  $type = $post['post_type'] ? $post['post_type'] : 'comment';
@@ -1109,46 +1262,67 @@ class wfScanEngine {
1109
  $title = $post['post_title'];
1110
  $contentMD5 = md5($post['post_content']);
1111
  }
1112
-
1113
  if ($result['badList'] == 'goog-malware-shavar') {
1114
- $shortMsg = "{$uctype} contains a suspected malware URL: " . esc_html($title);
1115
- $longMsg = "This " . esc_html($type) . " contains a suspected malware URL listed on Google's list of malware sites. The URL is: " . esc_html($result['URL']) . " - More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=" . urlencode($result['URL']) . "&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>.";
1116
- }
1117
- else if ($result['badList'] == 'googpub-phish-shavar') {
1118
- $shortMsg = "{$uctype} contains a suspected phishing site URL: " . esc_html($title);
1119
- $longMsg = "This " . esc_html($type) . " contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. The URL is: " . esc_html($result['URL']);
1120
- }
1121
- else if ($result['badList'] == 'wordfence-dbl') {
1122
- $shortMsg = "{$uctype} contains a suspected malware URL: " . esc_html($title);
1123
- $longMsg = "This " . esc_html($type) . " contains a URL that is currently listed on Wordfence's domain blocklist. The URL is: " . esc_html($result['URL']);
1124
- }
1125
- else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1126
  //A list type that may be new and the plugin has not been upgraded yet.
1127
  continue;
1128
  }
1129
-
1130
- $this->status(2, 'info', "Adding issue: $shortMsg");
1131
  if (is_multisite()) {
1132
  switch_to_blog($blogID);
1133
  }
1134
  $ignoreP = $idString;
1135
  $ignoreC = $idString . $contentMD5;
1136
  $added = $this->addIssue('postBadURL', wfIssues::SEVERITY_HIGH, $ignoreP, $ignoreC, $shortMsg, $longMsg, array(
1137
- 'postID' => $postID,
1138
- 'badURL' => $result['URL'],
1139
- 'postTitle' => $title,
1140
- 'type' => $type,
1141
- 'uctype' => $uctype,
1142
- 'permalink' => get_permalink($postID),
1143
  'editPostLink' => get_edit_post_link($postID),
1144
- 'postDate' => $postDate,
1145
- 'isMultisite' => $blog['isMultisite'],
1146
- 'domain' => $blog['domain'],
1147
- 'path' => $blog['path'],
1148
- 'blog_id' => $blogID
1149
  ));
1150
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1151
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
1152
  if (is_multisite()) {
1153
  restore_current_blog();
1154
  }
@@ -1158,22 +1332,24 @@ class wfScanEngine {
1158
  $this->scanController->completeStage(wfScanner::STAGE_CONTENT_SAFETY, $haveIssues);
1159
  $this->scanQueue = '';
1160
  }
1161
- private function scan_comments_init(){
1162
- $this->statusIDX['comments'] = wfIssues::statusStart('Scanning comments for URLs on a domain blocklist');
 
1163
  $this->scanController->startStage(wfScanner::STAGE_CONTENT_SAFETY);
1164
  $this->scanData = array();
1165
  $this->scanQueue = '';
1166
  $this->hoover = new wordfenceURLHoover($this->apiKey, $this->wp_version);
1167
  $blogsToScan = self::getBlogsToScan('comments');
1168
  $wfdb = new wfDB();
1169
- foreach($blogsToScan as $blog){
1170
  $q1 = $wfdb->querySelect("select comment_ID from " . $blog['table'] . " where comment_approved=1");
1171
- foreach($q1 as $idRow){
1172
  $this->scanQueue .= pack('LL', $blog['blog_id'], $idRow['comment_ID']);
1173
  }
1174
  }
1175
  }
1176
- private function scan_comments_main(){
 
1177
  global $wpdb;
1178
  $wfdb = new wfDB();
1179
  while (strlen($this->scanQueue) > 0) {
@@ -1182,47 +1358,48 @@ class wfScanEngine {
1182
  $elem = unpack('Lblog/Lcomment', $segment);
1183
  $queueSize = strlen($this->scanQueue) / 8;
1184
  if ($queueSize > 0 && $queueSize % 1000 == 0) {
1185
- wordfence::status(2, 'info', "Scanning comments with {$queueSize} left to scan.");
1186
  }
1187
-
1188
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_COMMENTS);
1189
-
1190
  $blogID = $elem['blog'];
1191
  $commentID = $elem['comment'];
1192
-
1193
  $table = wfDB::blogTable('comments', $blogID);
1194
-
1195
  $row = $wfdb->querySingleRec("select comment_ID, comment_date, comment_type, comment_author, comment_author_url, comment_content from {$table} where comment_ID=%d", $commentID);
1196
  $found = $this->hoover->hoover($blogID . '-' . $row['comment_ID'], $row['comment_author_url'] . ' ' . $row['comment_author'] . ' ' . $row['comment_content'], wordfenceURLHoover::standardExcludedHosts());
1197
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, $found);
1198
  $this->forkIfNeeded();
1199
  }
1200
  }
1201
- private function scan_comments_finish(){
 
1202
  $wfdb = new wfDB();
1203
  $hooverResults = $this->hoover->getBaddies();
1204
- if($this->hoover->errorMsg){
1205
  wfIssues::statusEndErr();
1206
  throw new Exception($this->hoover->errorMsg);
1207
  }
1208
  $this->hoover->cleanup();
1209
  $haveIssues = wfIssues::STATUS_SECURE;
1210
- foreach($hooverResults as $idString => $hresults){
1211
  $arr = explode('-', $idString);
1212
  $blogID = $arr[0];
1213
  $commentID = $arr[1];
1214
  $blog = null;
1215
  $comment = null;
1216
  foreach ($hresults as $result) {
1217
- if ($result['badList'] != 'goog-malware-shavar' && $result['badList'] != 'googpub-phish-shavar' && $result['badList'] != 'wordfence-dbl') {
1218
  continue; //A list type that may be new and the plugin has not been upgraded yet.
1219
  }
1220
-
1221
  if ($blog === null) {
1222
  $blogs = self::getBlogsToScan('comments', $blogID);
1223
  $blog = array_shift($blogs);
1224
  }
1225
-
1226
  if ($comment === null) {
1227
  $comment = $wfdb->querySingleRec("select comment_ID, comment_date, comment_type, comment_author, comment_author_url, comment_content from " . $blog['table'] . " where comment_ID=%d", $commentID);
1228
  $type = $comment['comment_type'] ? $comment['comment_type'] : 'comment';
@@ -1231,43 +1408,62 @@ class wfScanEngine {
1231
  $date = $comment['comment_date'];
1232
  $contentMD5 = md5($comment['comment_content'] . $comment['comment_author'] . $comment['comment_author_url']);
1233
  }
1234
-
1235
  if ($result['badList'] == 'goog-malware-shavar') {
1236
- $shortMsg = "$uctype with author " . esc_html($author) . " contains a suspected malware URL.";
1237
- $longMsg = "This " . esc_html($type) . " contains a suspected malware URL listed on Google's list of malware sites. The URL is: " . esc_html($result['URL']) . " - More info available at <a href=\"http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=" . urlencode($result['URL']) . "&client=googlechrome&hl=en-US\" target=\"_blank\" rel=\"noopener noreferrer\">Google Safe Browsing diagnostic page</a>.";
1238
- }
1239
- else if ($result['badList'] == 'googpub-phish-shavar') {
1240
- $shortMsg = "$uctype contains a suspected phishing site URL.";
1241
- $longMsg = "This " . esc_html($type) . " contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. The URL is: " . esc_html($result['URL']);
1242
- }
1243
- else if ($result['badList'] == 'wordfence-dbl') {
1244
- $shortMsg = "$uctype contains a suspected malware URL.";
1245
- $longMsg = "This " . esc_html($type) . " contains a URL that is currently listed on Wordfence's domain blocklist. The URL is: " . esc_html($result['URL']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1246
  }
1247
-
1248
- if(is_multisite()){
1249
  switch_to_blog($blogID);
1250
  }
1251
-
1252
  $ignoreP = $idString;
1253
  $ignoreC = $idString . '-' . $contentMD5;
1254
  $added = $this->addIssue('commentBadURL', wfIssues::SEVERITY_LOW, $ignoreP, $ignoreC, $shortMsg, $longMsg, array(
1255
- 'commentID' => $commentID,
1256
- 'badURL' => $result['URL'],
1257
- 'author' => $author,
1258
- 'type' => $type,
1259
- 'uctype' => $uctype,
1260
  'editCommentLink' => get_edit_comment_link($commentID),
1261
- 'commentDate' => $date,
1262
- 'isMultisite' => $blog['isMultisite'],
1263
- 'domain' => $blog['domain'],
1264
- 'path' => $blog['path'],
1265
- 'blog_id' => $blogID
1266
- ));
1267
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1268
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
1269
-
1270
- if(is_multisite()){
 
 
 
1271
  restore_current_blog();
1272
  }
1273
  }
@@ -1276,94 +1472,95 @@ class wfScanEngine {
1276
  $this->scanController->completeStage(wfScanner::STAGE_CONTENT_SAFETY, $haveIssues);
1277
  $this->scanQueue = '';
1278
  }
1279
- public function isBadComment($author, $email, $url, $IP, $content){
 
1280
  $content = $author . ' ' . $email . ' ' . $url . ' ' . $IP . ' ' . $content;
1281
  $cDesc = '';
1282
- if($author){
1283
- $cDesc = "Author: $author ";
1284
  }
1285
- if($email){
1286
- $cDesc .= "Email: $email ";
1287
  }
1288
- $cDesc .= "Source IP: $IP ";
1289
- $this->status(2, 'info', "Scanning comment with $cDesc");
1290
 
1291
  $h = new wordfenceURLHoover($this->apiKey, $this->wp_version);
1292
  $h->hoover(1, $content, wordfenceURLHoover::standardExcludedHosts());
1293
  $hooverResults = $h->getBaddies();
1294
- if($h->errorMsg){
1295
  return false;
1296
  }
1297
  $h->cleanup();
1298
- if(sizeof($hooverResults) > 0 && isset($hooverResults[1])){
1299
- $hresults = $hooverResults[1];
1300
- foreach($hresults as $result){
1301
- if($result['badList'] == 'goog-malware-shavar'){
1302
- $this->status(2, 'info', "Marking comment as spam for containing a malware URL. Comment has $cDesc");
1303
  return true;
1304
- }
1305
- else if($result['badList'] == 'googpub-phish-shavar'){
1306
- $this->status(2, 'info', "Marking comment as spam for containing a phishing URL. Comment has $cDesc");
1307
  return true;
1308
- }
1309
- else if ($result['badList'] == 'wordfence-dbl') {
1310
- $this->status(2, 'info', "Marking comment as spam for containing a malware URL. Comment has $cDesc");
1311
- }
1312
- else {
1313
  //A list type that may be new and the plugin has not been upgraded yet.
1314
  continue;
1315
  }
1316
  }
1317
  }
1318
- $this->status(2, 'info', "Scanned comment with $cDesc");
1319
  return false;
1320
  }
1321
- public static function getBlogsToScan($table, $withID = null){
 
1322
  $wfdb = new wfDB();
1323
  global $wpdb;
1324
  $blogsToScan = array();
1325
- if(is_multisite()){
1326
  if ($withID === null) {
1327
  $q1 = $wfdb->querySelect("select blog_id, domain, path from {$wpdb->blogs} where deleted=0 order by blog_id asc");
1328
- }
1329
- else {
1330
  $q1 = $wfdb->querySelect("select blog_id, domain, path from {$wpdb->blogs} where deleted=0 and blog_id = %d", $withID);
1331
  }
1332
-
1333
- foreach($q1 as $row){
1334
  $row['isMultisite'] = true;
1335
  $row['table'] = wfDB::blogTable($table, $row['blog_id']);
1336
- $blogsToScan[] = $row;
1337
  }
1338
  } else {
1339
  $blogsToScan[] = array(
1340
  'isMultisite' => false,
1341
- 'table' => wfDB::networkTable($table),
1342
- 'blog_id' => '1',
1343
- 'domain' => '',
1344
- 'path' => '',
1345
- );
1346
  }
1347
  return $blogsToScan;
1348
  }
1349
- private function highestCap($caps){
1350
- foreach(array('administrator', 'editor', 'author', 'contributor', 'subscriber') as $cap){
1351
- if(empty($caps[$cap]) === false && $caps[$cap]){
 
1352
  return $cap;
1353
  }
1354
  }
1355
  return '';
1356
  }
1357
- private function isEditor($caps){
1358
- foreach(array('contributor', 'author', 'editor', 'administrator') as $cap){
1359
- if(empty($caps[$cap]) === false && $caps[$cap]){
 
1360
  return true;
1361
  }
1362
  }
1363
  return false;
1364
  }
1365
- private function scan_passwds_init(){
1366
- $this->statusIDX['passwds'] = wfIssues::statusStart('Scanning for weak passwords');
 
1367
  $this->scanController->startStage(wfScanner::STAGE_PASSWORD_STRENGTH);
1368
  global $wpdb;
1369
  $counter = 0;
@@ -1374,89 +1571,124 @@ class wfScanEngine {
1374
  $result = $dbh->query($query);
1375
  if (!is_object($result)) {
1376
  return array(
1377
- 'errorMsg' => "We were unable to generate the user list for your password check.",
1378
  );
1379
  }
1380
  while ($rec = $result->fetch_assoc()) {
1381
  $this->userPasswdQueue .= pack('N', $rec['ID']);
1382
  $counter++;
1383
  }
1384
- }
1385
- else {
1386
  $res1 = $wpdb->get_results($query, ARRAY_A);
1387
- foreach($res1 as $rec){
1388
  $this->userPasswdQueue .= pack('N', $rec['ID']);
1389
  $counter++;
1390
  }
1391
  }
1392
- wordfence::status(2, 'info', "Starting password strength check on {$counter} users.");
 
 
1393
  }
1394
- private function scan_passwds_main(){
1395
- while(strlen($this->userPasswdQueue) > 3){
 
1396
  $usersLeft = strlen($this->userPasswdQueue) / 4; //4 byte ints
1397
- if($usersLeft % 100 == 0){
1398
- wordfence::status(2, 'info', "Total of {$usersLeft} users left to process in password strength check.");
 
 
 
 
 
 
 
 
1399
  }
1400
  $userID = unpack('N', substr($this->userPasswdQueue, 0, 4));
1401
  $userID = $userID[1];
1402
  $this->userPasswdQueue = substr($this->userPasswdQueue, 4);
1403
  $state = $this->scanUserPassword($userID);
1404
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_USERS);
1405
- if ($state == wfIssues::STATUS_PROBLEM) { $this->passwdHasIssues = wfIssues::STATUS_PROBLEM; }
1406
- else if ($this->passwdHasIssues != wfIssues::STATUS_PROBLEM && $state == wfIssues::STATUS_IGNORED) { $this->passwdHasIssues = wfIssues::STATUS_IGNORED; }
1407
-
 
 
 
1408
  $this->forkIfNeeded();
1409
  }
1410
  }
1411
- private function scan_passwds_finish(){
 
1412
  wfIssues::statusEnd($this->statusIDX['passwds'], $this->passwdHasIssues);
1413
  $this->scanController->completeStage(wfScanner::STAGE_PASSWORD_STRENGTH, $this->passwdHasIssues);
1414
  }
1415
- public function scanUserPassword($userID){
 
1416
  $suspended = wp_suspend_cache_addition();
1417
  wp_suspend_cache_addition(true);
1418
  require_once(ABSPATH . 'wp-includes/class-phpass.php');
1419
  $passwdHasher = new PasswordHash(8, TRUE);
1420
  $userDat = get_userdata($userID);
1421
  if ($userDat === false) {
1422
- wordfence::status(2, 'error', "Could not get username for user with ID {$userID} when checking password strength.");
1423
  return false;
1424
  }
1425
  //user_login
1426
- $this->status(4, 'info', "Checking password strength of user '" . $userDat->user_login . "' with ID {$userID}" . (function_exists('memory_get_usage') ? " (Mem:" . sprintf('%.1f', memory_get_usage(true) / (1024 * 1024)) . "M)" : ""));
 
 
 
 
 
1427
  $highCap = $this->highestCap($userDat->wp_capabilities);
1428
- if($this->isEditor($userDat->wp_capabilities)){
1429
- $shortMsg = "User \"" . esc_html($userDat->user_login) . "\" with \"" . esc_html($highCap) . "\" access has an easy password.";
1430
- $longMsg = "A user with the a role of '" . esc_html($highCap) . "' has a password that is easy to guess. Please change this password yourself or ask the user to change it.";
 
 
 
 
 
 
 
 
 
1431
  $level = wfIssues::SEVERITY_CRITICAL;
1432
  $words = $this->dictWords;
1433
  } else {
1434
- $shortMsg = "User \"" . esc_html($userDat->user_login) . "\" with 'subscriber' access has a very easy password.";
1435
- $longMsg = "A user with 'subscriber' access has a password that is very easy to guess. Please either change it or ask the user to change their password.";
 
 
1436
  $level = wfIssues::SEVERITY_HIGH;
1437
  $words = array($userDat->user_login);
1438
  }
1439
  $haveIssues = wfIssues::STATUS_SECURE;
1440
- for($i = 0; $i < sizeof($words); $i++){
1441
- if($passwdHasher->CheckPassword($words[$i], $userDat->user_pass)){
1442
- $this->status(2, 'info', "Adding issue " . $shortMsg);
1443
  $added = $this->addIssue('easyPassword', $level, $userDat->ID, $userDat->ID . '-' . $userDat->user_pass, $shortMsg, $longMsg, array(
1444
- 'ID' => $userDat->ID,
1445
- 'user_login' => $userDat->user_login,
1446
- 'user_email' => $userDat->user_email,
1447
- 'first_name' => $userDat->first_name,
1448
- 'last_name' => $userDat->last_name,
1449
  'editUserLink' => wfUtils::editUserLink($userDat->ID)
1450
- ));
1451
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1452
- else if ($haveIssues != wfIssues::STATUS_SECURE && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
1453
  break;
1454
  }
1455
  }
1456
- $this->status(4, 'info', "Completed checking password strength of user '" . $userDat->user_login . "'");
1457
  wp_suspend_cache_addition($suspended);
1458
  return $haveIssues;
1459
  }
 
1460
  /*
1461
  private function scan_sitePages(){
1462
  if(is_multisite()){ return; } //Multisite not supported by this function yet
@@ -1497,40 +1729,47 @@ class wfScanEngine {
1497
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, wfIssues::STATUS_SECURE);
1498
  return;
1499
  }
1500
-
1501
-
1502
- $this->status(2, 'info', sprintf(__('Total disk space: %s -- Free disk space: %s', 'wordfence'), wfUtils::formatBytes($total), wfUtils::formatBytes($free)));
 
 
 
 
 
1503
  $freeMegs = round($free / 1024 / 1024, 2);
1504
- $this->status(2, 'info', sprintf(__('The disk has %s MB available', 'wordfence'), $freeMegs));
1505
  if ($freeMegs < 5) {
1506
  $level = wfIssues::SEVERITY_CRITICAL;
1507
- }
1508
- else if ($freeMegs < 20) {
1509
  $level = wfIssues::SEVERITY_HIGH;
1510
- }
1511
- else {
1512
  wfIssues::statusEnd($this->statusIDX['diskSpace'], wfIssues::STATUS_SECURE);
1513
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, wfIssues::STATUS_SECURE);
1514
  return;
1515
  }
1516
  $haveIssues = wfIssues::STATUS_SECURE;
1517
- $added = $this->addIssue('diskSpace',
1518
- $level,
1519
- 'diskSpace',
1520
- 'diskSpace' . $level,
1521
- sprintf(__('You have %s disk space remaining', 'wordfence'), wfUtils::formatBytes($free)),
1522
- sprintf(__('You only have %s of your disk space remaining. Please free up disk space or your website may stop serving requests.', 'wordfence'), wfUtils::formatBytes($free)),
1523
  array('spaceLeft' => wfUtils::formatBytes($free))
1524
  );
1525
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1526
- else if ($haveIssues != wfIssues::STATUS_SECURE && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
1527
  wfIssues::statusEnd($this->statusIDX['diskSpace'], $haveIssues);
1528
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
1529
  }
 
1530
  private function scan_wafStatus() {
1531
  $this->statusIDX['wafStatus'] = wfIssues::statusStart(__('Checking Web Application Firewall status', 'wordfence'));
1532
  $this->scanController->startStage(wfScanner::STAGE_SERVER_STATE);
1533
-
1534
  $haveIssues = wfIssues::STATUS_SECURE;
1535
  $added = false;
1536
  $firewall = new wfFirewall();
@@ -1540,34 +1779,36 @@ class wfScanEngine {
1540
  'wafStatus',
1541
  'wafStatus' . $firewall->firewallMode(),
1542
  __('Web Application Firewall is disabled', 'wordfence'),
1543
- sprintf(__('Wordfence\'s Web Application Firewall has been unexpectedly disabled. If you see a notice at the top of the Wordfence admin pages that says "The Wordfence Web Application Firewall cannot run," click the link in that message to rebuild the configuration. If this does not work, you may need to fix file permissions. <a href="%s" target="_blank" rel="noopener noreferrer">More Details</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_WAF_DISABLED)),
1544
  array('wafStatus' => $firewall->firewallMode(), 'wafStatusDisplay' => $firewall->displayText())
1545
  );
1546
  }
1547
-
1548
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1549
- else if ($haveIssues != wfIssues::STATUS_SECURE && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
1550
  wfIssues::statusEnd($this->statusIDX['wafStatus'], $haveIssues);
1551
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
1552
  }
1553
-
1554
  private function scan_oldVersions_init() {
1555
- $this->statusIDX['oldVersions'] = wfIssues::statusStart("Scanning for old themes, plugins and core files");
1556
  $this->scanController->startStage(wfScanner::STAGE_VULNERABILITY_SCAN);
1557
-
1558
  $this->updateCheck = new wfUpdateCheck();
1559
  if ($this->isFullScan()) {
1560
  $this->updateCheck->checkAllUpdates(false);
1561
  $this->updateCheck->checkAllVulnerabilities();
1562
- }
1563
- else {
1564
  $this->updateCheck->checkAllUpdates();
1565
  }
1566
-
1567
  foreach ($this->updateCheck->getPluginSlugs() as $slug) {
1568
  $this->pluginRepoStatus[$slug] = false;
1569
  }
1570
-
1571
  //Strip plugins that have a pending update
1572
  if (count($this->updateCheck->getPluginUpdates()) > 0) {
1573
  foreach ($this->updateCheck->getPluginUpdates() as $plugin) {
@@ -1577,49 +1818,49 @@ class wfScanEngine {
1577
  }
1578
  }
1579
  }
1580
-
1581
  private function scan_oldVersions_main() {
1582
  if (!$this->isFullScan()) {
1583
  return;
1584
  }
1585
-
1586
  if (!function_exists('plugins_api')) {
1587
  require_once(ABSPATH . 'wp-admin/includes/plugin-install.php');
1588
  }
1589
-
1590
  foreach ($this->pluginRepoStatus as $slug => $status) {
1591
  if ($status === false) {
1592
  $result = plugins_api('plugin_information', array(
1593
- 'slug' => $slug,
1594
  'fields' => array(
1595
  'short_description' => false,
1596
- 'description' => false,
1597
- 'sections' => false,
1598
- 'tested' => true,
1599
- 'requires' => true,
1600
- 'rating' => false,
1601
- 'ratings' => false,
1602
- 'downloaded' => false,
1603
- 'downloadlink' => false,
1604
- 'last_updated' => true,
1605
- 'added' => false,
1606
- 'tags' => false,
1607
- 'compatibility' => true,
1608
- 'homepage' => true,
1609
- 'versions' => false,
1610
- 'donate_link' => false,
1611
- 'reviews' => false,
1612
- 'banners' => false,
1613
- 'icons' => false,
1614
- 'active_installs' => false,
1615
- 'group' => false,
1616
- 'contributors' => false,
1617
  ),
1618
  ));
1619
  unset($result->versions);
1620
  unset($result->screenshots);
1621
  $this->pluginRepoStatus[$slug] = $result;
1622
-
1623
  $this->forkIfNeeded();
1624
  }
1625
  }
@@ -1627,21 +1868,32 @@ class wfScanEngine {
1627
 
1628
  private function scan_oldVersions_finish() {
1629
  $haveIssues = wfIssues::STATUS_SECURE;
1630
-
1631
  if (!$this->isFullScan()) {
1632
  $this->deleteNewIssues(array('wfUpgrade', 'wfPluginUpgrade', 'wfThemeUpgrade'));
1633
  }
1634
 
1635
  // WordPress core updates needed
1636
  if ($this->updateCheck->needsCoreUpdate()) {
1637
- $added = $this->addIssue('wfUpgrade', wfIssues::SEVERITY_HIGH, 'wfUpgrade' . $this->updateCheck->getCoreUpdateVersion(), 'wfUpgrade' . $this->updateCheck->getCoreUpdateVersion(), "Your WordPress version is out of date", "WordPress version " . esc_html($this->updateCheck->getCoreUpdateVersion()) . " is now available. Please upgrade immediately to get the latest security updates from WordPress.", array(
1638
- 'currentVersion' => $this->wp_version,
1639
- 'newVersion' => $this->updateCheck->getCoreUpdateVersion(),
1640
- ));
1641
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1642
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
 
 
 
 
 
 
 
 
1643
  }
1644
-
1645
  $allPlugins = $this->updateCheck->getAllPlugins();
1646
 
1647
  // Plugin updates needed
@@ -1654,11 +1906,24 @@ class wfScanEngine {
1654
  }
1655
  }
1656
  $key = 'wfPluginUpgrade' . ' ' . $plugin['pluginFile'] . ' ' . $plugin['newVersion'] . ' ' . $plugin['Version'];
1657
- $shortMsg = "The Plugin \"" . (empty($plugin['Name']) ? $plugin['pluginFile'] : $plugin['Name']) . "\" needs an upgrade (" . $plugin['Version'] . " -> " . $plugin['newVersion'] . ").";
1658
- $added = $this->addIssue('wfPluginUpgrade', $severity, $key, $key, $shortMsg, "You need to upgrade \"" . (empty($plugin['Name']) ? $plugin['pluginFile'] : $plugin['Name']) . "\" to the newest version to ensure you have any security fixes the developer has released.", $plugin);
1659
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1660
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
1661
-
 
 
 
 
 
 
 
 
 
 
 
 
 
1662
  if (isset($plugin['slug'])) {
1663
  unset($allPlugins[$plugin['slug']]);
1664
  }
@@ -1675,13 +1940,26 @@ class wfScanEngine {
1675
  }
1676
  }
1677
  $key = 'wfThemeUpgrade' . ' ' . $theme['Name'] . ' ' . $theme['version'] . ' ' . $theme['newVersion'];
1678
- $shortMsg = "The Theme \"" . $theme['Name'] . "\" needs an upgrade (" . $theme['version'] . " -> " . $theme['newVersion'] . ").";
1679
- $added = $this->addIssue('wfThemeUpgrade', $severity, $key, $key, $shortMsg, "You need to upgrade \"" . esc_html($theme['Name']) . "\" to the newest version to ensure you have any security fixes the developer has released.", $theme);
1680
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1681
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
 
 
 
 
 
 
 
 
 
 
1682
  }
1683
  }
1684
-
1685
  if ($this->isFullScan()) {
1686
  //Abandoned plugins
1687
  foreach ($this->pluginRepoStatus as $slug => $status) {
@@ -1701,36 +1979,58 @@ class wfScanEngine {
1701
  $statusArray['vulnerabilityLink'] = $vulnerable;
1702
  }
1703
  }
1704
-
1705
  if (isset($allPlugins[$slug]) && isset($allPlugins[$slug]['wpURL'])) {
1706
  $statusArray['wpURL'] = $allPlugins[$slug]['wpURL'];
1707
  }
1708
-
1709
- $testedShort = '';
1710
- $testedLong = '';
1711
  if (isset($statusArray['tested'])) {
1712
- $testedShort = ', tested to WP ' . $statusArray['tested'];
1713
- $testedLong = ' and tested up to WordPress ' . esc_html($statusArray['tested']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1714
  }
1715
-
1716
- $key = "wfPluginAbandoned {$slug} {$statusArray['version']}";
1717
- $shortMsg = 'The Plugin "' . (empty($statusArray['name']) ? $slug : $statusArray['name']) . '" appears to be abandoned (updated ' . wfUtils::formatLocalTime(get_option('date_format'), $lastUpdateTimestamp) . "{$testedShort}).";
1718
- $longMsg = 'It was last updated ' . wfUtils::makeTimeAgo(time() - $lastUpdateTimestamp) . " ago{$testedLong}.";
1719
  if ($statusArray['vulnerable']) {
1720
- $longMsg .= ' It has unpatched security issues and may have compatibility problems with the current version of WordPress.';
1721
- }
1722
- else {
1723
- $longMsg .= ' Plugins can be removed from wordpress.org for various reasons. This can include benign issues like a plugin author discontinuing development or moving the plugin distribution to their own site, but some might also be due to security issues. In any case, future updates may or may not be available, so it is worth investigating the cause and deciding whether to temporarily or permanently replace or remove the plugin.';
1724
  }
1725
- $longMsg .= ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_PLUGIN_ABANDONED) . '" target="_blank" rel="noopener noreferrer">Get more information.</a>';
 
 
1726
  $added = $this->addIssue('wfPluginAbandoned', $severity, $key, $key, $shortMsg, $longMsg, $statusArray);
1727
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1728
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
1729
-
 
 
 
1730
  unset($allPlugins[$slug]);
1731
  }
1732
- }
1733
- else if ($status !== false && is_wp_error($status) && isset($status->errors['plugins_api_failed'])) { //The plugin does not exist in the wp.org repo
1734
  $knownFiles = $this->getKnownFilesLoader()->getKnownFiles();
1735
  if (isset($knownFiles['status']) && is_array($knownFiles['status']) && isset($knownFiles['status']['plugins']) && is_array($knownFiles['status']['plugins'])) {
1736
  $requestedPlugins = $this->getPlugins();
@@ -1747,27 +2047,33 @@ class wfScanEngine {
1747
  $pluginData['vulnerabilityLink'] = $vulnerable;
1748
  }
1749
  }
1750
-
1751
  $key = "wfPluginRemoved {$slug} {$pluginData['Version']}";
1752
- $shortMsg = 'The Plugin "' . (empty($pluginData['Name']) ? $slug : $pluginData['Name']) . '" has been removed from wordpress.org.';
 
 
1753
  if ($pluginData['vulnerable']) {
1754
- $longMsg = 'It has unpatched security issues and may have compatibility problems with the current version of WordPress.';
1755
- }
1756
- else {
1757
- $longMsg = 'Plugins can be removed from wordpress.org for various reasons. This can include benign issues like a plugin author discontinuing development or moving the plugin distribution to their own site, but some might also be due to security issues. In any case, future updates may or may not be available, so it is worth investigating the cause and deciding whether to temporarily or permanently replace or remove the plugin.';
1758
  }
1759
- $longMsg .= ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_PLUGIN_REMOVED) . '" target="_blank" rel="noopener noreferrer">Get more information.</a>';
 
 
1760
  $added = $this->addIssue('wfPluginRemoved', wfIssues::SEVERITY_CRITICAL, $key, $key, $shortMsg, $longMsg, $pluginData);
1761
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1762
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
1763
-
 
 
 
1764
  unset($allPlugins[$slug]);
1765
  }
1766
  }
1767
  }
1768
  }
1769
  }
1770
-
1771
  //Other vulnerable plugins
1772
  //Disabled until we improve the data source to weed out false positives
1773
  /*if (count($allPlugins) > 0) {
@@ -1789,7 +2095,7 @@ class wfScanEngine {
1789
  }
1790
  }*/
1791
  }
1792
-
1793
  $this->updateCheck = false;
1794
  $this->pluginRepoStatus = array();
1795
 
@@ -1798,7 +2104,7 @@ class wfScanEngine {
1798
  }
1799
 
1800
  public function scan_suspiciousAdminUsers() {
1801
- $this->statusIDX['suspiciousAdminUsers'] = wfIssues::statusStart("Scanning for admin users not created through WordPress");
1802
  $this->scanController->startStage(wfScanner::STAGE_OPTIONS_AUDIT);
1803
  $haveIssues = wfIssues::STATUS_SECURE;
1804
 
@@ -1820,13 +2126,16 @@ class wfScanEngine {
1820
  $user = new WP_User($userID);
1821
  $key = 'suspiciousAdminUsers' . $userID;
1822
  $added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
1823
- sprintf(__("An admin user with the username %s was created outside of WordPress.", 'wordfence'), esc_html($user->user_login)),
1824
- sprintf(__("An admin user with the username %s was created outside of WordPress. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it.", 'wordfence'), esc_html($user->user_login)),
1825
  array(
1826
  'userID' => $userID,
1827
  ));
1828
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1829
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
1830
  }
1831
  }
1832
 
@@ -1844,8 +2153,8 @@ class wfScanEngine {
1844
  foreach ($suspiciousAdminUsernames as $usernamePattern) {
1845
  if (preg_match($usernamePattern, $adminUser->user_login)) {
1846
  $added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
1847
- sprintf(__("An admin user with a suspicious username %s was found.", 'wordfence'), esc_html($adminUser->user_login)),
1848
- sprintf(__("An admin user with a suspicious username %s was found. Administrators accounts with usernames similar to this are commonly seen created by hackers. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it.", 'wordfence'), esc_html($adminUser->user_login)),
1849
  array(
1850
  'userID' => $userID,
1851
  ));
@@ -1853,23 +2162,26 @@ class wfScanEngine {
1853
  }
1854
  }
1855
 
1856
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1857
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
1858
  }
1859
  }
1860
 
1861
  wfIssues::statusEnd($this->statusIDX['suspiciousAdminUsers'], $haveIssues);
1862
  $this->scanController->completeStage(wfScanner::STAGE_OPTIONS_AUDIT, $haveIssues);
1863
  }
1864
-
1865
  public function scan_suspiciousOptions() {
1866
- $this->statusIDX['suspiciousOptions'] = wfIssues::statusStart("Scanning for suspicious site options");
1867
  $this->scanController->startStage(wfScanner::STAGE_OPTIONS_AUDIT);
1868
  $haveIssues = wfIssues::STATUS_SECURE;
1869
-
1870
  $blogsToScan = self::getBlogsToScan('options');
1871
  $wfdb = new wfDB();
1872
-
1873
  $this->hoover = new wordfenceURLHoover($this->apiKey, $this->wp_version);
1874
  foreach ($blogsToScan as $blog) {
1875
  $excludedHosts = array();
@@ -1884,12 +2196,11 @@ class wfScanEngine {
1884
  $excludedHosts[$host] = 1;
1885
  }
1886
  $excludedHosts = array_keys($excludedHosts);
1887
-
1888
  //Newspaper Theme
1889
  if (defined('TD_THEME_OPTIONS_NAME')) {
1890
  $q = $wfdb->querySelect("SELECT option_name, option_value FROM " . $blog['table'] . " WHERE option_name REGEXP '^td_[0-9]+$' OR option_name = '%s'", TD_THEME_OPTIONS_NAME);
1891
- }
1892
- else {
1893
  $q = $wfdb->querySelect("SELECT option_name, option_value FROM " . $blog['table'] . " WHERE option_name REGEXP '^td_[0-9]+$'");
1894
  }
1895
  foreach ($q as $row) {
@@ -1897,11 +2208,11 @@ class wfScanEngine {
1897
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, $found);
1898
  }
1899
  }
1900
-
1901
-
1902
- $this->status(2, 'info', "Examining URLs found in the options we scanned for dangerous websites");
1903
  $hooverResults = $this->hoover->getBaddies();
1904
- $this->status(2, 'info', "Done examining URLs");
1905
  if ($this->hoover->errorMsg) {
1906
  wfIssues::statusEndErr();
1907
  throw new Exception($this->hoover->errorMsg);
@@ -1916,124 +2227,136 @@ class wfScanEngine {
1916
  if ($result['badList'] != 'goog-malware-shavar' && $result['badList'] != 'googpub-phish-shavar' && $result['badList'] != 'wordfence-dbl') {
1917
  continue; //A list type that may be new and the plugin has not been upgraded yet.
1918
  }
1919
-
1920
  if ($blog === null) {
1921
  $blogs = self::getBlogsToScan('options', $blogID);
1922
  $blog = array_shift($blogs);
1923
  }
1924
-
1925
  if ($result['badList'] == 'goog-malware-shavar') {
1926
- $shortMsg = "Option contains a suspected malware URL: " . esc_html($optionKey);
1927
- $longMsg = "This option contains a suspected malware URL listed on Google's list of malware sites. It may indicate your site is infected with malware. The URL is: " . esc_html($result['URL']);
1928
- }
1929
- else if ($result['badList'] == 'googpub-phish-shavar') {
1930
- $shortMsg = "Option contains a suspected phishing site URL: " . esc_html($optionKey);
1931
- $longMsg = "This option contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. It may indicate your site is infected with malware. The URL is: " . esc_html($result['URL']);
1932
- }
1933
- else if ($result['badList'] == 'wordfence-dbl') {
1934
- $shortMsg = "Option contains a suspected malware URL: " . esc_html($optionKey);
1935
- $longMsg = "This option contains a URL that is currently listed on Wordfence's domain blocklist. It may indicate your site is infected with malware. The URL is: " . esc_html($result['URL']);
1936
- }
1937
- else {
1938
  //A list type that may be new and the plugin has not been upgraded yet.
1939
  continue;
1940
  }
1941
-
1942
- $longMsg .= ' - <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_OPTION_MALWARE_URL) . '" target="_blank" rel="noopener noreferrer">Get more information.</a>';
1943
-
1944
- $this->status(2, 'info', "Adding issue: $shortMsg");
1945
-
1946
  if (is_multisite()) {
1947
  switch_to_blog($blogID);
1948
  }
1949
-
1950
  $ignoreP = $idString;
1951
  $ignoreC = $idString . md5(serialize(get_option($optionKey, '')));
1952
  $added = $this->addIssue('optionBadURL', wfIssues::SEVERITY_HIGH, $ignoreP, $ignoreC, $shortMsg, $longMsg, array(
1953
- 'optionKey' => $optionKey,
1954
- 'badURL' => $result['URL'],
1955
  'isMultisite' => $blog['isMultisite'],
1956
- 'domain' => $blog['domain'],
1957
- 'path' => $blog['path'],
1958
- 'blog_id' => $blogID
1959
  ));
1960
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1961
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
1962
  if (is_multisite()) {
1963
  restore_current_blog();
1964
  }
1965
  }
1966
  }
1967
-
1968
  wfIssues::statusEnd($this->statusIDX['suspiciousOptions'], $haveIssues);
1969
  $this->scanController->completeStage(wfScanner::STAGE_OPTIONS_AUDIT, $haveIssues);
1970
  }
1971
-
1972
  public function scan_geoipSupport() {
1973
- $this->statusIDX['geoipSupport'] = wfIssues::statusStart("Checking for future GeoIP support");
1974
  $this->scanController->startStage(wfScanner::STAGE_SERVER_STATE);
1975
  $haveIssues = wfIssues::STATUS_SECURE;
1976
-
1977
  if (version_compare(phpversion(), '5.4') < 0 && wfConfig::get('isPaid') && wfBlock::hasCountryBlock()) {
1978
  $shortMsg = __('PHP Update Needed for Country Blocking', 'wordfence');
1979
- $longMsg = sprintf(__('The GeoIP database that is required for country blocking has been updated to a new format. This new format requires sites to run PHP 5.4 or newer, and this site is on PHP %s. To ensure country blocking continues functioning, please update PHP.', 'wordfence'), wfUtils::cleanPHPVersion());
1980
-
1981
- $longMsg .= ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_GEOIP_UPDATE) . '" target="_blank" rel="noopener noreferrer">Get more information.</a>';
1982
-
1983
- $this->status(2, 'info', "Adding issue: {$shortMsg}");
1984
-
1985
  $ignoreP = 'geoIPPHPDiscontinuing';
1986
  $ignoreC = $ignoreP;
1987
  $added = $this->addIssue('geoipSupport', wfIssues::SEVERITY_MEDIUM, $ignoreP, $ignoreC, $shortMsg, $longMsg, array());
1988
- if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
1989
- else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
 
 
 
1990
  }
1991
-
1992
  wfIssues::statusEnd($this->statusIDX['geoipSupport'], $haveIssues);
1993
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
1994
  }
1995
 
1996
- public function status($level, $type, $msg){
1997
  wordfence::status($level, $type, $msg);
1998
  }
 
1999
  public function addIssue($type, $severity, $ignoreP, $ignoreC, $shortMsg, $longMsg, $templateData, $alreadyHashed = false) {
2000
  wfIssues::updateScanStillRunning();
2001
  return $this->i->addIssue($type, $severity, $ignoreP, $ignoreC, $shortMsg, $longMsg, $templateData, $alreadyHashed);
2002
  }
2003
- public function addPendingIssue($type, $severity, $ignoreP, $ignoreC, $shortMsg, $longMsg, $templateData){
 
2004
  wfIssues::updateScanStillRunning();
2005
  return $this->i->addPendingIssue($type, $severity, $ignoreP, $ignoreC, $shortMsg, $longMsg, $templateData);
2006
  }
 
2007
  public function getPendingIssueCount() {
2008
  return $this->i->getPendingIssueCount();
2009
  }
 
2010
  public function getPendingIssues($offset = 0, $limit = 100) {
2011
  return $this->i->getPendingIssues($offset, $limit);
2012
  }
2013
- public static function requestKill(){
 
2014
  wfConfig::set('wfKillRequested', time(), wfConfig::DONT_AUTOLOAD);
2015
  }
2016
- public static function checkForKill(){
 
2017
  $kill = wfConfig::get('wfKillRequested', 0);
2018
- if($kill && time() - $kill < 600){ //Kill lasts for 10 minutes
2019
- wordfence::status(10, 'info', "SUM_KILLED:Previous scan was stopped successfully.");
2020
- throw new Exception("Scan was stopped on administrator request.", wfScanEngine::SCAN_MANUALLY_KILLED);
2021
  }
2022
  }
2023
- public static function startScan($isFork = false, $scanMode = false){
2024
- if (!defined('DONOTCACHEDB')) { define('DONOTCACHEDB', true); }
2025
-
 
 
 
2026
  if ($scanMode === false) {
2027
  $scanMode = wfScanner::shared()->scanType();
2028
  }
2029
-
2030
- if(! $isFork){ //beginning of scan
2031
- wfConfig::inc('totalScansRun');
2032
- wfConfig::set('wfKillRequested', 0, wfConfig::DONT_AUTOLOAD);
2033
- wordfence::status(4, 'info', "Entering start scan routine");
2034
  if (wfScanner::shared()->isRunning()) {
2035
  wfUtils::getScanFileError();
2036
- return "A scan is already running. Use the stop scan button if you would like to terminate the current scan.";
2037
  }
2038
  wfConfig::set('currentCronKey', ''); //Ensure the cron key is cleared
2039
  }
@@ -2042,87 +2365,94 @@ class wfScanEngine {
2042
  if (!wfConfig::get('startScansRemotely', false)) {
2043
  try {
2044
  $testResult = wp_remote_post($testURL, array(
2045
- 'timeout' => $timeout,
2046
- 'blocking' => true,
2047
  'sslverify' => false,
2048
- 'headers' => array()
2049
  ));
2050
- }
2051
- catch (Exception $e) {
2052
  //Fall through to the remote start test below
2053
  }
2054
-
2055
- wordfence::status(4, 'info', "Test result of scan start URL fetch: " . var_export($testResult, true));
2056
  }
2057
-
2058
  $cronKey = wfUtils::bigRandomHex();
2059
  wfConfig::set('currentCronKey', time() . ',' . $cronKey);
2060
  if ((!wfConfig::get('startScansRemotely', false)) && (!is_wp_error($testResult)) && (is_array($testResult) || $testResult instanceof ArrayAccess) && strstr($testResult['body'], 'WFSCANTESTOK') !== false) {
2061
  //ajax requests can be sent by the server to itself
2062
  $cronURL = self::_localStartURL($isFork, $scanMode, $cronKey);
2063
  $headers = array('Referer' => false/*, 'Cookie' => 'XDEBUG_SESSION=1'*/);
2064
- wordfence::status(4, 'info', "Starting cron with normal ajax at URL $cronURL");
2065
-
2066
  try {
2067
  wfConfig::set('scanStartAttempt', time());
2068
  $response = wp_remote_get($cronURL, array(
2069
- 'timeout' => 0.01,
2070
- 'blocking' => false,
2071
  'sslverify' => false,
2072
- 'headers' => $headers
2073
- ));
2074
  if (wfCentral::isConnected()) {
2075
  wfCentral::updateScanStatus();
2076
  }
2077
- }
2078
- catch (Exception $e) {
2079
  wfConfig::set('lastScanCompleted', $e->getMessage());
2080
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
2081
  return false;
2082
  }
2083
-
2084
  if (is_wp_error($response)) {
2085
  $error_message = $response->get_error_message();
2086
- wfConfig::set('lastScanCompleted', "There was an " . ($error_message ? '' : 'unknown ') . "error starting the scan" . ($error_message ? ": $error_message" : '.'));
 
 
 
 
 
 
2087
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
2088
  }
2089
-
2090
- wordfence::status(4, 'info', "Scan process ended after forking.");
2091
- }
2092
- else {
2093
  $cronURL = self::_remoteStartURL($isFork, $scanMode, $cronKey);
2094
  $headers = array();
2095
- wordfence::status(4, 'info', "Starting cron via proxy at URL $cronURL");
2096
-
2097
  try {
2098
  wfConfig::set('scanStartAttempt', time());
2099
  $response = wp_remote_get($cronURL, array(
2100
- 'timeout' => 0.01,
2101
- 'blocking' => false,
2102
  'sslverify' => false,
2103
- 'headers' => $headers
2104
- ));
2105
  if (wfCentral::isConnected()) {
2106
  wfCentral::updateScanStatus();
2107
  }
2108
- }
2109
- catch (Exception $e) {
2110
  wfConfig::set('lastScanCompleted', $e->getMessage());
2111
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
2112
  return false;
2113
  }
2114
-
2115
  if (is_wp_error($response)) {
2116
  $error_message = $response->get_error_message();
2117
- wfConfig::set('lastScanCompleted', "There was an " . ($error_message ? '' : 'unknown ') . "error starting the scan" . ($error_message ? ": $error_message" : '.'));
 
 
 
 
 
2118
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
2119
  }
2120
-
2121
- wordfence::status(4, 'info', "Scan process ended after forking.");
2122
  }
2123
  return false; //No error
2124
  }
2125
-
2126
  public static function verifyStartSignature($signature, $isFork, $scanMode, $cronKey, $remote) {
2127
  $url = self::_baseStartURL($isFork, $scanMode, $cronKey);
2128
  if ($remote) {
@@ -2132,18 +2462,18 @@ class wfScanEngine {
2132
  $test = self::_signStartURL($url);
2133
  return hash_equals($signature, $test);
2134
  }
2135
-
2136
  protected static function _baseStartURL($isFork, $scanMode, $cronKey) {
2137
  $url = admin_url('admin-ajax.php');
2138
  $url .= '?action=wordfence_doScan&isFork=' . ($isFork ? '1' : '0') . '&scanMode=' . urlencode($scanMode) . '&cronKey=' . urlencode($cronKey);
2139
  return $url;
2140
  }
2141
-
2142
  protected static function _localStartURL($isFork, $scanMode, $cronKey) {
2143
  $url = self::_baseStartURL($isFork, $scanMode, $cronKey);
2144
  return add_query_arg('signature', self::_signStartURL($url), $url);
2145
  }
2146
-
2147
  protected static function _remoteStartURL($isFork, $scanMode, $cronKey) {
2148
  $url = self::_baseStartURL($isFork, $scanMode, $cronKey);
2149
  $url = preg_replace('/^https?:\/\//i', (wfAPI::SSLEnabled() ? WORDFENCE_API_URL_SEC : WORDFENCE_API_URL_NONSEC) . 'scanp/', $url);
@@ -2151,37 +2481,55 @@ class wfScanEngine {
2151
  $url = add_query_arg('ssl', wfUtils::isFullSSL() ? '1' : '0', $url);
2152
  return add_query_arg('signature', self::_signStartURL($url), $url);
2153
  }
2154
-
2155
  protected static function _signStartURL($url) {
2156
  $payload = preg_replace('~^https?://[^/]+~i', '', $url);
2157
  return wfCrypt::local_sign($payload);
2158
  }
2159
-
2160
- public function processResponse($result){
2161
  return false;
2162
  }
 
2163
  public static function getMaxExecutionTime($staySilent = false) {
2164
  $config = wfConfig::get('maxExecutionTime');
2165
- if (!$staySilent) { wordfence::status(4, 'info', "Got value from wf config maxExecutionTime: $config"); }
 
 
2166
  if (is_numeric($config) && $config >= WORDFENCE_SCAN_MIN_EXECUTION_TIME) {
2167
- if (!$staySilent) { wordfence::status(4, 'info', "getMaxExecutionTime() returning config value: $config"); }
 
 
2168
  return $config;
2169
  }
2170
-
2171
  $ini = @ini_get('max_execution_time');
2172
- if (!$staySilent) { wordfence::status(4, 'info', "Got max_execution_time value from ini: $ini"); }
 
 
2173
  if (is_numeric($ini) && $ini >= WORDFENCE_SCAN_MIN_EXECUTION_TIME) {
2174
  if ($ini > WORDFENCE_SCAN_MAX_INI_EXECUTION_TIME) {
2175
- if (!$staySilent) { wordfence::status(4, 'info', "ini value of {$ini} is higher than value for WORDFENCE_SCAN_MAX_INI_EXECUTION_TIME (" . WORDFENCE_SCAN_MAX_INI_EXECUTION_TIME . "), reducing"); }
 
 
 
 
 
 
 
2176
  $ini = WORDFENCE_SCAN_MAX_INI_EXECUTION_TIME;
2177
  }
2178
-
2179
  $ini = floor($ini / 2);
2180
- if (!$staySilent) { wordfence::status(4, 'info', "getMaxExecutionTime() returning half ini value: $ini"); }
 
 
2181
  return $ini;
2182
  }
2183
-
2184
- if (!$staySilent) { wordfence::status(4, 'info', "getMaxExecutionTime() returning default of: 15"); }
 
 
2185
  return 15;
2186
  }
2187
 
@@ -2203,8 +2551,8 @@ class wfScanEngine {
2203
  if ($plugins !== null) {
2204
  return $plugins;
2205
  }
2206
-
2207
- if(! function_exists( 'get_plugins')){
2208
  require_once(ABSPATH . '/wp-admin/includes/plugin.php');
2209
  }
2210
  $pluginData = get_plugins();
@@ -2220,9 +2568,11 @@ class wfScanEngine {
2220
  'FullDir' => $pluginFullDir
2221
  );
2222
  }
2223
- if (!$this->pluginsCounted) { $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_PLUGINS); }
 
 
2224
  }
2225
-
2226
  $this->pluginsCounted = true;
2227
  return $plugins;
2228
  }
@@ -2235,7 +2585,7 @@ class wfScanEngine {
2235
  if ($themes !== null) {
2236
  return $themes;
2237
  }
2238
-
2239
  if (!function_exists('wp_get_themes')) {
2240
  require_once(ABSPATH . '/wp-includes/theme.php');
2241
  }
@@ -2252,26 +2602,27 @@ class wfScanEngine {
2252
  'FullDir' => $fullDir
2253
  );
2254
  }
2255
- if (!$this->themesCounted) { $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_THEMES); }
 
 
2256
  }
2257
-
2258
  $this->themesCounted = true;
2259
  return $themes;
2260
  }
2261
-
2262
  public function recordMetric($type, $key, $value, $singular = true) {
2263
  if (!isset($this->metrics[$type])) {
2264
  $this->metrics[$type] = array();
2265
  }
2266
-
2267
  if (!isset($this->metrics[$type][$key])) {
2268
  $this->metrics[$type][$key] = array();
2269
  }
2270
-
2271
  if ($singular) {
2272
  $this->metrics[$type][$key] = $value;
2273
- }
2274
- else {
2275
  $this->metrics[$type][$key][] = $value;
2276
  }
2277
  }
@@ -2379,11 +2730,11 @@ class wfScanKnownFilesLoader {
2379
  )));
2380
 
2381
  if ($dataArr['code'] != 200) {
2382
- throw new wfScanKnownFilesException("Got error response from Wordfence servers: " . $dataArr['code'], $dataArr['code']);
2383
  }
2384
  $this->knownFiles = @json_decode($dataArr['data'], true);
2385
  if (!is_array($this->knownFiles)) {
2386
- throw new wfScanKnownFilesException("Invalid response from Wordfence servers.");
2387
  }
2388
  } catch (Exception $e) {
2389
  throw new wfScanKnownFilesException($e->getMessage(), $e->getCode(), $e);
@@ -2472,7 +2823,7 @@ class wfScanKnownFilesException extends Exception {
2472
  class wfCommonBackupFileTest {
2473
  const MATCH_EXACT = 'exact';
2474
  const MATCH_REGEX = 'regex';
2475
-
2476
  /**
2477
  * @param string $path
2478
  * @param string $mode
@@ -2480,12 +2831,12 @@ class wfCommonBackupFileTest {
2480
  * @return wfCommonBackupFileTest
2481
  */
2482
  public static function createFromRootPath($path, $mode = self::MATCH_EXACT, $matcher = false) {
2483
- return new self(site_url($path), ABSPATH . $path, array(), $mode, $matcher);
2484
  }
2485
-
2486
  /**
2487
  * Identical to createFromRootPath except it returns an entry for each file in the index that matches $name
2488
- *
2489
  * @param $name
2490
  * @param string $mode
2491
  * @param bool|string $matcher
@@ -2500,7 +2851,7 @@ class wfCommonBackupFileTest {
2500
  foreach ($files as $f) {
2501
  $tests[] = new self(site_url($f), ABSPATH . $f, array(), $mode, $matcher);
2502
  }
2503
-
2504
  return $tests;
2505
  }
2506
 
@@ -2607,7 +2958,7 @@ class wfCommonBackupFileTest {
2607
  }
2608
 
2609
  class wfPubliclyAccessibleFileTest extends wfCommonBackupFileTest {
2610
-
2611
  }
2612
 
2613
  class wfScanEngineDurationLimitException extends Exception {
@@ -2615,5 +2966,6 @@ class wfScanEngineDurationLimitException extends Exception {
2615
 
2616
  class wfScanEngineCoreVersionChangeException extends Exception {
2617
  }
 
2618
  class wfScanEngineTestCallbackFailedException extends Exception {
2619
  }
6
  require_once(dirname(__FILE__) . '/wfIssues.php');
7
  require_once(dirname(__FILE__) . '/wfDB.php');
8
  require_once(dirname(__FILE__) . '/wfUtils.php');
9
+
10
  class wfScanEngine {
11
  const SCAN_MANUALLY_KILLED = -999;
12
+
13
  public $api = false;
14
  private $dictWords = array();
15
  private $forkRequested = false;
36
  private $hoover = false;
37
  private $scanData = array();
38
  private $statusIDX = array(
39
+ 'core' => false,
40
+ 'plugin' => false,
41
+ 'theme' => false,
42
+ 'unknown' => false
43
+ );
44
  private $userPasswdQueue = "";
45
  private $passwdHasIssues = wfIssues::STATUS_SECURE;
46
  private $suspectedFiles = false; //Files found with the ".suspected" extension
52
  private $scanMode = wfScanner::SCAN_TYPE_STANDARD;
53
  private $pluginsCounted = false;
54
  private $themesCounted = false;
55
+
56
  /**
57
  * @var wfScanner
58
  */
67
  * @var wfScanKnownFilesLoader
68
  */
69
  private $knownFilesLoader;
70
+
71
  private $metrics = array();
72
+
73
  private $checkHowGetIPsRequestTime = 0;
74
 
75
  public static function testForFullPathDisclosure($url = null, $filePath = null) {
93
  return !is_wp_error($response) && ($responseBody = wp_remote_retrieve_body($response)) &&
94
  stripos($responseBody, '<title>Index of') !== false;
95
  }
96
+
97
  public static function refreshScanNotification($issuesInstance = null) {
98
  if ($issuesInstance === null) {
99
  $issuesInstance = new wfIssues();
100
  }
101
+
102
  $message = wfConfig::get('lastScanCompleted', false);
103
  if ($message === false || empty($message)) {
104
  $n = wfNotification::getNotificationForCategory('wfplugin_scan');
105
  if ($n !== null) {
106
  $n->markAsRead();
107
  }
108
+ } else if ($message == 'ok') {
 
109
  $issueCount = $issuesInstance->getIssueCount();
110
  if ($issueCount) {
111
+ new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, "<a href=\"" . wfUtils::wpAdminURL('admin.php?page=WordfenceScan') . "\">" .
112
+ /* translators: Number of scan results. */
113
+ sprintf(_n('%d issue found in most recent scan', '%d issues found in most recent scan', $issueCount, 'wordfence'), $issueCount)
114
+ . '</a>', 'wfplugin_scan');
115
+ } else {
116
  $n = wfNotification::getNotificationForCategory('wfplugin_scan');
117
  if ($n !== null) {
118
  $n->markAsRead();
119
  }
120
  }
121
+ } else {
 
122
  $failureType = wfConfig::get('lastScanFailureType');
123
  if ($failureType == 'duration') {
124
  new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, '<a href="' . wfUtils::wpAdminURL('admin.php?page=WordfenceScan') . '">Scan aborted due to duration limit</a>', 'wfplugin_scan');
125
+ } else if ($failureType == 'versionchange') {
 
126
  //No need to create a notification
127
+ } else {
 
128
  $trimmedError = substr($message, 0, 100) . (strlen($message) > 100 ? '...' : '');
129
  new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, '<a href="' . wfUtils::wpAdminURL('admin.php?page=WordfenceScan') . '">Scan failed: ' . esc_html($trimmedError) . '</a>', 'wfplugin_scan');
130
  }
131
  }
132
  }
133
 
134
+ public function __sleep() { //Same order here as above for properties that are included in serialization
135
  return array('hasher', 'jobList', 'i', 'wp_version', 'apiKey', 'startTime', 'maxExecTime', 'publicScanEnabled', 'fileContentsResults', 'scanner', 'scanQueue', 'hoover', 'scanData', 'statusIDX', 'userPasswdQueue', 'passwdHasIssues', 'suspectedFiles', 'dbScanner', 'knownFilesLoader', 'metrics', 'checkHowGetIPsRequestTime', 'gsbMultisiteBlogOffset', 'updateCheck', 'pluginRepoStatus', 'malwarePrefixesHash', 'coreHashesHash', 'scanMode', 'pluginsCounted', 'themesCounted');
136
  }
137
+
138
  public function __construct($malwarePrefixesHash = '', $coreHashesHash = '', $scanMode = wfScanner::SCAN_TYPE_STANDARD) {
139
  $this->startTime = time();
140
  $this->recordMetric('scan', 'start', $this->startTime);
149
  include(dirname(__FILE__) . '/wfDict.php'); //$dictWords
150
  $this->dictWords = $dictWords;
151
  $this->scanMode = $scanMode;
152
+
153
  $this->scanController = new wfScanner($scanMode);
154
  $jobs = $this->scanController->jobs();
155
  foreach ($jobs as $job) {
157
  foreach (array('init', 'main', 'finish') as $op) {
158
  $this->jobList[] = $job . '_' . $op;
159
  }
160
+ } else if (method_exists($this, 'scan_' . $job)) {
 
161
  $this->jobList[] = $job;
162
  }
163
  }
164
  }
165
+
166
  public function scanController() {
167
  return $this->scanController;
168
  }
169
+
170
  /**
171
  * Deletes all new issues. To only delete specific types, provide an array of issue types.
172
+ *
173
  * @param null|array $types
174
  */
175
  public function deleteNewIssues($types = null) {
176
  $this->i->deleteNew($types);
177
  }
178
+
179
+ public function __wakeup() {
180
  $this->cycleStartTime = time();
181
  $this->api = new wfAPI($this->apiKey, $this->wp_version);
182
  include(dirname(__FILE__) . '/wfDict.php'); //$dictWords
183
  $this->dictWords = $dictWords;
184
  $this->scanController = new wfScanner($this->scanMode);
185
  }
186
+
187
  public function isFullScan() {
188
  return $this->scanMode != wfScanner::SCAN_TYPE_QUICK;
189
  }
190
+
191
+ public function go() {
192
  try {
193
  self::checkForKill();
194
  $this->doScan();
204
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
205
  $this->submitMetrics();
206
  }
207
+
208
  wfScanEngine::refreshScanNotification($this->i);
209
 
210
  if (wfCentral::isConnected()) {
211
  wfCentral::updateScanStatus();
212
  }
213
+ } catch (wfScanEngineDurationLimitException $e) {
 
214
  wfConfig::set('lastScanCompleted', $e->getMessage());
215
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_DURATION_REACHED);
216
  $this->scanController->recordLastScanTime();
217
+
218
  $this->emailNewIssues(true);
219
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
220
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
221
  $this->submitMetrics();
222
+
223
  wfScanEngine::refreshScanNotification($this->i);
224
  throw $e;
225
+ } catch (wfScanEngineCoreVersionChangeException $e) {
 
226
  wfConfig::set('lastScanCompleted', $e->getMessage());
227
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_VERSION_CHANGE);
228
  $this->scanController->recordLastScanTime();
229
+
230
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
231
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
232
  $this->submitMetrics();
235
 
236
  wfScanEngine::refreshScanNotification($this->i);
237
  throw $e;
238
+ } catch (wfScanEngineTestCallbackFailedException $e) {
 
239
  wfConfig::set('lastScanCompleted', $e->getMessage());
240
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
241
  $this->scanController->recordLastScanTime();
242
+
243
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
244
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
245
  $this->recordMetric('scan', 'failure', $e->getMessage());
246
  $this->submitMetrics();
247
+
248
  wfScanEngine::refreshScanNotification($this->i);
249
  throw $e;
250
+ } catch (Exception $e) {
 
251
  if ($e->getCode() != wfScanEngine::SCAN_MANUALLY_KILLED) {
252
  wfConfig::set('lastScanCompleted', $e->getMessage());
253
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_GENERAL);
254
  }
255
+
256
  $this->recordMetric('scan', 'duration', (time() - $this->startTime));
257
  $this->recordMetric('scan', 'memory', wfConfig::get('wfPeakMemory', 0, false));
258
  $this->recordMetric('scan', 'failure', $e->getMessage());
259
  $this->submitMetrics();
260
+
261
  wfScanEngine::refreshScanNotification($this->i);
262
  throw $e;
263
  }
264
  }
265
+
266
  public function checkForDurationLimit() {
267
  static $timeLimit = false;
268
  if ($timeLimit === false) {
271
  $timeLimit = WORDFENCE_DEFAULT_MAX_SCAN_TIME;
272
  }
273
  }
274
+
275
+ if ((time() - $this->startTime) > $timeLimit) {
276
+ $error = sprintf(
277
+ /* translators: 1. Time duration. 2. Support URL. */
278
+ __('The scan time limit of %1$s has been exceeded and the scan will be terminated. This limit can be customized on the options page. <a href="%2$s" target="_blank" rel="noopener noreferrer">Get More Information</a>', 'wordfence'),
279
+ wfUtils::makeDuration($timeLimit),
280
+ wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_TIME_LIMIT)
281
+ );
282
+ $this->addIssue('timelimit', wfIssues::SEVERITY_HIGH, md5($this->startTime), md5($this->startTime), __('Scan Time Limit Exceeded', 'wordfence'), $error, array());
283
+
284
  $this->status(1, 'info', '-------------------');
285
+ $this->status(1, 'info', sprintf(
286
+ /* translators: 1. Number of files. 2. Number of plugins. 3. Number of themes. 4. Number of posts. 5. Number of comments. 6. Number of URLs. 7. Time duration. */
287
+ __('Scan interrupted. Scanned %1$d files, %2$d plugins, %3$d themes, %4$d posts, %5$d comments and %6$d URLs in %7$s.', 'wordfence'),
288
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_FILES, 0),
289
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_PLUGINS, 0),
290
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_THEMES, 0),
291
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_POSTS, 0),
292
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_COMMENTS, 0),
293
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, 0),
294
+ wfUtils::makeDuration(time() - $this->startTime, true)
295
+ ));
296
+ if ($this->i->totalIssues > 0) {
297
+ $this->status(10, 'info', "SUM_FINAL:" . __("Scan interrupted. You have " . $this->i->totalIssues . " new issue" . ($this->i->totalIssues == 1 ? "" : "s") . " to fix. See below."));
298
+ $this->status(10, 'info', "SUM_FINAL:" . sprintf(
299
+ /* translators: Number of scan results. */
300
+ _n(
301
+ "Scan interrupted. You have %d new issue to fix. See below.",
302
+ "Scan interrupted. You have %d new issues to fix. See below.",
303
+ $this->i->totalIssues,
304
+ 'wordfence'),
305
+ $this->i->totalIssues
306
+ )
307
+ );
308
  } else {
309
+ $this->status(10, 'info', "SUM_FINAL:" . __('Scan interrupted. No problems found prior to stopping.', 'wordfence'));
310
  }
311
  throw new wfScanEngineDurationLimitException($error);
312
  }
313
  }
314
+
315
  public function checkForCoreVersionChange() {
316
  $startVersion = wfConfig::get('wfScanStartVersion');
317
  $currentVersion = wfUtils::getWPVersion(true);
318
  if (version_compare($startVersion, $currentVersion) != 0) {
319
+ throw new wfScanEngineCoreVersionChangeException(sprintf(
320
+ /* translators: 1. Software version. 2. Software version. */
321
+ __('Aborting scan because WordPress updated from version %1$s to %2$s. The scan will be reattempted later.', 'wordfence'), $startVersion, $currentVersion));
322
  }
323
  }
324
+
325
  public function shouldFork() {
326
  static $lastCheck = 0;
327
+
328
  if (time() - $this->cycleStartTime > $this->maxExecTime) {
329
  return true;
330
  }
331
+
332
  if ($lastCheck > time() - $this->maxExecTime) {
333
  return false;
334
  }
335
  $lastCheck = time();
336
+
337
  $this->checkForCoreVersionChange();
338
  wfIssues::updateScanStillRunning();
339
  self::checkForKill();
340
  $this->checkForDurationLimit();
341
+
342
  return false;
343
  }
344
+
345
+ public function forkIfNeeded() {
346
  wfIssues::updateScanStillRunning();
347
  $this->checkForCoreVersionChange();
348
  self::checkForKill();
349
  $this->checkForDurationLimit();
350
+ if (time() - $this->cycleStartTime > $this->maxExecTime) {
351
+ wordfence::status(4, 'info', __("Forking during hash scan to ensure continuity.", 'wordfence'));
352
  $this->fork();
353
  }
354
  }
355
+
356
+ public function fork() {
357
+ wordfence::status(4, 'info', __("Entered fork()", 'wordfence'));
358
+ if (wfConfig::set_ser('wfsd_engine', $this, true, wfConfig::DONT_AUTOLOAD)) {
359
  $this->scanController->flushSummaryItems();
360
+ wordfence::status(4, 'info', __("Calling startScan(true)", 'wordfence'));
361
  self::startScan(true, $this->scanMode);
362
  } //Otherwise there was an error so don't start another scan.
363
  exit(0);
364
  }
365
+
366
+ public function emailNewIssues($timeLimitReached = false) {
367
  if (!wfCentral::pluginAlertingDisabled()) {
368
  $this->i->emailNewIssues($timeLimitReached, $this->scanController);
369
  }
370
  }
371
+
372
  public function submitMetrics() {
373
  if (wfConfig::get('other_WFNet', true)) {
374
  //Trim down the malware matches if needed to allow the report call to succeed
384
  $rules_with_extras++;
385
  }
386
  }
387
+
388
  //Trim additional matches
389
  $overage = $extra_count - WORDFENCE_SCAN_ISSUES_MAX_REPORT;
390
  if ($overage > 0) {
396
  $this->metrics['malwareSignature'][$rule] = $sliced;
397
  }
398
  }
399
+
400
  //Trim single matches
401
  if ($count > WORDFENCE_SCAN_ISSUES_MAX_REPORT) {
402
  $sliced = array_slice($this->metrics['malwareSignature'], 0, WORDFENCE_SCAN_ISSUES_MAX_REPORT, true);
403
  $this->metrics['malwareSignature'] = $sliced;
404
  }
405
  }
406
+
407
  $this->api->call('record_scan_metrics', array(), array('metrics' => $this->metrics));
408
  }
409
  }
410
+
411
+ private function doScan() {
412
  if ($this->scanController->useLowResourceScanning()) {
413
  $isFork = ($_GET['isFork'] == '1' ? true : false);
414
  wfConfig::set('lowResourceScanWaitStep', !wfConfig::get('lowResourceScanWaitStep'));
417
  $this->fork(); //exits
418
  }
419
  }
420
+
421
+ while (sizeof($this->jobList) > 0) {
422
  self::checkForKill();
423
  $jobName = $this->jobList[0];
424
  $callback = array($this, 'scan_' . $jobName);
427
  }
428
  array_shift($this->jobList); //only shift once we're done because we may pause halfway through a job and need to pick up where we left off
429
  self::checkForKill();
430
+ if ($this->forkRequested) {
431
  $this->fork();
432
  } else {
433
+ $this->forkIfNeeded();
434
  }
435
  }
436
+
437
  $this->status(1, 'info', '-------------------');
438
+
439
  $peakMemory = wfScan::logPeakMemory();
440
+ $this->status(2, 'info', sprintf(
441
+ /* translators: 1. Memory in bytes. 2. Memory in bytes. */
442
+ __('Wordfence used %1$s of memory for scan. Server peak memory usage was: %2$s', 'wordfence'),
443
+ wfUtils::formatBytes($peakMemory - wfScan::$peakMemAtStart),
444
+ wfUtils::formatBytes($peakMemory)
445
+ ));
446
+
447
  if ($this->isFullScan()) {
448
+ $this->status(1, 'info', sprintf(
449
+ /* translators: 1. Number of files. 2. Number of plugins. 3. Number of themes. 4. Number of posts. 5. Number of comments. 6. Number of URLs. 7. Time duration. */
450
+ __('Scan Complete. Scanned %1$d files, %2$d plugins, %3$d themes, %4$d posts, %5$d comments and %6$d URLs in %7$s.', 'wordfence'),
451
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_FILES, 0),
452
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_PLUGINS, 0),
453
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_THEMES, 0),
454
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_POSTS, 0),
455
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_COMMENTS, 0),
456
+ $this->scanController->getSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, 0),
457
+ wfUtils::makeDuration(time() - $this->startTime, true)
458
+ ));
459
+ } else {
460
+ $this->status(1, 'info', sprintf(
461
+ /* translators: 1. Time duration. */
462
+ __("Quick Scan Complete. Scanned in %s.", 'wordfence'),
463
+ wfUtils::makeDuration(time() - $this->startTime, true)
464
+ ));
465
  }
466
+
467
  $ignoredText = '';
468
  if ($this->i->totalIgnoredIssues > 0) {
469
+ $ignoredText = ' ' . sprintf(
470
+ /* translators: Number of scan results. */
471
+ _n(
472
+ '%d ignored issue was also detected.',
473
+ '%d ignored issues were also detected.',
474
+ $this->i->totalIgnoredIssues,
475
+ 'wordfence'
476
+ ), $this->i->totalIgnoredIssues);
477
+ }
478
+
479
+ if ($this->i->totalIssues > 0) {
480
+ $this->status(10, 'info', "SUM_FINAL:" . sprintf(
481
+ /* translators: Number of scan results. */
482
+ _n(
483
+ "Scan complete. You have %d new issue to fix.",
484
+ "Scan complete. You have %d new issues to fix.",
485
+ $this->i->totalIssues,
486
+ 'wordfence'),
487
+ $this->i->totalIssues
488
+ ) .
489
+ $ignoredText . ' ' .
490
+ __('See below.', 'wordfence')
491
+ );
492
  } else {
493
+ $this->status(10, 'info', "SUM_FINAL:" . __('Scan complete. Congratulations, no new problems found.', 'wordfence') . $ignoredText);
494
  }
495
  return;
496
  }
497
+
498
+ public function getCurrentJob() {
499
  return $this->jobList[0];
500
  }
501
+
502
  private function scan_checkSpamIP() {
503
  if ($this->scanController->isPremiumScan()) {
504
+ $this->statusIDX['checkSpamIP'] = wfIssues::statusStart(__("Checking if your site IP is generating spam", 'wordfence'));
505
  $this->scanController->startStage(wfScanner::STAGE_SPAM_CHECK);
506
  $result = $this->api->call('check_spam_ip', array(), array(
507
  'siteURL' => site_url()
508
+ ));
509
  $haveIssues = wfIssues::STATUS_SECURE;
510
+ if (!empty($result['haveIssues']) && is_array($result['issues'])) {
511
+ foreach ($result['issues'] as $issue) {
512
  $added = $this->addIssue($issue['type'], wfIssues::SEVERITY_HIGH, $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
513
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
514
+ $haveIssues = wfIssues::STATUS_PROBLEM;
515
+ } else if ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC) {
516
+ $haveIssues = wfIssues::STATUS_IGNORED;
517
+ }
518
  }
519
  }
520
  wfIssues::statusEnd($this->statusIDX['checkSpamIP'], $haveIssues);
521
  $this->scanController->completeStage(wfScanner::STAGE_SPAM_CHECK, $haveIssues);
522
+ } else {
523
+ wfIssues::statusPaidOnly(__("Checking if your IP is generating spam is for paid members only", 'wordfence'));
 
524
  sleep(2);
525
  }
526
  }
527
+
528
  private function scan_checkGSB_init() {
529
  if ($this->scanController->isPremiumScan()) {
530
+ $this->statusIDX['checkGSB'] = wfIssues::statusStart(__("Checking if your site is on a domain blocklist", 'wordfence'));
531
  $this->scanController->startStage(wfScanner::STAGE_BLACKLIST_CHECK);
532
+ $h = new wordfenceURLHoover($this->apiKey, $this->wp_version);
533
+ $h->cleanup();
534
+ } else {
535
+ wfIssues::statusPaidOnly(__("Checking if your site is on a domain blocklist is for paid members only", 'wordfence'));
 
536
  sleep(2);
537
  }
538
  }
539
+
540
  private function scan_checkGSB_main() {
541
  if ($this->scanController->isPremiumScan()) {
542
  if (is_multisite()) {
552
  $h->hoover($id, $siteURL);
553
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_URLS);
554
  }
555
+
556
  if ($this->shouldFork()) {
557
  $this->gsbMultisiteBlogOffset = $id;
558
  $this->forkIfNeeded();
561
  }
562
  }
563
  }
564
+
565
  private function scan_checkGSB_finish() {
566
  if ($this->scanController->isPremiumScan()) {
567
  if (is_multisite()) {
568
  $h = new wordfenceURLHoover($this->apiKey, $this->wp_version, false, true);
569
  $badURLs = $h->getBaddies();
570
  if ($h->errorMsg) {
571
+ $this->status(4, 'info', sprintf(/* translators: Error message. */ __("Error checking domain blocklists: %s", 'wordfence'), $h->errorMsg));
572
  wfIssues::statusEnd($this->statusIDX['checkGSB'], wfIssues::STATUS_FAILED);
573
  $this->scanController->completeStage(wfScanner::STAGE_BLACKLIST_CHECK, wfIssues::STATUS_FAILED);
574
  return;
575
  }
576
  $h->cleanup();
577
+ } else {
 
578
  $urlsToCheck = array(array(wfUtils::wpHomeURL(), wfUtils::wpSiteURL()));
579
  $badURLs = $this->api->call('check_bad_urls', array(), array('toCheck' => json_encode($urlsToCheck))); //Skipping the separate prefix check since there are just two URLs
580
  $finalResults = array();
584
  }
585
  foreach ($badSiteList as $badSite) {
586
  $finalResults[$file][] = array(
587
+ 'URL' => $badSite[0],
588
  'badList' => $badSite[1]
589
  );
590
  }
591
  }
592
  $badURLs = $finalResults;
593
  }
594
+
595
  $haveIssues = wfIssues::STATUS_SECURE;
596
  if (is_array($badURLs) && count($badURLs) > 0) {
597
  foreach ($badURLs as $id => $badSiteList) {
599
  $url = $badSite['URL'];
600
  $badList = $badSite['badList'];
601
  $data = array('badURL' => $url);
602
+
603
  if ($badList == 'goog-malware-shavar') {
604
  if (is_multisite()) {
605
+ $shortMsg = sprintf(/* translators: WordPress site ID. */ __('The multisite blog with ID %d is listed on Google\'s Safe Browsing malware list.', 'wordfence'), intval($id));
606
  $data['multisite'] = intval($id);
607
+ } else {
608
+ $shortMsg = __('Your site is listed on Google\'s Safe Browsing malware list.', 'wordfence');
609
  }
610
+ $longMsg = sprintf(
611
+ /* translators: 1. URL. 2. URL. */
612
+ __('The URL %1$s is on the malware list. More info available at <a href="http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%2$s&client=googlechrome&hl=en-US" target="_blank" rel="noopener noreferrer">Google Safe Browsing diagnostic page</a>.', 'wordfence'), esc_html($url), urlencode($url));
 
613
  $data['gsb'] = $badList;
614
+ } else if ($badList == 'googpub-phish-shavar') {
 
615
  if (is_multisite()) {
616
+ $shortMsg = sprintf(
617
+ /* translators: WordPress site ID. */
618
+ __('The multisite blog with ID %d is listed on Google\'s Safe Browsing phishing list.', 'wordfence'), intval($id));
619
  $data['multisite'] = intval($id);
620
+ } else {
621
+ $shortMsg = __('Your site is listed on Google\'s Safe Browsing phishing list.', 'wordfence');
622
  }
623
+ $longMsg = sprintf(
624
+ /* translators: 1. URL. 2. URL. */
625
+ __('The URL %1$s is on the phishing list. More info available at <a href="http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%2$s&client=googlechrome&hl=en-US" target="_blank" rel="noopener noreferrer">Google Safe Browsing diagnostic page</a>.', 'wordfence'), esc_html($url), urlencode($url));
 
626
  $data['gsb'] = $badList;
627
+ } else if ($badList == 'wordfence-dbl') {
 
628
  if (is_multisite()) {
629
+ $shortMsg = sprintf(
630
+ /* translators: WordPress site ID. */
631
+ __('The multisite blog with ID %d is listed on the Wordfence domain blocklist.', 'wordfence'), intval($id));
632
  $data['multisite'] = intval($id);
633
+ } else {
634
+ $shortMsg = __('Your site is listed on the Wordfence domain blocklist.', 'wordfence');
635
  }
636
+ $longMsg = sprintf(
637
+ /* translators: URL. */
638
+ __("The URL %s is on the blocklist.", 'wordfence'), esc_html($url));
 
639
  $data['gsb'] = $badList;
640
+ } else {
 
641
  if (is_multisite()) {
642
+ $shortMsg = sprintf(
643
+ /* translators: WordPress site ID. */
644
+ __('The multisite blog with ID %d is listed on a domain blocklist.', 'wordfence'), intval($id));
645
  $data['multisite'] = intval($id);
646
+ } else {
647
+ $shortMsg = __('Your site is listed on a domain blocklist.', 'wordfence');
648
  }
649
+ $longMsg = sprintf(/* translators: URL. */ __("The URL is: %s", 'wordfence'), esc_html($url));
 
 
 
650
  $data['gsb'] = 'unknown';
651
  }
652
+
653
  $added = $this->addIssue('checkGSB', wfIssues::SEVERITY_CRITICAL, 'checkGSB', 'checkGSB' . $url, $shortMsg, $longMsg, $data);
654
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
655
+ $haveIssues = wfIssues::STATUS_PROBLEM;
656
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
657
+ $haveIssues = wfIssues::STATUS_IGNORED;
658
+ }
659
  }
660
  }
661
  }
662
+
663
  wfIssues::statusEnd($this->statusIDX['checkGSB'], $haveIssues);
664
  $this->scanController->completeStage(wfScanner::STAGE_BLACKLIST_CHECK, $haveIssues);
665
  }
666
  }
667
+
668
  private function scan_checkHowGetIPs_init() {
669
+ $this->statusIDX['checkHowGetIPs'] = wfIssues::statusStart(__("Checking for the most secure way to get IPs", 'wordfence'));
670
  $this->scanController->startStage(wfScanner::STAGE_SERVER_STATE);
671
  $this->checkHowGetIPsRequestTime = time();
672
  wfUtils::requestDetectProxyCallback();
673
  }
674
+
675
  private function scan_checkHowGetIPs_main() {
676
+ if (!defined('WORDFENCE_CHECKHOWGETIPS_TIMEOUT')) {
677
+ define('WORDFENCE_CHECKHOWGETIPS_TIMEOUT', 30);
678
+ }
679
+
680
  $haveIssues = wfIssues::STATUS_SECURE;
681
  $existing = wfConfig::get('howGetIPs', '');
682
  $recommendation = wfConfig::get('detectProxyRecommendation', '');
685
  $this->forkIfNeeded();
686
  $recommendation = wfConfig::get('detectProxyRecommendation', '');
687
  }
688
+
689
+ if ($recommendation == 'DEFERRED') {
690
  //Do nothing
691
  $haveIssues = wfIssues::STATUS_SKIPPED;
692
+ } else if (empty($recommendation)) {
 
693
  $haveIssues = wfIssues::STATUS_FAILED;
694
+ } else if ($recommendation == 'UNKNOWN') {
695
+ $added = $this->addIssue('checkHowGetIPs', wfIssues::SEVERITY_HIGH, 'checkHowGetIPs', 'checkHowGetIPs' . $recommendation . WORDFENCE_VERSION,
696
+ __("Unable to accurately detect IPs", 'wordfence'),
697
+ sprintf(/* translators: Support URL. */ __('Wordfence was unable to validate a test request to your website. This can happen if your website is behind a proxy that does not use one of the standard ways to convey the IP of the request or it is unreachable publicly. IP blocking and live traffic information may not be accurate. <a href="%s" target="_blank" rel="noopener noreferrer">Get More Information</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_MISCONFIGURED_HOW_GET_IPS))
698
+ , array());
699
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
700
+ $haveIssues = wfIssues::STATUS_PROBLEM;
701
+ } else if ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC) {
702
+ $haveIssues = wfIssues::STATUS_IGNORED;
703
+ }
704
+ } else if (!empty($existing) && $existing != $recommendation) {
705
  $extraMsg = '';
706
  if ($recommendation == 'REMOTE_ADDR') {
707
+ $extraMsg = ' ' . __('For maximum security use PHP\'s built in REMOTE_ADDR.', 'wordfence');
708
+ } else if ($recommendation == 'HTTP_X_FORWARDED_FOR') {
709
+ $extraMsg = ' ' . __('This site appears to be behind a front-end proxy, so using the X-Forwarded-For HTTP header will resolve to the correct IPs.', 'wordfence');
710
+ } else if ($recommendation == 'HTTP_X_REAL_IP') {
711
+ $extraMsg = ' ' . __('This site appears to be behind a front-end proxy, so using the X-Real-IP HTTP header will resolve to the correct IPs.', 'wordfence');
712
+ } else if ($recommendation == 'HTTP_CF_CONNECTING_IP') {
713
+ $extraMsg = ' ' . __('This site appears to be behind Cloudflare, so using the Cloudflare "CF-Connecting-IP" HTTP header will resolve to the correct IPs.', 'wordfence');
714
+ }
715
+
716
+ $added = $this->addIssue('checkHowGetIPs', wfIssues::SEVERITY_HIGH, 'checkHowGetIPs', 'checkHowGetIPs' . $recommendation . WORDFENCE_VERSION,
717
+ __("'How does Wordfence get IPs' is misconfigured", 'wordfence'),
718
+ sprintf(
719
+ /* translators: Support URL. */
720
+ __('A test request to this website was detected on a different value for this setting. IP blocking and live traffic information may not be accurate. <a href="%s" target="_blank" rel="noopener noreferrer">Get More Information</a>', 'wordfence'),
721
+ wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_MISCONFIGURED_HOW_GET_IPS)
722
+ ) . $extraMsg,
723
+ array('recommendation' => $recommendation));
724
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
725
+ $haveIssues = wfIssues::STATUS_PROBLEM;
726
+ } else if ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC) {
727
+ $haveIssues = wfIssues::STATUS_IGNORED;
728
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
729
  }
730
+
731
  wfIssues::statusEnd($this->statusIDX['checkHowGetIPs'], $haveIssues);
732
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
733
  }
734
+
735
  private function scan_checkHowGetIPs_finish() {
736
  /* Do nothing */
737
  }
738
 
739
  private function scan_checkReadableConfig() {
740
  $haveIssues = wfIssues::STATUS_SECURE;
741
+ $status = wfIssues::statusStart(__("Check for publicly accessible configuration files, backup files and logs", 'wordfence'));
742
  $this->scanController->startStage(wfScanner::STAGE_PUBLIC_FILES);
743
 
744
  $backupFileTests = array(
769
  )),
770
  );
771
  $backupFileTests = array_merge($backupFileTests, wfCommonBackupFileTest::createAllForFile('searchreplacedb2.php', wfCommonBackupFileTest::MATCH_REGEX, '/<title>Search and replace DB/i'));
772
+
773
  $userIniFilename = ini_get('user_ini.filename');
774
  if ($userIniFilename && $userIniFilename !== '.user.ini') {
775
+ $backupFileTests[] = wfCommonBackupFileTest::createFromRootPath($userIniFilename);
776
  }
777
 
778
 
779
  /** @var wfCommonBackupFileTest $test */
780
  foreach ($backupFileTests as $test) {
781
  $pathFromRoot = (strpos($test->getPath(), ABSPATH) === 0) ? substr($test->getPath(), strlen(ABSPATH)) : $test->getPath();
782
+ wordfence::status(4, 'info', "Testing {$pathFromRoot}");
783
  if ($test->fileExists() && $test->isPubliclyAccessible()) {
784
  $key = "configReadable" . bin2hex($test->getUrl());
785
  $added = $this->addIssue(
787
  wfIssues::SEVERITY_CRITICAL,
788
  $key,
789
  $key,
790
+ sprintf(
791
+ /* translators: File path. */
792
+ __('Publicly accessible config, backup, or log file found: %s', 'wordfence'), esc_html($pathFromRoot)),
793
+ sprintf(
794
+ /* translators: 1. URL to publicly accessible file. 2. Support URL. */
795
+ __('<a href="%1$s" target="_blank" rel="noopener noreferrer">%1$s</a> is publicly accessible and may expose source code or sensitive information about your site. Files such as this one are commonly checked for by scanners and should be made inaccessible. Alternately, some can be removed if you are certain your site does not need them. Sites using the nginx web server may need manual configuration changes to protect such files. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn more</a>', 'wordfence'),
796
+ $test->getUrl(),
797
+ wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_PUBLIC_CONFIG)
798
+ ),
799
  array(
800
  'url' => $test->getUrl(),
801
  'file' => $pathFromRoot,
802
  'canDelete' => true,
803
  )
804
  );
805
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
806
+ $haveIssues = wfIssues::STATUS_PROBLEM;
807
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
808
+ $haveIssues = wfIssues::STATUS_IGNORED;
809
+ }
810
  }
811
  }
812
 
821
  }
822
 
823
  $haveIssues = wfIssues::STATUS_SECURE;
824
+ $status = wfIssues::statusStart(__("Checking if your server discloses the path to the document root", 'wordfence'));
825
  $testPage = includes_url() . basename($file);
826
 
827
  if (self::testForFullPathDisclosure($testPage, $file)) {
828
+ $key = 'wpscan_fullPathDisclosure' . $testPage;
829
  $added = $this->addIssue(
830
  'wpscan_fullPathDisclosure',
831
  wfIssues::SEVERITY_HIGH,
832
  $key,
833
  $key,
834
+ __('Web server exposes the document root', 'wordfence'),
835
+ __('Full Path Disclosure (FPD) vulnerabilities enable the attacker to see the path to the webroot/file. e.g.: /home/user/htdocs/file/. Certain vulnerabilities, such as using the load_file() (within a SQL Injection) query to view the page source, require the attacker to have the full path to the file they wish to view.', 'wordfence'),
 
 
836
  array('url' => $testPage)
837
  );
838
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
839
+ $haveIssues = wfIssues::STATUS_PROBLEM;
840
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
841
+ $haveIssues = wfIssues::STATUS_IGNORED;
842
+ }
843
  }
844
 
845
  wfIssues::statusEnd($status, $haveIssues);
858
  wfIssues::SEVERITY_HIGH,
859
  'wpscan_directoryListingEnabled',
860
  'wpscan_directoryListingEnabled',
861
+ __("Directory listing is enabled", 'wordfence'),
862
+ __("Directory listing provides an attacker with the complete index of all the resources located inside of the directory. The specific risks and consequences vary depending on which files are listed and accessible, but it is recommended that you disable it unless it is needed.", 'wordfence'),
863
  array(
864
  'url' => $uploadPaths['baseurl'],
865
  )
866
  );
867
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
868
+ $haveIssues = wfIssues::STATUS_PROBLEM;
869
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
870
+ $haveIssues = wfIssues::STATUS_IGNORED;
871
+ }
872
  }
873
  wfIssues::statusEnd($this->statusIDX['wpscan_directoryListingEnabled'], $haveIssues);
874
  }
875
 
876
  private function scan_checkSpamvertized() {
877
  if ($this->scanController->isPremiumScan()) {
878
+ $this->statusIDX['spamvertizeCheck'] = wfIssues::statusStart(__("Checking if your site is being Spamvertised", 'wordfence'));
879
  $this->scanController->startStage(wfScanner::STAGE_SPAMVERTISING_CHECKS);
880
  $result = $this->api->call('spamvertize_check', array(), array(
881
  'siteURL' => site_url()
882
+ ));
883
  $haveIssues = wfIssues::STATUS_SECURE;
884
+ if ($result['haveIssues'] && is_array($result['issues'])) {
885
+ foreach ($result['issues'] as $issue) {
886
  $added = $this->addIssue($issue['type'], wfIssues::SEVERITY_CRITICAL, $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
887
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
888
+ $haveIssues = wfIssues::STATUS_PROBLEM;
889
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
890
+ $haveIssues = wfIssues::STATUS_IGNORED;
891
+ }
892
  }
893
  }
894
  wfIssues::statusEnd($this->statusIDX['spamvertizeCheck'], $haveIssues);
895
  $this->scanController->completeStage(wfScanner::STAGE_SPAMVERTISING_CHECKS, $haveIssues);
896
+ } else {
897
+ wfIssues::statusPaidOnly(__("Check if your site is being Spamvertized is for paid members only", 'wordfence'));
 
898
  sleep(2);
899
  }
900
  }
901
+
902
  private function _scannedSkippedPaths() {
903
  static $_cache = null;
904
  if ($_cache === null) {
905
  $base_abspath_relative = array('.htaccess', 'index.php', 'license.txt', 'readme.html', 'wp-activate.php', 'wp-admin', 'wp-app.php', 'wp-blog-header.php', 'wp-comments-post.php', 'wp-config-sample.php', 'wp-content', 'wp-cron.php', 'wp-includes', 'wp-links-opml.php', 'wp-load.php', 'wp-login.php', 'wp-mail.php', 'wp-pass.php', 'wp-register.php', 'wp-settings.php', 'wp-signup.php', 'wp-trackback.php', 'xmlrpc.php', '.well-known', 'cgi-bin');
906
  $base_absolute = array();
907
+ if (defined('WP_CONTENT_DIR') && strlen(WP_CONTENT_DIR)) {
908
+ $base_absolute[] = WP_CONTENT_DIR;
909
+ }
910
+ if (defined('WP_PLUGIN_DIR') && strlen(WP_PLUGIN_DIR)) {
911
+ $base_absolute[] = WP_PLUGIN_DIR;
912
+ }
913
+ if (defined('UPLOADS') && strlen(UPLOADS)) {
914
+ $base_absolute[] = ABSPATH . UPLOADS; /* UPLOADS is relative to ABSPATH unlike the others */
915
+ }
916
  $baseContents = scandir(ABSPATH);
917
  if (!is_array($baseContents)) {
918
+ throw new Exception(__("Wordfence could not read the contents of your base WordPress directory. This usually indicates your permissions are so strict that your web server can't read your WordPress directory.", 'wordfence'));
919
  }
920
+
921
  $scanOutside = $this->scanController->scanOutsideWordPress();
922
  if ($scanOutside) {
923
  $_cache = array('scanned' => array_merge(array(ABSPATH), $base_absolute), 'skipped' => array());
924
  return $_cache;
925
  }
926
+
927
  $scanned = array();
928
  $skipped = array();
929
  foreach ($baseContents as $file) { //Only include base files less than a meg that are files.
930
+ if ($file == '.' || $file == '..') {
931
+ continue;
932
+ }
933
  $fullFile = rtrim(ABSPATH, '/') . '/' . $file;
934
  if (!wfUtils::fileTooBig($fullFile)) { //Silently ignore files that are too large for the purposes of inclusion in the scan issue
935
  if (in_array($file, $base_abspath_relative) || in_array($fullFile, $base_absolute) || (@is_file($fullFile) && @is_readable($fullFile))) {
936
  $scanned[] = realpath($fullFile);
937
+ } else {
 
938
  $skipped[] = $fullFile;
939
  }
940
  }
949
  }
950
  return $_cache;
951
  }
952
+
953
  private function scan_checkSkippedFiles() {
954
  $haveIssues = wfIssues::STATUS_SECURE;
955
+ $status = wfIssues::statusStart(__("Checking for paths skipped due to scan settings", 'wordfence'));
956
  $this->scanController->startStage(wfScanner::STAGE_SERVER_STATE);
957
+
958
  $paths = $this->_scannedSkippedPaths();
959
  if (!empty($paths['skipped'])) {
960
  $skippedList = '';
963
  if (strpos($fullPath, ABSPATH) === 0) {
964
  $path = '~/' . esc_html(substr($fullPath, strlen(ABSPATH)));
965
  }
966
+
967
  if ($index >= 10) {
968
+ $skippedList .= sprintf(/* translators: Number of paths skipped in scan. */ __(', and %d more.', 'wordfence'), count($paths['skipped']) - 10);
969
  break;
970
  }
971
+
972
  if (!empty($skippedList)) {
973
  if (count($paths['skipped']) == 2) {
974
  $skippedList .= ' and ';
975
+ } else if ($index == count($paths['skipped']) - 1) {
 
976
  $skippedList .= ', and ';
977
+ } else {
 
978
  $skippedList .= ', ';
979
  }
980
  }
981
+
982
  $skippedList .= $path;
983
  }
984
+
985
  $c = count($paths['skipped']);
986
  $key = "skippedPaths";
987
  $added = $this->addIssue(
989
  wfIssues::SEVERITY_LOW,
990
  $key,
991
  $key,
992
+ sprintf(/* translators: Number of paths skipped in scan. */ _n('%d path was skipped for the malware scan due to scan settings', '%d paths were skipped for the malware scan due to scan settings', $c, 'wordfence'), $c),
993
+ sprintf(
994
+ /* translators: 1. Number of paths skipped in scan. 2. Support URL. 3. List of skipped paths. */
995
+ _n(
996
+ 'The option "Scan files outside your WordPress installation" is off by default, which means %1$d path and its file(s) will not be scanned for malware or unauthorized changes. To continue skipping this path, you may ignore this issue. Or to start scanning it, enable the option and subsequent scans will include it. Some paths may not be necessary to scan, so this is optional. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn More</a><br><br>The path skipped is %3$s',
997
+ 'The option "Scan files outside your WordPress installation" is off by default, which means %1$d paths and their file(s) will not be scanned for malware or unauthorized changes. To continue skipping these paths, you may ignore this issue. Or to start scanning them, enable the option and subsequent scans will include them. Some paths may not be necessary to scan, so this is optional. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn More</a><br><br>The paths skipped are %3$s',
998
+ $c,
999
+ 'wordfence'
1000
+ ),
1001
+ $c,
1002
+ wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_SKIPPED_PATHS),
1003
+ $skippedList
1004
+ ),
1005
  array()
1006
  );
1007
+
1008
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1009
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1010
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1011
+ $haveIssues = wfIssues::STATUS_IGNORED;
1012
+ }
1013
  }
1014
+
1015
  wfIssues::statusEnd($status, $haveIssues);
1016
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
1017
  }
1018
+
1019
+ private function scan_knownFiles_init() {
1020
  $paths = $this->_scannedSkippedPaths();
1021
  $includeInKnownFilesScan = $paths['scanned'];
1022
  if ($this->scanController->scanOutsideWordPress()) {
1023
+ wordfence::status(2, 'info', __("Including files that are outside the WordPress installation in the scan.", 'wordfence'));
1024
  }
1025
 
1026
+ $this->status(2, 'info', __("Getting plugin list from WordPress", 'wordfence'));
1027
  $knownFilesPlugins = $this->getPlugins();
1028
+ $this->status(2, 'info', sprintf(/* translators: Number of plugins. */ _n("Found %d plugin", "Found %d plugins", sizeof($knownFilesPlugins), 'wordfence'), sizeof($knownFilesPlugins)));
1029
 
1030
+ $this->status(2, 'info', __("Getting theme list from WordPress", 'wordfence'));
1031
  $knownFilesThemes = $this->getThemes();
1032
+ $this->status(2, 'info', sprintf(/* translators: Number of themes. */ _n("Found %d theme", "Found %d themes", sizeof($knownFilesThemes), 'wordfence'), sizeof($knownFilesThemes)));
1033
 
1034
  $this->hasher = new wordfenceHash(strlen(ABSPATH), ABSPATH, $includeInKnownFilesScan, $knownFilesThemes, $knownFilesPlugins, $this, wfUtils::hex2bin($this->malwarePrefixesHash), $this->coreHashesHash, $this->scanMode);
1035
  }
1036
+
1037
  private function scan_knownFiles_main() {
1038
  $this->hasher->run($this); //Include this so we can call addIssue and ->api->
1039
  $this->suspectedFiles = $this->hasher->getSuspectedFiles();
1040
  $this->hasher = false;
1041
  }
1042
+
1043
  private function scan_knownFiles_finish() {
1044
  }
1045
+
1046
  private function scan_fileContents_init() {
1047
  $options = $this->scanController->scanOptions();
1048
  if ($options['scansEnabled_fileContents']) {
1049
+ $this->statusIDX['infect'] = wfIssues::statusStart(__('Scanning file contents for infections and vulnerabilities', 'wordfence'));
1050
  //This stage is marked as started earlier in the hasher rather than here
1051
+ } else {
1052
+ wfIssues::statusDisabled(__("Skipping scan of file contents for infections and vulnerabilities", 'wordfence'));
1053
  }
1054
+
 
 
 
1055
  if ($options['scansEnabled_fileContentsGSB']) {
1056
+ $this->statusIDX['GSB'] = wfIssues::statusStart(__('Scanning file contents for URLs on a domain blocklist', 'wordfence'));
1057
  //This stage is marked as started earlier in the hasher rather than here
1058
+ } else {
1059
+ wfIssues::statusDisabled(__("Skipping scan of file contents for URLs on a domain blocklist", 'wordfence'));
1060
  }
1061
+
 
 
 
1062
  if ($options['scansEnabled_fileContents'] || $options['scansEnabled_fileContentsGSB']) {
1063
  $this->scanner = new wordfenceScanner($this->apiKey, $this->wp_version, ABSPATH, $this);
1064
+ $this->status(2, 'info', __("Starting scan of file contents", 'wordfence'));
1065
+ } else {
 
1066
  $this->scanner = false;
1067
  }
1068
  }
1069
+
1070
  private function scan_fileContents_main() {
1071
  $options = $this->scanController->scanOptions();
1072
  if ($options['scansEnabled_fileContents'] || $options['scansEnabled_fileContentsGSB']) {
1073
  $this->fileContentsResults = $this->scanner->scan($this);
1074
  }
1075
  }
1076
+
1077
  private function scan_fileContents_finish() {
1078
  $options = $this->scanController->scanOptions();
1079
  if ($options['scansEnabled_fileContents'] || $options['scansEnabled_fileContentsGSB']) {
1080
+ $this->status(2, 'info', __("Done file contents scan", 'wordfence'));
1081
+ if ($this->scanner->errorMsg) {
1082
  throw new Exception($this->scanner->errorMsg);
1083
  }
1084
  $this->scanner = null;
1085
  $haveIssues = wfIssues::STATUS_SECURE;
1086
  $haveIssuesGSB = wfIssues::STATUS_SECURE;
1087
+ foreach ($this->fileContentsResults as $issue) {
1088
+ $this->status(2, 'info', sprintf(/* translators: Scan result description. */ __("Adding issue: %s", 'wordfence'), $issue['shortMsg']));
1089
  $added = $this->addIssue($issue['type'], $issue['severity'], $issue['ignoreP'], $issue['ignoreC'], $issue['shortMsg'], $issue['longMsg'], $issue['data']);
1090
+
1091
  if (isset($issue['data']['gsb'])) {
1092
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1093
+ $haveIssuesGSB = wfIssues::STATUS_PROBLEM;
1094
+ } else if ($haveIssuesGSB != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1095
+ $haveIssuesGSB = wfIssues::STATUS_IGNORED;
1096
+ }
1097
+ } else {
1098
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1099
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1100
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1101
+ $haveIssues = wfIssues::STATUS_IGNORED;
1102
+ }
1103
  }
1104
  }
1105
  $this->fileContentsResults = null;
1106
+
1107
  if ($options['scansEnabled_fileContents']) {
1108
  wfIssues::statusEnd($this->statusIDX['infect'], $haveIssues);
1109
  $this->scanController->completeStage(wfScanner::STAGE_MALWARE_SCAN, $haveIssues);
1110
  }
1111
+
1112
  if ($options['scansEnabled_fileContentsGSB']) {
1113
  wfIssues::statusEnd($this->statusIDX['GSB'], $haveIssuesGSB);
1114
  $this->scanController->completeStage(wfScanner::STAGE_CONTENT_SAFETY, $haveIssuesGSB);
1118
 
1119
  private function scan_suspectedFiles() {
1120
  $haveIssues = wfIssues::STATUS_SECURE;
1121
+ $status = wfIssues::statusStart(__("Scanning for publicly accessible quarantined files", 'wordfence'));
1122
  $this->scanController->startStage(wfScanner::STAGE_PUBLIC_FILES);
1123
+
1124
  if (is_array($this->suspectedFiles) && count($this->suspectedFiles) > 0) {
1125
  foreach ($this->suspectedFiles as $file) {
1126
+ wordfence::status(4, 'info', sprintf(/* translators: File path. */ __("Testing accessibility of: %s", 'wordfence'), $file));
1127
  $test = wfPubliclyAccessibleFileTest::createFromRootPath($file);
1128
  if ($test->fileExists() && $test->isPubliclyAccessible()) {
1129
  $key = "publiclyAccessible" . bin2hex($test->getUrl());
1132
  wfIssues::SEVERITY_HIGH,
1133
  $key,
1134
  $key,
1135
+ sprintf(/* translators: File path. */ __('Publicly accessible quarantined file found: %s', 'wordfence'), esc_html($file)),
1136
+ sprintf(
1137
+ /* translators: URL to publicly accessible file. */
1138
+ __('<a href="%1$s" target="_blank" rel="noopener noreferrer">%1$s</a> is publicly accessible and may expose source code or sensitive information about your site. Files such as this one are commonly checked for by scanners and should be removed or made inaccessible.', 'wordfence'),
1139
+ $test->getUrl()
1140
+ ),
1141
  array(
1142
  'url' => $test->getUrl(),
1143
  'file' => $file,
1144
  'canDelete' => true,
1145
  )
1146
  );
1147
+
1148
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1149
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1150
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1151
+ $haveIssues = wfIssues::STATUS_IGNORED;
1152
+ }
1153
  }
1154
  }
1155
  }
1156
+
1157
  wfIssues::statusEnd($status, $haveIssues);
1158
  $this->scanController->completeStage(wfScanner::STAGE_PUBLIC_FILES, $haveIssues);
1159
  }
1160
 
1161
  private function scan_posts_init() {
1162
+ $this->statusIDX['posts'] = wfIssues::statusStart(__('Scanning posts for URLs on a domain blocklist', 'wordfence'));
1163
  $this->scanController->startStage(wfScanner::STAGE_CONTENT_SAFETY);
1164
  $blogsToScan = self::getBlogsToScan('posts');
1165
  $this->scanQueue = '';
1166
  $wfdb = new wfDB();
1167
  $this->hoover = new wordfenceURLHoover($this->apiKey, $this->wp_version);
1168
+ foreach ($blogsToScan as $blog) {
1169
  $q1 = $wfdb->querySelect("select ID from " . $blog['table'] . " where post_type IN ('page', 'post') and post_status = 'publish'");
1170
+ foreach ($q1 as $idRow) {
1171
  $this->scanQueue .= pack('LL', $blog['blog_id'], $idRow['ID']);
1172
  }
1173
  }
1174
  }
1175
+
1176
  private function scan_posts_main() {
1177
  global $wpdb;
1178
  $wfdb = new wfDB();
1182
  $elem = unpack('Lblog/Lpost', $segment);
1183
  $queueSize = strlen($this->scanQueue) / 8;
1184
  if ($queueSize > 0 && $queueSize % 1000 == 0) {
1185
+ wordfence::status(2, 'info', sprintf(/* translators: Number of posts left to scan. */ __("Scanning posts with %d left to scan.", 'wordfence'), $queueSize));
1186
  }
1187
+
1188
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_POSTS);
1189
+
1190
  $blogID = $elem['blog'];
1191
  $postID = $elem['post'];
1192
+
1193
  $blogs = self::getBlogsToScan('posts', $blogID);
1194
  $blog = array_shift($blogs);
1195
+
1196
  $table = wfDB::blogTable('posts', $blogID);
1197
+
1198
  $row = $wfdb->querySingleRec("select ID, post_title, post_type, post_date, post_content from {$table} where ID = %d", $postID);
1199
  $found = $this->hoover->hoover($blogID . '-' . $row['ID'], $row['post_title'] . ' ' . $row['post_content'], wordfenceURLHoover::standardExcludedHosts());
1200
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, $found);
1201
  if (preg_match('/(?:<[\s\n\r\t]*script[\r\s\n\t]+.*>|<[\s\n\r\t]*meta.*refresh)/i', $row['post_title'])) {
1202
+ $this->addIssue(
1203
+ 'postBadTitle',
1204
+ wfIssues::SEVERITY_HIGH,
1205
+ $row['ID'],
1206
+ md5($row['post_title']),
1207
+ __("Post title contains suspicious code", 'wordfence'),
1208
+ __("This post contains code that is suspicious. Please check the title of the post and confirm that the code in the title is not malicious.", 'wordfence'),
1209
+ array(
1210
+ 'postID' => $postID,
1211
+ 'postTitle' => $row['post_title'],
1212
+ 'permalink' => get_permalink($postID),
1213
+ 'editPostLink' => get_edit_post_link($postID),
1214
+ 'type' => $row['post_type'],
1215
+ 'postDate' => $row['post_date'],
1216
+ 'isMultisite' => $blog['isMultisite'],
1217
+ 'domain' => $blog['domain'],
1218
+ 'path' => $blog['path'],
1219
+ 'blog_id' => $blog['blog_id']
1220
+ )
1221
+ );
1222
  }
1223
+
1224
  $this->forkIfNeeded();
1225
  }
1226
  }
1227
+
1228
  private function scan_posts_finish() {
1229
  global $wpdb;
1230
  $wfdb = new wfDB();
1231
+ $this->status(2, 'info', __("Examining URLs found in posts we scanned for dangerous websites", 'wordfence'));
1232
  $hooverResults = $this->hoover->getBaddies();
1233
+ $this->status(2, 'info', __("Done examining URLs", 'wordfence'));
1234
  if ($this->hoover->errorMsg) {
1235
  wfIssues::statusEndErr();
1236
  throw new Exception($this->hoover->errorMsg);
1248
  if ($result['badList'] != 'goog-malware-shavar' && $result['badList'] != 'googpub-phish-shavar' && $result['badList'] != 'wordfence-dbl') {
1249
  continue; //A list type that may be new and the plugin has not been upgraded yet.
1250
  }
1251
+
1252
  if ($blog === null) {
1253
  $blogs = self::getBlogsToScan('posts', $blogID);
1254
  $blog = array_shift($blogs);
1255
  }
1256
+
1257
  if ($post === null) {
1258
  $post = $wfdb->querySingleRec("select ID, post_title, post_type, post_date, post_content from {$table} where ID = %d", $postID);
1259
  $type = $post['post_type'] ? $post['post_type'] : 'comment';
1262
  $title = $post['post_title'];
1263
  $contentMD5 = md5($post['post_content']);
1264
  }
1265
+
1266
  if ($result['badList'] == 'goog-malware-shavar') {
1267
+ $shortMsg = sprintf(
1268
+ /* translators: 1. WordPress Post type. 2. URL. */
1269
+ __('%1$s contains a suspected malware URL: %2$s', 'wordfence'),
1270
+ $uctype,
1271
+ esc_html($title)
1272
+ );
1273
+ $longMsg = sprintf(
1274
+ /* translators: 1. WordPress Post type. 2. URL. 3. URL. */
1275
+ __('This %1$s contains a suspected malware URL listed on Google\'s list of malware sites. The URL is: %2$s - More info available at <a href="http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%3$s&client=googlechrome&hl=en-US" target="_blank" rel="noopener noreferrer">Google Safe Browsing diagnostic page</a>.', 'wordfence'),
1276
+ esc_html($type),
1277
+ esc_html($result['URL']),
1278
+ urlencode($result['URL'])
1279
+ );
1280
+ } else if ($result['badList'] == 'googpub-phish-shavar') {
1281
+ $shortMsg = sprintf(/* translators: 1. WordPress Post type. 2. URL. */ __('%1$s contains a suspected phishing site URL: %2$s', 'wordfence'), $uctype, esc_html($title));
1282
+ $longMsg = sprintf(
1283
+ /* translators: 1. WordPress Post type. 2. URL. */
1284
+ __('This %1$s contains a URL that is a suspected phishing site that is currently listed on Google\'s list of known phishing sites. The URL is: %2$s', 'wordfence'),
1285
+ esc_html($type),
1286
+ esc_html($result['URL'])
1287
+ );
1288
+ } else if ($result['badList'] == 'wordfence-dbl') {
1289
+ $shortMsg = sprintf(/* translators: 1. WordPress Post type. 2. URL. */ __('%1$s contains a suspected malware URL: %2$s', 'wordfence'), $uctype, esc_html($title));
1290
+ $longMsg = sprintf(
1291
+ /* translators: 1. WordPress Post type. 2. URL. */
1292
+ __('This %1$s contains a URL that is currently listed on Wordfence\'s domain blocklist. The URL is: %2$s', 'wordfence'),
1293
+ esc_html($type),
1294
+ esc_html($result['URL'])
1295
+ );
1296
+ } else {
1297
  //A list type that may be new and the plugin has not been upgraded yet.
1298
  continue;
1299
  }
1300
+
1301
+ $this->status(2, 'info', sprintf(/* translators: Scan result description. */ __('Adding issue: %1$s', 'wordfence'), $shortMsg));
1302
  if (is_multisite()) {
1303
  switch_to_blog($blogID);
1304
  }
1305
  $ignoreP = $idString;
1306
  $ignoreC = $idString . $contentMD5;
1307
  $added = $this->addIssue('postBadURL', wfIssues::SEVERITY_HIGH, $ignoreP, $ignoreC, $shortMsg, $longMsg, array(
1308
+ 'postID' => $postID,
1309
+ 'badURL' => $result['URL'],
1310
+ 'postTitle' => $title,
1311
+ 'type' => $type,
1312
+ 'uctype' => $uctype,
1313
+ 'permalink' => get_permalink($postID),
1314
  'editPostLink' => get_edit_post_link($postID),
1315
+ 'postDate' => $postDate,
1316
+ 'isMultisite' => $blog['isMultisite'],
1317
+ 'domain' => $blog['domain'],
1318
+ 'path' => $blog['path'],
1319
+ 'blog_id' => $blogID
1320
  ));
1321
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1322
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1323
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1324
+ $haveIssues = wfIssues::STATUS_IGNORED;
1325
+ }
1326
  if (is_multisite()) {
1327
  restore_current_blog();
1328
  }
1332
  $this->scanController->completeStage(wfScanner::STAGE_CONTENT_SAFETY, $haveIssues);
1333
  $this->scanQueue = '';
1334
  }
1335
+
1336
+ private function scan_comments_init() {
1337
+ $this->statusIDX['comments'] = wfIssues::statusStart(__('Scanning comments for URLs on a domain blocklist', 'wordfence'));
1338
  $this->scanController->startStage(wfScanner::STAGE_CONTENT_SAFETY);
1339
  $this->scanData = array();
1340
  $this->scanQueue = '';
1341
  $this->hoover = new wordfenceURLHoover($this->apiKey, $this->wp_version);
1342
  $blogsToScan = self::getBlogsToScan('comments');
1343
  $wfdb = new wfDB();
1344
+ foreach ($blogsToScan as $blog) {
1345
  $q1 = $wfdb->querySelect("select comment_ID from " . $blog['table'] . " where comment_approved=1");
1346
+ foreach ($q1 as $idRow) {
1347
  $this->scanQueue .= pack('LL', $blog['blog_id'], $idRow['comment_ID']);
1348
  }
1349
  }
1350
  }
1351
+
1352
+ private function scan_comments_main() {
1353
  global $wpdb;
1354
  $wfdb = new wfDB();
1355
  while (strlen($this->scanQueue) > 0) {
1358
  $elem = unpack('Lblog/Lcomment', $segment);
1359
  $queueSize = strlen($this->scanQueue) / 8;
1360
  if ($queueSize > 0 && $queueSize % 1000 == 0) {
1361
+ wordfence::status(2, 'info', sprintf(/* translators: Number of comments left to scan. */ __("Scanning comments with %d left to scan.", 'wordfence'), $queueSize));
1362
  }
1363
+
1364
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_COMMENTS);
1365
+
1366
  $blogID = $elem['blog'];
1367
  $commentID = $elem['comment'];
1368
+
1369
  $table = wfDB::blogTable('comments', $blogID);
1370
+
1371
  $row = $wfdb->querySingleRec("select comment_ID, comment_date, comment_type, comment_author, comment_author_url, comment_content from {$table} where comment_ID=%d", $commentID);
1372
  $found = $this->hoover->hoover($blogID . '-' . $row['comment_ID'], $row['comment_author_url'] . ' ' . $row['comment_author'] . ' ' . $row['comment_content'], wordfenceURLHoover::standardExcludedHosts());
1373
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, $found);
1374
  $this->forkIfNeeded();
1375
  }
1376
  }
1377
+
1378
+ private function scan_comments_finish() {
1379
  $wfdb = new wfDB();
1380
  $hooverResults = $this->hoover->getBaddies();
1381
+ if ($this->hoover->errorMsg) {
1382
  wfIssues::statusEndErr();
1383
  throw new Exception($this->hoover->errorMsg);
1384
  }
1385
  $this->hoover->cleanup();
1386
  $haveIssues = wfIssues::STATUS_SECURE;
1387
+ foreach ($hooverResults as $idString => $hresults) {
1388
  $arr = explode('-', $idString);
1389
  $blogID = $arr[0];
1390
  $commentID = $arr[1];
1391
  $blog = null;
1392
  $comment = null;
1393
  foreach ($hresults as $result) {
1394
+ if ($result['badList'] != 'goog-malware-shavar' && $result['badList'] != 'googpub-phish-shavar' && $result['badList'] != 'wordfence-dbl') {
1395
  continue; //A list type that may be new and the plugin has not been upgraded yet.
1396
  }
1397
+
1398
  if ($blog === null) {
1399
  $blogs = self::getBlogsToScan('comments', $blogID);
1400
  $blog = array_shift($blogs);
1401
  }
1402
+
1403
  if ($comment === null) {
1404
  $comment = $wfdb->querySingleRec("select comment_ID, comment_date, comment_type, comment_author, comment_author_url, comment_content from " . $blog['table'] . " where comment_ID=%d", $commentID);
1405
  $type = $comment['comment_type'] ? $comment['comment_type'] : 'comment';
1408
  $date = $comment['comment_date'];
1409
  $contentMD5 = md5($comment['comment_content'] . $comment['comment_author'] . $comment['comment_author_url']);
1410
  }
1411
+
1412
  if ($result['badList'] == 'goog-malware-shavar') {
1413
+ $shortMsg = sprintf(
1414
+ /* translators: 1. WordPress post type. 2. WordPress author username. */
1415
+ __('%1$s with author %2$s contains a suspected malware URL.', 'wordfence'), $uctype, esc_html($author));
1416
+ $longMsg = sprintf(
1417
+ /* translators: 1. WordPress post type. 2. URL. 3. URL. */
1418
+ __('This %$1s contains a suspected malware URL listed on Google\'s list of malware sites. The URL is: %2$s - More info available at <a href="http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%3$s&client=googlechrome&hl=en-US" target="_blank" rel="noopener noreferrer">Google Safe Browsing diagnostic page</a>.', 'wordfence'),
1419
+ esc_html($type),
1420
+ esc_html($result['URL']),
1421
+ urlencode($result['URL'])
1422
+ );
1423
+ } else if ($result['badList'] == 'googpub-phish-shavar') {
1424
+ $shortMsg = sprintf(/* translators: WordPress post type. */ __("%s contains a suspected phishing site URL.", 'wordfence'), $uctype);
1425
+ $longMsg = sprintf(
1426
+ /* translators: 1. WordPress post type. 2. URL. */
1427
+ __('This %1$s contains a URL that is a suspected phishing site that is currently listed on Google\'s list of known phishing sites. The URL is: %2$s', 'wordfence'),
1428
+ esc_html($type),
1429
+ esc_html($result['URL'])
1430
+ );
1431
+ } else if ($result['badList'] == 'wordfence-dbl') {
1432
+ $shortMsg = sprintf(/* translators: URL. */ __("%s contains a suspected malware URL.", 'wordfence'), $uctype);
1433
+ $longMsg = sprintf(
1434
+ /* translators: 1. WordPress post type. 2. URL. */
1435
+ __('This %1$s contains a URL that is currently listed on Wordfence\'s domain blocklist. The URL is: %2$s', 'wordfence'),
1436
+ esc_html($type),
1437
+ esc_html($result['URL'])
1438
+ );
1439
  }
1440
+
1441
+ if (is_multisite()) {
1442
  switch_to_blog($blogID);
1443
  }
1444
+
1445
  $ignoreP = $idString;
1446
  $ignoreC = $idString . '-' . $contentMD5;
1447
  $added = $this->addIssue('commentBadURL', wfIssues::SEVERITY_LOW, $ignoreP, $ignoreC, $shortMsg, $longMsg, array(
1448
+ 'commentID' => $commentID,
1449
+ 'badURL' => $result['URL'],
1450
+ 'author' => $author,
1451
+ 'type' => $type,
1452
+ 'uctype' => $uctype,
1453
  'editCommentLink' => get_edit_comment_link($commentID),
1454
+ 'commentDate' => $date,
1455
+ 'isMultisite' => $blog['isMultisite'],
1456
+ 'domain' => $blog['domain'],
1457
+ 'path' => $blog['path'],
1458
+ 'blog_id' => $blogID
1459
+ ));
1460
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1461
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1462
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1463
+ $haveIssues = wfIssues::STATUS_IGNORED;
1464
+ }
1465
+
1466
+ if (is_multisite()) {
1467
  restore_current_blog();
1468
  }
1469
  }
1472
  $this->scanController->completeStage(wfScanner::STAGE_CONTENT_SAFETY, $haveIssues);
1473
  $this->scanQueue = '';
1474
  }
1475
+
1476
+ public function isBadComment($author, $email, $url, $IP, $content) {
1477
  $content = $author . ' ' . $email . ' ' . $url . ' ' . $IP . ' ' . $content;
1478
  $cDesc = '';
1479
+ if ($author) {
1480
+ $cDesc = sprintf(/* translators: WordPress username. */ __("Author: %s", 'wordfence'), $author) . ' ';
1481
  }
1482
+ if ($email) {
1483
+ $cDesc .= sprintf(/* translators: Email address. */ __("Email: %s", 'wordfence'), $email) . ' ';
1484
  }
1485
+ $cDesc .= sprintf(/* translators: IP address. */ __("Source IP: %s", 'wordfence'), $IP) . ' ';
1486
+ $this->status(2, 'info', sprintf(/* translators: Comment description. */ __("Scanning comment with %s", 'wordfence'), $cDesc));
1487
 
1488
  $h = new wordfenceURLHoover($this->apiKey, $this->wp_version);
1489
  $h->hoover(1, $content, wordfenceURLHoover::standardExcludedHosts());
1490
  $hooverResults = $h->getBaddies();
1491
+ if ($h->errorMsg) {
1492
  return false;
1493
  }
1494
  $h->cleanup();
1495
+ if (sizeof($hooverResults) > 0 && isset($hooverResults[1])) {
1496
+ $hresults = $hooverResults[1];
1497
+ foreach ($hresults as $result) {
1498
+ if ($result['badList'] == 'goog-malware-shavar') {
1499
+ $this->status(2, 'info', sprintf(/* translators: Comment description. */ __("Marking comment as spam for containing a malware URL. Comment has %s", 'wordfence'), $cDesc));
1500
  return true;
1501
+ } else if ($result['badList'] == 'googpub-phish-shavar') {
1502
+ $this->status(2, 'info', sprintf(/* translators: Comment description. */ __("Marking comment as spam for containing a phishing URL. Comment has %s", 'wordfence'), $cDesc));
 
1503
  return true;
1504
+ } else if ($result['badList'] == 'wordfence-dbl') {
1505
+ $this->status(2, 'info', sprintf(/* translators: Comment description. */ __("Marking comment as spam for containing a malware URL. Comment has %s", 'wordfence'), $cDesc));
1506
+ } else {
 
 
1507
  //A list type that may be new and the plugin has not been upgraded yet.
1508
  continue;
1509
  }
1510
  }
1511
  }
1512
+ $this->status(2, 'info', sprintf(/* translators: Comment description. */ __("Scanned comment with %s", 'wordfence'), $cDesc));
1513
  return false;
1514
  }
1515
+
1516
+ public static function getBlogsToScan($table, $withID = null) {
1517
  $wfdb = new wfDB();
1518
  global $wpdb;
1519
  $blogsToScan = array();
1520
+ if (is_multisite()) {
1521
  if ($withID === null) {
1522
  $q1 = $wfdb->querySelect("select blog_id, domain, path from {$wpdb->blogs} where deleted=0 order by blog_id asc");
1523
+ } else {
 
1524
  $q1 = $wfdb->querySelect("select blog_id, domain, path from {$wpdb->blogs} where deleted=0 and blog_id = %d", $withID);
1525
  }
1526
+
1527
+ foreach ($q1 as $row) {
1528
  $row['isMultisite'] = true;
1529
  $row['table'] = wfDB::blogTable($table, $row['blog_id']);
1530
+ $blogsToScan[] = $row;
1531
  }
1532
  } else {
1533
  $blogsToScan[] = array(
1534
  'isMultisite' => false,
1535
+ 'table' => wfDB::networkTable($table),
1536
+ 'blog_id' => '1',
1537
+ 'domain' => '',
1538
+ 'path' => '',
1539
+ );
1540
  }
1541
  return $blogsToScan;
1542
  }
1543
+
1544
+ private function highestCap($caps) {
1545
+ foreach (array('administrator', 'editor', 'author', 'contributor', 'subscriber') as $cap) {
1546
+ if (empty($caps[$cap]) === false && $caps[$cap]) {
1547
  return $cap;
1548
  }
1549
  }
1550
  return '';
1551
  }
1552
+
1553
+ private function isEditor($caps) {
1554
+ foreach (array('contributor', 'author', 'editor', 'administrator') as $cap) {
1555
+ if (empty($caps[$cap]) === false && $caps[$cap]) {
1556
  return true;
1557
  }
1558
  }
1559
  return false;
1560
  }
1561
+
1562
+ private function scan_passwds_init() {
1563
+ $this->statusIDX['passwds'] = wfIssues::statusStart(__('Scanning for weak passwords', 'wordfence'));
1564
  $this->scanController->startStage(wfScanner::STAGE_PASSWORD_STRENGTH);
1565
  global $wpdb;
1566
  $counter = 0;
1571
  $result = $dbh->query($query);
1572
  if (!is_object($result)) {
1573
  return array(
1574
+ 'errorMsg' => __("We were unable to generate the user list for your password check.", 'wordfence'),
1575
  );
1576
  }
1577
  while ($rec = $result->fetch_assoc()) {
1578
  $this->userPasswdQueue .= pack('N', $rec['ID']);
1579
  $counter++;
1580
  }
1581
+ } else {
 
1582
  $res1 = $wpdb->get_results($query, ARRAY_A);
1583
+ foreach ($res1 as $rec) {
1584
  $this->userPasswdQueue .= pack('N', $rec['ID']);
1585
  $counter++;
1586
  }
1587
  }
1588
+ wordfence::status(2, 'info', sprintf(
1589
+ /* translators: Number of users. */
1590
+ _n("Starting password strength check on %d user.", "Starting password strength check on %d users.", $counter, 'wordfence'), $counter));
1591
  }
1592
+
1593
+ private function scan_passwds_main() {
1594
+ while (strlen($this->userPasswdQueue) > 3) {
1595
  $usersLeft = strlen($this->userPasswdQueue) / 4; //4 byte ints
1596
+ if ($usersLeft % 100 == 0) {
1597
+ wordfence::status(2, 'info', sprintf(
1598
+ /* translators: Number of users. */
1599
+ _n(
1600
+ "Total of %d users left to process in password strength check.",
1601
+ "Total of %d users left to process in password strength check.",
1602
+ $usersLeft,
1603
+ 'wordfence'),
1604
+ $usersLeft
1605
+ ));
1606
  }
1607
  $userID = unpack('N', substr($this->userPasswdQueue, 0, 4));
1608
  $userID = $userID[1];
1609
  $this->userPasswdQueue = substr($this->userPasswdQueue, 4);
1610
  $state = $this->scanUserPassword($userID);
1611
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_USERS);
1612
+ if ($state == wfIssues::STATUS_PROBLEM) {
1613
+ $this->passwdHasIssues = wfIssues::STATUS_PROBLEM;
1614
+ } else if ($this->passwdHasIssues != wfIssues::STATUS_PROBLEM && $state == wfIssues::STATUS_IGNORED) {
1615
+ $this->passwdHasIssues = wfIssues::STATUS_IGNORED;
1616
+ }
1617
+
1618
  $this->forkIfNeeded();
1619
  }
1620
  }
1621
+
1622
+ private function scan_passwds_finish() {
1623
  wfIssues::statusEnd($this->statusIDX['passwds'], $this->passwdHasIssues);
1624
  $this->scanController->completeStage(wfScanner::STAGE_PASSWORD_STRENGTH, $this->passwdHasIssues);
1625
  }
1626
+
1627
+ public function scanUserPassword($userID) {
1628
  $suspended = wp_suspend_cache_addition();
1629
  wp_suspend_cache_addition(true);
1630
  require_once(ABSPATH . 'wp-includes/class-phpass.php');
1631
  $passwdHasher = new PasswordHash(8, TRUE);
1632
  $userDat = get_userdata($userID);
1633
  if ($userDat === false) {
1634
+ wordfence::status(2, 'error', sprintf(/* translators: WordPress user ID. */ __("Could not get username for user with ID %d when checking password strength.", 'wordfence'), $userID));
1635
  return false;
1636
  }
1637
  //user_login
1638
+ $this->status(4, 'info', sprintf(
1639
+ /* translators: 1. WordPress username. 2. WordPress user ID. */
1640
+ __('Checking password strength of user \'%1$s\' with ID %2$d', 'wordfence'),
1641
+ $userDat->user_login,
1642
+ $userID
1643
+ ) . (function_exists('memory_get_usage') ? " (Mem:" . sprintf('%.1f', memory_get_usage(true) / (1024 * 1024)) . "M)" : ""));
1644
  $highCap = $this->highestCap($userDat->wp_capabilities);
1645
+ if ($this->isEditor($userDat->wp_capabilities)) {
1646
+ $shortMsg = sprintf(
1647
+ /* translators: 1. WordPress username. 2. WordPress capability. */
1648
+ __('User "%1$s" with "%2$s" access has an easy password.', 'wordfence'),
1649
+ esc_html($userDat->user_login),
1650
+ esc_html($highCap)
1651
+ );
1652
+ $longMsg = sprintf(
1653
+ /* translators: WordPress capability. */
1654
+ __("A user with the a role of '%s' has a password that is easy to guess. Please change this password yourself or ask the user to change it.", 'wordfence'),
1655
+ esc_html($highCap)
1656
+ );
1657
  $level = wfIssues::SEVERITY_CRITICAL;
1658
  $words = $this->dictWords;
1659
  } else {
1660
+ $shortMsg = sprintf(
1661
+ /* translators: WordPress username. */
1662
+ __("User \"%s\" with 'subscriber' access has a very easy password.", 'wordfence'), esc_html($userDat->user_login));
1663
+ $longMsg = __("A user with 'subscriber' access has a password that is very easy to guess. Please either change it or ask the user to change their password.", 'wordfence');
1664
  $level = wfIssues::SEVERITY_HIGH;
1665
  $words = array($userDat->user_login);
1666
  }
1667
  $haveIssues = wfIssues::STATUS_SECURE;
1668
+ for ($i = 0; $i < sizeof($words); $i++) {
1669
+ if ($passwdHasher->CheckPassword($words[$i], $userDat->user_pass)) {
1670
+ $this->status(2, 'info', sprintf(/* translators: Scan result description. */ __('Adding issue %s', 'wordfence'), $shortMsg));
1671
  $added = $this->addIssue('easyPassword', $level, $userDat->ID, $userDat->ID . '-' . $userDat->user_pass, $shortMsg, $longMsg, array(
1672
+ 'ID' => $userDat->ID,
1673
+ 'user_login' => $userDat->user_login,
1674
+ 'user_email' => $userDat->user_email,
1675
+ 'first_name' => $userDat->first_name,
1676
+ 'last_name' => $userDat->last_name,
1677
  'editUserLink' => wfUtils::editUserLink($userDat->ID)
1678
+ ));
1679
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1680
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1681
+ } else if ($haveIssues != wfIssues::STATUS_SECURE && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1682
+ $haveIssues = wfIssues::STATUS_IGNORED;
1683
+ }
1684
  break;
1685
  }
1686
  }
1687
+ $this->status(4, 'info', sprintf(/* translators: WordPress username. */ __("Completed checking password strength of user '%s'", 'wordfence'), $userDat->user_login));
1688
  wp_suspend_cache_addition($suspended);
1689
  return $haveIssues;
1690
  }
1691
+
1692
  /*
1693
  private function scan_sitePages(){
1694
  if(is_multisite()){ return; } //Multisite not supported by this function yet
1729
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, wfIssues::STATUS_SECURE);
1730
  return;
1731
  }
1732
+
1733
+
1734
+ $this->status(2, 'info', sprintf(
1735
+ /* translators: 1. Number of bytes. 2. Number of bytes. */
1736
+ __('Total disk space: %1$s -- Free disk space: %2$s', 'wordfence'),
1737
+ wfUtils::formatBytes($total),
1738
+ wfUtils::formatBytes($free)
1739
+ ));
1740
  $freeMegs = round($free / 1024 / 1024, 2);
1741
+ $this->status(2, 'info', sprintf(/* translators: Number of bytes. */ __('The disk has %s MB available', 'wordfence'), $freeMegs));
1742
  if ($freeMegs < 5) {
1743
  $level = wfIssues::SEVERITY_CRITICAL;
1744
+ } else if ($freeMegs < 20) {
 
1745
  $level = wfIssues::SEVERITY_HIGH;
1746
+ } else {
 
1747
  wfIssues::statusEnd($this->statusIDX['diskSpace'], wfIssues::STATUS_SECURE);
1748
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, wfIssues::STATUS_SECURE);
1749
  return;
1750
  }
1751
  $haveIssues = wfIssues::STATUS_SECURE;
1752
+ $added = $this->addIssue('diskSpace',
1753
+ $level,
1754
+ 'diskSpace',
1755
+ 'diskSpace' . $level,
1756
+ sprintf(/* translators: Number of bytes. */ __('You have %s disk space remaining', 'wordfence'), wfUtils::formatBytes($free)),
1757
+ sprintf(/* translators: Number of bytes. */ __('You only have %s of your disk space remaining. Please free up disk space or your website may stop serving requests.', 'wordfence'), wfUtils::formatBytes($free)),
1758
  array('spaceLeft' => wfUtils::formatBytes($free))
1759
  );
1760
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1761
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1762
+ } else if ($haveIssues != wfIssues::STATUS_SECURE && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1763
+ $haveIssues = wfIssues::STATUS_IGNORED;
1764
+ }
1765
  wfIssues::statusEnd($this->statusIDX['diskSpace'], $haveIssues);
1766
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
1767
  }
1768
+
1769
  private function scan_wafStatus() {
1770
  $this->statusIDX['wafStatus'] = wfIssues::statusStart(__('Checking Web Application Firewall status', 'wordfence'));
1771
  $this->scanController->startStage(wfScanner::STAGE_SERVER_STATE);
1772
+
1773
  $haveIssues = wfIssues::STATUS_SECURE;
1774
  $added = false;
1775
  $firewall = new wfFirewall();
1779
  'wafStatus',
1780
  'wafStatus' . $firewall->firewallMode(),
1781
  __('Web Application Firewall is disabled', 'wordfence'),
1782
+ sprintf(/* translators: Support URL. */ __('Wordfence\'s Web Application Firewall has been unexpectedly disabled. If you see a notice at the top of the Wordfence admin pages that says "The Wordfence Web Application Firewall cannot run," click the link in that message to rebuild the configuration. If this does not work, you may need to fix file permissions. <a href="%s" target="_blank" rel="noopener noreferrer">More Details</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_WAF_DISABLED)),
1783
  array('wafStatus' => $firewall->firewallMode(), 'wafStatusDisplay' => $firewall->displayText())
1784
  );
1785
  }
1786
+
1787
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1788
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1789
+ } else if ($haveIssues != wfIssues::STATUS_SECURE && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1790
+ $haveIssues = wfIssues::STATUS_IGNORED;
1791
+ }
1792
  wfIssues::statusEnd($this->statusIDX['wafStatus'], $haveIssues);
1793
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
1794
  }
1795
+
1796
  private function scan_oldVersions_init() {
1797
+ $this->statusIDX['oldVersions'] = wfIssues::statusStart(__("Scanning for old themes, plugins and core files", 'wordfence'));
1798
  $this->scanController->startStage(wfScanner::STAGE_VULNERABILITY_SCAN);
1799
+
1800
  $this->updateCheck = new wfUpdateCheck();
1801
  if ($this->isFullScan()) {
1802
  $this->updateCheck->checkAllUpdates(false);
1803
  $this->updateCheck->checkAllVulnerabilities();
1804
+ } else {
 
1805
  $this->updateCheck->checkAllUpdates();
1806
  }
1807
+
1808
  foreach ($this->updateCheck->getPluginSlugs() as $slug) {
1809
  $this->pluginRepoStatus[$slug] = false;
1810
  }
1811
+
1812
  //Strip plugins that have a pending update
1813
  if (count($this->updateCheck->getPluginUpdates()) > 0) {
1814
  foreach ($this->updateCheck->getPluginUpdates() as $plugin) {
1818
  }
1819
  }
1820
  }
1821
+
1822
  private function scan_oldVersions_main() {
1823
  if (!$this->isFullScan()) {
1824
  return;
1825
  }
1826
+
1827
  if (!function_exists('plugins_api')) {
1828
  require_once(ABSPATH . 'wp-admin/includes/plugin-install.php');
1829
  }
1830
+
1831
  foreach ($this->pluginRepoStatus as $slug => $status) {
1832
  if ($status === false) {
1833
  $result = plugins_api('plugin_information', array(
1834
+ 'slug' => $slug,
1835
  'fields' => array(
1836
  'short_description' => false,
1837
+ 'description' => false,
1838
+ 'sections' => false,
1839
+ 'tested' => true,
1840
+ 'requires' => true,
1841
+ 'rating' => false,
1842
+ 'ratings' => false,
1843
+ 'downloaded' => false,
1844
+ 'downloadlink' => false,
1845
+ 'last_updated' => true,
1846
+ 'added' => false,
1847
+ 'tags' => false,
1848
+ 'compatibility' => true,
1849
+ 'homepage' => true,
1850
+ 'versions' => false,
1851
+ 'donate_link' => false,
1852
+ 'reviews' => false,
1853
+ 'banners' => false,
1854
+ 'icons' => false,
1855
+ 'active_installs' => false,
1856
+ 'group' => false,
1857
+ 'contributors' => false,
1858
  ),
1859
  ));
1860
  unset($result->versions);
1861
  unset($result->screenshots);
1862
  $this->pluginRepoStatus[$slug] = $result;
1863
+
1864
  $this->forkIfNeeded();
1865
  }
1866
  }
1868
 
1869
  private function scan_oldVersions_finish() {
1870
  $haveIssues = wfIssues::STATUS_SECURE;
1871
+
1872
  if (!$this->isFullScan()) {
1873
  $this->deleteNewIssues(array('wfUpgrade', 'wfPluginUpgrade', 'wfThemeUpgrade'));
1874
  }
1875
 
1876
  // WordPress core updates needed
1877
  if ($this->updateCheck->needsCoreUpdate()) {
1878
+ $added = $this->addIssue(
1879
+ 'wfUpgrade',
1880
+ wfIssues::SEVERITY_HIGH,
1881
+ 'wfUpgrade' . $this->updateCheck->getCoreUpdateVersion(),
1882
+ 'wfUpgrade' . $this->updateCheck->getCoreUpdateVersion(),
1883
+ __("Your WordPress version is out of date", 'wordfence'),
1884
+ sprintf(/* translators: Software version. */ __("WordPress version %s is now available. Please upgrade immediately to get the latest security updates from WordPress.", 'wordfence'), esc_html($this->updateCheck->getCoreUpdateVersion())),
1885
+ array(
1886
+ 'currentVersion' => $this->wp_version,
1887
+ 'newVersion' => $this->updateCheck->getCoreUpdateVersion(),
1888
+ )
1889
+ );
1890
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1891
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1892
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1893
+ $haveIssues = wfIssues::STATUS_IGNORED;
1894
+ }
1895
  }
1896
+
1897
  $allPlugins = $this->updateCheck->getAllPlugins();
1898
 
1899
  // Plugin updates needed
1906
  }
1907
  }
1908
  $key = 'wfPluginUpgrade' . ' ' . $plugin['pluginFile'] . ' ' . $plugin['newVersion'] . ' ' . $plugin['Version'];
1909
+ $shortMsg = sprintf(
1910
+ /* translators: 1. Plugin name. 2. Software version. 3. Software version. */
1911
+ __('The Plugin "%1$s" needs an upgrade (%2$s -> %3$s).', 'wordfence'),
1912
+ empty($plugin['Name']) ? $plugin['pluginFile'] : $plugin['Name'],
1913
+ $plugin['Version'],
1914
+ $plugin['newVersion']
1915
+ );
1916
+ $added = $this->addIssue('wfPluginUpgrade', $severity, $key, $key, $shortMsg,
1917
+ sprintf(
1918
+ __("You need to upgrade \"%s\" to the newest version to ensure you have any security fixes the developer has released.", 'wordfence'),
1919
+ empty($plugin['Name']) ? $plugin['pluginFile'] : $plugin['Name']
1920
+ ), $plugin);
1921
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1922
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1923
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1924
+ $haveIssues = wfIssues::STATUS_IGNORED;
1925
+ }
1926
+
1927
  if (isset($plugin['slug'])) {
1928
  unset($allPlugins[$plugin['slug']]);
1929
  }
1940
  }
1941
  }
1942
  $key = 'wfThemeUpgrade' . ' ' . $theme['Name'] . ' ' . $theme['version'] . ' ' . $theme['newVersion'];
1943
+ $shortMsg = sprintf(
1944
+ /* translators: 1. Theme name. 2. Software version. 3. Software version. */
1945
+ __('The Theme "%1$s" needs an upgrade (%2$s -> %3$s).', 'wordfence'),
1946
+ $theme['Name'],
1947
+ $theme['version'],
1948
+ $theme['newVersion']
1949
+ );
1950
+ $added = $this->addIssue('wfThemeUpgrade', $severity, $key, $key, $shortMsg, sprintf(
1951
+ /* translators: Theme name. */
1952
+ __("You need to upgrade \"%s\" to the newest version to ensure you have any security fixes the developer has released.", 'wordfence'),
1953
+ esc_html($theme['Name'])
1954
+ ), $theme);
1955
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
1956
+ $haveIssues = wfIssues::STATUS_PROBLEM;
1957
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
1958
+ $haveIssues = wfIssues::STATUS_IGNORED;
1959
+ }
1960
  }
1961
  }
1962
+
1963
  if ($this->isFullScan()) {
1964
  //Abandoned plugins
1965
  foreach ($this->pluginRepoStatus as $slug => $status) {
1979
  $statusArray['vulnerabilityLink'] = $vulnerable;
1980
  }
1981
  }
1982
+
1983
  if (isset($allPlugins[$slug]) && isset($allPlugins[$slug]['wpURL'])) {
1984
  $statusArray['wpURL'] = $allPlugins[$slug]['wpURL'];
1985
  }
1986
+
1987
+ $key = "wfPluginAbandoned {$slug} {$statusArray['version']}";
 
1988
  if (isset($statusArray['tested'])) {
1989
+ $shortMsg = sprintf(
1990
+ /* translators: 1. Plugin name. 2. Software version. 3. Software version. */
1991
+ __('The Plugin "%1$s" appears to be abandoned (updated %2$s, tested to WP %3$s).', 'wordfence'),
1992
+ (empty($statusArray['name']) ? $slug : $statusArray['name']),
1993
+ wfUtils::formatLocalTime(get_option('date_format'), $lastUpdateTimestamp),
1994
+ $statusArray['tested']
1995
+ );
1996
+ $longMsg = sprintf(
1997
+ /* translators: 1. Plugin name. 2. Software version. */
1998
+ __('It was last updated %1$s ago and tested up to WordPress %2$s.', 'wordfence'),
1999
+ wfUtils::makeTimeAgo(time() - $lastUpdateTimestamp),
2000
+ esc_html($statusArray['tested'])
2001
+ );
2002
+ } else {
2003
+ $shortMsg = sprintf(
2004
+ /* translators: 1. Plugin name. 2. Software version. */
2005
+ __('The Plugin "%1$s" appears to be abandoned (updated %2$s).', 'wordfence'),
2006
+ (empty($statusArray['name']) ? $slug : $statusArray['name']),
2007
+ wfUtils::formatLocalTime(get_option('date_format'), $lastUpdateTimestamp)
2008
+ );
2009
+ $longMsg = sprintf(
2010
+ /* translators: Time duration. */
2011
+ __('It was last updated %s ago.', 'wordfence'),
2012
+ wfUtils::makeTimeAgo(time() - $lastUpdateTimestamp)
2013
+ );
2014
  }
2015
+
 
 
 
2016
  if ($statusArray['vulnerable']) {
2017
+ $longMsg .= ' ' . __('It has unpatched security issues and may have compatibility problems with the current version of WordPress.', 'wordfence');
2018
+ } else {
2019
+ $longMsg .= ' ' . __('Plugins can be removed from wordpress.org for various reasons. This can include benign issues like a plugin author discontinuing development or moving the plugin distribution to their own site, but some might also be due to security issues. In any case, future updates may or may not be available, so it is worth investigating the cause and deciding whether to temporarily or permanently replace or remove the plugin.', 'wordfence');
 
2020
  }
2021
+ $longMsg .= ' ' . sprintf(
2022
+ /* translators: Support URL. */
2023
+ __('<a href="%s" target="_blank" rel="noopener noreferrer">Get more information.</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_PLUGIN_ABANDONED));
2024
  $added = $this->addIssue('wfPluginAbandoned', $severity, $key, $key, $shortMsg, $longMsg, $statusArray);
2025
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
2026
+ $haveIssues = wfIssues::STATUS_PROBLEM;
2027
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
2028
+ $haveIssues = wfIssues::STATUS_IGNORED;
2029
+ }
2030
+
2031
  unset($allPlugins[$slug]);
2032
  }
2033
+ } else if ($status !== false && is_wp_error($status) && isset($status->errors['plugins_api_failed'])) { //The plugin does not exist in the wp.org repo
 
2034
  $knownFiles = $this->getKnownFilesLoader()->getKnownFiles();
2035
  if (isset($knownFiles['status']) && is_array($knownFiles['status']) && isset($knownFiles['status']['plugins']) && is_array($knownFiles['status']['plugins'])) {
2036
  $requestedPlugins = $this->getPlugins();
2047
  $pluginData['vulnerabilityLink'] = $vulnerable;
2048
  }
2049
  }
2050
+
2051
  $key = "wfPluginRemoved {$slug} {$pluginData['Version']}";
2052
+ $shortMsg = sprintf(
2053
+ /* translators: Plugin name. */
2054
+ __('The Plugin "%s" has been removed from wordpress.org.', 'wordfence'), (empty($pluginData['Name']) ? $slug : $pluginData['Name']));
2055
  if ($pluginData['vulnerable']) {
2056
+ $longMsg = __('It has unpatched security issues and may have compatibility problems with the current version of WordPress.', 'wordfence');
2057
+ } else {
2058
+ $longMsg = __('Plugins can be removed from wordpress.org for various reasons. This can include benign issues like a plugin author discontinuing development or moving the plugin distribution to their own site, but some might also be due to security issues. In any case, future updates may or may not be available, so it is worth investigating the cause and deciding whether to temporarily or permanently replace or remove the plugin.', 'wordfence');
 
2059
  }
2060
+ $longMsg .= ' ' . sprintf(
2061
+ /* translators: Support URL. */
2062
+ __('<a href="%s" target="_blank" rel="noopener noreferrer">Get more information.</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_PLUGIN_REMOVED));
2063
  $added = $this->addIssue('wfPluginRemoved', wfIssues::SEVERITY_CRITICAL, $key, $key, $shortMsg, $longMsg, $pluginData);
2064
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
2065
+ $haveIssues = wfIssues::STATUS_PROBLEM;
2066
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
2067
+ $haveIssues = wfIssues::STATUS_IGNORED;
2068
+ }
2069
+
2070
  unset($allPlugins[$slug]);
2071
  }
2072
  }
2073
  }
2074
  }
2075
  }
2076
+
2077
  //Other vulnerable plugins
2078
  //Disabled until we improve the data source to weed out false positives
2079
  /*if (count($allPlugins) > 0) {
2095
  }
2096
  }*/
2097
  }
2098
+
2099
  $this->updateCheck = false;
2100
  $this->pluginRepoStatus = array();
2101
 
2104
  }
2105
 
2106
  public function scan_suspiciousAdminUsers() {
2107
+ $this->statusIDX['suspiciousAdminUsers'] = wfIssues::statusStart(__("Scanning for admin users not created through WordPress", 'wordfence'));
2108
  $this->scanController->startStage(wfScanner::STAGE_OPTIONS_AUDIT);
2109
  $haveIssues = wfIssues::STATUS_SECURE;
2110
 
2126
  $user = new WP_User($userID);
2127
  $key = 'suspiciousAdminUsers' . $userID;
2128
  $added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
2129
+ sprintf(/* translators: WordPress username. */ __("An admin user with the username %s was created outside of WordPress.", 'wordfence'), esc_html($user->user_login)),
2130
+ sprintf(/* translators: WordPress username. */ __("An admin user with the username %s was created outside of WordPress. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it.", 'wordfence'), esc_html($user->user_login)),
2131
  array(
2132
  'userID' => $userID,
2133
  ));
2134
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
2135
+ $haveIssues = wfIssues::STATUS_PROBLEM;
2136
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
2137
+ $haveIssues = wfIssues::STATUS_IGNORED;
2138
+ }
2139
  }
2140
  }
2141
 
2153
  foreach ($suspiciousAdminUsernames as $usernamePattern) {
2154
  if (preg_match($usernamePattern, $adminUser->user_login)) {
2155
  $added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
2156
+ sprintf(/* translators: WordPress username. */ __("An admin user with a suspicious username %s was found.", 'wordfence'), esc_html($adminUser->user_login)),
2157
+ sprintf(/* translators: WordPress username. */ __("An admin user with a suspicious username %s was found. Administrators accounts with usernames similar to this are commonly seen created by hackers. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it.", 'wordfence'), esc_html($adminUser->user_login)),
2158
  array(
2159
  'userID' => $userID,
2160
  ));
2162
  }
2163
  }
2164
 
2165
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
2166
+ $haveIssues = wfIssues::STATUS_PROBLEM;
2167
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
2168
+ $haveIssues = wfIssues::STATUS_IGNORED;
2169
+ }
2170
  }
2171
  }
2172
 
2173
  wfIssues::statusEnd($this->statusIDX['suspiciousAdminUsers'], $haveIssues);
2174
  $this->scanController->completeStage(wfScanner::STAGE_OPTIONS_AUDIT, $haveIssues);
2175
  }
2176
+
2177
  public function scan_suspiciousOptions() {
2178
+ $this->statusIDX['suspiciousOptions'] = wfIssues::statusStart(__("Scanning for suspicious site options", 'wordfence'));
2179
  $this->scanController->startStage(wfScanner::STAGE_OPTIONS_AUDIT);
2180
  $haveIssues = wfIssues::STATUS_SECURE;
2181
+
2182
  $blogsToScan = self::getBlogsToScan('options');
2183
  $wfdb = new wfDB();
2184
+
2185
  $this->hoover = new wordfenceURLHoover($this->apiKey, $this->wp_version);
2186
  foreach ($blogsToScan as $blog) {
2187
  $excludedHosts = array();
2196
  $excludedHosts[$host] = 1;
2197
  }
2198
  $excludedHosts = array_keys($excludedHosts);
2199
+
2200
  //Newspaper Theme
2201
  if (defined('TD_THEME_OPTIONS_NAME')) {
2202
  $q = $wfdb->querySelect("SELECT option_name, option_value FROM " . $blog['table'] . " WHERE option_name REGEXP '^td_[0-9]+$' OR option_name = '%s'", TD_THEME_OPTIONS_NAME);
2203
+ } else {
 
2204
  $q = $wfdb->querySelect("SELECT option_name, option_value FROM " . $blog['table'] . " WHERE option_name REGEXP '^td_[0-9]+$'");
2205
  }
2206
  foreach ($q as $row) {
2208
  $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, $found);
2209
  }
2210
  }
2211
+
2212
+
2213
+ $this->status(2, 'info', __("Examining URLs found in the options we scanned for dangerous websites", 'wordfence'));
2214
  $hooverResults = $this->hoover->getBaddies();
2215
+ $this->status(2, 'info', __("Done examining URLs", 'wordfence'));
2216
  if ($this->hoover->errorMsg) {
2217
  wfIssues::statusEndErr();
2218
  throw new Exception($this->hoover->errorMsg);
2227
  if ($result['badList'] != 'goog-malware-shavar' && $result['badList'] != 'googpub-phish-shavar' && $result['badList'] != 'wordfence-dbl') {
2228
  continue; //A list type that may be new and the plugin has not been upgraded yet.
2229
  }
2230
+
2231
  if ($blog === null) {
2232
  $blogs = self::getBlogsToScan('options', $blogID);
2233
  $blog = array_shift($blogs);
2234
  }
2235
+
2236
  if ($result['badList'] == 'goog-malware-shavar') {
2237
+ $shortMsg = sprintf(/* translators: URL. */ __("Option contains a suspected malware URL: %s", 'wordfence'), esc_html($optionKey));
2238
+ $longMsg = sprintf(/* translators: URL. */ __("This option contains a suspected malware URL listed on Google's list of malware sites. It may indicate your site is infected with malware. The URL is: %s", 'wordfence'), esc_html($result['URL']));
2239
+ } else if ($result['badList'] == 'googpub-phish-shavar') {
2240
+ $shortMsg = sprintf(/* translators: URL. */ __("Option contains a suspected phishing site URL: %s", 'wordfence'), esc_html($optionKey));
2241
+ $longMsg = sprintf(/* translators: URL. */ __("This option contains a URL that is a suspected phishing site that is currently listed on Google's list of known phishing sites. It may indicate your site is infected with malware. The URL is: %s", 'wordfence'), esc_html($result['URL']));
2242
+ } else if ($result['badList'] == 'wordfence-dbl') {
2243
+ $shortMsg = sprintf(/* translators: URL. */ __("Option contains a suspected malware URL: %s", 'wordfence'), esc_html($optionKey));
2244
+ $longMsg = sprintf(/* translators: URL. */ __("This option contains a URL that is currently listed on Wordfence's domain blocklist. It may indicate your site is infected with malware. The URL is: %s", 'wordfence'), esc_html($result['URL']));
2245
+ } else {
 
 
 
2246
  //A list type that may be new and the plugin has not been upgraded yet.
2247
  continue;
2248
  }
2249
+
2250
+ $longMsg .= ' - ' . sprintf(/* translators: Support URL. */ __('<a href="%s" target="_blank" rel="noopener noreferrer">Get more information.</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_OPTION_MALWARE_URL));
2251
+
2252
+ $this->status(2, 'info', sprintf(/* translators: Scan result description. */ __("Adding issue: %s", 'wordfence'), $shortMsg));
2253
+
2254
  if (is_multisite()) {
2255
  switch_to_blog($blogID);
2256
  }
2257
+
2258
  $ignoreP = $idString;
2259
  $ignoreC = $idString . md5(serialize(get_option($optionKey, '')));
2260
  $added = $this->addIssue('optionBadURL', wfIssues::SEVERITY_HIGH, $ignoreP, $ignoreC, $shortMsg, $longMsg, array(
2261
+ 'optionKey' => $optionKey,
2262
+ 'badURL' => $result['URL'],
2263
  'isMultisite' => $blog['isMultisite'],
2264
+ 'domain' => $blog['domain'],
2265
+ 'path' => $blog['path'],
2266
+ 'blog_id' => $blogID
2267
  ));
2268
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
2269
+ $haveIssues = wfIssues::STATUS_PROBLEM;
2270
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
2271
+ $haveIssues = wfIssues::STATUS_IGNORED;
2272
+ }
2273
  if (is_multisite()) {
2274
  restore_current_blog();
2275
  }
2276
  }
2277
  }
2278
+
2279
  wfIssues::statusEnd($this->statusIDX['suspiciousOptions'], $haveIssues);
2280
  $this->scanController->completeStage(wfScanner::STAGE_OPTIONS_AUDIT, $haveIssues);
2281
  }
2282
+
2283
  public function scan_geoipSupport() {
2284
+ $this->statusIDX['geoipSupport'] = wfIssues::statusStart(__("Checking for future GeoIP support", 'wordfence'));
2285
  $this->scanController->startStage(wfScanner::STAGE_SERVER_STATE);
2286
  $haveIssues = wfIssues::STATUS_SECURE;
2287
+
2288
  if (version_compare(phpversion(), '5.4') < 0 && wfConfig::get('isPaid') && wfBlock::hasCountryBlock()) {
2289
  $shortMsg = __('PHP Update Needed for Country Blocking', 'wordfence');
2290
+ $longMsg = sprintf(/* translators: Software version. */ __('The GeoIP database that is required for country blocking has been updated to a new format. This new format requires sites to run PHP 5.4 or newer, and this site is on PHP %s. To ensure country blocking continues functioning, please update PHP.', 'wordfence'), wfUtils::cleanPHPVersion());
2291
+
2292
+ $longMsg .= ' ' . sprintf(/* translators: Support URL. */ __('<a href="%s" target="_blank" rel="noopener noreferrer">Get more information.</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_RESULT_GEOIP_UPDATE));
2293
+
2294
+ $this->status(2, 'info', sprintf(/* translators: Scan result description. */ __("Adding issue: %s", 'wordfence'), $shortMsg));
2295
+
2296
  $ignoreP = 'geoIPPHPDiscontinuing';
2297
  $ignoreC = $ignoreP;
2298
  $added = $this->addIssue('geoipSupport', wfIssues::SEVERITY_MEDIUM, $ignoreP, $ignoreC, $shortMsg, $longMsg, array());
2299
+ if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) {
2300
+ $haveIssues = wfIssues::STATUS_PROBLEM;
2301
+ } else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) {
2302
+ $haveIssues = wfIssues::STATUS_IGNORED;
2303
+ }
2304
  }
2305
+
2306
  wfIssues::statusEnd($this->statusIDX['geoipSupport'], $haveIssues);
2307
  $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
2308
  }
2309
 
2310
+ public function status($level, $type, $msg) {
2311
  wordfence::status($level, $type, $msg);
2312
  }
2313
+
2314
  public function addIssue($type, $severity, $ignoreP, $ignoreC, $shortMsg, $longMsg, $templateData, $alreadyHashed = false) {
2315
  wfIssues::updateScanStillRunning();
2316
  return $this->i->addIssue($type, $severity, $ignoreP, $ignoreC, $shortMsg, $longMsg, $templateData, $alreadyHashed);
2317
  }
2318
+
2319
+ public function addPendingIssue($type, $severity, $ignoreP, $ignoreC, $shortMsg, $longMsg, $templateData) {
2320
  wfIssues::updateScanStillRunning();
2321
  return $this->i->addPendingIssue($type, $severity, $ignoreP, $ignoreC, $shortMsg, $longMsg, $templateData);
2322
  }
2323
+
2324
  public function getPendingIssueCount() {
2325
  return $this->i->getPendingIssueCount();
2326
  }
2327
+
2328
  public function getPendingIssues($offset = 0, $limit = 100) {
2329
  return $this->i->getPendingIssues($offset, $limit);
2330
  }
2331
+
2332
+ public static function requestKill() {
2333
  wfConfig::set('wfKillRequested', time(), wfConfig::DONT_AUTOLOAD);
2334
  }
2335
+
2336
+ public static function checkForKill() {
2337
  $kill = wfConfig::get('wfKillRequested', 0);
2338
+ if ($kill && time() - $kill < 600) { //Kill lasts for 10 minutes
2339
+ wordfence::status(10, 'info', "SUM_KILLED:" . __('Previous scan was stopped successfully.', 'wordfence'));
2340
+ throw new Exception(__("Scan was stopped on administrator request.", 'wordfence'), wfScanEngine::SCAN_MANUALLY_KILLED);
2341
  }
2342
  }
2343
+
2344
+ public static function startScan($isFork = false, $scanMode = false) {
2345
+ if (!defined('DONOTCACHEDB')) {
2346
+ define('DONOTCACHEDB', true);
2347
+ }
2348
+
2349
  if ($scanMode === false) {
2350
  $scanMode = wfScanner::shared()->scanType();
2351
  }
2352
+
2353
+ if (!$isFork) { //beginning of scan
2354
+ wfConfig::inc('totalScansRun');
2355
+ wfConfig::set('wfKillRequested', 0, wfConfig::DONT_AUTOLOAD);
2356
+ wordfence::status(4, 'info', __("Entering start scan routine", 'wordfence'));
2357
  if (wfScanner::shared()->isRunning()) {
2358
  wfUtils::getScanFileError();
2359
+ return __("A scan is already running. Use the stop scan button if you would like to terminate the current scan.", 'wordfence');
2360
  }
2361
  wfConfig::set('currentCronKey', ''); //Ensure the cron key is cleared
2362
  }
2365
  if (!wfConfig::get('startScansRemotely', false)) {
2366
  try {
2367
  $testResult = wp_remote_post($testURL, array(
2368
+ 'timeout' => $timeout,
2369
+ 'blocking' => true,
2370
  'sslverify' => false,
2371
+ 'headers' => array()
2372
  ));
2373
+ } catch (Exception $e) {
 
2374
  //Fall through to the remote start test below
2375
  }
2376
+
2377
+ wordfence::status(4, 'info', sprintf(/* translators: Support URL. */ __("Test result of scan start URL fetch: %s", 'wordfence'), var_export($testResult, true)));
2378
  }
2379
+
2380
  $cronKey = wfUtils::bigRandomHex();
2381
  wfConfig::set('currentCronKey', time() . ',' . $cronKey);
2382
  if ((!wfConfig::get('startScansRemotely', false)) && (!is_wp_error($testResult)) && (is_array($testResult) || $testResult instanceof ArrayAccess) && strstr($testResult['body'], 'WFSCANTESTOK') !== false) {
2383
  //ajax requests can be sent by the server to itself
2384
  $cronURL = self::_localStartURL($isFork, $scanMode, $cronKey);
2385
  $headers = array('Referer' => false/*, 'Cookie' => 'XDEBUG_SESSION=1'*/);
2386
+ wordfence::status(4, 'info', sprintf(/* translators: WordPress admin panel URL. */ __("Starting cron with normal ajax at URL %s", 'wordfence'), $cronURL));
2387
+
2388
  try {
2389
  wfConfig::set('scanStartAttempt', time());
2390
  $response = wp_remote_get($cronURL, array(
2391
+ 'timeout' => 0.01,
2392
+ 'blocking' => false,
2393
  'sslverify' => false,
2394
+ 'headers' => $headers
2395
+ ));
2396
  if (wfCentral::isConnected()) {
2397
  wfCentral::updateScanStatus();
2398
  }
2399
+ } catch (Exception $e) {
 
2400
  wfConfig::set('lastScanCompleted', $e->getMessage());
2401
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
2402
  return false;
2403
  }
2404
+
2405
  if (is_wp_error($response)) {
2406
  $error_message = $response->get_error_message();
2407
+ if ($error_message) {
2408
+ $lastScanCompletedMessage = sprintf(/* translators: Error message. */ __("There was an error starting the scan: %s.", 'wordfence'), $error_message);
2409
+ } else {
2410
+ $lastScanCompletedMessage = __("There was an unknown error starting the scan.", 'wordfence');
2411
+ }
2412
+
2413
+ wfConfig::set('lastScanCompleted', $lastScanCompletedMessage);
2414
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
2415
  }
2416
+
2417
+ wordfence::status(4, 'info', __("Scan process ended after forking.", 'wordfence'));
2418
+ } else {
 
2419
  $cronURL = self::_remoteStartURL($isFork, $scanMode, $cronKey);
2420
  $headers = array();
2421
+ wordfence::status(4, 'info', sprintf(/* translators: WordPress admin panel URL. */ __("Starting cron via proxy at URL %s", 'wordfence'), $cronURL));
2422
+
2423
  try {
2424
  wfConfig::set('scanStartAttempt', time());
2425
  $response = wp_remote_get($cronURL, array(
2426
+ 'timeout' => 0.01,
2427
+ 'blocking' => false,
2428
  'sslverify' => false,
2429
+ 'headers' => $headers
2430
+ ));
2431
  if (wfCentral::isConnected()) {
2432
  wfCentral::updateScanStatus();
2433
  }
2434
+ } catch (Exception $e) {
 
2435
  wfConfig::set('lastScanCompleted', $e->getMessage());
2436
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
2437
  return false;
2438
  }
2439
+
2440
  if (is_wp_error($response)) {
2441
  $error_message = $response->get_error_message();
2442
+ if ($error_message) {
2443
+ $lastScanCompletedMessage = sprintf(/* translators: WordPress admin panel URL. */ __("There was an error starting the scan: %s.", 'wordfence'), $error_message);
2444
+ } else {
2445
+ $lastScanCompletedMessage = __("There was an unknown error starting the scan.", 'wordfence');
2446
+ }
2447
+ wfConfig::set('lastScanCompleted', $lastScanCompletedMessage);
2448
  wfConfig::set('lastScanFailureType', wfIssues::SCAN_FAILED_CALLBACK_TEST_FAILED);
2449
  }
2450
+
2451
+ wordfence::status(4, 'info', __("Scan process ended after forking.", 'wordfence'));
2452
  }
2453
  return false; //No error
2454
  }
2455
+
2456
  public static function verifyStartSignature($signature, $isFork, $scanMode, $cronKey, $remote) {
2457
  $url = self::_baseStartURL($isFork, $scanMode, $cronKey);
2458
  if ($remote) {
2462
  $test = self::_signStartURL($url);
2463
  return hash_equals($signature, $test);
2464
  }
2465
+
2466
  protected static function _baseStartURL($isFork, $scanMode, $cronKey) {
2467
  $url = admin_url('admin-ajax.php');
2468
  $url .= '?action=wordfence_doScan&isFork=' . ($isFork ? '1' : '0') . '&scanMode=' . urlencode($scanMode) . '&cronKey=' . urlencode($cronKey);
2469
  return $url;
2470
  }
2471
+
2472
  protected static function _localStartURL($isFork, $scanMode, $cronKey) {
2473
  $url = self::_baseStartURL($isFork, $scanMode, $cronKey);
2474
  return add_query_arg('signature', self::_signStartURL($url), $url);
2475
  }
2476
+
2477
  protected static function _remoteStartURL($isFork, $scanMode, $cronKey) {
2478
  $url = self::_baseStartURL($isFork, $scanMode, $cronKey);
2479
  $url = preg_replace('/^https?:\/\//i', (wfAPI::SSLEnabled() ? WORDFENCE_API_URL_SEC : WORDFENCE_API_URL_NONSEC) . 'scanp/', $url);
2481
  $url = add_query_arg('ssl', wfUtils::isFullSSL() ? '1' : '0', $url);
2482
  return add_query_arg('signature', self::_signStartURL($url), $url);
2483
  }
2484
+
2485
  protected static function _signStartURL($url) {
2486
  $payload = preg_replace('~^https?://[^/]+~i', '', $url);
2487
  return wfCrypt::local_sign($payload);
2488
  }
2489
+
2490
+ public function processResponse($result) {
2491
  return false;
2492
  }
2493
+
2494
  public static function getMaxExecutionTime($staySilent = false) {
2495
  $config = wfConfig::get('maxExecutionTime');
2496
+ if (!$staySilent) {
2497
+ wordfence::status(4, 'info', sprintf(/* translators: Time in seconds. */ __("Got value from wf config maxExecutionTime: %s", 'wordfence'), $config));
2498
+ }
2499
  if (is_numeric($config) && $config >= WORDFENCE_SCAN_MIN_EXECUTION_TIME) {
2500
+ if (!$staySilent) {
2501
+ wordfence::status(4, 'info', sprintf(/* translators: Time in seconds. */ __("getMaxExecutionTime() returning config value: %s", 'wordfence'), $config));
2502
+ }
2503
  return $config;
2504
  }
2505
+
2506
  $ini = @ini_get('max_execution_time');
2507
+ if (!$staySilent) {
2508
+ wordfence::status(4, 'info', sprintf(/* translators: PHP ini value. */ __("Got max_execution_time value from ini: %s", 'wordfence'), $ini));
2509
+ }
2510
  if (is_numeric($ini) && $ini >= WORDFENCE_SCAN_MIN_EXECUTION_TIME) {
2511
  if ($ini > WORDFENCE_SCAN_MAX_INI_EXECUTION_TIME) {
2512
+ if (!$staySilent) {
2513
+ wordfence::status(4, 'info', sprintf(
2514
+ /* translators: 1. PHP ini setting. 2. Time in seconds. */
2515
+ __('ini value of %1$d is higher than value for WORDFENCE_SCAN_MAX_INI_EXECUTION_TIME (%2$d), reducing', 'wordfence'),
2516
+ $ini,
2517
+ WORDFENCE_SCAN_MAX_INI_EXECUTION_TIME
2518
+ ));
2519
+ }
2520
  $ini = WORDFENCE_SCAN_MAX_INI_EXECUTION_TIME;
2521
  }
2522
+
2523
  $ini = floor($ini / 2);
2524
+ if (!$staySilent) {
2525
+ wordfence::status(4, 'info', sprintf(/* translators: PHP ini setting. */ __("getMaxExecutionTime() returning half ini value: %d", 'wordfence'), $ini));
2526
+ }
2527
  return $ini;
2528
  }
2529
+
2530
+ if (!$staySilent) {
2531
+ wordfence::status(4, 'info', __("getMaxExecutionTime() returning default of: 15", 'wordfence'));
2532
+ }
2533
  return 15;
2534
  }
2535
 
2551
  if ($plugins !== null) {
2552
  return $plugins;
2553
  }
2554
+
2555
+ if (!function_exists('get_plugins')) {
2556
  require_once(ABSPATH . '/wp-admin/includes/plugin.php');
2557
  }
2558
  $pluginData = get_plugins();
2568
  'FullDir' => $pluginFullDir
2569
  );
2570
  }
2571
+ if (!$this->pluginsCounted) {
2572
+ $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_PLUGINS);
2573
+ }
2574
  }
2575
+
2576
  $this->pluginsCounted = true;
2577
  return $plugins;
2578
  }
2585
  if ($themes !== null) {
2586
  return $themes;
2587
  }
2588
+
2589
  if (!function_exists('wp_get_themes')) {
2590
  require_once(ABSPATH . '/wp-includes/theme.php');
2591
  }
2602
  'FullDir' => $fullDir
2603
  );
2604
  }
2605
+ if (!$this->themesCounted) {
2606
+ $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_THEMES);
2607
+ }
2608
  }
2609
+
2610
  $this->themesCounted = true;
2611
  return $themes;
2612
  }
2613
+
2614
  public function recordMetric($type, $key, $value, $singular = true) {
2615
  if (!isset($this->metrics[$type])) {
2616
  $this->metrics[$type] = array();
2617
  }
2618
+
2619
  if (!isset($this->metrics[$type][$key])) {
2620
  $this->metrics[$type][$key] = array();
2621
  }
2622
+
2623
  if ($singular) {
2624
  $this->metrics[$type][$key] = $value;
2625
+ } else {
 
2626
  $this->metrics[$type][$key][] = $value;
2627
  }
2628
  }
2730
  )));
2731
 
2732
  if ($dataArr['code'] != 200) {
2733
+ throw new wfScanKnownFilesException(sprintf(/* translators: 1. HTTP status code. */ __("Got error response from Wordfence servers: %s", 'wordfence'), $dataArr['code']), $dataArr['code']);
2734
  }
2735
  $this->knownFiles = @json_decode($dataArr['data'], true);
2736
  if (!is_array($this->knownFiles)) {
2737
+ throw new wfScanKnownFilesException(__("Invalid response from Wordfence servers.", 'wordfence'));
2738
  }
2739
  } catch (Exception $e) {
2740
  throw new wfScanKnownFilesException($e->getMessage(), $e->getCode(), $e);
2823
  class wfCommonBackupFileTest {
2824
  const MATCH_EXACT = 'exact';
2825
  const MATCH_REGEX = 'regex';
2826
+
2827
  /**
2828
  * @param string $path
2829
  * @param string $mode
2831
  * @return wfCommonBackupFileTest
2832
  */
2833
  public static function createFromRootPath($path, $mode = self::MATCH_EXACT, $matcher = false) {
2834
+ return new self(site_url($path), ABSPATH . $path, array(), $mode, $matcher);
2835
  }
2836
+
2837
  /**
2838
  * Identical to createFromRootPath except it returns an entry for each file in the index that matches $name
2839
+ *
2840
  * @param $name
2841
  * @param string $mode
2842
  * @param bool|string $matcher
2851
  foreach ($files as $f) {
2852
  $tests[] = new self(site_url($f), ABSPATH . $f, array(), $mode, $matcher);
2853
  }
2854
+
2855
  return $tests;
2856
  }
2857
 
2958
  }
2959
 
2960
  class wfPubliclyAccessibleFileTest extends wfCommonBackupFileTest {
2961
+
2962
  }
2963
 
2964
  class wfScanEngineDurationLimitException extends Exception {
2966
 
2967
  class wfScanEngineCoreVersionChangeException extends Exception {
2968
  }
2969
+
2970
  class wfScanEngineTestCallbackFailedException extends Exception {
2971
  }
lib/wfSupportController.php CHANGED
@@ -168,7 +168,8 @@ class wfSupportController {
168
  const ITEM_DIAGNOSTICS_OPTION_SSL_VERIFICATION = 'diagnostics-option-ssl-verification';
169
  const ITEM_DIAGNOSTICS_OPTION_DISABLE_PHP_INPUT = 'diagnostics-option-disable-php-input';
170
  const ITEM_DIAGNOSTICS_OPTION_BETA_TDF = 'diagnostics-option-beta-tdf';
171
-
 
172
  const ITEM_MODULE_LOGIN_SECURITY = 'module-login-security';
173
  const ITEM_MODULE_LOGIN_SECURITY_2FA = 'module-login-security-2fa';
174
  const ITEM_MODULE_LOGIN_SECURITY_CAPTCHA = 'module-login-security-captcha';
@@ -350,7 +351,8 @@ class wfSupportController {
350
  case self::ITEM_DIAGNOSTICS_OPTION_SSL_VERIFICATION:
351
  case self::ITEM_DIAGNOSTICS_OPTION_DISABLE_PHP_INPUT:
352
  case self::ITEM_DIAGNOSTICS_OPTION_BETA_TDF:
353
-
 
354
  case self::ITEM_MODULE_LOGIN_SECURITY:
355
  case self::ITEM_MODULE_LOGIN_SECURITY_2FA:
356
  case self::ITEM_MODULE_LOGIN_SECURITY_CAPTCHA:
168
  const ITEM_DIAGNOSTICS_OPTION_SSL_VERIFICATION = 'diagnostics-option-ssl-verification';
169
  const ITEM_DIAGNOSTICS_OPTION_DISABLE_PHP_INPUT = 'diagnostics-option-disable-php-input';
170
  const ITEM_DIAGNOSTICS_OPTION_BETA_TDF = 'diagnostics-option-beta-tdf';
171
+ const ITEM_DIAGNOSTICS_OPTION_WORDFENCE_TRANSLATIONS = 'diagnostics-option-wordfence-translations';
172
+
173
  const ITEM_MODULE_LOGIN_SECURITY = 'module-login-security';
174
  const ITEM_MODULE_LOGIN_SECURITY_2FA = 'module-login-security-2fa';
175
  const ITEM_MODULE_LOGIN_SECURITY_CAPTCHA = 'module-login-security-captcha';
351
  case self::ITEM_DIAGNOSTICS_OPTION_SSL_VERIFICATION:
352
  case self::ITEM_DIAGNOSTICS_OPTION_DISABLE_PHP_INPUT:
353
  case self::ITEM_DIAGNOSTICS_OPTION_BETA_TDF:
354
+ case self::ITEM_DIAGNOSTICS_OPTION_WORDFENCE_TRANSLATIONS:
355
+
356
  case self::ITEM_MODULE_LOGIN_SECURITY:
357
  case self::ITEM_MODULE_LOGIN_SECURITY_2FA:
358
  case self::ITEM_MODULE_LOGIN_SECURITY_CAPTCHA:
lib/wfUnlockMsg.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
- <p><?php _e('If you are a WordPress user with administrative privileges on this site please enter your email in the box below and click &quot;Send&quot;. You will then receive an email that helps you regain access.', 'wordfence'); ?></p>
3
  <form method="POST" id="unlock-form" action="#">
4
  <?php require_once(ABSPATH . 'wp-includes/pluggable.php'); ?>
5
  <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('wf-form'); ?>">
1
  <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?>
2
+ <p><?php esc_html_e('If you are a WordPress user with administrative privileges on this site please enter your email in the box below and click &quot;Send&quot;. You will then receive an email that helps you regain access.', 'wordfence'); ?></p>
3
  <form method="POST" id="unlock-form" action="#">
4
  <?php require_once(ABSPATH . 'wp-includes/pluggable.php'); ?>
5
  <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('wf-form'); ?>">
lib/wfUtils.php CHANGED
@@ -22,7 +22,7 @@ class wfUtils {
22
  }
23
  public static function makeTimeAgo($secs, $noSeconds = false) {
24
  if($secs < 1){
25
- return "a moment";
26
  }
27
 
28
  if (function_exists('date_diff')) {
@@ -57,25 +57,29 @@ class wfUtils {
57
  }
58
 
59
  if ($years) {
60
- return self::pluralize($years, 'year', $months, 'month');
 
61
  }
62
  else if ($months) {
63
- return self::pluralize($months, 'month', $days, 'day');
 
64
  }
65
  else if ($days) {
66
- return self::pluralize($days, 'day', $hours, 'hour');
 
67
  }
68
  else if ($hours) {
69
- return self::pluralize($hours, 'hour', $minutes, 'min');
 
70
  }
71
  else if ($minutes) {
72
- return self::pluralize($minutes, 'min');
73
  }
74
  else {
75
  if($noSeconds){
76
- return "less than a minute";
77
  } else {
78
- return floor($secs) . " secs";
79
  }
80
  }
81
  }
@@ -88,47 +92,43 @@ class wfUtils {
88
  $minutes = floor($secs / 60); $secs -= $minutes * 60;
89
 
90
  if ($months) {
91
- $components[] = self::pluralize($months, 'month');
92
  if (!$createExact) {
93
  $hours = $minutes = $secs = 0;
94
  }
95
  }
96
  if ($days) {
97
- $components[] = self::pluralize($days, 'day');
98
  if (!$createExact) {
99
  $minutes = $secs = 0;
100
  }
101
  }
102
  if ($hours) {
103
- $components[] = self::pluralize($hours, 'hour');
104
  if (!$createExact) {
105
  $secs = 0;
106
  }
107
  }
108
  if ($minutes) {
109
- $components[] = self::pluralize($minutes, 'minute');
110
  }
111
  if ($secs && $secs >= 1) {
112
- $components[] = self::pluralize($secs, 'second');
113
  }
114
 
115
  if (empty($components)) {
116
- $components[] = 'less than 1 second';
117
  }
118
 
119
  return implode(' ', $components);
120
  }
121
- public static function pluralize($m1, $t1, $m2 = false, $t2 = false) {
122
- if($m1 != 1) {
123
- $t1 = $t1 . 's';
124
- }
125
- if($m2 != 1) {
126
- $t2 = $t2 . 's';
127
- }
128
- if($m1 && $m2){
129
- return "$m1 $t1 $m2 $t2";
130
  } else {
131
- return "$m1 $t1";
132
  }
133
  }
134
  public static function formatBytes($bytes, $precision = 2) {
@@ -1200,7 +1200,7 @@ class wfUtils {
1200
  public static function encrypt($str){
1201
  $key = wfConfig::get('encKey');
1202
  if(! $key){
1203
- wordfence::status(1, 'error', "Wordfence error: No encryption key found!");
1204
  return false;
1205
  }
1206
  $db = new wfDB();
@@ -1209,7 +1209,7 @@ class wfUtils {
1209
  public static function decrypt($str){
1210
  $key = wfConfig::get('encKey');
1211
  if(! $key){
1212
- wordfence::status(1, 'error', "Wordfence error: No encryption key found!");
1213
  return false;
1214
  }
1215
  $db = new wfDB();
@@ -1481,7 +1481,7 @@ class wfUtils {
1481
  }
1482
  }
1483
  } catch(Exception $e){
1484
- wordfence::status(2, 'error', "Call to Wordfence API to resolve IPs failed: " . $e->getMessage());
1485
  return array();
1486
  }
1487
  }
@@ -2156,6 +2156,7 @@ class wfUtils {
2156
  's' => $siteurl,
2157
  'h' => $homeurl,
2158
  't' => microtime(true),
 
2159
  ), null, '&'),
2160
  array(
2161
  'body' => json_encode($payload),
22
  }
23
  public static function makeTimeAgo($secs, $noSeconds = false) {
24
  if($secs < 1){
25
+ return __("a moment", 'wordfence');
26
  }
27
 
28
  if (function_exists('date_diff')) {
57
  }
58
 
59
  if ($years) {
60
+ return $years . ' ' . _n('year', 'years', $years, 'wordfence') .
61
+ (is_numeric($months) ? ' ' . $months . ' ' . _n('month', 'months', $months, 'wordfence') : '');
62
  }
63
  else if ($months) {
64
+ return $months . ' ' . _n('month', 'months', $months, 'wordfence') .
65
+ (is_numeric($days) ? ' ' . $days . ' ' . _n('day', 'days', $days, 'wordfence') : '');
66
  }
67
  else if ($days) {
68
+ return $days . ' ' . _n('day', 'days', $days, 'wordfence') .
69
+ (is_numeric($hours) ? ' ' . $hours . ' ' . _n('hour', 'hours', $hours, 'wordfence') : '');
70
  }
71
  else if ($hours) {
72
+ return $hours . ' ' . _n('hour', 'hours', $hours, 'wordfence') .
73
+ (is_numeric($minutes) ? ' ' . $minutes . ' ' . _n('minute', 'minutes', $minutes, 'wordfence') : '');
74
  }
75
  else if ($minutes) {
76
+ return $minutes . ' ' . _n('minute', 'minutes', $minutes, 'wordfence');
77
  }
78
  else {
79
  if($noSeconds){
80
+ return __("less than a minute", 'wordfence');
81
  } else {
82
+ return sprintf(/* translators: Number of seconds. */ __("%d seconds", 'wordfence'), floor($secs));
83
  }
84
  }
85
  }
92
  $minutes = floor($secs / 60); $secs -= $minutes * 60;
93
 
94
  if ($months) {
95
+ $components[] = $months . ' ' . _n('month', 'months', $months, 'wordfence');
96
  if (!$createExact) {
97
  $hours = $minutes = $secs = 0;
98
  }
99
  }
100
  if ($days) {
101
+ $components[] = $days . ' ' . _n('day', 'days', $days, 'wordfence');
102
  if (!$createExact) {
103
  $minutes = $secs = 0;
104
  }
105
  }
106
  if ($hours) {
107
+ $components[] = $hours . ' ' . _n('hour', 'hours', $hours, 'wordfence');
108
  if (!$createExact) {
109
  $secs = 0;
110
  }
111
  }
112
  if ($minutes) {
113
+ $components[] = $minutes . ' ' . _n('minute', 'minutes', $minutes, 'wordfence');
114
  }
115
  if ($secs && $secs >= 1) {
116
+ $components[] = $secs . ' ' . _n('second', 'seconds', $secs, 'wordfence');
117
  }
118
 
119
  if (empty($components)) {
120
+ $components[] = __('less than 1 second', 'wordfence');
121
  }
122
 
123
  return implode(' ', $components);
124
  }
125
+ public static function pluralize($m1, $m1Singular, $m1Plural, $m2 = false, $m2Singular = false, $m2Plural = false) {
126
+ $m1Text = _n($m1Singular, $m1Plural, $m1, 'wordfence');
127
+ if (is_numeric($m2)) {
128
+ $m2Text = _n($m2Singular, $m2Plural, $m2, 'wordfence');
129
+ return "$m1 $m1Text $m2 $m2Text";
 
 
 
 
130
  } else {
131
+ return "$m1 $m1Text";
132
  }
133
  }
134
  public static function formatBytes($bytes, $precision = 2) {
1200
  public static function encrypt($str){
1201
  $key = wfConfig::get('encKey');
1202
  if(! $key){
1203
+ wordfence::status(1, 'error', __("Wordfence error: No encryption key found!", 'wordfence'));
1204
  return false;
1205
  }
1206
  $db = new wfDB();
1209
  public static function decrypt($str){
1210
  $key = wfConfig::get('encKey');
1211
  if(! $key){
1212
+ wordfence::status(1, 'error', __("Wordfence error: No encryption key found!", 'wordfence'));
1213
  return false;
1214
  }
1215
  $db = new wfDB();
1481
  }
1482
  }
1483
  } catch(Exception $e){
1484
+ wordfence::status(2, 'error', sprintf(/* translators: Error message. */ __("Call to Wordfence API to resolve IPs failed: %s", 'wordfence'), $e->getMessage()));
1485
  return array();
1486
  }
1487
  }
2156
  's' => $siteurl,
2157
  'h' => $homeurl,
2158
  't' => microtime(true),
2159
+ 'lang' => get_site_option('WPLANG'),
2160
  ), null, '&'),
2161
  array(
2162
  'body' => json_encode($payload),
lib/wfVersionCheckController.php CHANGED
@@ -47,26 +47,48 @@ class wfVersionCheckController {
47
  $this->_alertEmail(
48
  'phpVersionCheckDeprecationEmail_' . self::PHP_DEPRECATING,
49
  __('PHP version too old', 'wordfence'),
50
- sprintf(__('Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
 
 
 
 
 
 
 
51
  );
52
 
53
  $this->_adminNotice(
54
  'phpVersionCheckDeprecationNotice_' . self::PHP_DEPRECATING,
55
  'phpVersionCheck',
56
- sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
 
 
 
 
 
57
  );
58
  }
59
  else if ($php == self::VERSION_UNSUPPORTED) {
60
  $this->_alertEmail(
61
  'phpVersionCheckUnsupportedEmail_' . self::PHP_MINIMUM,
62
  __('PHP version too old', 'wordfence'),
63
- sprintf(__('Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
 
 
 
 
 
64
  );
65
 
66
  $this->_adminNotice(
67
  'phpVersionCheckUnsupportedNotice_' . self::PHP_MINIMUM,
68
  'phpVersionCheck',
69
- sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
 
 
 
 
 
70
  );
71
  }
72
  else {
@@ -126,13 +148,23 @@ class wfVersionCheckController {
126
  $this->_alertEmail(
127
  'wordpressVersionCheckDeprecationEmail_' . self::WORDPRESS_DEPRECATING,
128
  __('WordPress version too old', 'wordfence'),
129
- sprintf(__('Your site is using a WordPress version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), $wp_version, self::WORDPRESS_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS))
 
 
 
 
 
130
  );
131
 
132
  $this->_adminNotice(
133
  'wordpressVersionCheckDeprecationNotice_' . self::WORDPRESS_DEPRECATING,
134
  'wordpressVersionCheck',
135
- sprintf(__('<strong>WARNING: </strong> Your site is using a WordPress version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), $wp_version, self::WORDPRESS_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
 
 
 
 
 
136
  );
137
  }
138
  else if ($wordpress == self::VERSION_UNSUPPORTED) {
@@ -141,13 +173,17 @@ class wfVersionCheckController {
141
  $this->_alertEmail(
142
  'wordpressVersionCheckUnsupportedEmail_' . self::WORDPRESS_MINIMUM,
143
  __('WordPress version too old', 'wordfence'),
144
- sprintf(__('Your site is using a WordPress version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), $wp_version, self::WORDPRESS_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS))
 
 
145
  );
146
 
147
  $this->_adminNotice(
148
  'wordpressVersionCheckUnsupportedNotice_' . self::WORDPRESS_MINIMUM,
149
  'wordpressVersionCheck',
150
- sprintf(__('<strong>WARNING: </strong> Your site is using a WordPress version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), $wp_version, self::WORDPRESS_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
 
 
151
  );
152
  }
153
  else {
47
  $this->_alertEmail(
48
  'phpVersionCheckDeprecationEmail_' . self::PHP_DEPRECATING,
49
  __('PHP version too old', 'wordfence'),
50
+ sprintf(
51
+ /* translators: 1. PHP version. 2. PHP version. */
52
+ __('Your site is using a PHP version (%1$s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'),
53
+ phpversion(),
54
+ self::PHP_DEPRECATING
55
+ )
56
+ . ' ' .
57
+ sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
58
  );
59
 
60
  $this->_adminNotice(
61
  'phpVersionCheckDeprecationNotice_' . self::PHP_DEPRECATING,
62
  'phpVersionCheck',
63
+ wp_kses(sprintf(
64
+ /* translators: 1. PHP version. 2. PHP version. */
65
+ __('<strong>WARNING: </strong> Your site is using a PHP version (%1$s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'),
66
+ phpversion(),
67
+ self::PHP_DEPRECATING
68
+ ), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . esc_html__('Learn More', 'wordfence') . '</a>'
69
  );
70
  }
71
  else if ($php == self::VERSION_UNSUPPORTED) {
72
  $this->_alertEmail(
73
  'phpVersionCheckUnsupportedEmail_' . self::PHP_MINIMUM,
74
  __('PHP version too old', 'wordfence'),
75
+ sprintf(
76
+ /* translators: 1. PHP version. 2. PHP version. */
77
+ __('Your site is using a PHP version (%1$s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'),
78
+ phpversion(),
79
+ self::PHP_DEPRECATING
80
+ ) . ' ' . sprintf(/* translators: Support URL. */ __('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
81
  );
82
 
83
  $this->_adminNotice(
84
  'phpVersionCheckUnsupportedNotice_' . self::PHP_MINIMUM,
85
  'phpVersionCheck',
86
+ wp_kses(sprintf(
87
+ /* translators: 1. PHP version. 2. PHP version. */
88
+ __('<strong>WARNING: </strong> Your site is using a PHP version (%1$s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'),
89
+ phpversion(),
90
+ self::PHP_DEPRECATING
91
+ ), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . esc_html__('Learn More', 'wordfence') . '</a>'
92
  );
93
  }
94
  else {
148
  $this->_alertEmail(
149
  'wordpressVersionCheckDeprecationEmail_' . self::WORDPRESS_DEPRECATING,
150
  __('WordPress version too old', 'wordfence'),
151
+ sprintf(
152
+ /* translators: 1. WordPress version. 2. WordPress version. */
153
+ __('Your site is using a WordPress version (%1$s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'),
154
+ $wp_version,
155
+ self::WORDPRESS_DEPRECATING
156
+ ) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS))
157
  );
158
 
159
  $this->_adminNotice(
160
  'wordpressVersionCheckDeprecationNotice_' . self::WORDPRESS_DEPRECATING,
161
  'wordpressVersionCheck',
162
+ wp_kses(sprintf(
163
+ /* translators: 1. WordPress version. 2. WordPress version. */
164
+ __('<strong>WARNING: </strong> Your site is using a WordPress version (%1$s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'),
165
+ $wp_version,
166
+ self::WORDPRESS_DEPRECATING
167
+ ), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS) . '" target="_blank" rel="noopener noreferrer">' . esc_html__('Learn More', 'wordfence') . '</a>'
168
  );
169
  }
170
  else if ($wordpress == self::VERSION_UNSUPPORTED) {
173
  $this->_alertEmail(
174
  'wordpressVersionCheckUnsupportedEmail_' . self::WORDPRESS_MINIMUM,
175
  __('WordPress version too old', 'wordfence'),
176
+ sprintf(
177
+ /* translators: 1. WordPress version. 2. WordPress version. */
178
+ __('Your site is using a WordPress version (%1$s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), $wp_version, self::WORDPRESS_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS))
179
  );
180
 
181
  $this->_adminNotice(
182
  'wordpressVersionCheckUnsupportedNotice_' . self::WORDPRESS_MINIMUM,
183
  'wordpressVersionCheck',
184
+ wp_kses(sprintf(
185
+ /* translators: 1. WordPress version. 2. WordPress version. */
186
+ __('<strong>WARNING: </strong> Your site is using a WordPress version (%1$s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of WordPress but will currently support WordPress versions as old as %2$s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), $wp_version, self::WORDPRESS_DEPRECATING), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()))) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_WORDPRESS) . '" target="_blank" rel="noopener noreferrer">' . esc_html__('Learn More', 'wordfence') . '</a>'
187
  );
188
  }
189
  else {
lib/wfView.php CHANGED
@@ -49,7 +49,7 @@ class wfView {
49
  $view = preg_replace('/\.{2,}/', '.', $this->view);
50
  $view_path = $this->view_path . '/' . $view . $this->view_file_extension;
51
  if (!file_exists($view_path)) {
52
- throw new wfViewNotFoundException('The view ' . $view_path . ' does not exist or is not readable.');
53
  }
54
 
55
  extract($this->data, EXTR_SKIP);
@@ -67,7 +67,7 @@ class wfView {
67
  try {
68
  return $this->render();
69
  } catch (wfViewNotFoundException $e) {
70
- return defined('WP_DEBUG') && WP_DEBUG ? $e->getMessage() : 'The view could not be loaded.';
71
  }
72
  }
73
 
@@ -124,4 +124,4 @@ class wfView {
124
  }
125
 
126
  class wfViewNotFoundException extends Exception {
127
- }
49
  $view = preg_replace('/\.{2,}/', '.', $this->view);
50
  $view_path = $this->view_path . '/' . $view . $this->view_file_extension;
51
  if (!file_exists($view_path)) {
52
+ throw new wfViewNotFoundException(sprintf(/* translators: File path. */ __('The view %s does not exist or is not readable.', 'wordfence'), $view_path));
53
  }
54
 
55
  extract($this->data, EXTR_SKIP);
67
  try {
68
  return $this->render();
69
  } catch (wfViewNotFoundException $e) {
70
+ return defined('WP_DEBUG') && WP_DEBUG ? esc_html($e->getMessage()) : esc_html__('The view could not be loaded.', 'wordfence');
71
  }
72
  }
73
 
124
  }
125
 
126
  class wfViewNotFoundException extends Exception {
127
+ }
lib/wfViewResult.php CHANGED
@@ -5,11 +5,11 @@
5
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
  <link rel='stylesheet' id='wordfence-main-style-css' href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/diff.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>' type='text/css' media='all' />
7
  <body>
8
- <h1>Wordfence: File Viewer</h1>
9
  <table border="0" style="margin: 0 0 20px 0;" class="summary">
10
- <tr><td>Filename:</td><td><?php echo wp_kses($localFile, array()); ?></td></tr>
11
- <tr><td>File Size:</td><td><?php echo $fileSize; ?></td></tr>
12
- <tr><td>File last modified:</td><td><?php echo $fileMTime; ?></td></tr>
13
  </table>
14
 
15
  <?php
@@ -19,9 +19,9 @@
19
  highlight_string($cont);
20
  }
21
  ?>
22
-
23
 
24
 
25
- <div class="diffFooter">&copy;&nbsp;2011 to <?php echo date('Y'); ?> Wordfence &mdash; Visit <a href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.</div>
 
26
  </body>
27
- </html>
5
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
  <link rel='stylesheet' id='wordfence-main-style-css' href='<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/diff.css'); ?>?ver=<?php echo WORDFENCE_VERSION; ?>' type='text/css' media='all' />
7
  <body>
8
+ <h1><?php esc_html_e('Wordfence: File Viewer', 'wordfence') ?></h1>
9
  <table border="0" style="margin: 0 0 20px 0;" class="summary">
10
+ <tr><td><?php esc_html_e('Filename:', 'wordfence') ?></td><td><?php echo wp_kses($localFile, array()); ?></td></tr>
11
+ <tr><td><?php esc_html_e('File Size:', 'wordfence') ?></td><td><?php echo $fileSize; ?></td></tr>
12
+ <tr><td><?php esc_html_e('File last modified:', 'wordfence') ?></td><td><?php echo $fileMTime; ?></td></tr>
13
  </table>
14
 
15
  <?php
19
  highlight_string($cont);
20
  }
21
  ?>
 
22
 
23
 
24
+
25
+ <div class="diffFooter"><?php echo wp_kses(sprintf(__('&copy;&nbsp;%d to %d Wordfence &mdash; Visit <a href="http://wordfence.com/">Wordfence.com</a> for help, security updates and more.', 'wordfence'), date_i18n('Y', WORDFENCE_EPOCH), date_i18n('Y')), array('a'=>array('href'=>array()))); ?></div>
26
  </body>
27
+ </html>
lib/wordfenceClass.php CHANGED
@@ -174,7 +174,7 @@ class wordfence {
174
  wfVersionCheckController::shared()->checkVersionsAndWarn();
175
  }
176
  private static function keyAlert($msg){
177
- 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.", false);
178
  }
179
  public static function dailyCron() {
180
  $lastDailyCron = (int) wfConfig::get('lastDailyCron', 0);
@@ -204,8 +204,8 @@ class wordfence {
204
  wfConfig::set('keyAutoRenew10Sent', '');
205
  } else if ($keyExpDays <= 12 && $keyExpDays > 0 && !wfConfig::get('keyAutoRenew10Sent')) {
206
  wfConfig::set('keyAutoRenew10Sent', 1);
207
- $email = "Your Premium Wordfence License is set to auto-renew in 10 days.";
208
- self::alert($email, "$email To update your license settings please visit http://www.wordfence.com/zz9/dashboard", false);
209
  }
210
  } else {
211
  if($keyExpDays > 15){
@@ -217,20 +217,20 @@ class wordfence {
217
  } else if($keyExpDays <= 15 && $keyExpDays > 0){
218
  if($keyExpDays <= 15 && $keyExpDays >= 11 && (! wfConfig::get('keyExp15Sent'))){
219
  wfConfig::set('keyExp15Sent', 1);
220
- self::keyAlert("Your Premium Wordfence License expires in less than 2 weeks.");
221
  } else if($keyExpDays <= 7 && $keyExpDays >= 4 && (! wfConfig::get('keyExp7Sent'))){
222
  wfConfig::set('keyExp7Sent', 1);
223
- self::keyAlert("Your Premium Wordfence License expires in less than a week.");
224
  } else if($keyExpDays == 2 && (! wfConfig::get('keyExp2Sent'))){
225
  wfConfig::set('keyExp2Sent', 1);
226
- self::keyAlert("Your Premium Wordfence License expires in 2 days.");
227
  } else if($keyExpDays == 1 && (! wfConfig::get('keyExp1Sent'))){
228
  wfConfig::set('keyExp1Sent', 1);
229
- self::keyAlert("Your Premium Wordfence License expires in 1 day.");
230
  }
231
  } else if($keyIsExpired && (! wfConfig::get('keyExpFinalSent')) ){
232
  wfConfig::set('keyExpFinalSent', 1);
233
- self::keyAlert("Your Wordfence Premium License has Expired!");
234
  }
235
  }
236
  }
@@ -260,10 +260,14 @@ class wordfence {
260
  wfConfig::set('showWfCentralUI', (int) $keyData['showWfCentralUI']);
261
  }
262
 
 
 
 
 
263
  wfConfig::set('keyType', $keyType);
264
  }
265
  catch(Exception $e){
266
- wordfence::status(4, 'error', "Could not verify Wordfence License: " . $e->getMessage());
267
  }
268
 
269
  $allowMySQLi = wfConfig::testDB();
@@ -345,37 +349,25 @@ class wordfence {
345
  $items = array();
346
  $plural = false;
347
  if ($updatesNeeded['core']) {
348
- $items[] = 'WordPress (v' . esc_html($updatesNeeded['core']) . ')';
349
  }
350
 
351
  if ($updatesNeeded['plugins']) {
352
- $entry = count($updatesNeeded['plugins']) . ' plugin';
353
- if (count($updatesNeeded['plugins']) > 1) {
354
- $entry .= 's';
355
- $plural = true;
356
- }
357
  $items[] = $entry;
358
  }
359
 
360
  if ($updatesNeeded['themes']) {
361
- $entry = count($updatesNeeded['themes']) . ' theme';
362
- if (count($updatesNeeded['themes']) > 1) {
363
- $entry .= 's';
364
- $plural = true;
365
- }
366
  $items[] = $entry;
367
  }
368
 
369
- $message = 'An update is available for ';
370
- $plural = ($plural || (count($items) > 1));
371
- if ($plural) {
372
- $message = 'Updates are available for ';
373
- }
374
-
375
  for ($i = 0; $i < count($items); $i++) {
376
  if ($i > 0 && count($items) > 2) { $message .= ', '; }
377
  else if ($i > 0) { $message .= ' '; }
378
- if ($i > 0 && $i == count($items) - 1) { $message .= 'and '; }
379
  $message .= $items[$i];
380
  }
381
 
@@ -414,7 +406,7 @@ class wordfence {
414
  update_option('wordfence_version', WORDFENCE_VERSION); //In case we have a fatal error we don't want to keep running install.
415
  }
416
 
417
- wordfence::status(4, 'info', 'runInstall called with previous version = ' . $previous_version);
418
 
419
  //EVERYTHING HERE MUST BE IDEMPOTENT
420
 
@@ -466,7 +458,7 @@ SQL
466
  wfConfig::set('touppPromptNeeded', true);
467
  $freshAPIKey = true;
468
  } else {
469
- throw new Exception("Could not understand the response we received from the Wordfence servers when applying for a free license key.");
470
  }
471
  } catch(Exception $e){
472
  error_log("Could not fetch free license key from Wordfence: " . $e->getMessage());
@@ -1358,10 +1350,19 @@ SQL
1358
  } else {
1359
  add_action('wordfence_security_event', 'wfCentral::sendAlertCallback', 10, 3);
1360
  }
 
 
 
 
 
 
 
 
 
1361
  }
1362
  public static function _pluginPageActionLinks($links) {
1363
  if (!wfConfig::get('isPaid')) {
1364
- $links = array_merge(array('aWordfencePluginCallout' => '<a href="https://www.wordfence.com/zz12/wordfence-signup/" target="_blank" rel="noopener noreferrer"><strong style="color: #11967A; display: inline;">Upgrade To Premium</strong></a>'), $links);
1365
  }
1366
  return $links;
1367
  }
@@ -1380,7 +1381,7 @@ SQL
1380
 
1381
  public static function fixWPMailFromAddress($from_email) {
1382
  if ($from_email == 'wordpress@') { //$_SERVER['SERVER_NAME'] is undefined so we get an incomplete email address
1383
- wordfence::status(4, 'info', "wp_mail from address is incomplete, attempting to fix");
1384
  $urls = array(get_site_url(), get_home_url());
1385
  foreach ($urls as $u) {
1386
  if (!empty($u)) {
@@ -1390,7 +1391,7 @@ SQL
1390
  }
1391
 
1392
  if (!empty($u)) {
1393
- wordfence::status(4, 'info', "Fixing wp_mail from address: " . $from_email . $u);
1394
  return $from_email . $u;
1395
  }
1396
  }
@@ -1415,10 +1416,12 @@ SQL
1415
  $wafDisabled = !WFWAF_ENABLED || (class_exists('wfWAFConfig') && wfWAFConfig::isDisabled());
1416
  if (wfUtils::isAdmin() && !$wafDisabled) {
1417
  wp_enqueue_style('wordfenceAJAXcss', wfUtils::getBaseURL() . wfUtils::versionedAsset('css/wordfenceBox.css'), '', WORDFENCE_VERSION);
 
1418
  wp_enqueue_script('wordfenceAJAXjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/admin.ajaxWatcher.js'), array('jquery'), WORDFENCE_VERSION);
1419
  wp_localize_script('wordfenceAJAXjs', 'WFAJAXWatcherVars', array(
1420
  'nonce' => wp_create_nonce('wf-waf-error-page'),
1421
  ));
 
1422
  }
1423
  }
1424
  public static function enqueueDashboard() {
@@ -1481,18 +1484,18 @@ SQL
1481
  }
1482
  public static function ajaxReceiver(){
1483
  if(! wfUtils::isAdmin()){
1484
- wfUtils::send_json(array('errorMsg' => "You appear to have logged out or you are not an admin. Please sign-out and sign-in again."));
1485
  }
1486
  $func = (isset($_POST['action']) && $_POST['action']) ? $_POST['action'] : $_GET['action'];
1487
  $nonce = (isset($_POST['nonce']) && $_POST['nonce']) ? $_POST['nonce'] : $_GET['nonce'];
1488
  if(! wp_verify_nonce($nonce, 'wp-ajax')){
1489
- wfUtils::send_json(array('errorMsg' => "Your browser sent an invalid security token to Wordfence. Please try reloading this page or signing out and in again.", 'tokenInvalid' => 1));
1490
  }
1491
  //func is e.g. wordfence_ticker so need to munge it
1492
  $func = str_replace('wordfence_', '', $func);
1493
  $returnArr = call_user_func('wordfence::ajax_' . $func . '_callback');
1494
  if($returnArr === false){
1495
- $returnArr = array('errorMsg' => "Wordfence encountered an internal error executing that request.");
1496
  }
1497
 
1498
  if(! is_array($returnArr)){
@@ -1598,7 +1601,7 @@ SQL
1598
  $imported = WFLSPHP52Compatability::import_2fa($import);
1599
  }
1600
  catch (Exception $e) {
1601
- wordfence::status(4, 'error', '2FA Migration Error: ' . $e->getMessage());
1602
  return array('ok' => 0, 'fail' => 1);
1603
  }
1604
 
@@ -1659,7 +1662,7 @@ SQL
1659
  }
1660
 
1661
  if ($enforceBreachedPasswds && wfCredentialsController::isLeakedPassword($username, $password)) {
1662
- $errors->add('pass', sprintf(__('Please choose a different password. The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. <a href="%s">Learn More</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
1663
  return $errors;
1664
  }
1665
  else if ($user_id !== false) {
@@ -1729,7 +1732,7 @@ SQL
1729
 
1730
  }
1731
  if(wfConfig::get('loginSecurityEnabled')){
1732
- $tKey = 'wffgt_' . bin2hex(wfUtils::inet_pton($IP));
1733
  $forgotAttempts = get_transient($tKey);
1734
  if($forgotAttempts){
1735
  $forgotAttempts++;
@@ -1737,7 +1740,12 @@ SQL
1737
  $forgotAttempts = 1;
1738
  }
1739
  if($forgotAttempts >= wfConfig::get('loginSec_maxForgotPasswd')){
1740
- self::lockOutIP($IP, "Exceeded the maximum number of tries to recover their password which is set at: " . wfConfig::get('loginSec_maxForgotPasswd') . ". The last username or email they entered before getting locked out was: '" . $_POST['user_login'] . "'");
 
 
 
 
 
1741
  $customText = wpautop(wp_strip_all_tags(wfConfig::get('blockCustomText', '')));
1742
  require(dirname(__FILE__) . '/wfLockedOut.php');
1743
  }
@@ -1756,6 +1764,19 @@ SQL
1756
 
1757
  }
1758
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1759
  public static function veryFirstAction() {
1760
  /** @var wpdb $wpdb ; */
1761
  global $wpdb;
@@ -1769,11 +1790,14 @@ SQL
1769
  $nonceValid = wfWAF::getInstance()->verifyNonce(@$_POST['nonce'], 'wf-form');
1770
  }
1771
  if(!$nonceValid){
1772
- die("Sorry but your browser sent an invalid security token when trying to use this form.");
1773
  }
1774
  $numTries = get_transient('wordfenceUnlockTries');
1775
  if($numTries > 10){
1776
- echo "<html><body><h1>Please wait 3 minutes and try again</h1><p>You have used this form too much. Please wait 3 minutes and try again.</p></body></html>";
 
 
 
1777
  exit();
1778
  }
1779
  if(! $numTries){ $numTries = 1; } else { $numTries = $numTries + 1; }
@@ -1811,10 +1835,10 @@ SQL
1811
  'key' => $key,
1812
  'IP' => $IP
1813
  ));
1814
- wp_mail($email, "Unlock email requested", $content, "Content-Type: text/html");
1815
  }
1816
- echo "<html><body><h1>" . __('Your request was received', 'wordfence') . "</h1><p>" .
1817
- sprintf(__("We received a request to email \"%s\" instructions to unlock their access. If that is the email address of a site administrator or someone on the Wordfence alert list, they have been emailed instructions on how to regain access to this system. The instructions we sent will expire 30 minutes from now.", 'wordfence'), wp_kses($email, array()))
1818
  . "</p></body></html>";
1819
 
1820
  exit();
@@ -1827,14 +1851,14 @@ SQL
1827
  if($_GET['func'] == 'unlockMyIP'){
1828
  wfBlock::unblockIP(wfUtils::getIP());
1829
  if (class_exists('wfWAFIPBlocksController')) { wfWAFIPBlocksController::setNeedsSynchronizeConfigSettings(); }
1830
- delete_transient('wflginfl_' . bin2hex(wfUtils::inet_pton(wfUtils::getIP()))); //Reset login failure counter
1831
  header('Location: ' . wp_login_url());
1832
  exit();
1833
  } else if($_GET['func'] == 'unlockAllIPs'){
1834
  wordfence::status(1, 'info', __("Request received via unlock email link to unblock all IPs.", 'wordfence'));
1835
  wfBlock::removeAllIPBlocks();
1836
  if (class_exists('wfWAFIPBlocksController')) { wfWAFIPBlocksController::setNeedsSynchronizeConfigSettings(); }
1837
- delete_transient('wflginfl_' . bin2hex(wfUtils::inet_pton(wfUtils::getIP()))); //Reset login failure counter
1838
  header('Location: ' . wp_login_url());
1839
  exit();
1840
  } else if($_GET['func'] == 'disableRules'){
@@ -1844,7 +1868,7 @@ SQL
1844
  wfBlock::removeAllIPBlocks();
1845
  wfBlock::removeAllCountryBlocks();
1846
  if (class_exists('wfWAFIPBlocksController')) { wfWAFIPBlocksController::setNeedsSynchronizeConfigSettings(); }
1847
- delete_transient('wflginfl_' . bin2hex(wfUtils::inet_pton(wfUtils::getIP()))); //Reset login failure counter
1848
  header('Location: ' . wp_login_url());
1849
  exit();
1850
  } else {
@@ -1957,7 +1981,7 @@ SQL
1957
  if ($errors !== true) {
1958
  $error = __('An error occurred while saving the license.', 'wordfence');
1959
  if (count($errors) == 1) {
1960
- $error = sprintf(__('An error occurred while saving the license: %s', 'wordfence'), $errors[0]['error']);
1961
  }
1962
 
1963
  echo wfView::create('common/license', array(
@@ -1977,7 +2001,7 @@ SQL
1977
  catch (Exception $e) {
1978
  echo wfView::create('common/license', array(
1979
  'state' => 'bad',
1980
- 'error' => sprintf(__('An error occurred while saving the license: %s', 'wordfence'), $e->getMessage()),
1981
  ))->render();
1982
  exit();
1983
  }
@@ -1993,12 +2017,12 @@ SQL
1993
  if (is_main_site() && wfUtils::isAdmin()) {
1994
  if (wp_next_scheduled('wordfence_daily_cron') === false) {
1995
  wp_schedule_event(time() + 600, 'daily', 'wordfence_daily_cron');
1996
- wordfence::status(2, 'info', "Rescheduled missing daily cron");
1997
  }
1998
 
1999
  if (wp_next_scheduled('wordfence_hourly_cron') === false) {
2000
  wp_schedule_event(time() + 600, 'hourly', 'wordfence_hourly_cron');
2001
- wordfence::status(2, 'info', "Rescheduled missing hourly cron");
2002
  }
2003
  }
2004
 
@@ -2466,33 +2490,37 @@ SQL
2466
  }
2467
 
2468
  $salt = wp_salt('logged_in');
2469
- $cookiename = 'wf_loginalerted_' . hash_hmac('sha256', wfUtils::getIP() . '|' . $user->ID, $salt);
2470
- $cookievalue = hash_hmac('sha256', $user->user_login, $salt);
 
 
 
 
 
 
 
 
 
2471
  if(wfUtils::isAdmin($userID)){
2472
- $securityEvent = 'adminLoginNewLocation';
2473
- if (isset($_COOKIE[$cookiename]) && hash_equals($cookievalue, $_COOKIE[$cookiename])) {
2474
- $securityEvent = 'adminLogin';
2475
- }
2476
- $alertCallback = array(new wfAdminLoginAlert($cookiename, $cookievalue, $username, wfUtils::getIP()), 'send');
2477
- do_action('wordfence_security_event', $securityEvent, array(
2478
- 'username' => $username,
2479
- 'ip' => wfUtils::getIP(),
2480
- ), $alertCallback);
2481
 
2482
  } else {
2483
- $securityEvent = 'nonAdminLoginNewLocation';
2484
- if (isset($_COOKIE[$cookiename]) && hash_equals($cookievalue, $_COOKIE[$cookiename])) {
2485
- $securityEvent = 'nonAdminLogin';
2486
- }
2487
- $alertCallback = array(new wfNonAdminLoginAlert($cookiename, $cookievalue, $username, wfUtils::getIP()), 'send');
2488
- do_action('wordfence_security_event', $securityEvent, array(
2489
- 'username' => $username,
2490
- 'ip' => wfUtils::getIP(),
2491
- ), $alertCallback);
2492
  }
 
 
 
 
 
 
2493
 
2494
- if (wfConfig::get('alertOn_firstAdminLoginOnly') || wfConfig::get('alertOn_firstNonAdminLoginOnly')) {
2495
- wfUtils::setcookie($cookiename, $cookievalue, time() + (86400 * 365), '/', null, wfUtils::isFullSSL(), true);
 
 
 
2496
  }
2497
  }
2498
  public static function registrationFilter($errors, $sanitizedLogin, $userEmail) {
@@ -2695,7 +2723,7 @@ SQL
2695
  else { //Code path for old method, invalid password the second time
2696
  self::$authError = $authUser;
2697
  if (is_wp_error(self::$authError) && (self::$authError->get_error_code() == 'invalid_username' || $authUser->get_error_code() == 'invalid_email' || self::$authError->get_error_code() == 'incorrect_password' || $authUser->get_error_code() == 'authentication_failed') && wfConfig::get('loginSec_maskLoginErrors')) {
2698
- self::$authError = new WP_Error('incorrect_password', sprintf(__('<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%2$s" title="Password Lost and Found">Lost your password</a>?'), $username, wp_lostpassword_url()));
2699
  }
2700
 
2701
  return self::processBruteForceAttempt(self::$authError, $username, $passwd);
@@ -2703,7 +2731,12 @@ SQL
2703
 
2704
  if ($usingBreachedPassword) {
2705
  wfAdminNoticeQueue::removeAdminNotice(false, 'previousIPBreachPassword', array($userID));
2706
- wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, sprintf(__('<strong>WARNING: </strong>The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">change your password</a>. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>', 'wordfence'), self_admin_url('profile.php'), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), '2faBreachPassword', array($authUser->ID));
 
 
 
 
 
2707
  }
2708
 
2709
  if (isset($twoFactorRecord[5])) { //New method TOTP
@@ -2834,7 +2867,9 @@ SQL
2834
  if ($twoFactorRecord[0] == $userDat->ID && $twoFactorRecord[3] == 'activated') { //Yup, enabled, so require the code
2835
  if ($usingBreachedPassword) {
2836
  wfAdminNoticeQueue::removeAdminNotice(false, 'previousIPBreachPassword', array($authUser->ID));
2837
- wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, sprintf(__('<strong>WARNING: </strong>The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">change your password</a>. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>', 'wordfence'), self_admin_url('profile.php'), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), '2faBreachPassword', array($authUser->ID));
 
 
2838
  }
2839
 
2840
  $loginNonce = wfWAFUtils::random_bytes(20);
@@ -2989,7 +3024,7 @@ SQL
2989
  else if ($usingBreachedPassword) {
2990
  if (wfCredentialsController::hasPreviousLoginFromIP($authUser, wfUtils::getIP())) {
2991
  wfAdminNoticeQueue::removeAdminNotice(false, '2faBreachPassword', array($authUser->ID));
2992
- wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, sprintf(__('<strong>WARNING: </strong>Your login has been allowed because you have previously logged in from the same IP, but you will be blocked if your IP changes. The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">change your password</a>. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>', 'wordfence'), self_admin_url('profile.php'), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), 'previousIPBreachPassword', array($authUser->ID));
2993
  }
2994
  else {
2995
  $username = $authUser->user_login;
@@ -3004,7 +3039,9 @@ SQL
3004
  ), $alertCallback);
3005
 
3006
  remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
3007
- self::$authError = new WP_Error('breached_password', sprintf(__('<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">reset your password</a> to reactivate your account. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>'), wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
 
 
3008
  return self::$authError;
3009
  }
3010
  }
@@ -3012,7 +3049,7 @@ SQL
3012
  if ($requireAdminTwoFactor && wfUtils::isAdmin($authUser)) {
3013
  $username = $authUser->user_login;
3014
  self::getLog()->logLogin('loginFailValidUsername', 1, $username);
3015
- wordfence::alert("Admin Login Blocked", "A user with username \"$username\" who has administrator access tried to sign in to your WordPress site. Access was denied because all administrator accounts are required to have Cellphone Sign-in enabled but this account does not.", wfUtils::getIP());
3016
  self::$authError = new WP_Error('twofactor_disabled_required', __('<strong>Cellphone Sign-in Required</strong>: Cellphone Sign-in is required for all administrator accounts. Please contact the site administrator to enable it for your account.'));
3017
  return self::$authError;
3018
  }
@@ -3023,7 +3060,7 @@ SQL
3023
  else if ($usingBreachedPassword) {
3024
  if (wfCredentialsController::hasPreviousLoginFromIP($authUser, wfUtils::getIP())) {
3025
  wfAdminNoticeQueue::removeAdminNotice(false, '2faBreachPassword', array($authUser->ID));
3026
- wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, sprintf(__('<strong>WARNING: </strong>Your login has been allowed because you have previously logged in from the same IP, but you will be blocked if your IP changes. The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">change your password</a>. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>', 'wordfence'), self_admin_url('profile.php'), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), 'previousIPBreachPassword', array($authUser->ID));
3027
  }
3028
  else {
3029
  $username = $authUser->user_login;
@@ -3038,7 +3075,9 @@ SQL
3038
  ), $alertCallback);
3039
 
3040
  remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
3041
- self::$authError = new WP_Error('breached_password', sprintf(__('<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">reset your password</a> to reactivate your account. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>'), wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
 
 
3042
  return self::$authError;
3043
  }
3044
  }
@@ -3091,14 +3130,14 @@ SQL
3091
  }
3092
  if(wfConfig::get('loginSec_lockInvalidUsers')){
3093
  if(strlen($username) > 0 && preg_match('/[^\r\s\n\t]+/', $username)){
3094
- self::lockOutIP($IP, "Used an invalid username '" . $username . "' to try to sign in");
3095
  self::getLog()->logLogin('loginFailInvalidUsername', true, $username);
3096
  }
3097
  $customText = wpautop(wp_strip_all_tags(wfConfig::get('blockCustomText', '')));
3098
  require(dirname(__FILE__) . '/wfLockedOut.php');
3099
  }
3100
  }
3101
- $tKey = 'wflginfl_' . bin2hex(wfUtils::inet_pton($IP));
3102
  if(is_wp_error($authUser) && in_array($authUser->get_error_code(), $failureErrorCodes)) {
3103
  $tries = get_transient($tKey);
3104
  if($tries){
@@ -3107,7 +3146,14 @@ SQL
3107
  $tries = 1;
3108
  }
3109
  if($tries >= wfConfig::get('loginSec_maxFailures')){
3110
- self::lockOutIP($IP, "Exceeded the maximum number of login failures which is: " . wfConfig::get('loginSec_maxFailures') . ". The last username they tried to sign in with was: '" . $username . "'");
 
 
 
 
 
 
 
3111
  $customText = wpautop(wp_strip_all_tags(wfConfig::get('blockCustomText', '')));
3112
  require(dirname(__FILE__) . '/wfLockedOut.php');
3113
  }
@@ -3125,7 +3171,9 @@ SQL
3125
  }
3126
 
3127
  if(is_wp_error($authUser) && ($authUser->get_error_code() == 'invalid_username' || $authUser->get_error_code() == 'invalid_email' || $authUser->get_error_code() == 'incorrect_password') && wfConfig::get('loginSec_maskLoginErrors')){
3128
- return new WP_Error( 'incorrect_password', sprintf( __( '<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%2$s" title="Password Lost and Found">Lost your password</a>?' ), $username, wp_lostpassword_url() ) );
 
 
3129
  }
3130
 
3131
  return $authUser;
@@ -3534,7 +3582,7 @@ SQL
3534
  }
3535
  $result = false;
3536
  if (count($emails)) {
3537
- $result = wp_mail(implode(', ', $emails), __('Wordfence Test Email', 'wordfence'), sprintf(__("This is a test email from %s.\nThe IP address that requested this was: %s", 'wordfence'), site_url(), wfUtils::getIP()));
3538
  }
3539
  $result = $result ? 'True' : 'False';
3540
  return array('result' => $result);
@@ -3586,7 +3634,7 @@ SQL
3586
  return array('errorMsg' => wp_kses($codeResult['errorMsg'], array()));
3587
  }
3588
  else {
3589
- wordfence::status(4, 'info', sprintf(__("Could not gen verification code: %s", 'wordfence'), var_export($codeResult, true)));
3590
  return array('errorMsg' => __("We could not generate a verification code.", 'wordfence'));
3591
  }
3592
  self::twoFactorAdd($user->ID, $phone, '', 'phone', $secretID);
@@ -3606,7 +3654,7 @@ SQL
3606
  $codeResult = $api->call('twoFactorTOTP_register', array(), array('mode' => $mode));
3607
  }
3608
  catch (Exception $e) {
3609
- return array('errorMsg' => sprintf(__("Could not contact Wordfence servers to generate a verification code: %s", 'wordfence'), wp_kses($e->getMessage(), array())));
3610
  }
3611
 
3612
  /* Expected Fields:
@@ -3630,7 +3678,7 @@ SQL
3630
  return array('errorMsg' => wp_kses($codeResult['errorMsg'], array()));
3631
  }
3632
  else {
3633
- wordfence::status(4, 'info', sprintf(__("Could not gen verification code: %s", 'wordfence'), var_export($codeResult, true)));
3634
  return array('errorMsg' => __("We could not generate a verification code.", 'wordfence'));
3635
  }
3636
  self::twoFactorAdd($user->ID, '', '', 'authenticator', $secretID);
@@ -3669,7 +3717,7 @@ SQL
3669
  $codeResult = $api->call('twoFactorTOTP_verify', array(), array('totpid' => $twoFactorUsers[$i][6], 'code' => $code, 'mode' => $mode));
3670
  }
3671
  catch (Exception $e) {
3672
- return array('errorMsg' => "Could not contact Wordfence servers to generate a verification code: " . wp_kses($e->getMessage(), array()));
3673
  }
3674
 
3675
  if (isset($codeResult['ok']) && $codeResult['ok']) {
@@ -3680,12 +3728,12 @@ SQL
3680
  break;
3681
  }
3682
  else {
3683
- return array('errorMsg' => "The code you entered is invalid. Cellphone sign-in will not be enabled for this user until you enter a valid code.");
3684
  }
3685
  }
3686
  }
3687
  if(! $found){
3688
- return array('errorMsg' => "We could not find the user you are trying to activate. They may have been removed from the list of Cellphone Sign-in users. Please reload this page.");
3689
  }
3690
  wfConfig::set_ser('twoFactorUsers', $twoFactorUsers);
3691
  $WPuser = get_userdata($userID);
@@ -3767,7 +3815,7 @@ SQL
3767
  if($deleted){
3768
  return array('ok' => 1, 'userID' => $ID);
3769
  } else {
3770
- return array('errorMsg' => "That user has already been removed from the list.");
3771
  }
3772
  }
3773
  public static function getNextScanStartTimestamp() {
@@ -3787,15 +3835,15 @@ SQL
3787
  }
3788
 
3789
  if (!$nextTime) {
3790
- return 'No scan is scheduled';
3791
  }
3792
 
3793
  $difference = $nextTime - time();
3794
  if ($difference < 1) {
3795
- return "Next scan is starting now";
3796
  }
3797
-
3798
- return 'Next scan in ' . wfUtils::makeDuration($difference) . ' (' . date('M j, Y g:i:s A', $nextTime + (3600 * get_option('gmt_offset'))) . ')';
3799
  }
3800
  public static function wordfenceStartScheduledScan($scheduledStartTime) {
3801
 
@@ -3812,7 +3860,7 @@ SQL
3812
  }
3813
  wfConfig::set('originalScheduledScanStart', $scheduledStartTime);
3814
  wfConfig::set('lastScheduledScanStart', time());
3815
- wordfence::status(1, 'info', "Scheduled Wordfence scan starting at " . date('l jS \of F Y h:i:s A', current_time('timestamp')) );
3816
 
3817
  //We call this before the scan actually starts to advance the schedule for the next week.
3818
  //This ensures that if the scan crashes for some reason, the schedule will hold.
@@ -3835,7 +3883,7 @@ SQL
3835
  }
3836
  public static function ajax_saveCountryBlocking_callback(){
3837
  if(! wfConfig::get('isPaid')){
3838
- return array('errorMsg' => "Sorry but this feature is only available for paid customers.");
3839
  }
3840
  wfConfig::set('cbl_action', $_POST['blockAction']);
3841
  wfConfig::set('cbl_countries', $_POST['codes']);
@@ -3849,7 +3897,13 @@ SQL
3849
  return array('ok' => 1);
3850
  }
3851
  public static function ajax_sendActivityLog_callback(){
3852
- $content = "SITE: " . site_url() . "\nPLUGIN VERSION: " . WORDFENCE_VERSION . "\nWP VERSION: " . wfUtils::getWPVersion() . "\nLICENSE KEY: " . wfConfig::get('apiKey') . "\nADMIN EMAIL: " . get_option('admin_email') . "\nLOG:\n\n";
 
 
 
 
 
 
3853
  $wfdb = new wfDB();
3854
  $table_wfStatus = wfDB::networkTable('wfStatus');
3855
  $q = $wfdb->querySelect("select ctime, level, type, msg from {$table_wfStatus} order by ctime desc limit 10000");
@@ -3869,7 +3923,7 @@ SQL
3869
  $issueCounts = array_merge(array('new' => 0, 'ignoreP' => 0, 'ignoreC' => 0), wfIssues::shared()->getIssueCounts());
3870
  $issueTypes = wfIssues::validIssueTypes();
3871
 
3872
- $content .= sprintf(__('## New Issues (%d total)', 'wordfence'), $issueCounts['new']) . "\n\n";
3873
  if (isset($issues['new']) && count($issues['new'])) {
3874
  foreach ($issues['new'] as $i) {
3875
  if (!in_array($i['type'], $issueTypes)) {
@@ -3896,7 +3950,7 @@ SQL
3896
  $content .= str_repeat('-', 10);
3897
  $content .= "\n\n";
3898
 
3899
- $content .= sprintf(__('## Ignored Issues (%d total)', 'wordfence'), $issueCounts['ignoreP'] + $issueCounts['ignoreC']) . "\n\n";
3900
  if (isset($issues['new']) && count($issues['new'])) {
3901
  foreach ($issues['ignored'] as $i) {
3902
  if (!in_array($i['type'], $issueTypes)) {
@@ -3964,10 +4018,10 @@ SQL
3964
  wfWAF::getInstance()->getStorageEngine()->purgeIPBlocks(wfWAFStorageInterface::IP_BLOCKS_BLACKLIST);
3965
  }
3966
  } else {
3967
- throw new Exception("Could not understand the response we received from the Wordfence servers when applying for a free license key.");
3968
  }
3969
  } catch(Exception $e){
3970
- return array('errorMsg' => "Could not fetch free license key from Wordfence: " . wp_kses($e->getMessage(), array()));
3971
  }
3972
  return array('ok' => 1);
3973
  }
@@ -4052,12 +4106,12 @@ SQL
4052
  }
4053
  $file = wfCache::getHtaccessPath();
4054
  if(! $file){
4055
- return array('err' => "We could not find your .htaccess file to modify it.");
4056
  }
4057
  $fh = @fopen($file, 'r+');
4058
  if(! $fh){
4059
  $err = error_get_last();
4060
- return array('err' => "We found your .htaccess file but could not open it for writing: " . $err['message']);
4061
  }
4062
  return array('ok' => 1);
4063
  }
@@ -4146,7 +4200,7 @@ SQL
4146
  $entry['detailDisplay'] = __('1 Country', 'wordfence');
4147
  }
4148
  else {
4149
- $entry['detailDisplay'] = sprintf(__('%d Countries', 'wordfence'), count($countries));
4150
  }
4151
 
4152
  if ($b->blockLogin && $b->blockSite) {
@@ -4284,7 +4338,12 @@ SQL
4284
  }
4285
 
4286
  if (!empty($_POST['blocks']) && ($blocks = json_decode(stripslashes($_POST['blocks']), true)) !== false && is_array($blocks)) {
4287
- wfBlock::removeBlockIDs($blocks); //wfBlock::removeBlockIDs sanitizes the array
 
 
 
 
 
4288
  $hasCountryBlock = false;
4289
  $blocks = self::_blocksAJAXReponse($hasCountryBlock, $offset, $sortColumn, $sortDirection, $filter);
4290
  return array('success' => true, 'blocks' => $blocks, 'hasCountryBlock' => $hasCountryBlock);
@@ -4446,7 +4505,7 @@ SQL
4446
  if ($errors !== true) {
4447
  if (count($errors) == 1) {
4448
  return array(
4449
- 'error' => sprintf(__('An error occurred while saving the configuration: %s', 'wordfence'), $errors[0]['error']),
4450
  );
4451
  }
4452
  else if (count($errors) > 1) {
@@ -4455,7 +4514,7 @@ SQL
4455
  $compoundMessage[] = $e['error'];
4456
  }
4457
  return array(
4458
- 'error' => sprintf(__('Errors occurred while saving the configuration: %s', 'wordfence'), implode(', ', $compoundMessage)),
4459
  );
4460
  }
4461
 
@@ -4529,7 +4588,7 @@ SQL
4529
  $issues = new wfIssues();
4530
  $issue = $issues->getIssueByID((int) $_POST['issueID']);
4531
  if (!$issue) {
4532
- return array('errorMsg' => "We could not find that issue in our database.");
4533
  }
4534
 
4535
  if (!function_exists('get_home_path')) {
@@ -4539,7 +4598,7 @@ SQL
4539
  $homeURL = get_home_url();
4540
  $components = parse_url($homeURL);
4541
  if ($components === false) {
4542
- return array('errorMsg' => "An error occurred while trying to hide the file.");
4543
  }
4544
 
4545
  $sitePath = '';
@@ -4552,7 +4611,7 @@ SQL
4552
  $localFile = ABSPATH . '/' . $file; //The scanner uses ABSPATH as its base rather than get_home_path()
4553
  $localFile = realpath($localFile);
4554
  if (strpos($localFile, $homePath) !== 0) {
4555
- return array('errorMsg' => "An invalid file was requested for hiding.");
4556
  }
4557
  $localFile = substr($localFile, strlen($homePath));
4558
  $absoluteURIPath = trim($sitePath . '/' . $localFile, '/');
@@ -4579,7 +4638,7 @@ SQL
4579
  HTACCESS;
4580
 
4581
  if (!wfUtils::htaccessPrepend($htaccessContent)) {
4582
- return array('errorMsg' => "You don't have permission to repair .htaccess. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file.");
4583
  }
4584
  $issues->updateIssue((int) $_POST['issueID'], 'delete');
4585
  wfScanEngine::refreshScanNotification($issues);
@@ -4592,11 +4651,13 @@ HTACCESS;
4592
  public static function ajax_unlockOutIP_callback(){
4593
  $IP = $_POST['IP'];
4594
  wfBlock::unlockOutIP($IP);
 
4595
  return array('ok' => 1);
4596
  }
4597
  public static function ajax_unblockIP_callback(){
4598
  $IP = $_POST['IP'];
4599
  wfBlock::unblockIP($IP);
 
4600
  return array('ok' => 1);
4601
  }
4602
  public static function ajax_permBlockIP_callback(){
@@ -4637,22 +4698,22 @@ HTACCESS;
4637
  $IP = trim($_POST['IP']);
4638
  $perm = (isset($_POST['perm']) && $_POST['perm'] == '1') ? wfBlock::DURATION_FOREVER : wfConfig::getInt('blockedTime');
4639
  if (!wfUtils::isValidIP($IP)) {
4640
- return array('err' => 1, 'errorMsg' => "Please enter a valid IP address to block.");
4641
  }
4642
  if ($IP == wfUtils::getIP()) {
4643
- return array('err' => 1, 'errorMsg' => "You can't block your own IP address.");
4644
  }
4645
  $forcedWhitelistEntry = false;
4646
  if (wfBlock::isWhitelisted($IP, $forcedWhitelistEntry)) {
4647
- $message = "The IP address " . wp_kses($IP, array()) . " is allowlisted and can't be blocked. You can remove this IP from the allowlist on the Wordfence options page.";
4648
  if ($forcedWhitelistEntry) {
4649
- $message = "The IP address " . wp_kses($IP, array()) . " is in a range of IP addresses that Wordfence does not block. The IP range may be internal or belong to a service safe to allow access for.";
4650
  }
4651
  return array('err' => 1, 'errorMsg' => $message);
4652
  }
4653
  if (wfConfig::get('neverBlockBG') != 'treatAsOtherCrawlers') { //Either neverBlockVerified or neverBlockUA is selected which means the user doesn't want to block google
4654
  if (wfCrawl::isVerifiedGoogleCrawler($IP)) {
4655
- return array('err' => 1, 'errorMsg' => "The IP address you're trying to block belongs to Google. Your options are currently set to not block these crawlers. Change this in Wordfence options if you want to manually block Google.");
4656
  }
4657
  }
4658
  wfBlock::createIP($_POST['reason'], $IP, $perm);
@@ -4695,7 +4756,7 @@ HTACCESS;
4695
  } else if($op == 'ignoreAllNew'){
4696
  $i->ignoreAllNew();
4697
  } else {
4698
- return array('errorMsg' => "An invalid operation was called.");
4699
  }
4700
  wfScanEngine::refreshScanNotification($i);
4701
  return array('ok' => 1);
@@ -4705,7 +4766,7 @@ HTACCESS;
4705
  $status = $_POST['status'];
4706
  $issueID = $_POST['id'];
4707
  if(! preg_match('/^(?:new|delete|ignoreP|ignoreC)$/', $status)){
4708
- return array('errorMsg' => "An invalid status was specified when trying to update that issue.");
4709
  }
4710
  $wfIssues->updateIssue($issueID, $status);
4711
  wfScanEngine::refreshScanNotification($wfIssues);
@@ -4717,8 +4778,8 @@ HTACCESS;
4717
  );
4718
  }
4719
  public static function ajax_killScan_callback(){
4720
- wordfence::status(1, 'info', "Scan stop request received.");
4721
- wordfence::status(10, 'info', "SUM_KILLED:A request was received to stop the previous scan.");
4722
  wfUtils::clearScanLock(); //Clear the lock now because there may not be a scan running to pick up the kill request and clear the lock
4723
  wfScanEngine::requestKill();
4724
  wfConfig::remove('scanStartAttempt');
@@ -4776,7 +4837,7 @@ HTACCESS;
4776
  else if ($lastScanCompleted == 'ok') {
4777
  $scanLastCompletion = (int) wfScanner::shared()->lastScanTime();
4778
  if ($scanLastCompletion) {
4779
- $lastMessage = sprintf(__('Scan completed on %s', 'wordfence'), wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $scanLastCompletion));
4780
  }
4781
  }
4782
  else if ($lastScanCompleted === false || empty($lastScanCompleted)) {
@@ -4846,11 +4907,11 @@ HTACCESS;
4846
  $scanFailedTiming = wfUtils::makeTimeAgo($scanFailedSeconds);
4847
 
4848
  if ($scanFailedSeconds > $timeLimit) {
4849
- $scanFailedTiming = 'more than ' . wfUtils::makeTimeAgo($timeLimit);
4850
  }
4851
 
4852
  $scanFailedHTML = wfView::create('scanner/scan-failed', array(
4853
- 'messageHTML' => sprintf(__('The current scan looks like it has failed. Its last status update was <span id="wf-scan-failed-time-ago">%s</span> ago. You may continue to wait in case it resumes or stop and restart the scan. Some sites may need adjustments to run scans reliably.', 'wordfence'), $scanFailedTiming) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_FAILS) . '" target="_blank" rel="noopener noreferrer">' . __('Click here for steps you can try.', 'wordfence') . '</a>',
4854
  'buttonTitle' => __('Cancel Scan', 'wordfence'),
4855
  ))->render();
4856
 
@@ -4864,13 +4925,13 @@ HTACCESS;
4864
  break;
4865
  case wfIssues::SCAN_FAILED_DURATION_REACHED:
4866
  $scanFailedHTML = wfView::create('scanner/scan-failed', array(
4867
- 'messageHTML' => sprintf(__('The previous scan has terminated because the time limit of %s was reached. This limit can be customized on the options page.', 'wordfence'), wfUtils::makeDuration($timeLimit)) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_OPTION_OVERALL_TIME_LIMIT) . '" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i></a>',
4868
  'buttonTitle' => __('Close', 'wordfence'),
4869
  ))->render();
4870
  break;
4871
  case wfIssues::SCAN_FAILED_VERSION_CHANGE:
4872
  $scanFailedHTML = wfView::create('scanner/scan-failed', array(
4873
- 'messageHTML' => __('The previous scan has terminated because we detected an update occurring during the scan.', 'wordfence'),
4874
  'buttonTitle' => __('Close', 'wordfence'),
4875
  ))->render();
4876
  break;
@@ -4883,7 +4944,7 @@ HTACCESS;
4883
  break;
4884
  case wfIssues::SCAN_FAILED_API_SSL_UNAVAILABLE:
4885
  $scanFailedHTML = wfView::create('scanner/scan-failed', array(
4886
- 'messageHTML' => __('Scans are not functional because SSL is unavailable.', 'wordfence'),
4887
  'buttonTitle' => __('Close', 'wordfence'),
4888
  ))->render();
4889
  break;
@@ -4924,7 +4985,7 @@ HTACCESS;
4924
  public static function ajax_updateAlertEmail_callback(){
4925
  $email = trim($_POST['email']);
4926
  if(! preg_match('/[^\@]+\@[^\.]+\.[^\.]+/', $email) || in_array(hash('sha256', $email), wfConfig::alertEmailBlacklist())){
4927
- return array( 'err' => "Invalid email address given.");
4928
  }
4929
  wfConfig::set('alertEmails', $email);
4930
  return array('ok' => 1, 'email' => $email);
@@ -4958,7 +5019,7 @@ HTACCESS;
4958
  }
4959
  else {
4960
  $err = error_get_last();
4961
- $errors[] = esc_html(sprintf(__('Could not delete file %s. Error was: %s', 'wordfence'), wp_kses($file, array()), wp_kses(str_replace(ABSPATH, '{WordPress Root}/', $err['message']), array())));
4962
  }
4963
  }
4964
  else if ($op == 'repair' && @$i['data']['canFix']) {
@@ -4982,12 +5043,12 @@ HTACCESS;
4982
  continue;
4983
  }
4984
  else if (!is_array($result) || !isset($result['fileContent'])) {
4985
- $errors[] = esc_html(sprintf(__('We could not retrieve the original file of %s to do a repair.', 'wordfence'), wp_kses($file, array())));
4986
  continue;
4987
  }
4988
 
4989
  if (preg_match('/\.\./', $file)) {
4990
- $errors[] = sprintf(__('An invalid file %s was specified for repair.', 'wordfence'), wp_kses($file, array()));
4991
  continue;
4992
  }
4993
 
@@ -4995,10 +5056,10 @@ HTACCESS;
4995
  if (!$fh) {
4996
  $err = error_get_last();
4997
  if (preg_match('/Permission denied/i', $err['message'])) {
4998
- $errMsg = esc_html(sprintf(__('You don\'t have permission to repair %s. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file.', 'wordfence'), wp_kses($file, array())));
4999
  }
5000
  else {
5001
- $errMsg = esc_html(sprintf(__('We could not write to %s. The error was: %s', 'wordfence'), wp_kses($file, array()), $err['message']));
5002
  }
5003
  $errors[] = $errMsg;
5004
  continue;
@@ -5009,7 +5070,7 @@ HTACCESS;
5009
  flock($fh, LOCK_UN);
5010
  fclose($fh);
5011
  if ($bytes < 1) {
5012
- $errors[] = esc_html(sprintf(__('We could not write to %s. (%d bytes written) You may not have permission to modify files on your WordPress server.', 'wordfence'), wp_kses($file, array()), $bytes));
5013
  continue;
5014
  }
5015
 
@@ -5022,15 +5083,24 @@ HTACCESS;
5022
 
5023
  if ($filesWorkedOn > 0 && count($errors) > 0) {
5024
  $headMsg = esc_html($op == 'del' ? __('Deleted some files with errors', 'wordfence') : __('Repaired some files with errors', 'wordfence'));
5025
- $bodyMsg = sprintf(esc_html($op == 'del' ? __('Deleted %d files but we encountered the following errors with other files: %s', 'wordfence') : __('Repaired %d files but we encountered the following errors with other files: %s', 'wordfence')), $filesWorkedOn, implode('<br>', $errors));
 
 
 
 
 
5026
  }
5027
  else if ($filesWorkedOn > 0) {
5028
- $headMsg = sprintf(esc_html($op == 'del' ? __('Deleted %d files successfully', 'wordfence') : __('Repaired %d files successfully', 'wordfence')), $filesWorkedOn);
5029
- $bodyMsg = sprintf(esc_html($op == 'del' ? __('Deleted %d files successfully. No errors were encountered.', 'wordfence') : __('Repaired %d files successfully. No errors were encountered.', 'wordfence')), $filesWorkedOn);
5030
  }
5031
  else if (count($errors) > 0) {
5032
  $headMsg = esc_html($op == 'del' ? __('Could not delete files', 'wordfence') : __('Could not repair files', 'wordfence'));
5033
- $bodyMsg = sprintf(esc_html($op == 'del' ? __('We could not delete any of the files you selected. We encountered the following errors: %s', 'wordfence') : __('We could not repair any of the files you selected. We encountered the following errors: %s', 'wordfence')), implode('<br>', $errors));
 
 
 
 
5034
  }
5035
  else {
5036
  $headMsg = esc_html__('Nothing done', 'wordfence');
@@ -5101,7 +5171,14 @@ HTACCESS;
5101
  }
5102
 
5103
  $err = error_get_last();
5104
- return array('errorMsg' => "Could not delete file " . wp_kses($file, array()) . ". The error was: " . wp_kses(str_replace(ABSPATH, '{WordPress Root}/', $err['message']), array()));
 
 
 
 
 
 
 
5105
  }
5106
  public static function ajax_deleteDatabaseOption_callback(){
5107
  /** @var wpdb $wpdb */
@@ -5110,10 +5187,10 @@ HTACCESS;
5110
  $wfIssues = new wfIssues();
5111
  $issue = $wfIssues->getIssueByID($issueID);
5112
  if (!$issue) {
5113
- return array('errorMsg' => "Could not remove the option because we could not find that issue.");
5114
  }
5115
  if (empty($issue['data']['option_name'])) {
5116
- return array('errorMsg' => "Could not remove the option because that issue does not appear to be a database related issue.");
5117
  }
5118
  $table_options = wfDB::blogTable('options', $issue['data']['site_id']);
5119
  if ($wpdb->query($wpdb->prepare("DELETE FROM {$table_options} WHERE option_name = %s", $issue['data']['option_name']))) {
@@ -5124,14 +5201,19 @@ HTACCESS;
5124
  'option_name' => $issue['data']['option_name'],
5125
  );
5126
  } else {
5127
- return array('errorMsg' => "Could not remove the option " . esc_html($issue['data']['option_name']) . ". The error was: " . esc_html($wpdb->last_error));
 
 
 
 
 
5128
  }
5129
  }
5130
  public static function ajax_fixFPD_callback(){
5131
  $issues = new wfIssues();
5132
  $issue = $issues->getIssueByID($_POST['issueID']);
5133
  if (!$issue) {
5134
- return array('cerrorMsg' => "We could not find that issue in our database.");
5135
  }
5136
 
5137
  $htaccess = ABSPATH . '/.htaccess';
@@ -5142,16 +5224,13 @@ HTACCESS;
5142
  }
5143
 
5144
  if (@file_put_contents($htaccess, trim($content . "\n" . $change), LOCK_EX) === false) {
5145
- return array('cerrorMsg' => "You don't have permission to repair .htaccess. You need to either fix the file
5146
- manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file.");
5147
  }
5148
  if (wfScanEngine::testForFullPathDisclosure()) {
5149
  // Didn't fix it, so revert the changes and return an error
5150
  file_put_contents($htaccess, $content, LOCK_EX);
5151
  return array(
5152
- 'cerrorMsg' => "Modifying the .htaccess file did not resolve the issue, so the original .htaccess file
5153
- was restored. You can fix this manually by setting <code>display_errors</code> to <code>Off</code> in
5154
- your php.ini if your site is on a VPS or dedicated server that you control.",
5155
  );
5156
  }
5157
  $issues->updateIssue($_POST['issueID'], 'delete');
@@ -5165,7 +5244,7 @@ HTACCESS;
5165
  $wfIssues = new wfIssues();
5166
  $issue = $wfIssues->getIssueByID($issueID);
5167
  if(! $issue){
5168
- return array('cerrorMsg' => "We could not find that issue in our database.");
5169
  }
5170
 
5171
  /** @var WP_Filesystem_Base $wp_filesystem */
@@ -5193,11 +5272,11 @@ HTACCESS;
5193
  if(isset($result['errorMsg']) && $result['errorMsg']){
5194
  return $result;
5195
  } else if(! $result['fileContent']){
5196
- return array('errorMsg' => "We could not get the original file to do a repair.");
5197
  }
5198
 
5199
  if(preg_match('/\.\./', $file)){
5200
- return array('errorMsg' => "An invalid file was specified for repair.");
5201
  }
5202
  $localFile = rtrim(ABSPATH, '/') . '/' . preg_replace('/^[\.\/]+/', '', $file);
5203
  if ($wp_filesystem->put_contents($localFile, $result['fileContent'])) {
@@ -5212,11 +5291,11 @@ HTACCESS;
5212
  );
5213
  }
5214
  return array(
5215
- 'errorMsg' => "We could not write to that file. You may not have permission to modify files on your WordPress server.",
5216
  );
5217
  }
5218
  public static function ajax_scan_callback(){
5219
- self::status(4, 'info', "Ajax request received to start scan.");
5220
  $err = wfScanEngine::startScan();
5221
  if ($err) {
5222
  return array('errorMsg' => wp_kses($err, array()));
@@ -5268,7 +5347,13 @@ HTACCESS;
5268
  $hresults = $hooverResults[1];
5269
  $count = count($hresults);
5270
  if ($count > 0) {
5271
- new wfNotification(null, wfNotification::PRIORITY_HIGH_WARNING, "Page contains {$count} malware URL" . ($count == 1 ? '' : 's') . ': ' . esc_html($pageURL), 'wfplugin_malwareurl_' . md5($pageURL), null, array(array('link' => wfUtils::wpAdminURL('admin.php?page=WordfenceScan'), 'label' => 'Run a Scan')));
 
 
 
 
 
 
5272
  return array('bad' => $count);
5273
  }
5274
  }
@@ -5316,7 +5401,7 @@ HTACCESS;
5316
  }
5317
  }
5318
 
5319
- return array('error' => 'Unknown dashboard data set.');
5320
  }
5321
  public static function startScan(){
5322
  wfScanEngine::startScan();
@@ -5338,7 +5423,7 @@ HTACCESS;
5338
  //End logging
5339
 
5340
 
5341
- if(! ($wfFunc == 'diff' || $wfFunc == 'view' || $wfFunc == 'viewOption' || $wfFunc == 'sysinfo' || $wfFunc == 'cronview' || $wfFunc == 'dbview' || $wfFunc == 'conntest' || $wfFunc == 'unknownFiles' || $wfFunc == 'IPTraf' || $wfFunc == 'viewActivityLog' || $wfFunc == 'testmem' || $wfFunc == 'testtime' || $wfFunc == 'download' || $wfFunc == 'blockedIPs' || ($wfFunc == 'debugWAF' && WFWAF_DEBUG))){
5342
  return;
5343
  }
5344
  if(! wfUtils::isAdmin()){
@@ -5347,7 +5432,7 @@ HTACCESS;
5347
 
5348
  $nonce = $_GET['nonce'];
5349
  if(! wp_verify_nonce($nonce, 'wp-ajax')){
5350
- echo "Bad security token. It may have been more than 12 hours since you reloaded the page you came from. Try reloading the page you came from. If that doesn't work, please sign out and sign-in again.";
5351
  exit(0);
5352
  }
5353
  if($wfFunc == 'diff'){
@@ -5358,14 +5443,6 @@ HTACCESS;
5358
  self::wfFunc_viewOption();
5359
  } else if($wfFunc == 'sysinfo') {
5360
  require(dirname(__FILE__) . '/sysinfo.php' );
5361
- } else if($wfFunc == 'dbview'){
5362
- require(dirname(__FILE__) . '/dbview.php');
5363
- } else if($wfFunc == 'cronview') {
5364
- require(dirname(__FILE__) . '/cronview.php');
5365
- } else if($wfFunc == 'conntest'){
5366
- require(dirname(__FILE__) . '/conntest.php');
5367
- } else if($wfFunc == 'unknownFiles'){
5368
- require(dirname(__FILE__) . '/unknownFiles.php');
5369
  } else if($wfFunc == 'IPTraf'){
5370
  self::wfFunc_IPTraf();
5371
  } else if($wfFunc == 'viewActivityLog'){
@@ -5542,7 +5619,7 @@ HTML;
5542
 
5543
  private static function IPTraf($ip) {
5544
  if(!wfUtils::isValidIP($ip)){
5545
- throw new InvalidArgumentException("An invalid IP address was specified.");
5546
  }
5547
  $reverseLookup = wfUtils::reverseLookup($ip);
5548
  $wfLog = wfLog::shared();
@@ -5595,16 +5672,16 @@ HTML;
5595
  public static function wfFunc_view(){
5596
  wfUtils::doNotCache();
5597
  if (WORDFENCE_DISABLE_FILE_VIEWER) {
5598
- echo "File access blocked. (WORDFENCE_DISABLE_FILE_VIEWER is true)";
5599
  exit();
5600
  }
5601
  $localFile = ABSPATH . preg_replace('/^(?:\.\.|[\/]+)/', '', sanitize_text_field($_GET['file']));
5602
  if(strpos($localFile, '..') !== false){
5603
- echo "Invalid file requested. (Relative paths not allowed)";
5604
  exit();
5605
  }
5606
  if(preg_match('/[\'\"<>\!\{\}\(\)\&\@\%\$\*\+\[\]\?]+/', $localFile)){
5607
- echo "File contains illegal characters.";
5608
  exit();
5609
  }
5610
  $cont = @file_get_contents($localFile);
@@ -5614,7 +5691,7 @@ HTML;
5614
  $isEmpty = true;
5615
  } else {
5616
  $err = error_get_last();
5617
- echo "We could not open the requested file for reading. The error was: " . $err['message'];
5618
  exit(0);
5619
  }
5620
  }
@@ -5622,12 +5699,12 @@ HTML;
5622
  $fileMTime = date('l jS \of F Y h:i:s A', $fileMTime);
5623
  try {
5624
  if(wfUtils::fileOver2Gigs($localFile)){
5625
- $fileSize = "Greater than 2 Gigs";
5626
  } else {
5627
  $fileSize = @filesize($localFile); //Checked if over 2 gigs above
5628
  $fileSize = number_format($fileSize, 0, '', ',') . ' bytes';
5629
  }
5630
- } catch(Exception $e){ $fileSize = 'Unknown file size.'; }
5631
 
5632
  require(dirname(__FILE__) . '/wfViewResult.php');
5633
  exit(0);
@@ -5635,11 +5712,11 @@ HTML;
5635
  public static function wfFunc_diff(){
5636
  wfUtils::doNotCache();
5637
  if (WORDFENCE_DISABLE_FILE_VIEWER) {
5638
- echo "File access blocked. (WORDFENCE_DISABLE_FILE_VIEWER is true)";
5639
  exit();
5640
  }
5641
  if(preg_match('/[\'\"<>\!\{\}\(\)\&\@\%\$\*\+\[\]\?]+/', $_GET['file'])){
5642
- echo "File contains illegal characters.";
5643
  exit();
5644
  }
5645
 
@@ -5648,7 +5725,7 @@ HTML;
5648
  echo wp_kses($result['errorMsg'], array());
5649
  exit(0);
5650
  } else if(! $result['fileContent']){
5651
- echo "We could not get the contents of the original file to do a comparison.";
5652
  exit(0);
5653
  }
5654
 
@@ -5673,20 +5750,21 @@ HTML;
5673
  public static function wfFunc_download() {
5674
  wfUtils::doNotCache();
5675
  if (WORDFENCE_DISABLE_FILE_VIEWER) {
5676
- echo "File access blocked. (WORDFENCE_DISABLE_FILE_VIEWER is true)";
5677
  exit();
5678
  }
5679
  $localFile = ABSPATH . preg_replace('/^(?:\.\.|[\/]+)/', '', sanitize_text_field($_GET['file']));
5680
  if (strpos($localFile, '..') !== false) {
5681
- echo "Invalid file requested. (Relative paths not allowed)";
5682
  exit();
5683
  }
5684
  if (preg_match('/[\'\"<>\!\{\}\(\)\&\@\%\$\*\+\[\]\?]+/', $localFile)) {
5685
- echo "File contains illegal characters.";
5686
  exit();
5687
  }
5688
  if (!file_exists($localFile)) {
5689
- exit('File does not exist.');
 
5690
  }
5691
 
5692
  $filename = basename($localFile);
@@ -5862,8 +5940,9 @@ HTML;
5862
  wp_enqueue_script('jquery.wfdataTables', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/jquery.dataTables.min.js'), array('jquery'), WORDFENCE_VERSION);
5863
  wp_enqueue_script('jquery.qrcode', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/jquery.qrcode.min.js'), array('jquery'), WORDFENCE_VERSION);
5864
  //wp_enqueue_script('jquery.tools', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/jquery.tools.min.js'), array('jquery'));
5865
- wp_enqueue_script('wordfenceAdminjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/admin.js'), array('jquery', 'jquery-ui-core', 'jquery-ui-menu'), WORDFENCE_VERSION);
5866
  wp_enqueue_script('wordfenceAdminExtjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/wfglobal.js'), array('jquery'), WORDFENCE_VERSION);
 
5867
  wp_enqueue_script('wordfenceDropdownjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/wfdropdown.js'), array('jquery'), WORDFENCE_VERSION);
5868
  self::setupAdminVars();
5869
 
@@ -5873,6 +5952,7 @@ HTML;
5873
  } else {
5874
  wp_enqueue_style('wp-pointer');
5875
  wp_enqueue_script('wp-pointer');
 
5876
  wp_enqueue_script('wordfenceAdminExtjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/wfglobal.js'), array('jquery'), WORDFENCE_VERSION);
5877
  wp_enqueue_style('wordfence-font-awesome-style');
5878
  wp_enqueue_style('wordfence-global-style', wfUtils::getBaseURL() . wfUtils::versionedAsset('css/wf-global.css'), '', WORDFENCE_VERSION);
@@ -5939,7 +6019,184 @@ HTML;
5939
  'supportURLs' => array(
5940
  'scan-result-repair-modified-files' => esc_url_raw(wfSupportController::supportURL(wfSupportController::ITEM_SCAN_RESULT_REPAIR_MODIFIED_FILES)),
5941
  ),
5942
- ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5943
  }
5944
  public static function showTOUPPOverlay($classList) {
5945
  return trim($classList . ' wf-toupp-required');
@@ -5950,12 +6207,17 @@ HTML;
5950
  $activationError = substr($activationError, 0, 400) . '...[output truncated]';
5951
  }
5952
  if($activationError){
5953
- echo '<div id="wordfenceConfigWarning" class="updated fade"><p><strong>Wordfence generated an error on activation. The output we received during activation was:</strong> ' . wp_kses($activationError, array()) . '</p></div>';
 
 
5954
  }
5955
  delete_option('wf_plugin_act_error');
5956
  }
5957
  public static function noKeyError(){
5958
- echo '<div id="wordfenceConfigWarning" class="fade error"><p><strong>Wordfence could not register with the Wordfence scanning servers when it activated.</strong> You can try to fix this by deactivating Wordfence and then activating it again, so Wordfence will retry registering for you. If you keep seeing this error, it usually means your WordPress server can\'t connect to our scanning servers, or your wfConfig database table cannot be created to save the key. You can try asking your host to allow your server to connect to noc1.wordfence.com or check the wfConfig database table and database privileges.</p></div>';
 
 
 
5959
  }
5960
  public static function wafConfigInaccessibleNotice() {
5961
  if (function_exists('network_admin_url') && is_multisite()) {
@@ -5968,7 +6230,13 @@ HTML;
5968
  'waf-nonce' => wp_create_nonce('wafconfigrebuild'),
5969
  ), $wafMenuURL);
5970
 
5971
- echo '<div id="wafConfigInaccessibleNotice" class="fade error"><p><strong>' . __('The Wordfence Web Application Firewall cannot run.', 'wordfence') . '</strong> ' . sprintf('The configuration files are corrupt or inaccessible by the web server, which is preventing the WAF from functioning. Please verify the web server has permission to access the configuration files. You may also try to rebuild the configuration file by <a href="%s">clicking here</a>. It will automatically resume normal operation when it is fixed. <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="%s"></a>', $wafMenuURL, wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_WAF_INACCESSIBLE_CONFIG)) . '</p></div>';
 
 
 
 
 
 
5972
  }
5973
  public static function wafConfigNeedsUpdate_mod_php() {
5974
  if (function_exists('network_admin_url') && is_multisite()) {
@@ -5981,7 +6249,13 @@ HTML;
5981
  'waf-nonce' => wp_create_nonce('wafconfigfixmodphp'),
5982
  ), $wafMenuURL);
5983
 
5984
- echo '<div id="wafConfigNeedsUpdateNotice" class="fade error"><p><strong>' . __('The Wordfence Web Application Firewall needs a configuration update.', 'wordfence') . '</strong> ' . sprintf('It is currently configured to use an older version of PHP and may become deactivated if PHP is updated. You may perform the configuration update automatically by <a href="%s">clicking here</a>. <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="%s"></a>', $wafMenuURL, wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_WAF_MOD_PHP_FIX)) . '</p></div>';
 
 
 
 
 
 
5985
  }
5986
  public static function wafConfigNeedsFixed_mod_php() {
5987
  if (function_exists('network_admin_url') && is_multisite()) {
@@ -5994,7 +6268,13 @@ HTML;
5994
  'waf-nonce' => wp_create_nonce('wafconfigfixmodphp'),
5995
  ), $wafMenuURL);
5996
 
5997
- echo '<div id="wafConfigNeedsFixedNotice" class="fade error"><p><strong>' . __('The Wordfence Web Application Firewall needs a configuration update.', 'wordfence') . '</strong> ' . sprintf('It is not currently in extended protection mode but was configured to use an older version of PHP and may have become deactivated when PHP was updated. You may perform the configuration update automatically by <a href="%s">clicking here</a> or use the "Optimize the Wordfence Firewall" button on the Firewall Options page. <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="%s"></a>', $wafMenuURL, wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_WAF_MOD_PHP_FIX)) . '</p></div>';
 
 
 
 
 
 
5998
  }
5999
  public static function wafReadOnlyNotice() {
6000
  echo '<div id="wordfenceWAFReadOnlyNotice" class="fade error"><p><strong>' . __('The Wordfence Web Application Firewall is in read-only mode.', 'wordfence') . '</strong> ' . sprintf('PHP is currently running as a command line user and to avoid file permission issues, the WAF is running in read-only mode. It will automatically resume normal operation when run normally by a web server. <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="%s"></a>', wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_WAF_READ_ONLY_WARNING)) . '</p></div>';
@@ -6006,36 +6286,54 @@ HTML;
6006
 
6007
  $existingMsg = '';
6008
  if ($existing == 'REMOTE_ADDR') {
6009
- $existingMsg = 'This site is currently using PHP\'s built in REMOTE_ADDR.';
6010
  }
6011
  else if ($existing == 'HTTP_X_FORWARDED_FOR') {
6012
- $existingMsg = 'This site is currently using the X-Forwarded-For HTTP header, which should only be used when the site is behind a front-end proxy that outputs this header.';
6013
  }
6014
  else if ($existing == 'HTTP_X_REAL_IP') {
6015
- $existingMsg = 'This site is currently using the X-Real-IP HTTP header, which should only be used when the site is behind a front-end proxy that outputs this header.';
6016
  }
6017
  else if ($existing == 'HTTP_CF_CONNECTING_IP') {
6018
- $existingMsg = 'This site is currently using the Cloudflare "CF-Connecting-IP" HTTP header, which should only be used when the site is behind Cloudflare.';
6019
  }
6020
 
6021
  $recommendationMsg = '';
6022
  if ($recommendation == 'REMOTE_ADDR') {
6023
- $recommendationMsg = 'For maximum security use PHP\'s built in REMOTE_ADDR.';
6024
  }
6025
  else if ($recommendation == 'HTTP_X_FORWARDED_FOR') {
6026
- $recommendationMsg = 'This site appears to be behind a front-end proxy, so using the X-Forwarded-For HTTP header will resolve to the correct IPs.';
6027
  }
6028
  else if ($recommendation == 'HTTP_X_REAL_IP') {
6029
- $recommendationMsg = 'This site appears to be behind a front-end proxy, so using the X-Real-IP HTTP header will resolve to the correct IPs.';
6030
  }
6031
  else if ($recommendation == 'HTTP_CF_CONNECTING_IP') {
6032
- $recommendationMsg = 'This site appears to be behind Cloudflare, so using the Cloudflare "CF-Connecting-IP" HTTP header will resolve to the correct IPs.';
6033
- }
6034
- echo '<div id="wordfenceMisconfiguredHowGetIPsNotice" class="fade error"><p><strong>Your \'How does Wordfence get IPs\' setting is misconfigured.</strong> ' . $existingMsg . ' ' . $recommendationMsg . ' <a href="#" onclick="wordfenceExt.misconfiguredHowGetIPsChoice(\'yes\'); return false;">Click here to use the recommended setting</a> or <a href="' . $url . '">visit the options page</a> to manually update it.</p><p>
6035
- <a class="wf-btn wf-btn-default wf-btn-sm wf-dismiss-link" href="#" onclick="wordfenceExt.misconfiguredHowGetIPsChoice(\'no\'); return false;">Dismiss</a> <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_MISCONFIGURED_HOW_GET_IPS) . '"></a></p></div>';
 
 
 
 
 
 
 
 
 
 
 
 
6036
  }
6037
  public static function autoUpdateNotice(){
6038
- echo '<div id="wordfenceAutoUpdateChoice" class="fade error"><p><strong>Do you want Wordfence to stay up-to-date automatically?</strong>&nbsp;&nbsp;&nbsp;<a href="#" onclick="wordfenceExt.autoUpdateChoice(\'yes\'); return false;">Yes, enable auto-update.</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href="#" onclick="wordfenceExt.autoUpdateChoice(\'no\'); return false;">No thanks.</a></p></div>';
 
 
 
 
 
 
6039
  }
6040
  public static function admin_menus(){
6041
  if(! wfUtils::isAdmin()){ return; }
@@ -6115,19 +6413,28 @@ HTML;
6115
  }
6116
  }
6117
 
6118
- $message = sprintf(__('The last rules update for the Wordfence Web Application Firewall was unsuccessful. The last successful update check was %s, so this site may be missing new rules added since then.', 'wordfence'), wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $lastChecked));
 
 
 
 
6119
 
6120
  if (!$firewall->isSubDirectoryInstallation()) {
6121
  if ($nextUpdate < PHP_INT_MAX) {
6122
- $message .= ' ' . sprintf(__('You may wait for the next automatic attempt at %s or try to <a href="%s">Manually Update</a> by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence'), wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $nextUpdate), esc_url(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#wf-option-wafRules')));
 
 
 
 
 
6123
  }
6124
  else {
6125
- $message .= ' ' . sprintf(__('You may wait for the next automatic attempt or try to <a href="%s">Manually Update</a> by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence'), esc_url(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#waf-rules-next-update')));
6126
  }
6127
  }
6128
  else {
6129
  if ($nextUpdate < PHP_INT_MAX) {
6130
- $message .= ' ' . sprintf(__('You may wait for the next automatic attempt at %s or log into the parent site to manually update by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence'), wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $nextUpdate));
6131
  }
6132
  else {
6133
  $message .= ' ' . __('You may wait for the next automatic attempt or log into the parent site to manually update by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence');
@@ -6214,9 +6521,10 @@ HTML;
6214
  }
6215
 
6216
  if (version_compare(PHP_VERSION, '8.0', '>=') && !get_user_option('wordfence_php8_nag')) {
6217
- wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_INFO, <<<HTML
6218
  PHP 8 includes significant changes from PHP 7, which may cause unexpected bugs in plugins, themes, and WordPress itself. Wordfence is not yet officially supported on PHP 8, but will be supported in the near future. <a href="https://www.wordfence.com/blog/2020/11/php-8-what-wordpress-users-need-to-know/">Read More</a>
6219
  HTML
 
6220
  , 'php8', array(get_current_user_id()));
6221
  update_user_option(get_current_user_id(), 'wordfence_php8_nag', 1);
6222
  }
@@ -6232,49 +6540,49 @@ HTML
6232
 
6233
  //These are split to allow our module plugins to insert their menu item(s) at any point in the hierarchy
6234
  public static function admin_menus_20() {
6235
- add_submenu_page("Wordfence", "Wordfence Dashboard", "Dashboard", "activate_plugins", "Wordfence", 'wordfence::menu_dashboard');
6236
  }
6237
 
6238
  public static function admin_menus_30() {
6239
- add_submenu_page("Wordfence", "Firewall", "Firewall", "activate_plugins", "WordfenceWAF", 'wordfence::menu_firewall');
6240
  if (wfConfig::get('displayTopLevelBlocking')) {
6241
- add_submenu_page("Wordfence", "Blocking", "Blocking", "activate_plugins", "WordfenceBlocking", 'wordfence::menu_blocking');
6242
  }
6243
  }
6244
 
6245
  public static function admin_menus_40() {
6246
- add_submenu_page("Wordfence", "Scan", "Scan", "activate_plugins", "WordfenceScan", 'wordfence::menu_scan');
6247
  }
6248
 
6249
  public static function admin_menus_50() {
6250
- add_submenu_page('Wordfence', 'Tools', 'Tools', 'activate_plugins', 'WordfenceTools', 'wordfence::menu_tools');
6251
  if (wfConfig::get('displayTopLevelLiveTraffic')) {
6252
- add_submenu_page("Wordfence", "Live Traffic", "Live Traffic", "activate_plugins", "WordfenceLiveTraffic", 'wordfence::menu_tools');
6253
  }
6254
  }
6255
 
6256
  public static function admin_menus_60() {
6257
  if (wfConfig::get('displayTopLevelOptions')) {
6258
- add_submenu_page("Wordfence", "All Options", "All Options", "activate_plugins", "WordfenceOptions", 'wordfence::menu_options');
6259
  }
6260
  }
6261
 
6262
  public static function admin_menus_70() {
6263
- add_submenu_page('Wordfence', 'Help', 'Help', 'activate_plugins', 'WordfenceSupport', 'wordfence::menu_support');
6264
  }
6265
 
6266
  public static function admin_menus_80() {
6267
  if (wfCentral::isSupported()) {
6268
- add_submenu_page(null, 'Wordfence Central', 'Wordfence Central', 'activate_plugins', 'WordfenceCentral', 'wordfence::menu_wordfence_central');
6269
  }
6270
  }
6271
 
6272
  public static function admin_menus_90() {
6273
  if (wfConfig::get('isPaid')) {
6274
- add_submenu_page("Wordfence", "Protect More Sites", "<strong id=\"wfMenuCallout\" style=\"color: #FCB214;\">Protect More Sites</strong>", "activate_plugins", "WordfenceProtectMoreSites", 'wordfence::_menu_noop');
6275
  }
6276
  else {
6277
- add_submenu_page("Wordfence", "Upgrade To Premium", "<strong id=\"wfMenuCallout\" style=\"color: #FCB214;\">Upgrade To Premium</strong>", "activate_plugins", "WordfenceUpgradeToPremium", 'wordfence::_menu_noop');
6278
  }
6279
  add_filter('clean_url', 'wordfence::_patchWordfenceSubmenuCallout', 10, 3);
6280
  }
@@ -6311,7 +6619,9 @@ JQUERY;
6311
  $count = count(wfNotification::notifications());
6312
  $sinceCount = count(wfNotification::notifications((int) get_user_meta(get_current_user_id(), 'wordfence-notifications', true)));
6313
  if ($sinceCount > 0) {
6314
- $counter = '<span id="wf-notification-popover" data-toggle="popover" data-trigger="focus" data-content="You have ' . $sinceCount . ' new Wordfence notification' . ($sinceCount == 1 ? '' : 's') . '." data-container="body" data-placement="wf-bottom">&nbsp;</span>';
 
 
6315
  update_user_meta(get_current_user_id(), 'wordfence-notifications', time());
6316
  }
6317
  else {
@@ -6328,19 +6638,19 @@ JQUERY;
6328
  $wp_admin_bar->add_menu( array(
6329
  'parent' => 'wordfence-menu',
6330
  'id' => 'wordfence-notifications',
6331
- 'title' => '<div id="wordfence-notifications-display" class="wf-adminbar-submenu-title">Notifications</div>' . $badge,
6332
  'href' => network_admin_url('admin.php?page=Wordfence'),
6333
  ));
6334
  $wp_admin_bar->add_menu( array(
6335
  'parent' => 'wordfence-menu',
6336
  'id' => 'wordfence-javascripterror',
6337
- 'title' => '<div id="wordfence-javascripterror-display" class="wf-adminbar-submenu-title">Javascript Errors</div><div class="wf-adminbar-status wf-adminbar-status-good">&bullet;</div>',
6338
  'href' => 'javascript:void(0)',
6339
  ));
6340
  $wp_admin_bar->add_menu( array(
6341
  'parent' => 'wordfence-menu',
6342
  'id' => 'wordfence-malwareurl',
6343
- 'title' => '<div id="wordfence-malwareurl-display' . (is_admin() ? '-skip' : '') . '" class="wf-adminbar-submenu-title">Malware URLs</div><div class="wf-adminbar-status wf-adminbar-status-neutral">&bullet;</div>',
6344
  'href' => network_admin_url('admin.php?page=WordfenceScan'),
6345
  ));
6346
  }
@@ -6458,7 +6768,7 @@ JQUERY;
6458
  $wafMenuURL = add_query_arg(array(
6459
  'waf-nonce' => wp_create_nonce('wafconfigrebuild'),
6460
  ), $wafMenuURL);
6461
- $storageExceptionMessage = $e->getMessage() . ' <a href="' . esc_url($wafMenuURL) . '">Click here</a> to rebuild the configuration file.';
6462
  } catch (wfWAFStorageFileException $e) {
6463
  // We don't have anywhere to write files in this scenario. Let's notify the user to update the permissions.
6464
  $wafData = array(
@@ -6469,8 +6779,7 @@ JQUERY;
6469
  'isPaid' => (bool) wfConfig::get('isPaid', 0),
6470
  );
6471
  $logPath = str_replace(ABSPATH, '~/', WFWAF_LOG_PATH);
6472
- $storageExceptionMessage = 'We were unable to write to ' . $logPath . ' which the WAF uses for storage. Please
6473
- update permissions on the parent directory so the web server can write to it.';
6474
  } catch (wfWAFStorageEngineMySQLiException $e) {
6475
  $wafData = array(
6476
  'learningMode' => false,
@@ -6480,8 +6789,7 @@ JQUERY;
6480
  'isPaid' => (bool) wfConfig::get('isPaid', 0),
6481
  );
6482
  $logPath = null;
6483
- $storageExceptionMessage = 'An error occured when fetching the WAF configuration from the database. <pre>' .
6484
- esc_html($e->getMessage()) . '</pre>';
6485
  }
6486
 
6487
  require(dirname(__FILE__) . '/menu_options.php');
@@ -6523,7 +6831,7 @@ JQUERY;
6523
  $wafMenuURL = add_query_arg(array(
6524
  'waf-nonce' => wp_create_nonce('wafconfigrebuild'),
6525
  ), $wafMenuURL);
6526
- $storageExceptionMessage = $e->getMessage() . ' <a href="' . esc_url($wafMenuURL) . '">Click here</a> to rebuild the configuration file.';
6527
  } catch (wfWAFStorageFileException $e) {
6528
  // We don't have anywhere to write files in this scenario. Let's notify the user to update the permissions.
6529
  $wafData = array(
@@ -6534,8 +6842,7 @@ JQUERY;
6534
  'isPaid' => (bool) wfConfig::get('isPaid', 0),
6535
  );
6536
  $logPath = str_replace(ABSPATH, '~/', WFWAF_LOG_PATH);
6537
- $storageExceptionMessage = 'We were unable to write to ' . $logPath . ' which the WAF uses for storage. Please
6538
- update permissions on the parent directory so the web server can write to it.';
6539
  } catch (wfWAFStorageEngineMySQLiException $e) {
6540
  $wafData = array(
6541
  'learningMode' => false,
@@ -6545,8 +6852,7 @@ JQUERY;
6545
  'isPaid' => (bool) wfConfig::get('isPaid', 0),
6546
  );
6547
  $logPath = null;
6548
- $storageExceptionMessage = 'An error occured when fetching the WAF configuration from the database. <pre>' .
6549
- esc_html($e->getMessage()) . '</pre>';
6550
  }
6551
 
6552
  if (isset($_GET['subpage']) && $_GET['subpage'] == 'waf_options') {
@@ -6567,7 +6873,11 @@ JQUERY;
6567
  echo self::cachingWarning("WP Super Cache");
6568
  }
6569
  public static function cachingWarning($plugin){
6570
- return '<div id="wordfenceConfigWarning" class="error fade"><p><strong>The Wordfence Live Traffic feature has been disabled because you have ' . $plugin . ' active which is not compatible with Wordfence Live Traffic.</strong> If you want to reenable Wordfence Live Traffic, you need to deactivate ' . $plugin . ' and then go to the Wordfence options page and reenable Live Traffic there. Wordfence does work with ' . $plugin . ', however Live Traffic will be disabled and the Wordfence firewall will also count less hits per visitor because of the ' . $plugin . ' caching function. All other functions should work correctly.</p></div>';
 
 
 
 
6571
  }
6572
  public static function menu_dashboard() {
6573
  wp_enqueue_style('wordfence-select2-css');
@@ -6627,21 +6937,22 @@ JQUERY;
6627
  $issueID = filter_input(INPUT_GET, 'issueID', FILTER_SANITIZE_NUMBER_INT);
6628
  $response = self::ajax_restoreFile_callback($issueID);
6629
  if (!empty($response['ok'])) {
6630
- $result = sprintf('<p>The file <code>%s</code> was restored successfully.</p>',
6631
  esc_html(strpos($response['file'], ABSPATH) === 0 ? substr($response['file'], strlen(ABSPATH) + 1) : $response['file']));
6632
  } else if (!empty($response['cerrorMessage'])) {
6633
  $result = sprintf('<div class="wfSummaryErr">%s</div>', esc_html($response['cerrorMessage']));
6634
  } else {
6635
- $result = '<div class="wfSummaryErr">There was an error restoring the file.</div>';
6636
  }
6637
  printf(<<<HTML
6638
  <br>
6639
  %s
6640
- <p><a href="%s">Return to scan results</a></p>
6641
  HTML
6642
  ,
6643
  $result,
6644
- esc_url(network_admin_url('admin.php?page=WordfenceScan'))
 
6645
  );
6646
  wfScanEngine::refreshScanNotification();
6647
  }
@@ -6650,20 +6961,21 @@ HTML
6650
  $issueID = filter_input(INPUT_GET, 'issueID', FILTER_SANITIZE_NUMBER_INT);
6651
  $response = self::ajax_deleteFile_callback($issueID);
6652
  if (!empty($response['ok'])) {
6653
- $result = sprintf('<p>The file <code>%s</code> was deleted successfully.</p>', esc_html($response['file']));
6654
  } else if (!empty($response['errorMessage'])) {
6655
  $result = sprintf('<div class="wfSummaryErr">%s</div>', esc_html($response['errorMessage']));
6656
  } else {
6657
- $result = '<div class="wfSummaryErr">There was an error deleting the file.</div>';
6658
  }
6659
  printf(<<<HTML
6660
  <br>
6661
  %s
6662
- <p><a href="%s">Return to scan results</a></p>
6663
  HTML
6664
  ,
6665
  $result,
6666
- esc_url(network_admin_url('admin.php?page=WordfenceScan'))
 
6667
  );
6668
  wfScanEngine::refreshScanNotification();
6669
  }
@@ -6674,7 +6986,7 @@ HTML
6674
  }
6675
  if($type != 'info' && $type != 'error'){ error_log("Invalid status type: $type"); return; }
6676
  if(self::$printStatus){
6677
- echo "STATUS: $level : $type : $msg\n";
6678
  } else {
6679
  self::getLog()->addStatus($level, $type, $msg);
6680
  }
@@ -6721,10 +7033,10 @@ HTML
6721
 
6722
  $IPMsg = "";
6723
  if ($IP) {
6724
- $IPMsg = sprintf(__("User IP: %s\n", 'wordfence'), $IP);
6725
  $reverse = wfUtils::reverseLookup($IP);
6726
  if ($reverse) {
6727
- $IPMsg .= sprintf(__("User hostname: %s\n", 'wordfence'), $reverse);
6728
  }
6729
  $userLoc = wfUtils::getIPGeo($IP);
6730
  if ($userLoc) {
@@ -6783,7 +7095,7 @@ HTML
6783
  }
6784
  wfConfig::set('lastEmailHash', time() . ':' . $hash);
6785
  foreach ($emails as $email) {
6786
- $uniqueContent = $content . "\n\n" . sprintf(__('No longer an administrator for this site? Click here to stop receiving security alerts: %s', 'wordfence'), wfUtils::getSiteBaseURL() . '?_wfsf=removeAlertEmail&jwt=' . wfUtils::generateJWT(array('email' => $email)));
6787
  wp_mail($email, $subject, $uniqueContent);
6788
  }
6789
  }
@@ -6823,7 +7135,7 @@ SQL
6823
  $IP = trim($IP);
6824
  $user_range = new wfUserIPRange($IP);
6825
  if (!$user_range->isValidRange()) {
6826
- throw new Exception("The IP you provided must be in dotted quad notation or use ranges with square brackets. e.g. 10.11.12.13 or 10.11.12.[1-50]");
6827
  }
6828
  $whites = wfConfig::get('whitelisted', '');
6829
  $arr = explode(',', $whites);
@@ -6847,8 +7159,8 @@ SQL
6847
 
6848
  $report = new wfActivityReport();
6849
  return $report->sendReportViaEmail($email) ?
6850
- array('ok' => 1, 'result' => 'Test email sent successfully') :
6851
- array('err' => "Test email failed to send.");
6852
  }
6853
 
6854
  public static function addDashboardWidget() {
@@ -6866,7 +7178,7 @@ SQL
6866
  }
6867
  wp_add_dashboard_widget(
6868
  'wordfence_activity_report_widget',
6869
- 'Wordfence activity in the past ' . $report_date_range,
6870
  array('wfActivityReport', 'outputDashboardWidget')
6871
  );
6872
  }
@@ -6902,19 +7214,19 @@ SQL
6902
  $wfIssues = new wfIssues();
6903
  $issue = $wfIssues->getIssueByID($issueID);
6904
  if (!$issue) {
6905
- return array('errorMsg' => "We could not find that issue in our database.");
6906
  }
6907
  $data = $issue['data'];
6908
  if (empty($data['userID'])) {
6909
- return array('errorMsg' => "We could not find that user in the database.");
6910
  }
6911
  $user = new WP_User($data['userID']);
6912
  if (!$user->exists()) {
6913
- return array('errorMsg' => "We could not find that user in the database.");
6914
  }
6915
  $userLogin = $user->user_login;
6916
  if (is_multisite() && strcasecmp($user->user_email, get_site_option('admin_email')) === 0) {
6917
- return array('errorMsg' => "This user's email is the network admin email. It will need to be changed before deleting this user.");
6918
  }
6919
  if (is_multisite()) {
6920
  revoke_super_admin($data['userID']);
@@ -6937,11 +7249,11 @@ SQL
6937
  $wfIssues = new wfIssues();
6938
  $issue = $wfIssues->getIssueByID($issueID);
6939
  if (!$issue) {
6940
- return array('errorMsg' => "We could not find that issue in our database.");
6941
  }
6942
  $data = $issue['data'];
6943
  if (empty($data['userID'])) {
6944
- return array('errorMsg' => "We could not find that user in the
174
  wfVersionCheckController::shared()->checkVersionsAndWarn();
175
  }
176
  private static function keyAlert($msg){
177
+ 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);
178
  }
179
  public static function dailyCron() {
180
  $lastDailyCron = (int) wfConfig::get('lastDailyCron', 0);
204
  wfConfig::set('keyAutoRenew10Sent', '');
205
  } else if ($keyExpDays <= 12 && $keyExpDays > 0 && !wfConfig::get('keyAutoRenew10Sent')) {
206
  wfConfig::set('keyAutoRenew10Sent', 1);
207
+ $email = __("Your Premium Wordfence License is set to auto-renew in 10 days.", 'wordfence');
208
+ self::alert($email, $email . " " . __("To update your license settings please visit http://www.wordfence.com/zz9/dashboard", 'wordfence'), false);
209
  }
210
  } else {
211
  if($keyExpDays > 15){
217
  } else if($keyExpDays <= 15 && $keyExpDays > 0){
218
  if($keyExpDays <= 15 && $keyExpDays >= 11 && (! wfConfig::get('keyExp15Sent'))){
219
  wfConfig::set('keyExp15Sent', 1);
220
+ self::keyAlert(__("Your Premium Wordfence License expires in less than 2 weeks.", 'wordfence'));
221
  } else if($keyExpDays <= 7 && $keyExpDays >= 4 && (! wfConfig::get('keyExp7Sent'))){
222
  wfConfig::set('keyExp7Sent', 1);
223
+ self::keyAlert(__("Your Premium Wordfence License expires in less than a week.", 'wordfence'));
224
  } else if($keyExpDays == 2 && (! wfConfig::get('keyExp2Sent'))){
225
  wfConfig::set('keyExp2Sent', 1);
226
+ self::keyAlert(__("Your Premium Wordfence License expires in 2 days.", 'wordfence'));
227
  } else if($keyExpDays == 1 && (! wfConfig::get('keyExp1Sent'))){
228
  wfConfig::set('keyExp1Sent', 1);
229
+ self::keyAlert(__("Your Premium Wordfence License expires in 1 day.", 'wordfence'));
230
  }
231
  } else if($keyIsExpired && (! wfConfig::get('keyExpFinalSent')) ){
232
  wfConfig::set('keyExpFinalSent', 1);
233
+ self::keyAlert(__("Your Wordfence Premium License has Expired!", 'wordfence'));
234
  }
235
  }
236
  }
260
  wfConfig::set('showWfCentralUI', (int) $keyData['showWfCentralUI']);
261
  }
262
 
263
+ if (isset($keyData['_keyNoLongerValid']) && $keyData['_keyNoLongerValid'] == 1) {
264
+ 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);
265
+ }
266
+
267
  wfConfig::set('keyType', $keyType);
268
  }
269
  catch(Exception $e){
270
+ wordfence::status(4, 'error', sprintf(/* translators: Wordfence license key. */ __("Could not verify Wordfence License: %s", 'wordfence'), $e->getMessage()));
271
  }
272
 
273
  $allowMySQLi = wfConfig::testDB();
349
  $items = array();
350
  $plural = false;
351
  if ($updatesNeeded['core']) {
352
+ $items[] = sprintf(/* translators: WordPress version. */ __('WordPress (v%s)', 'wordfence'), esc_html($updatesNeeded['core']));
353
  }
354
 
355
  if ($updatesNeeded['plugins']) {
356
+ $entry = sprintf(/* translators: Number of plugins. */ _n('%d plugin', '%d plugins', count($updatesNeeded['plugins']), 'wordfence'), count($updatesNeeded['plugins']));
 
 
 
 
357
  $items[] = $entry;
358
  }
359
 
360
  if ($updatesNeeded['themes']) {
361
+ $entry = sprintf(/* translators: Number of themes. */ _n('%d theme', '%d themes', count($updatesNeeded['themes']), 'wordfence'), count($updatesNeeded['themes']));
 
 
 
 
362
  $items[] = $entry;
363
  }
364
 
365
+ $message = _n('An update is available for ', 'Updates are available for ', count($items), 'wordfence');
366
+
 
 
 
 
367
  for ($i = 0; $i < count($items); $i++) {
368
  if ($i > 0 && count($items) > 2) { $message .= ', '; }
369
  else if ($i > 0) { $message .= ' '; }
370
+ if ($i > 0 && $i == count($items) - 1) { $message .= __('and ', 'wordfence'); }
371
  $message .= $items[$i];
372
  }
373
 
406
  update_option('wordfence_version', WORDFENCE_VERSION); //In case we have a fatal error we don't want to keep running install.
407
  }
408
 
409
+ wordfence::status(4, 'info', sprintf(/* translators: Wordfence version. */ __('`runInstall` called with previous version = %s', 'wordfence'), $previous_version));
410
 
411
  //EVERYTHING HERE MUST BE IDEMPOTENT
412
 
458
  wfConfig::set('touppPromptNeeded', true);
459
  $freshAPIKey = true;
460
  } else {
461
+ throw new Exception(__("Could not understand the response we received from the Wordfence servers when applying for a free license key.", 'wordfence'));
462
  }
463
  } catch(Exception $e){
464
  error_log("Could not fetch free license key from Wordfence: " . $e->getMessage());
1350
  } else {
1351
  add_action('wordfence_security_event', 'wfCentral::sendAlertCallback', 10, 3);
1352
  }
1353
+
1354
+ if (!wfConfig::get('wordfenceI18n', true)) {
1355
+ add_filter('gettext', function ($translation, $text, $domain) {
1356
+ if ($domain === 'wordfence') {
1357
+ return $text;
1358
+ }
1359
+ return $translation;
1360
+ }, 10, 3);
1361
+ }
1362
  }
1363
  public static function _pluginPageActionLinks($links) {
1364
  if (!wfConfig::get('isPaid')) {
1365
+ $links = array_merge(array('aWordfencePluginCallout' => '<a href="https://www.wordfence.com/zz12/wordfence-signup/" target="_blank" rel="noopener noreferrer"><strong style="color: #11967A; display: inline;">' . esc_html__('Upgrade To Premium', 'wordfence') . '</strong></a>'), $links);
1366
  }
1367
  return $links;
1368
  }
1381
 
1382
  public static function fixWPMailFromAddress($from_email) {
1383
  if ($from_email == 'wordpress@') { //$_SERVER['SERVER_NAME'] is undefined so we get an incomplete email address
1384
+ wordfence::status(4, 'info', __("wp_mail from address is incomplete, attempting to fix", 'wordfence'));
1385
  $urls = array(get_site_url(), get_home_url());
1386
  foreach ($urls as $u) {
1387
  if (!empty($u)) {
1391
  }
1392
 
1393
  if (!empty($u)) {
1394
+ wordfence::status(4, 'info', sprintf(/* translators: Email address. */ __("Fixing wp_mail from address: %s", 'wordfence'), $from_email . $u));
1395
  return $from_email . $u;
1396
  }
1397
  }
1416
  $wafDisabled = !WFWAF_ENABLED || (class_exists('wfWAFConfig') && wfWAFConfig::isDisabled());
1417
  if (wfUtils::isAdmin() && !$wafDisabled) {
1418
  wp_enqueue_style('wordfenceAJAXcss', wfUtils::getBaseURL() . wfUtils::versionedAsset('css/wordfenceBox.css'), '', WORDFENCE_VERSION);
1419
+ wp_enqueue_script('wfi18njs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/wfi18n.js'), array(), WORDFENCE_VERSION);
1420
  wp_enqueue_script('wordfenceAJAXjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/admin.ajaxWatcher.js'), array('jquery'), WORDFENCE_VERSION);
1421
  wp_localize_script('wordfenceAJAXjs', 'WFAJAXWatcherVars', array(
1422
  'nonce' => wp_create_nonce('wf-waf-error-page'),
1423
  ));
1424
+ self::setupI18nJSStrings();
1425
  }
1426
  }
1427
  public static function enqueueDashboard() {
1484
  }
1485
  public static function ajaxReceiver(){
1486
  if(! wfUtils::isAdmin()){
1487
+ wfUtils::send_json(array('errorMsg' => __("You appear to have logged out or you are not an admin. Please sign-out and sign-in again.", 'wordfence')));
1488
  }
1489
  $func = (isset($_POST['action']) && $_POST['action']) ? $_POST['action'] : $_GET['action'];
1490
  $nonce = (isset($_POST['nonce']) && $_POST['nonce']) ? $_POST['nonce'] : $_GET['nonce'];
1491
  if(! wp_verify_nonce($nonce, 'wp-ajax')){
1492
+ wfUtils::send_json(array('errorMsg' => __("Your browser sent an invalid security token to Wordfence. Please try reloading this page or signing out and in again.", 'wordfence'), 'tokenInvalid' => 1));
1493
  }
1494
  //func is e.g. wordfence_ticker so need to munge it
1495
  $func = str_replace('wordfence_', '', $func);
1496
  $returnArr = call_user_func('wordfence::ajax_' . $func . '_callback');
1497
  if($returnArr === false){
1498
+ $returnArr = array('errorMsg' => __("Wordfence encountered an internal error executing that request.", 'wordfence'));
1499
  }
1500
 
1501
  if(! is_array($returnArr)){
1601
  $imported = WFLSPHP52Compatability::import_2fa($import);
1602
  }
1603
  catch (Exception $e) {
1604
+ wordfence::status(4, 'error', sprintf(/* translators: Error message. */ __('2FA Migration Error: %s', 'wordfence'), $e->getMessage()));
1605
  return array('ok' => 0, 'fail' => 1);
1606
  }
1607
 
1662
  }
1663
 
1664
  if ($enforceBreachedPasswds && wfCredentialsController::isLeakedPassword($username, $password)) {
1665
+ $errors->add('pass', sprintf(/* translators: Support URL. */ __('Please choose a different password. The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. <a href="%s">Learn More</a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
1666
  return $errors;
1667
  }
1668
  else if ($user_id !== false) {
1732
 
1733
  }
1734
  if(wfConfig::get('loginSecurityEnabled')){
1735
+ $tKey = self::getForgotPasswordFailureCountTransient($IP);
1736
  $forgotAttempts = get_transient($tKey);
1737
  if($forgotAttempts){
1738
  $forgotAttempts++;
1740
  $forgotAttempts = 1;
1741
  }
1742
  if($forgotAttempts >= wfConfig::get('loginSec_maxForgotPasswd')){
1743
+ self::lockOutIP($IP, sprintf(
1744
+ /* translators: 1. Password reset limit (number). 2. WordPress username. */
1745
+ __('Exceeded the maximum number of tries to recover their password which is set at: %1$s. The last username or email they entered before getting locked out was: \'%2$s\''),
1746
+ wfConfig::get('loginSec_maxForgotPasswd'),
1747
+ $_POST['user_login']
1748
+ ));
1749
  $customText = wpautop(wp_strip_all_tags(wfConfig::get('blockCustomText', '')));
1750
  require(dirname(__FILE__) . '/wfLockedOut.php');
1751
  }
1764
 
1765
  }
1766
 
1767
+ public static function getLoginFailureCountTransient($IP) {
1768
+ return 'wflginfl_' . bin2hex(wfUtils::inet_pton($IP));
1769
+ }
1770
+
1771
+ public static function getForgotPasswordFailureCountTransient($IP) {
1772
+ return 'wffgt_' . bin2hex(wfUtils::inet_pton($IP));
1773
+ }
1774
+
1775
+ public static function clearLockoutCounters($IP) {
1776
+ delete_transient(self::getLoginFailureCountTransient($IP));
1777
+ delete_transient(self::getForgotPasswordFailureCountTransient($IP));
1778
+ }
1779
+
1780
  public static function veryFirstAction() {
1781
  /** @var wpdb $wpdb ; */
1782
  global $wpdb;
1790
  $nonceValid = wfWAF::getInstance()->verifyNonce(@$_POST['nonce'], 'wf-form');
1791
  }
1792
  if(!$nonceValid){
1793
+ die(__("Sorry but your browser sent an invalid security token when trying to use this form.", 'wordfence'));
1794
  }
1795
  $numTries = get_transient('wordfenceUnlockTries');
1796
  if($numTries > 10){
1797
+ printf("<html><body><h1>%s</h1><p>%s</p></body></html>",
1798
+ esc_html__('Please wait 3 minutes and try again', 'wordfence'),
1799
+ esc_html__('You have used this form too much. Please wait 3 minutes and try again.', 'wordfence')
1800
+ );
1801
  exit();
1802
  }
1803
  if(! $numTries){ $numTries = 1; } else { $numTries = $numTries + 1; }
1835
  'key' => $key,
1836
  'IP' => $IP
1837
  ));
1838
+ wp_mail($email, __("Unlock email requested", 'wordfence'), $content, "Content-Type: text/html");
1839
  }
1840
+ echo "<html><body><h1>" . esc_html__('Your request was received', 'wordfence') . "</h1><p>" .
1841
+ esc_html(sprintf(/* translators: Email address. */ __("We received a request to email \"%s\" instructions to unlock their access. If that is the email address of a site administrator or someone on the Wordfence alert list, they have been emailed instructions on how to regain access to this system. The instructions we sent will expire 30 minutes from now.", 'wordfence'), wp_kses($email, array())))
1842
  . "</p></body></html>";
1843
 
1844
  exit();
1851
  if($_GET['func'] == 'unlockMyIP'){
1852
  wfBlock::unblockIP(wfUtils::getIP());
1853
  if (class_exists('wfWAFIPBlocksController')) { wfWAFIPBlocksController::setNeedsSynchronizeConfigSettings(); }
1854
+ self::clearLockoutCounters(wfUtils::getIP());
1855
  header('Location: ' . wp_login_url());
1856
  exit();
1857
  } else if($_GET['func'] == 'unlockAllIPs'){
1858
  wordfence::status(1, 'info', __("Request received via unlock email link to unblock all IPs.", 'wordfence'));
1859
  wfBlock::removeAllIPBlocks();
1860
  if (class_exists('wfWAFIPBlocksController')) { wfWAFIPBlocksController::setNeedsSynchronizeConfigSettings(); }
1861
+ self::clearLockoutCounters(wfUtils::getIP());
1862
  header('Location: ' . wp_login_url());
1863
  exit();
1864
  } else if($_GET['func'] == 'disableRules'){
1868
  wfBlock::removeAllIPBlocks();
1869
  wfBlock::removeAllCountryBlocks();
1870
  if (class_exists('wfWAFIPBlocksController')) { wfWAFIPBlocksController::setNeedsSynchronizeConfigSettings(); }
1871
+ self::clearLockoutCounters(wfUtils::getIP());
1872
  header('Location: ' . wp_login_url());
1873
  exit();
1874
  } else {
1981
  if ($errors !== true) {
1982
  $error = __('An error occurred while saving the license.', 'wordfence');
1983
  if (count($errors) == 1) {
1984
+ $error = sprintf(/* translators: Error message. */ __('An error occurred while saving the license: %s', 'wordfence'), $errors[0]['error']);
1985
  }
1986
 
1987
  echo wfView::create('common/license', array(
2001
  catch (Exception $e) {
2002
  echo wfView::create('common/license', array(
2003
  'state' => 'bad',
2004
+ 'error' => sprintf(/* translators: Error message. */ __('An error occurred while saving the license: %s', 'wordfence'), $e->getMessage()),
2005
  ))->render();
2006
  exit();
2007
  }
2017
  if (is_main_site() && wfUtils::isAdmin()) {
2018
  if (wp_next_scheduled('wordfence_daily_cron') === false) {
2019
  wp_schedule_event(time() + 600, 'daily', 'wordfence_daily_cron');
2020
+ wordfence::status(2, 'info', __("Rescheduled missing daily cron", 'wordfence'));
2021
  }
2022
 
2023
  if (wp_next_scheduled('wordfence_hourly_cron') === false) {
2024
  wp_schedule_event(time() + 600, 'hourly', 'wordfence_hourly_cron');
2025
+ wordfence::status(2, 'info', __("Rescheduled missing hourly cron", 'wordfence'));
2026
  }
2027
  }
2028
 
2490
  }
2491
 
2492
  $salt = wp_salt('logged_in');
2493
+ //TODO: Drop support for legacy cookie after 1 year
2494
+ $legacyCookieName = 'wf_loginalerted_' . hash_hmac('sha256', wfUtils::getIP() . '|' . $user->ID, $salt);
2495
+ $cookieName = 'wf_loginalerted_' . hash_hmac('sha256', $user->ID, $salt);
2496
+ $cookieValue = hash_hmac('sha256', $user->user_login, $salt);
2497
+ $newDevice = !(isset($_COOKIE[$legacyCookieName]) && hash_equals($cookieValue, $_COOKIE[$legacyCookieName])); //Check legacy cookie
2498
+ if($newDevice){
2499
+ $newDevice = !(isset($_COOKIE[$cookieName]) && hash_equals($cookieValue, $_COOKIE[$cookieName]));
2500
+ }
2501
+ else{
2502
+ $_COOKIE[$cookieName]=$cookieValue;
2503
+ }
2504
  if(wfUtils::isAdmin($userID)){
2505
+ $securityEvent = 'adminLogin';
2506
+ $alertCallback = array(new wfAdminLoginAlert($cookieName, $cookieValue, $username, wfUtils::getIP()), 'send');
 
 
 
 
 
 
 
2507
 
2508
  } else {
2509
+ $securityEvent = 'nonAdminLogin';
2510
+ $alertCallback = array(new wfNonAdminLoginAlert($cookieName, $cookieValue, $username, wfUtils::getIP()), 'send');
 
 
 
 
 
 
 
2511
  }
2512
+ if($newDevice)
2513
+ $securityEvent.='NewLocation';
2514
+ do_action('wordfence_security_event', $securityEvent, array(
2515
+ 'username' => $username,
2516
+ 'ip' => wfUtils::getIP(),
2517
+ ), $alertCallback);
2518
 
2519
+ if (wfConfig::get(wfUtils::isAdmin($userID)?'alertOn_firstAdminLoginOnly':'alertOn_firstNonAdminLoginOnly')) {
2520
+ //Purge legacy cookie if still present
2521
+ if(array_key_exists($legacyCookieName, $_COOKIE))
2522
+ wfUtils::setcookie($legacyCookieName, '', 1, '/', null, wfUtils::isFullSSL(), true);
2523
+ wfUtils::setcookie($cookieName, $cookieValue, time() + (86400 * 365), '/', null, wfUtils::isFullSSL(), true);
2524
  }
2525
  }
2526
  public static function registrationFilter($errors, $sanitizedLogin, $userEmail) {
2723
  else { //Code path for old method, invalid password the second time
2724
  self::$authError = $authUser;
2725
  if (is_wp_error(self::$authError) && (self::$authError->get_error_code() == 'invalid_username' || $authUser->get_error_code() == 'invalid_email' || self::$authError->get_error_code() == 'incorrect_password' || $authUser->get_error_code() == 'authentication_failed') && wfConfig::get('loginSec_maskLoginErrors')) {
2726
+ self::$authError = new WP_Error('incorrect_password', sprintf(/* translators: 1. WordPress username. 2. Password reset URL. */ __('<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%2$s" title="Password Lost and Found">Lost your password</a>?'), $username, wp_lostpassword_url()));
2727
  }
2728
 
2729
  return self::processBruteForceAttempt(self::$authError, $username, $passwd);
2731
 
2732
  if ($usingBreachedPassword) {
2733
  wfAdminNoticeQueue::removeAdminNotice(false, 'previousIPBreachPassword', array($userID));
2734
+ wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, sprintf(
2735
+ /* translators: 1. WordPress admin panel URL. 2. Support URL. */
2736
+ __('<strong>WARNING: </strong>The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%1$s">change your password</a>. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn More</a>', 'wordfence'),
2737
+ self_admin_url('profile.php'),
2738
+ wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)
2739
+ ), '2faBreachPassword', array($authUser->ID));
2740
  }
2741
 
2742
  if (isset($twoFactorRecord[5])) { //New method TOTP
2867
  if ($twoFactorRecord[0] == $userDat->ID && $twoFactorRecord[3] == 'activated') { //Yup, enabled, so require the code
2868
  if ($usingBreachedPassword) {
2869
  wfAdminNoticeQueue::removeAdminNotice(false, 'previousIPBreachPassword', array($authUser->ID));
2870
+ wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, sprintf(
2871
+ /* translators: 1. WordPress admin panel URL. 2. Support URL. */
2872
+ __('<strong>WARNING: </strong>The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%1$s">change your password</a>. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn More</a>', 'wordfence'), self_admin_url('profile.php'), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), '2faBreachPassword', array($authUser->ID));
2873
  }
2874
 
2875
  $loginNonce = wfWAFUtils::random_bytes(20);
3024
  else if ($usingBreachedPassword) {
3025
  if (wfCredentialsController::hasPreviousLoginFromIP($authUser, wfUtils::getIP())) {
3026
  wfAdminNoticeQueue::removeAdminNotice(false, '2faBreachPassword', array($authUser->ID));
3027
+ wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, sprintf(__('<strong>WARNING: </strong>Your login has been allowed because you have previously logged in from the same IP, but you will be blocked if your IP changes. The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%1$s">change your password</a>. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn More</a>', 'wordfence'), self_admin_url('profile.php'), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), 'previousIPBreachPassword', array($authUser->ID));
3028
  }
3029
  else {
3030
  $username = $authUser->user_login;
3039
  ), $alertCallback);
3040
 
3041
  remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
3042
+ self::$authError = new WP_Error('breached_password', sprintf(
3043
+ /* translators: 1. Reset password URL. 2. Support URL. */
3044
+ __('<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%1$s">reset your password</a> to reactivate your account. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn More</a>'), wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
3045
  return self::$authError;
3046
  }
3047
  }
3049
  if ($requireAdminTwoFactor && wfUtils::isAdmin($authUser)) {
3050
  $username = $authUser->user_login;
3051
  self::getLog()->logLogin('loginFailValidUsername', 1, $username);
3052
+ wordfence::alert(__("Admin Login Blocked"), sprintf(/* translators: WordPress username. */__("A user with username \"%s\" who has administrator access tried to sign in to your WordPress site. Access was denied because all administrator accounts are required to have Cellphone Sign-in enabled but this account does not.", 'wordfence'), $username), wfUtils::getIP());
3053
  self::$authError = new WP_Error('twofactor_disabled_required', __('<strong>Cellphone Sign-in Required</strong>: Cellphone Sign-in is required for all administrator accounts. Please contact the site administrator to enable it for your account.'));
3054
  return self::$authError;
3055
  }
3060
  else if ($usingBreachedPassword) {
3061
  if (wfCredentialsController::hasPreviousLoginFromIP($authUser, wfUtils::getIP())) {
3062
  wfAdminNoticeQueue::removeAdminNotice(false, '2faBreachPassword', array($authUser->ID));
3063
+ wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, sprintf(/* translators: 1. Reset password URL. 2. Support URL. */ __('<strong>WARNING: </strong>Your login has been allowed because you have previously logged in from the same IP, but you will be blocked if your IP changes. The password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%1$s">change your password</a>. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn More</a>', 'wordfence'), self_admin_url('profile.php'), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), 'previousIPBreachPassword', array($authUser->ID));
3064
  }
3065
  else {
3066
  $username = $authUser->user_login;
3075
  ), $alertCallback);
3076
 
3077
  remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
3078
+ self::$authError = new WP_Error('breached_password', sprintf(
3079
+ /* translators: 1. Reset password URL. 2. Support URL. */
3080
+ __('<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%1$s">reset your password</a> to reactivate your account. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn More</a>'), wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
3081
  return self::$authError;
3082
  }
3083
  }
3130
  }
3131
  if(wfConfig::get('loginSec_lockInvalidUsers')){
3132
  if(strlen($username) > 0 && preg_match('/[^\r\s\n\t]+/', $username)){
3133
+ self::lockOutIP($IP, sprintf(/* translators: WordPress username. */ __("Used an invalid username '%s' to try to sign in", 'wordfence'), $username));
3134
  self::getLog()->logLogin('loginFailInvalidUsername', true, $username);
3135
  }
3136
  $customText = wpautop(wp_strip_all_tags(wfConfig::get('blockCustomText', '')));
3137
  require(dirname(__FILE__) . '/wfLockedOut.php');
3138
  }
3139
  }
3140
+ $tKey = self::getLoginFailureCountTransient($IP);
3141
  if(is_wp_error($authUser) && in_array($authUser->get_error_code(), $failureErrorCodes)) {
3142
  $tries = get_transient($tKey);
3143
  if($tries){
3146
  $tries = 1;
3147
  }
3148
  if($tries >= wfConfig::get('loginSec_maxFailures')){
3149
+ self::lockOutIP($IP,
3150
+ sprintf(
3151
+ /* translators: 1. Login attempt limit. 2. WordPress username. */
3152
+ __('Exceeded the maximum number of login failures which is: %1$s. The last username they tried to sign in with was: \'%2$s\'', 'wordfence'),
3153
+ wfConfig::get('loginSec_maxFailures'),
3154
+ $username
3155
+ )
3156
+ );
3157
  $customText = wpautop(wp_strip_all_tags(wfConfig::get('blockCustomText', '')));
3158
  require(dirname(__FILE__) . '/wfLockedOut.php');
3159
  }
3171
  }
3172
 
3173
  if(is_wp_error($authUser) && ($authUser->get_error_code() == 'invalid_username' || $authUser->get_error_code() == 'invalid_email' || $authUser->get_error_code() == 'incorrect_password') && wfConfig::get('loginSec_maskLoginErrors')){
3174
+ return new WP_Error( 'incorrect_password', sprintf(
3175
+ /* translators: 1. WordPress username. 2. Reset password URL. */
3176
+ __( '<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%2$s" title="Password Lost and Found">Lost your password</a>?' ), $username, wp_lostpassword_url() ) );
3177
  }
3178
 
3179
  return $authUser;
3582
  }
3583
  $result = false;
3584
  if (count($emails)) {
3585
+ $result = wp_mail(implode(', ', $emails), __('Wordfence Test Email', 'wordfence'), sprintf(/* translators: 1. Site URL. 2. IP address. */ __("This is a test email from %1\$s.\nThe IP address that requested this was: %2\$s", 'wordfence'), site_url(), wfUtils::getIP()));
3586
  }
3587
  $result = $result ? 'True' : 'False';
3588
  return array('result' => $result);
3634
  return array('errorMsg' => wp_kses($codeResult['errorMsg'], array()));
3635
  }
3636
  else {
3637
+ wordfence::status(4, 'info', sprintf(__("Could not generate verification code: %s", 'wordfence'), var_export($codeResult, true)));
3638
  return array('errorMsg' => __("We could not generate a verification code.", 'wordfence'));
3639
  }
3640
  self::twoFactorAdd($user->ID, $phone, '', 'phone', $secretID);
3654
  $codeResult = $api->call('twoFactorTOTP_register', array(), array('mode' => $mode));
3655
  }
3656
  catch (Exception $e) {
3657
+ return array('errorMsg' => sprintf(/* translators: Error message. */ __("Could not contact Wordfence servers to generate a verification code: %s", 'wordfence'), wp_kses($e->getMessage(), array())));
3658
  }
3659
 
3660
  /* Expected Fields:
3678
  return array('errorMsg' => wp_kses($codeResult['errorMsg'], array()));
3679
  }
3680
  else {
3681
+ wordfence::status(4, 'info', sprintf(/* translators: Error message. */ __("Could not generate verification code: %s", 'wordfence'), var_export($codeResult, true)));
3682
  return array('errorMsg' => __("We could not generate a verification code.", 'wordfence'));
3683
  }
3684
  self::twoFactorAdd($user->ID, '', '', 'authenticator', $secretID);
3717
  $codeResult = $api->call('twoFactorTOTP_verify', array(), array('totpid' => $twoFactorUsers[$i][6], 'code' => $code, 'mode' => $mode));
3718
  }
3719
  catch (Exception $e) {
3720
+ return array('errorMsg' => sprintf(/* translators: Error message. */ __("Could not contact Wordfence servers to generate a verification code: %s", 'wordfence'), wp_kses($e->getMessage(), array())));
3721
  }
3722
 
3723
  if (isset($codeResult['ok']) && $codeResult['ok']) {
3728
  break;
3729
  }
3730
  else {
3731
+ return array('errorMsg' => __("The code you entered is invalid. Cellphone sign-in will not be enabled for this user until you enter a valid code.", 'wordfence'));
3732
  }
3733
  }
3734
  }
3735
  if(! $found){
3736
+ return array('errorMsg' => __("We could not find the user you are trying to activate. They may have been removed from the list of Cellphone Sign-in users. Please reload this page.", 'wordfence'));
3737
  }
3738
  wfConfig::set_ser('twoFactorUsers', $twoFactorUsers);
3739
  $WPuser = get_userdata($userID);
3815
  if($deleted){
3816
  return array('ok' => 1, 'userID' => $ID);
3817
  } else {
3818
+ return array('errorMsg' => __("That user has already been removed from the list.", 'wordfence'));
3819
  }
3820
  }
3821
  public static function getNextScanStartTimestamp() {
3835
  }
3836
 
3837
  if (!$nextTime) {
3838
+ return __('No scan is scheduled', 'wordfence');
3839
  }
3840
 
3841
  $difference = $nextTime - time();
3842
  if ($difference < 1) {
3843
+ return __("Next scan is starting now", 'wordfence');
3844
  }
3845
+
3846
+ return sprintf(/* translators: 1. Time until. 2. Localized date. */ __('Next scan in %1$s (%2$s)', 'wordfence'), wfUtils::makeDuration($difference), date_i18n('M j, Y g:i:s A', $nextTime + (3600 * get_option('gmt_offset'))));
3847
  }
3848
  public static function wordfenceStartScheduledScan($scheduledStartTime) {
3849
 
3860
  }
3861
  wfConfig::set('originalScheduledScanStart', $scheduledStartTime);
3862
  wfConfig::set('lastScheduledScanStart', time());
3863
+ wordfence::status(1, 'info', sprintf(/* translators: Localized date. */ __("Scheduled Wordfence scan starting at %s", 'wordfence'), date('l jS \of F Y h:i:s A', current_time('timestamp'))) );
3864
 
3865
  //We call this before the scan actually starts to advance the schedule for the next week.
3866
  //This ensures that if the scan crashes for some reason, the schedule will hold.
3883
  }
3884
  public static function ajax_saveCountryBlocking_callback(){
3885
  if(! wfConfig::get('isPaid')){
3886
+ return array('errorMsg' => __("Sorry but this feature is only available for paid customers.", 'wordfence'));
3887
  }
3888
  wfConfig::set('cbl_action', $_POST['blockAction']);
3889
  wfConfig::set('cbl_countries', $_POST['codes']);
3897
  return array('ok' => 1);
3898
  }
3899
  public static function ajax_sendActivityLog_callback(){
3900
+ $content = sprintf(/* translators: Site URL. */ __('SITE: %s', 'wordfence'), site_url()) . "\n";
3901
+ $content .= sprintf(/* translators: Plugin version. */ __('PLUGIN VERSION: %s', 'wordfence'), WORDFENCE_VERSION) . "\n";
3902
+ $content .= sprintf(/* translators: WordPress version. */ __('WORDPRESS VERSION: %s', 'wordfence'), wfUtils::getWPVersion()) . "\n";
3903
+ $content .= sprintf(/* translators: Wordfence license key. */ __('LICENSE KEY: %s', 'wordfence'), wfConfig::get('apiKey')) . "\n";
3904
+ $content .= sprintf(/* translators: Email address. */ __('ADMIN EMAIL: %s', 'wordfence'), get_option('admin_email')) . "\n";
3905
+ $content .= __('LOG:', 'wordfence') . "\n\n";
3906
+
3907
  $wfdb = new wfDB();
3908
  $table_wfStatus = wfDB::networkTable('wfStatus');
3909
  $q = $wfdb->querySelect("select ctime, level, type, msg from {$table_wfStatus} order by ctime desc limit 10000");
3923
  $issueCounts = array_merge(array('new' => 0, 'ignoreP' => 0, 'ignoreC' => 0), wfIssues::shared()->getIssueCounts());
3924
  $issueTypes = wfIssues::validIssueTypes();
3925
 
3926
+ $content .= sprintf(/* translators: Number of scan results. */ __('## New Issues (%d total)', 'wordfence'), $issueCounts['new']) . "\n\n";
3927
  if (isset($issues['new']) && count($issues['new'])) {
3928
  foreach ($issues['new'] as $i) {
3929
  if (!in_array($i['type'], $issueTypes)) {
3950
  $content .= str_repeat('-', 10);
3951
  $content .= "\n\n";
3952
 
3953
+ $content .= sprintf(/* translators: Number of scan results. */ __('## Ignored Issues (%d total)', 'wordfence'), $issueCounts['ignoreP'] + $issueCounts['ignoreC']) . "\n\n";
3954
  if (isset($issues['new']) && count($issues['new'])) {
3955
  foreach ($issues['ignored'] as $i) {
3956
  if (!in_array($i['type'], $issueTypes)) {
4018
  wfWAF::getInstance()->getStorageEngine()->purgeIPBlocks(wfWAFStorageInterface::IP_BLOCKS_BLACKLIST);
4019
  }
4020
  } else {
4021
+ throw new Exception(__("Could not understand the response we received from the Wordfence servers when applying for a free license key.", 'wordfence'));
4022
  }
4023
  } catch(Exception $e){
4024
+ return array('errorMsg' => sprintf(/* translators: Error message. */ __("Could not fetch free license key from Wordfence: %s", 'wordfence'), wp_kses($e->getMessage(), array())));
4025
  }
4026
  return array('ok' => 1);
4027
  }
4106
  }
4107
  $file = wfCache::getHtaccessPath();
4108
  if(! $file){
4109
+ return array('err' => __("We could not find your .htaccess file to modify it.", 'wordfence'));
4110
  }
4111
  $fh = @fopen($file, 'r+');
4112
  if(! $fh){
4113
  $err = error_get_last();
4114
+ return array('err' => sprintf(/* translators: Error message. */ __("We found your .htaccess file but could not open it for writing: %s", 'wordfence'), $err['message']));
4115
  }
4116
  return array('ok' => 1);
4117
  }
4200
  $entry['detailDisplay'] = __('1 Country', 'wordfence');
4201
  }
4202
  else {
4203
+ $entry['detailDisplay'] = sprintf(/* translators: Number of countries. */ __('%d Countries', 'wordfence'), count($countries));
4204
  }
4205
 
4206
  if ($b->blockLogin && $b->blockSite) {
4338
  }
4339
 
4340
  if (!empty($_POST['blocks']) && ($blocks = json_decode(stripslashes($_POST['blocks']), true)) !== false && is_array($blocks)) {
4341
+ $removed = wfBlock::removeBlockIDs($blocks, true); //wfBlock::removeBlockIDs sanitizes the array
4342
+ if($removed!==false) {
4343
+ foreach($removed as $block) {
4344
+ self::clearLockoutCounters(wfUtils::inet_ntop($block->IP));
4345
+ }
4346
+ }
4347
  $hasCountryBlock = false;
4348
  $blocks = self::_blocksAJAXReponse($hasCountryBlock, $offset, $sortColumn, $sortDirection, $filter);
4349
  return array('success' => true, 'blocks' => $blocks, 'hasCountryBlock' => $hasCountryBlock);
4505
  if ($errors !== true) {
4506
  if (count($errors) == 1) {
4507
  return array(
4508
+ 'error' => sprintf(/* translators: Error message. */ __('An error occurred while saving the configuration: %s', 'wordfence'), $errors[0]['error']),
4509
  );
4510
  }
4511
  else if (count($errors) > 1) {
4514
  $compoundMessage[] = $e['error'];
4515
  }
4516
  return array(
4517
+ 'error' => sprintf(/* translators: Error message. */ __('Errors occurred while saving the configuration: %s', 'wordfence'), implode(', ', $compoundMessage)),
4518
  );
4519
  }
4520
 
4588
  $issues = new wfIssues();
4589
  $issue = $issues->getIssueByID((int) $_POST['issueID']);
4590
  if (!$issue) {
4591
+ return array('errorMsg' => __("We could not find that issue in our database.", 'wordfence'));
4592
  }
4593
 
4594
  if (!function_exists('get_home_path')) {
4598
  $homeURL = get_home_url();
4599
  $components = parse_url($homeURL);
4600
  if ($components === false) {
4601
+ return array('errorMsg' => __("An error occurred while trying to hide the file.", 'wordfence'));
4602
  }
4603
 
4604
  $sitePath = '';
4611
  $localFile = ABSPATH . '/' . $file; //The scanner uses ABSPATH as its base rather than get_home_path()
4612
  $localFile = realpath($localFile);
4613
  if (strpos($localFile, $homePath) !== 0) {
4614
+ return array('errorMsg' => __("An invalid file was requested for hiding.", 'wordfence'));
4615
  }
4616
  $localFile = substr($localFile, strlen($homePath));
4617
  $absoluteURIPath = trim($sitePath . '/' . $localFile, '/');
4638
  HTACCESS;
4639
 
4640
  if (!wfUtils::htaccessPrepend($htaccessContent)) {
4641
+ return array('errorMsg' => __("You don't have permission to repair .htaccess. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file.", 'wordfence'));
4642
  }
4643
  $issues->updateIssue((int) $_POST['issueID'], 'delete');
4644
  wfScanEngine::refreshScanNotification($issues);
4651
  public static function ajax_unlockOutIP_callback(){
4652
  $IP = $_POST['IP'];
4653
  wfBlock::unlockOutIP($IP);
4654
+ self::clearLockoutCounters($IP);
4655
  return array('ok' => 1);
4656
  }
4657
  public static function ajax_unblockIP_callback(){
4658
  $IP = $_POST['IP'];
4659
  wfBlock::unblockIP($IP);
4660
+ self::clearLockoutCounters($IP);
4661
  return array('ok' => 1);
4662
  }
4663
  public static function ajax_permBlockIP_callback(){
4698
  $IP = trim($_POST['IP']);
4699
  $perm = (isset($_POST['perm']) && $_POST['perm'] == '1') ? wfBlock::DURATION_FOREVER : wfConfig::getInt('blockedTime');
4700
  if (!wfUtils::isValidIP($IP)) {
4701
+ return array('err' => 1, 'errorMsg' => __("Please enter a valid IP address to block.", 'wordfence'));
4702
  }
4703
  if ($IP == wfUtils::getIP()) {
4704
+ return array('err' => 1, 'errorMsg' => __("You can't block your own IP address.", 'wordfence'));
4705
  }
4706
  $forcedWhitelistEntry = false;
4707
  if (wfBlock::isWhitelisted($IP, $forcedWhitelistEntry)) {
4708
+ $message = sprintf(/* translators: IP address. */ __("The IP address %s is allowlisted and can't be blocked. You can remove this IP from the allowlist on the Wordfence options page.", 'wordfence'), wp_kses($IP, array()));
4709
  if ($forcedWhitelistEntry) {
4710
+ $message = sprintf(/* translators: IP address. */ __("The IP address %s is in a range of IP addresses that Wordfence does not block. The IP range may be internal or belong to a service safe to allow access for.", 'wordfence'), wp_kses($IP, array()));
4711
  }
4712
  return array('err' => 1, 'errorMsg' => $message);
4713
  }
4714
  if (wfConfig::get('neverBlockBG') != 'treatAsOtherCrawlers') { //Either neverBlockVerified or neverBlockUA is selected which means the user doesn't want to block google
4715
  if (wfCrawl::isVerifiedGoogleCrawler($IP)) {
4716
+ return array('err' => 1, 'errorMsg' => __("The IP address you're trying to block belongs to Google. Your options are currently set to not block these crawlers. Change this in Wordfence options if you want to manually block Google.", 'wordfence'));
4717
  }
4718
  }
4719
  wfBlock::createIP($_POST['reason'], $IP, $perm);
4756
  } else if($op == 'ignoreAllNew'){
4757
  $i->ignoreAllNew();
4758
  } else {
4759
+ return array('errorMsg' => __("An invalid operation was called.", 'wordfence'));
4760
  }
4761
  wfScanEngine::refreshScanNotification($i);
4762
  return array('ok' => 1);
4766
  $status = $_POST['status'];
4767
  $issueID = $_POST['id'];
4768
  if(! preg_match('/^(?:new|delete|ignoreP|ignoreC)$/', $status)){
4769
+ return array('errorMsg' => __("An invalid status was specified when trying to update that issue.", 'wordfence'));
4770
  }
4771
  $wfIssues->updateIssue($issueID, $status);
4772
  wfScanEngine::refreshScanNotification($wfIssues);
4778
  );
4779
  }
4780
  public static function ajax_killScan_callback(){
4781
+ wordfence::status(1, 'info', __("Scan stop request received.", 'wordfence'));
4782
+ wordfence::status(10, 'info', 'SUM_KILLED:' . __("A request was received to stop the previous scan.", 'wordfence'));
4783
  wfUtils::clearScanLock(); //Clear the lock now because there may not be a scan running to pick up the kill request and clear the lock
4784
  wfScanEngine::requestKill();
4785
  wfConfig::remove('scanStartAttempt');
4837
  else if ($lastScanCompleted == 'ok') {
4838
  $scanLastCompletion = (int) wfScanner::shared()->lastScanTime();
4839
  if ($scanLastCompletion) {
4840
+ $lastMessage = sprintf(/* translators: Localized date. */ __('Scan completed on %s', 'wordfence'), wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $scanLastCompletion));
4841
  }
4842
  }
4843
  else if ($lastScanCompleted === false || empty($lastScanCompleted)) {
4907
  $scanFailedTiming = wfUtils::makeTimeAgo($scanFailedSeconds);
4908
 
4909
  if ($scanFailedSeconds > $timeLimit) {
4910
+ $scanFailedTiming = sprintf(/* translators: Time until. */ __('more than %s', 'wordfence'), wfUtils::makeTimeAgo($timeLimit));
4911
  }
4912
 
4913
  $scanFailedHTML = wfView::create('scanner/scan-failed', array(
4914
+ 'messageHTML' => sprintf(/* translators: Localized date. */ __('The current scan looks like it has failed. Its last status update was <span id="wf-scan-failed-time-ago">%s</span> ago. You may continue to wait in case it resumes or stop and restart the scan. Some sites may need adjustments to run scans reliably.', 'wordfence'), $scanFailedTiming) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_FAILS) . '" target="_blank" rel="noopener noreferrer">' . __('Click here for steps you can try.', 'wordfence') . '</a>',
4915
  'buttonTitle' => __('Cancel Scan', 'wordfence'),
4916
  ))->render();
4917
 
4925
  break;
4926
  case wfIssues::SCAN_FAILED_DURATION_REACHED:
4927
  $scanFailedHTML = wfView::create('scanner/scan-failed', array(
4928
+ 'messageHTML' => sprintf(/* translators: Time limit (number). */ __('The previous scan has terminated because the time limit of %s was reached. This limit can be customized on the options page.', 'wordfence'), wfUtils::makeDuration($timeLimit)) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_SCAN_OPTION_OVERALL_TIME_LIMIT) . '" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i></a>',
4929
  'buttonTitle' => __('Close', 'wordfence'),
4930
  ))->render();
4931
  break;
4932
  case wfIssues::SCAN_FAILED_VERSION_CHANGE:
4933
  $scanFailedHTML = wfView::create('scanner/scan-failed', array(
4934
+ 'messageHTML' => esc_html__('The previous scan has terminated because we detected an update occurring during the scan.', 'wordfence'),
4935
  'buttonTitle' => __('Close', 'wordfence'),
4936
  ))->render();
4937
  break;
4944
  break;
4945
  case wfIssues::SCAN_FAILED_API_SSL_UNAVAILABLE:
4946
  $scanFailedHTML = wfView::create('scanner/scan-failed', array(
4947
+ 'messageHTML' => esc_html__('Scans are not functional because SSL is unavailable.', 'wordfence'),
4948
  'buttonTitle' => __('Close', 'wordfence'),
4949
  ))->render();
4950
  break;
4985
  public static function ajax_updateAlertEmail_callback(){
4986
  $email = trim($_POST['email']);
4987
  if(! preg_match('/[^\@]+\@[^\.]+\.[^\.]+/', $email) || in_array(hash('sha256', $email), wfConfig::alertEmailBlacklist())){
4988
+ return array( 'err' => __("Invalid email address given.", 'wordfence'));
4989
  }
4990
  wfConfig::set('alertEmails', $email);
4991
  return array('ok' => 1, 'email' => $email);
5019
  }
5020
  else {
5021
  $err = error_get_last();
5022
+ $errors[] = esc_html(sprintf(/* translators: 1. File path. 2. Error message. */ __('Could not delete file %1$s. Error was: %2$s', 'wordfence'), wp_kses($file, array()), wp_kses(str_replace(ABSPATH, '{WordPress Root}/', $err['message']), array())));
5023
  }
5024
  }
5025
  else if ($op == 'repair' && @$i['data']['canFix']) {
5043
  continue;
5044
  }
5045
  else if (!is_array($result) || !isset($result['fileContent'])) {
5046
+ $errors[] = esc_html(sprintf(/* translators: File path. */ __('We could not retrieve the original file of %s to do a repair.', 'wordfence'), wp_kses($file, array())));
5047
  continue;
5048
  }
5049
 
5050
  if (preg_match('/\.\./', $file)) {
5051
+ $errors[] = sprintf(/* translators: File path. */ __('An invalid file %s was specified for repair.', 'wordfence'), wp_kses($file, array()));
5052
  continue;
5053
  }
5054
 
5056
  if (!$fh) {
5057
  $err = error_get_last();
5058
  if (preg_match('/Permission denied/i', $err['message'])) {
5059
+ $errMsg = esc_html(sprintf(/* translators: File path. */ __('You don\'t have permission to repair %s. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file.', 'wordfence'), wp_kses($file, array())));
5060
  }
5061
  else {
5062
+ $errMsg = esc_html(sprintf(/* translators: 1. File path. 2. Error message. */ __('We could not write to %1$s. The error was: %2$s', 'wordfence'), wp_kses($file, array()), $err['message']));
5063
  }
5064
  $errors[] = $errMsg;
5065
  continue;
5070
  flock($fh, LOCK_UN);
5071
  fclose($fh);
5072
  if ($bytes < 1) {
5073
+ $errors[] = esc_html(sprintf(/* translators: 1. File path. 2. Number of bytes. */ __('We could not write to %1$s. (%2$d bytes written) You may not have permission to modify files on your WordPress server.', 'wordfence'), wp_kses($file, array()), $bytes));
5074
  continue;
5075
  }
5076
 
5083
 
5084
  if ($filesWorkedOn > 0 && count($errors) > 0) {
5085
  $headMsg = esc_html($op == 'del' ? __('Deleted some files with errors', 'wordfence') : __('Repaired some files with errors', 'wordfence'));
5086
+ $bodyMsg = sprintf(esc_html($op == 'del' ?
5087
+ /* translators: 1. Number of files. 2. Error message. */
5088
+ __('Deleted %1$d files but we encountered the following errors with other files: %2$s', 'wordfence') :
5089
+ /* translators: 1. Number of files. 2. Error message. */
5090
+ __('Repaired %1$d files but we encountered the following errors with other files: %2$s', 'wordfence')),
5091
+ $filesWorkedOn, implode('<br>', $errors));
5092
  }
5093
  else if ($filesWorkedOn > 0) {
5094
+ $headMsg = sprintf(esc_html($op == 'del' ? /* translators: Number of files. */ __('Deleted %d files successfully', 'wordfence') : /* translators: Number of files. */ __('Repaired %d files successfully', 'wordfence')), $filesWorkedOn);
5095
+ $bodyMsg = sprintf(esc_html($op == 'del' ? /* translators: Number of files. */ __('Deleted %d files successfully. No errors were encountered.', 'wordfence') : /* translators: Number of files. */ __('Repaired %d files successfully. No errors were encountered.', 'wordfence')), $filesWorkedOn);
5096
  }
5097
  else if (count($errors) > 0) {
5098
  $headMsg = esc_html($op == 'del' ? __('Could not delete files', 'wordfence') : __('Could not repair files', 'wordfence'));
5099
+ $bodyMsg = sprintf(esc_html($op == 'del' ?
5100
+ /* translators: Error message. */
5101
+ __('We could not delete any of the files you selected. We encountered the following errors: %s', 'wordfence') :
5102
+ /* translators: Error message. */
5103
+ __('We could not repair any of the files you selected. We encountered the following errors: %s', 'wordfence')), implode('<br>', $errors));
5104
  }
5105
  else {
5106
  $headMsg = esc_html__('Nothing done', 'wordfence');
5171
  }
5172
 
5173
  $err = error_get_last();
5174
+ return array(
5175
+ 'errorMsg' => sprintf(
5176
+ /* translators: 1. File path. 2. Error message. */
5177
+ __('Could not delete file %1$s. The error was: %2$s', 'wordfence'),
5178
+ wp_kses($file, array()),
5179
+ wp_kses(str_replace(ABSPATH, '{WordPress Root}/', $err['message']), array())
5180
+ )
5181
+ );
5182
  }
5183
  public static function ajax_deleteDatabaseOption_callback(){
5184
  /** @var wpdb $wpdb */
5187
  $wfIssues = new wfIssues();
5188
  $issue = $wfIssues->getIssueByID($issueID);
5189
  if (!$issue) {
5190
+ return array('errorMsg' => __("Could not remove the option because we could not find that issue.", 'wordfence'));
5191
  }
5192
  if (empty($issue['data']['option_name'])) {
5193
+ return array('errorMsg' => __("Could not remove the option because that issue does not appear to be a database related issue.", 'wordfence'));
5194
  }
5195
  $table_options = wfDB::blogTable('options', $issue['data']['site_id']);
5196
  if ($wpdb->query($wpdb->prepare("DELETE FROM {$table_options} WHERE option_name = %s", $issue['data']['option_name']))) {
5201
  'option_name' => $issue['data']['option_name'],
5202
  );
5203
  } else {
5204
+ return array('errorMsg' => sprintf(
5205
+ /* translators: 1. WordPress option. 2. Error message. */
5206
+ __('Could not remove the option %1$s. The error was: %2$s', 'wordfence'),
5207
+ esc_html($issue['data']['option_name']),
5208
+ esc_html($wpdb->last_error)
5209
+ ));
5210
  }
5211
  }
5212
  public static function ajax_fixFPD_callback(){
5213
  $issues = new wfIssues();
5214
  $issue = $issues->getIssueByID($_POST['issueID']);
5215
  if (!$issue) {
5216
+ return array('cerrorMsg' => __("We could not find that issue in our database.", 'wordfence'));
5217
  }
5218
 
5219
  $htaccess = ABSPATH . '/.htaccess';
5224
  }
5225
 
5226
  if (@file_put_contents($htaccess, trim($content . "\n" . $change), LOCK_EX) === false) {
5227
+ return array('cerrorMsg' => __("You don't have permission to repair .htaccess. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file.", 'wordfence'));
 
5228
  }
5229
  if (wfScanEngine::testForFullPathDisclosure()) {
5230
  // Didn't fix it, so revert the changes and return an error
5231
  file_put_contents($htaccess, $content, LOCK_EX);
5232
  return array(
5233
+ 'cerrorMsg' => __("Modifying the .htaccess file did not resolve the issue, so the original .htaccess file was restored. You can fix this manually by setting <code>display_errors</code> to <code>Off</code> in your php.ini if your site is on a VPS or dedicated server that you control.", 'wordfence'),
 
 
5234
  );
5235
  }
5236
  $issues->updateIssue($_POST['issueID'], 'delete');
5244
  $wfIssues = new wfIssues();
5245
  $issue = $wfIssues->getIssueByID($issueID);
5246
  if(! $issue){
5247
+ return array('cerrorMsg' => __("We could not find that issue in our database.", 'wordfence'));
5248
  }
5249
 
5250
  /** @var WP_Filesystem_Base $wp_filesystem */
5272
  if(isset($result['errorMsg']) && $result['errorMsg']){
5273
  return $result;
5274
  } else if(! $result['fileContent']){
5275
+ return array('errorMsg' => __("We could not get the original file to do a repair.", 'wordfence'));
5276
  }
5277
 
5278
  if(preg_match('/\.\./', $file)){
5279
+ return array('errorMsg' => __("An invalid file was specified for repair.", 'wordfence'));
5280
  }
5281
  $localFile = rtrim(ABSPATH, '/') . '/' . preg_replace('/^[\.\/]+/', '', $file);
5282
  if ($wp_filesystem->put_contents($localFile, $result['fileContent'])) {
5291
  );
5292
  }
5293
  return array(
5294
+ 'errorMsg' => __("We could not write to that file. You may not have permission to modify files on your WordPress server.", 'wordfence'),
5295
  );
5296
  }
5297
  public static function ajax_scan_callback(){
5298
+ self::status(4, 'info', __("Ajax request received to start scan.", 'wordfence'));
5299
  $err = wfScanEngine::startScan();
5300
  if ($err) {
5301
  return array('errorMsg' => wp_kses($err, array()));
5347
  $hresults = $hooverResults[1];
5348
  $count = count($hresults);
5349
  if ($count > 0) {
5350
+ new wfNotification(
5351
+ null,
5352
+ wfNotification::PRIORITY_HIGH_WARNING,
5353
+ sprintf(/* translators: Number of URLs. */ _n("Page contains %d malware URL: ", "Page contains %d malware URLs: ", $count, 'wordfence') . esc_html($pageURL)),
5354
+ 'wfplugin_malwareurl_' . md5($pageURL),
5355
+ null,
5356
+ array(array('link' => wfUtils::wpAdminURL('admin.php?page=WordfenceScan'), 'label' => __('Run a Scan', 'wordfence'))));
5357
  return array('bad' => $count);
5358
  }
5359
  }
5401
  }
5402
  }
5403
 
5404
+ return array('error' => __('Unknown dashboard data set.', 'wordfence'));
5405
  }
5406
  public static function startScan(){
5407
  wfScanEngine::startScan();
5423
  //End logging
5424
 
5425
 
5426
+ if(! ($wfFunc == 'diff' || $wfFunc == 'view' || $wfFunc == 'viewOption' || $wfFunc == 'sysinfo' || $wfFunc == 'IPTraf' || $wfFunc == 'viewActivityLog' || $wfFunc == 'testmem' || $wfFunc == 'testtime' || $wfFunc == 'download' || $wfFunc == 'blockedIPs' || ($wfFunc == 'debugWAF' && WFWAF_DEBUG))){
5427
  return;
5428
  }
5429
  if(! wfUtils::isAdmin()){
5432
 
5433
  $nonce = $_GET['nonce'];
5434
  if(! wp_verify_nonce($nonce, 'wp-ajax')){
5435
+ _e("Bad security token. It may have been more than 12 hours since you reloaded the page you came from. Try reloading the page you came from. If that doesn't work, please sign out and sign-in again.", 'wordfence');
5436
  exit(0);
5437
  }
5438
  if($wfFunc == 'diff'){
5443
  self::wfFunc_viewOption();
5444
  } else if($wfFunc == 'sysinfo') {
5445
  require(dirname(__FILE__) . '/sysinfo.php' );
 
 
 
 
 
 
 
 
5446
  } else if($wfFunc == 'IPTraf'){
5447
  self::wfFunc_IPTraf();
5448
  } else if($wfFunc == 'viewActivityLog'){
5619
 
5620
  private static function IPTraf($ip) {
5621
  if(!wfUtils::isValidIP($ip)){
5622
+ throw new InvalidArgumentException(__("An invalid IP address was specified.", 'wordfence'));
5623
  }
5624
  $reverseLookup = wfUtils::reverseLookup($ip);
5625
  $wfLog = wfLog::shared();
5672
  public static function wfFunc_view(){
5673
  wfUtils::doNotCache();
5674
  if (WORDFENCE_DISABLE_FILE_VIEWER) {
5675
+ _e("File access blocked. (WORDFENCE_DISABLE_FILE_VIEWER is true)", 'wordfence');
5676
  exit();
5677
  }
5678
  $localFile = ABSPATH . preg_replace('/^(?:\.\.|[\/]+)/', '', sanitize_text_field($_GET['file']));
5679
  if(strpos($localFile, '..') !== false){
5680
+ _e("Invalid file requested. (Relative paths not allowed)", 'wordfence');
5681
  exit();
5682
  }
5683
  if(preg_match('/[\'\"<>\!\{\}\(\)\&\@\%\$\*\+\[\]\?]+/', $localFile)){
5684
+ _e("File contains illegal characters.", 'wordfence');
5685
  exit();
5686
  }
5687
  $cont = @file_get_contents($localFile);
5691
  $isEmpty = true;
5692
  } else {
5693
  $err = error_get_last();
5694
+ printf(/* translators: Error message. */ __("We could not open the requested file for reading. The error was: %s", 'wordfence'), $err['message']);
5695
  exit(0);
5696
  }
5697
  }
5699
  $fileMTime = date('l jS \of F Y h:i:s A', $fileMTime);
5700
  try {
5701
  if(wfUtils::fileOver2Gigs($localFile)){
5702
+ $fileSize = __("Greater than 2 Gigs", 'wordfence');
5703
  } else {
5704
  $fileSize = @filesize($localFile); //Checked if over 2 gigs above
5705
  $fileSize = number_format($fileSize, 0, '', ',') . ' bytes';
5706
  }
5707
+ } catch(Exception $e){ $fileSize = __('Unknown file size.', 'wordfence'); }
5708
 
5709
  require(dirname(__FILE__) . '/wfViewResult.php');
5710
  exit(0);
5712
  public static function wfFunc_diff(){
5713
  wfUtils::doNotCache();
5714
  if (WORDFENCE_DISABLE_FILE_VIEWER) {
5715
+ esc_html_e("File access blocked. (WORDFENCE_DISABLE_FILE_VIEWER is true)", 'wordfence');
5716
  exit();
5717
  }
5718
  if(preg_match('/[\'\"<>\!\{\}\(\)\&\@\%\$\*\+\[\]\?]+/', $_GET['file'])){
5719
+ esc_html_e("File contains illegal characters.", 'wordfence');
5720
  exit();
5721
  }
5722
 
5725
  echo wp_kses($result['errorMsg'], array());
5726
  exit(0);
5727
  } else if(! $result['fileContent']){
5728
+ esc_html_e("We could not get the contents of the original file to do a comparison.", 'wordfence');
5729
  exit(0);
5730
  }
5731
 
5750
  public static function wfFunc_download() {
5751
  wfUtils::doNotCache();
5752
  if (WORDFENCE_DISABLE_FILE_VIEWER) {
5753
+ esc_html_e("File access blocked. (WORDFENCE_DISABLE_FILE_VIEWER is true)", 'wordfence');
5754
  exit();
5755
  }
5756
  $localFile = ABSPATH . preg_replace('/^(?:\.\.|[\/]+)/', '', sanitize_text_field($_GET['file']));
5757
  if (strpos($localFile, '..') !== false) {
5758
+ esc_html_e("Invalid file requested. (Relative paths not allowed)", 'wordfence');
5759
  exit();
5760
  }
5761
  if (preg_match('/[\'\"<>\!\{\}\(\)\&\@\%\$\*\+\[\]\?]+/', $localFile)) {
5762
+ esc_html_e("File contains illegal characters.", 'wordfence');
5763
  exit();
5764
  }
5765
  if (!file_exists($localFile)) {
5766
+ _e('File does not exist.', 'wordfence');
5767
+ exit();
5768
  }
5769
 
5770
  $filename = basename($localFile);
5940
  wp_enqueue_script('jquery.wfdataTables', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/jquery.dataTables.min.js'), array('jquery'), WORDFENCE_VERSION);
5941
  wp_enqueue_script('jquery.qrcode', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/jquery.qrcode.min.js'), array('jquery'), WORDFENCE_VERSION);
5942
  //wp_enqueue_script('jquery.tools', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/jquery.tools.min.js'), array('jquery'));
5943
+ wp_enqueue_script('wfi18njs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/wfi18n.js'), array(), WORDFENCE_VERSION);
5944
  wp_enqueue_script('wordfenceAdminExtjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/wfglobal.js'), array('jquery'), WORDFENCE_VERSION);
5945
+ wp_enqueue_script('wordfenceAdminjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/admin.js'), array('jquery', 'jquery-ui-core', 'jquery-ui-menu'), WORDFENCE_VERSION);
5946
  wp_enqueue_script('wordfenceDropdownjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/wfdropdown.js'), array('jquery'), WORDFENCE_VERSION);
5947
  self::setupAdminVars();
5948
 
5952
  } else {
5953
  wp_enqueue_style('wp-pointer');
5954
  wp_enqueue_script('wp-pointer');
5955
+ wp_enqueue_script('wfi18njs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/wfi18n.js'), array(), WORDFENCE_VERSION);
5956
  wp_enqueue_script('wordfenceAdminExtjs', wfUtils::getBaseURL() . wfUtils::versionedAsset('js/wfglobal.js'), array('jquery'), WORDFENCE_VERSION);
5957
  wp_enqueue_style('wordfence-font-awesome-style');
5958
  wp_enqueue_style('wordfence-global-style', wfUtils::getBaseURL() . wfUtils::versionedAsset('css/wf-global.css'), '', WORDFENCE_VERSION);
6019
  'supportURLs' => array(
6020
  'scan-result-repair-modified-files' => esc_url_raw(wfSupportController::supportURL(wfSupportController::ITEM_SCAN_RESULT_REPAIR_MODIFIED_FILES)),
6021
  ),
6022
+ ));
6023
+ self::setupI18nJSStrings();
6024
+ }
6025
+
6026
+ private static function setupI18nJSStrings() {
6027
+ static $called;
6028
+ if ($called) {
6029
+ return;
6030
+ }
6031
+ $called = true;
6032
+ wp_localize_script('wfi18njs', 'WordfenceI18nStrings', array(
6033
+ '${totalIPs} addresses in this network' => __('${totalIPs} addresses in this network', 'wordfence'),
6034
+ '%s in POST body: %s' => /* translators: 1. Description of firewall action. 2. Description of input parameters. */ __('%s in POST body: %s', 'wordfence'),
6035
+ '%s in cookie: %s' => /* translators: 1. Description of firewall action. 2. Description of input parameters. */ __('%s in cookie: %s', 'wordfence'),
6036
+ '%s in file: %s' => /* translators: 1. Description of firewall action. 2. Description of input parameters. */ __('%s in file: %s', 'wordfence'),
6037
+ '%s in query string: %s' => /* translators: 1. Description of firewall action. 2. Description of input parameters. */ __('%s in query string: %s', 'wordfence'),
6038
+ '%s is not valid hostname' => /* translators: Domain name. */ __('%s is not valid hostname', 'wordfence'),
6039
+ '.htaccess Updated' => __('.htaccess Updated', 'wordfence'),
6040
+ '.htaccess change' => __('.htaccess change', 'wordfence'),
6041
+ '404 Not Found' => __('404 Not Found', 'wordfence'),
6042
+ 'Activity Log Sent' => __('Activity Log Sent', 'wordfence'),
6043
+ 'Add action to allowlist' => __('Add action to allowlist', 'wordfence'),
6044
+ 'Add code to .htaccess' => __('Add code to .htaccess', 'wordfence'),
6045
+ 'All Hits' => __('All Hits', 'wordfence'),
6046
+ 'All capabilties of admin user %s were successfully revoked.' => /* translators: WordPress username. */ __('All capabilties of admin user %s were successfully revoked.', 'wordfence'),
6047
+ 'An error occurred' => __('An error occurred', 'wordfence'),
6048
+ 'An error occurred when adding the request to the allowlist.' => __('An error occurred when adding the request to the allowlist.', 'wordfence'),
6049
+ 'Are you sure you want to allowlist this action?' => __('Are you sure you want to allowlist this action?', 'wordfence'),
6050
+ 'Authentication Code' => __('Authentication Code', 'wordfence'),
6051
+ 'Background Request Blocked' => __('Background Request Blocked', 'wordfence'),
6052
+ 'Block This Network' => __('Block This Network', 'wordfence'),
6053
+ 'Blocked' => __('Blocked', 'wordfence'),
6054
+ 'Blocked By Firewall' => __('Blocked By Firewall', 'wordfence'),
6055
+ 'Blocked WAF' => __('Blocked WAF', 'wordfence'),
6056
+ 'Blocked by Wordfence' => __('Blocked by Wordfence', 'wordfence'),
6057
+ 'Blocked by Wordfence plugin settings' => __('Blocked by Wordfence plugin settings', 'wordfence'),
6058
+ 'Blocked by the Wordfence Application Firewall and plugin settings' => __('Blocked by the Wordfence Application Firewall and plugin settings', 'wordfence'),
6059
+ 'Blocked by the Wordfence Security Network' => __('Blocked by the Wordfence Security Network', 'wordfence'),
6060
+ 'Blocked by the Wordfence Web Application Firewall' => __('Blocked by the Wordfence Web Application Firewall', 'wordfence'),
6061
+ 'Bot' => __('Bot', 'wordfence'),
6062
+ 'Cancel Changes' => __('Cancel Changes', 'wordfence'),
6063
+ 'Cellphone Sign-In Recovery Codes' => __('Cellphone Sign-In Recovery Codes', 'wordfence'),
6064
+ 'Cellphone Sign-in activated for user.' => __('Cellphone Sign-in activated for user.', 'wordfence'),
6065
+ 'Click here to download a backup copy of this file now' => __('Click here to download a backup copy of this file now', 'wordfence'),
6066
+ 'Click here to download a backup copy of your .htaccess file now' => __('Click here to download a backup copy of your .htaccess file now', 'wordfence'),
6067
+ 'Click to fix .htaccess' => __('Click to fix .htaccess', 'wordfence'),
6068
+ 'Close' => __('Close', 'wordfence'),
6069
+ 'Crawlers' => __('Crawlers', 'wordfence'),
6070
+ 'Diagnostic report has been sent successfully.' => __('Diagnostic report has been sent successfully.', 'wordfence'),
6071
+ 'Directory Listing Disabled' => __('Directory Listing Disabled', 'wordfence'),
6072
+ 'Directory listing has been disabled on your server.' => __('Directory listing has been disabled on your server.', 'wordfence'),
6073
+ 'Disabled' => __('Disabled', 'wordfence'),
6074
+ 'Dismiss' => __('Dismiss', 'wordfence'),
6075
+ 'Don\'t ask again' => __('Don\'t ask again', 'wordfence'),
6076
+ 'Download' => __('Download', 'wordfence'),
6077
+ 'Download Backup File' => __('Download Backup File', 'wordfence'),
6078
+ 'Each line of 16 letters and numbers is a single recovery code, with optional spaces for readability. When typing your password, enter "wf" followed by the entire code like "mypassword wf1234 5678 90AB CDEF". If your site shows a separate prompt for entering a code after entering only your username and password, enter only the code like "1234 5678 90AB CDEF". Your recovery codes are:' => __('Each line of 16 letters and numbers is a single recovery code, with optional spaces for readability. When typing your password, enter "wf" followed by the entire code like "mypassword wf1234 5678 90AB CDEF". If your site shows a separate prompt for entering a code after entering only your username and password, enter only the code like "1234 5678 90AB CDEF". Your recovery codes are:', 'wordfence'),
6079
+ 'Email Diagnostic Report' => __('Email Diagnostic Report', 'wordfence'),
6080
+ 'Email Wordfence Activity Log' => __('Email Wordfence Activity Log', 'wordfence'),
6081
+ 'Enter a valid IP or domain' => __('Enter a valid IP or domain', 'wordfence'),
6082
+ '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.' => __('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.', 'wordfence'),
6083
+ 'Error' => __('Error', 'wordfence'),
6084
+ 'Error Enabling All Options Page' => __('Error Enabling All Options Page', 'wordfence'),
6085
+ 'Error Restoring Defaults' => __('Error Restoring Defaults', 'wordfence'),
6086
+ 'Error Saving Option' => __('Error Saving Option', 'wordfence'),
6087
+ 'Error Saving Options' => __('Error Saving Options', 'wordfence'),
6088
+ 'Failed Login' => __('Failed Login', 'wordfence'),
6089
+ 'Failed Login: Invalid Username' => __('Failed Login: Invalid Username', 'wordfence'),
6090
+ 'Failed Login: Valid Username' => __('Failed Login: Valid Username', 'wordfence'),
6091
+ 'File hidden successfully' => __('File hidden successfully', 'wordfence'),
6092
+ 'File restored OK' => __('File restored OK', 'wordfence'),
6093
+ 'Filter Traffic' => __('Filter Traffic', 'wordfence'),
6094
+ 'Firewall Response' => __('Firewall Response', 'wordfence'),
6095
+ 'Full Path Disclosure' => __('Full Path Disclosure', 'wordfence'),
6096
+ 'Google Bot' => __('Google Bot', 'wordfence'),
6097
+ 'Google Crawlers' => __('Google Crawlers', 'wordfence'),
6098
+ 'HTTP Response Code' => __('HTTP Response Code', 'wordfence'),
6099
+ 'Human' => __('Human', 'wordfence'),
6100
+ 'Humans' => __('Humans', 'wordfence'),
6101
+ 'IP' => __('IP', 'wordfence'),
6102
+ 'Key:' => __('Key:', 'wordfence'),
6103
+ 'Last Updated: %s' => /* translators: Localized date. */ __('Last Updated: %s', 'wordfence'),
6104
+ 'Learn more about repairing modified files.' => __('Learn more about repairing modified files.', 'wordfence'),
6105
+ 'Loading...' => __('Loading...', 'wordfence'),
6106
+ 'Locked Out' => __('Locked Out', 'wordfence'),
6107
+ 'Locked out from logging in' => __('Locked out from logging in', 'wordfence'),
6108
+ 'Logged In' => __('Logged In', 'wordfence'),
6109
+ 'Logins' => __('Logins', 'wordfence'),
6110
+ 'Logins and Logouts' => __('Logins and Logouts', 'wordfence'),
6111
+ 'Look up IP or Domain' => __('Look up IP or Domain', 'wordfence'),
6112
+ 'Manual block by administrator' => __('Manual block by administrator', 'wordfence'),
6113
+ 'Next Update Check: %s' => /* translators: Localized date. */ __('Next Update Check: %s', 'wordfence'),
6114
+ 'No activity to report yet. Please complete your first scan.' => __('No activity to report yet. Please complete your first scan.', 'wordfence'),
6115
+ 'No issues have been ignored.' => __('No issues have been ignored.', 'wordfence'),
6116
+ 'No new issues have been found.' => __('No new issues have been found.', 'wordfence'),
6117
+ 'No rules were updated. Please verify you have permissions to write to the /wp-content/wflogs directory.' => __('No rules were updated. Please verify you have permissions to write to the /wp-content/wflogs directory.', 'wordfence'),
6118
+ 'No rules were updated. Please verify your website can reach the Wordfence servers.' => __('No rules were updated. Please verify your website can reach the Wordfence servers.', 'wordfence'),
6119
+ 'No rules were updated. Your website has reached the maximum number of rule update requests. Please try again later.' => __('No rules were updated. Your website has reached the maximum number of rule update requests. Please try again later.', 'wordfence'),
6120
+ 'Note: Status will update when changes are saved' => __('Note: Status will update when changes are saved', 'wordfence'),
6121
+ 'OK' => __('OK', 'wordfence'),
6122
+ 'Pages Not Found' => __('Pages Not Found', 'wordfence'),
6123
+ 'Paid Members Only' => __('Paid Members Only', 'wordfence'),
6124
+ 'Please enter a valid IP address or domain name for your whois lookup.' => __('Please enter a valid IP address or domain name for your whois lookup.', 'wordfence'),
6125
+ 'Please enter a valid email address.' => __('Please enter a valid email address.', 'wordfence'),
6126
+ 'Please include your support ticket number or forum username.' => __('Please include your support ticket number or forum username.', 'wordfence'),
6127
+ 'Please make a backup of this file before proceeding. If you need to restore this backup file, you can copy it to the following path from your site\'s root:' => __('Please make a backup of this file before proceeding. If you need to restore this backup file, you can copy it to the following path from your site\'s root:', 'wordfence'),
6128
+ 'Please specify a reason' => __('Please specify a reason', 'wordfence'),
6129
+ 'Please specify a valid IP address range in the form of "1.2.3.4 - 1.2.3.5" without quotes. Make sure the dash between the IP addresses in a normal dash (a minus sign on your keyboard) and not another character that looks like a dash.' => __('Please specify a valid IP address range in the form of "1.2.3.4 - 1.2.3.5" without quotes. Make sure the dash between the IP addresses in a normal dash (a minus sign on your keyboard) and not another character that looks like a dash.', 'wordfence'),
6130
+ 'Please specify either an IP address range, Hostname or a web browser pattern to match.' => __('Please specify either an IP address range, Hostname or a web browser pattern to match.', 'wordfence'),
6131
+ 'Recent Activity' => __('Recent Activity', 'wordfence'),
6132
+ 'Recovery Codes' => __('Recovery Codes', 'wordfence'),
6133
+ 'Redirected' => __('Redirected', 'wordfence'),
6134
+ 'Redirected by Country Blocking bypass URL' => __('Redirected by Country Blocking bypass URL', 'wordfence'),
6135
+ 'Referer' => __('Referer', 'wordfence'),
6136
+ 'Registered Users' => __('Registered Users', 'wordfence'),
6137
+ 'Restore Defaults' => __('Restore Defaults', 'wordfence'),
6138
+ 'Rule Update Failed' => __('Rule Update Failed', 'wordfence'),
6139
+ 'Rules Updated' => __('Rules Updated', 'wordfence'),
6140
+ 'Save Changes' => __('Save Changes', 'wordfence'),
6141
+ 'Scan Complete.' => __('Scan Complete.', 'wordfence'),
6142
+ 'Scan the code below with your authenticator app to add this account. Some authenticator apps also allow you to type in the text version instead.' => __('Scan the code below with your authenticator app to add this account. Some authenticator apps also allow you to type in the text version instead.', 'wordfence'),
6143
+ 'Security Event' => __('Security Event', 'wordfence'),
6144
+ 'Send' => __('Send', 'wordfence'),
6145
+ 'Sorry, but no data for that IP or domain was found.' => __('Sorry, but no data for that IP or domain was found.', 'wordfence'),
6146
+ 'Specify a valid IP range' => __('Specify a valid IP range', 'wordfence'),
6147
+ 'Specify a valid hostname' => __('Specify a valid hostname', 'wordfence'),
6148
+ 'Specify an IP range, Hostname or Browser pattern' => __('Specify an IP range, Hostname or Browser pattern', 'wordfence'),
6149
+ 'Success deleting file' => __('Success deleting file', 'wordfence'),
6150
+ 'Success removing option' => __('Success removing option', 'wordfence'),
6151
+ 'Success restoring file' => __('Success restoring file', 'wordfence'),
6152
+ 'Success updating option' => __('Success updating option', 'wordfence'),
6153
+ 'Successfully deleted admin' => __('Successfully deleted admin', 'wordfence'),
6154
+ 'Successfully revoked admin' => __('Successfully revoked admin', 'wordfence'),
6155
+ 'Test Email Sent' => __('Test Email Sent', 'wordfence'),
6156
+ 'The \'How does Wordfence get IPs\' option was successfully updated to the recommended value.' => __('The \'How does Wordfence get IPs\' option was successfully updated to the recommended value.', 'wordfence'),
6157
+ 'The Full Path disclosure issue has been fixed' => __('The Full Path disclosure issue has been fixed', 'wordfence'),
6158
+ 'The admin user %s was successfully deleted.' => /* translators: WordPress username. */ __('The admin user %s was successfully deleted.', 'wordfence'),
6159
+ 'The file %s was successfully deleted.' => /* translators: File path. */ __('The file %s was successfully deleted.', 'wordfence'),
6160
+ 'The file %s was successfully hidden from public view.' => /* translators: File path. */ __('The file %s was successfully hidden from public view.', 'wordfence'),
6161
+ 'The file %s was successfully restored.' => /* translators: File path. */ __('The file %s was successfully restored.', 'wordfence'),
6162
+ 'The option %s was successfully removed.' => /* translators: WordPress option. */ __('The option %s was successfully removed.', 'wordfence'),
6163
+ 'The request has been allowlisted. Please try it again.' => __('The request has been allowlisted. Please try it again.', 'wordfence'),
6164
+ 'There was an error while sending the email.' => __('There was an error while sending the email.', 'wordfence'),
6165
+ 'This will be shown only once. Keep these codes somewhere safe.' => __('This will be shown only once. Keep these codes somewhere safe.', 'wordfence'),
6166
+ 'Throttled' => __('Throttled', 'wordfence'),
6167
+ 'Two Factor Status' => __('Two Factor Status', 'wordfence'),
6168
+ 'Type' => __('Type', 'wordfence'),
6169
+ 'Type: %s' => /* translators: HTTP client type. */ __('Type: %s', 'wordfence'),
6170
+ 'URL' => __('URL', 'wordfence'),
6171
+ 'Unable to automatically hide file' => __('Unable to automatically hide file', 'wordfence'),
6172
+ 'Use one of these %s codes to log in if you are unable to access your phone. Codes are 16 characters long, plus optional spaces. Each one may be used only once.' => /* translators: 2FA backup codes. */ __('Use one of these %s codes to log in if you are unable to access your phone. Codes are 16 characters long, plus optional spaces. Each one may be used only once.', 'wordfence'),
6173
+ 'Use one of these %s codes to log in if you lose access to your authenticator device. Codes are 16 characters long, plus optional spaces. Each one may be used only once.' => /* translators: 2FA backup codes. */ __('Use one of these %s codes to log in if you lose access to your authenticator device. Codes are 16 characters long, plus optional spaces. Each one may be used only once.', 'wordfence'),
6174
+ 'User Agent' => __('User Agent', 'wordfence'),
6175
+ 'User ID' => __('User ID', 'wordfence'),
6176
+ 'Username' => __('Username', 'wordfence'),
6177
+ 'WHOIS LOOKUP' => __('WHOIS LOOKUP', 'wordfence'),
6178
+ 'We are about to change your <em>.htaccess</em> file. Please make a backup of this file before proceeding.' => __('We are about to change your <em>.htaccess</em> file. Please make a backup of this file before proceeding.', 'wordfence'),
6179
+ 'We can\'t modify your .htaccess file for you because: %s' => /* translators: Error message. */ __('We can\'t modify your .htaccess file for you because: %s', 'wordfence'),
6180
+ 'We encountered a problem' => __('We encountered a problem', 'wordfence'),
6181
+ 'Wordfence Firewall blocked a background request to WordPress for the URL %s. If this occurred as a result of an intentional action, you may consider allowlisting the request to allow it in the future.' => /* translators: URL. */ __('Wordfence Firewall blocked a background request to WordPress for the URL %s. If this occurred as a result of an intentional action, you may consider allowlisting the request to allow it in the future.', 'wordfence'),
6182
+ 'Wordfence is working...' => __('Wordfence is working...', 'wordfence'),
6183
+ 'You are using Nginx as your web server. You\'ll need to disable autoindexing in your nginx.conf. See the <a target=\'_blank\' rel=\'noopener noreferrer\' href=\'http://nginx.org/en/docs/http/ngx_http_autoindex_module.html\'>Nginx docs for more info</a> on how to do this.' => __('You are using Nginx as your web server. You\'ll need to disable autoindexing in your nginx.conf. See the <a target=\'_blank\' rel=\'noopener noreferrer\' href=\'http://nginx.org/en/docs/http/ngx_http_autoindex_module.html\'>Nginx docs for more info</a> on how to do this.', 'wordfence'),
6184
+ 'You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. You will need to manually delete or hide those files.' => __('You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. You will need to manually delete or hide those files.', 'wordfence'),
6185
+ 'You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. You will need to manually modify your php.ini to disable <em>display_error</em>' => __('You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. You will need to manually modify your php.ini to disable <em>display_error</em>', 'wordfence'),
6186
+ 'You forgot to include a reason you\'re blocking this IP range. We ask you to include this for your own record keeping.' => __('You forgot to include a reason you\'re blocking this IP range. We ask you to include this for your own record keeping.', 'wordfence'),
6187
+ 'You have unsaved changes to your options. If you leave this page, those changes will be lost.' => __('You have unsaved changes to your options. If you leave this page, those changes will be lost.', 'wordfence'),
6188
+ 'Your .htaccess has been updated successfully. Please verify your site is functioning normally.' => __('Your .htaccess has been updated successfully. Please verify your site is functioning normally.', 'wordfence'),
6189
+ 'Your Wordfence activity log was sent to %s' => /* translators: Email address. */ __('Your Wordfence activity log was sent to %s', 'wordfence'),
6190
+ 'Your rules have been updated successfully.' => __('Your rules have been updated successfully.', 'wordfence'),
6191
+ 'Your rules have been updated successfully. You are currently using the free version of Wordfence. Upgrade to Wordfence premium to have your rules updated automatically as new threats emerge. <a href="https://www.wordfence.com/wafUpdateRules1/wordfence-signup/">Click here to purchase a premium license</a>. <em>Note: Your rules will still update every 30 days as a free user.</em>' => __('Your rules have been updated successfully. You are currently using the free version of Wordfence. Upgrade to Wordfence premium to have your rules updated automatically as new threats emerge. <a href="https://www.wordfence.com/wafUpdateRules1/wordfence-signup/">Click here to purchase a premium license</a>. <em>Note: Your rules will still update every 30 days as a free user.</em>', 'wordfence'),
6192
+ 'Your test email was sent to the requested email address. The result we received from the WordPress wp_mail() function was: %s<br /><br />A \'True\' result means WordPress thinks the mail was sent without errors. A \'False\' result means that WordPress encountered an error sending your mail. Note that it\'s possible to get a \'True\' response with an error elsewhere in your mail system that may cause emails to not be delivered.' => /* translators: wp_mail() return value. */ __('Your test email was sent to the requested email address. The result we received from the WordPress wp_mail() function was: %s<br /><br />A \'True\' result means WordPress thinks the mail was sent without errors. A \'False\' result means that WordPress encountered an error sending your mail. Note that it\'s possible to get a \'True\' response with an error elsewhere in your mail system that may cause emails to not be delivered.', 'wordfence'),
6193
+ 'blocked by firewall' => __('blocked by firewall', 'wordfence'),
6194
+ 'blocked by firewall for %s' => /* translators: Reason for firewall action. */ __('blocked by firewall for %s', 'wordfence'),
6195
+ 'blocked by real-time IP blocklist' => __('blocked by real-time IP blocklist', 'wordfence'),
6196
+ 'blocked by the Wordfence Security Network' => __('blocked by the Wordfence Security Network', 'wordfence'),
6197
+ 'blocked for %s' => /* translators: Reason for firewall action. */ __('blocked for %s', 'wordfence'),
6198
+ 'locked out from logging in' => __('locked out from logging in', 'wordfence'),
6199
+ ));
6200
  }
6201
  public static function showTOUPPOverlay($classList) {
6202
  return trim($classList . ' wf-toupp-required');
6207
  $activationError = substr($activationError, 0, 400) . '...[output truncated]';
6208
  }
6209
  if($activationError){
6210
+ echo '<div id="wordfenceConfigWarning" class="updated fade"><p><strong>' .
6211
+ __('Wordfence generated an error on activation. The output we received during activation was:', 'wordfence')
6212
+ . '</strong> ' . wp_kses($activationError, array()) . '</p></div>';
6213
  }
6214
  delete_option('wf_plugin_act_error');
6215
  }
6216
  public static function noKeyError(){
6217
+ echo '<div id="wordfenceConfigWarning" class="fade error"><p>' .
6218
+ sprintf('<strong>%s</strong> ', __('Wordfence could not register with the Wordfence scanning servers when it activated.', 'wordfence')) .
6219
+ __('You can try to fix this by deactivating Wordfence and then activating it again, so Wordfence will retry registering for you. If you keep seeing this error, it usually means your WordPress server can\'t connect to our scanning servers, or your wfConfig database table cannot be created to save the key. You can try asking your host to allow your server to connect to noc1.wordfence.com or check the wfConfig database table and database privileges.', 'wordfence')
6220
+ . '</p></div>';
6221
  }
6222
  public static function wafConfigInaccessibleNotice() {
6223
  if (function_exists('network_admin_url') && is_multisite()) {
6230
  'waf-nonce' => wp_create_nonce('wafconfigrebuild'),
6231
  ), $wafMenuURL);
6232
 
6233
+ echo '<div id="wafConfigInaccessibleNotice" class="fade error"><p><strong>' . __('The Wordfence Web Application Firewall cannot run.', 'wordfence') . '</strong> ' .
6234
+ sprintf(
6235
+ /* translators: 1. WordPress admin panel URL. 2. Support URL. */
6236
+ __('The configuration files are corrupt or inaccessible by the web server, which is preventing the WAF from functioning. Please verify the web server has permission to access the configuration files. You may also try to rebuild the configuration file by <a href="%1$s">clicking here</a>. It will automatically resume normal operation when it is fixed. <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="%2$s"></a>', 'wordfence'),
6237
+ $wafMenuURL,
6238
+ wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_WAF_INACCESSIBLE_CONFIG)
6239
+ ) . '</p></div>';
6240
  }
6241
  public static function wafConfigNeedsUpdate_mod_php() {
6242
  if (function_exists('network_admin_url') && is_multisite()) {
6249
  'waf-nonce' => wp_create_nonce('wafconfigfixmodphp'),
6250
  ), $wafMenuURL);
6251
 
6252
+ echo '<div id="wafConfigNeedsUpdateNotice" class="fade error"><p><strong>' . __('The Wordfence Web Application Firewall needs a configuration update.', 'wordfence') . '</strong> ' .
6253
+ sprintf(
6254
+ /* translators: 1. WordPress admin panel URL. 2. Support URL. */
6255
+ __('It is currently configured to use an older version of PHP and may become deactivated if PHP is updated. You may perform the configuration update automatically by <a href="%1$s">clicking here</a>. <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="%2$s"></a>', 'wordfence'),
6256
+ $wafMenuURL,
6257
+ wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_WAF_MOD_PHP_FIX)
6258
+ ) . '</p></div>';
6259
  }
6260
  public static function wafConfigNeedsFixed_mod_php() {
6261
  if (function_exists('network_admin_url') && is_multisite()) {
6268
  'waf-nonce' => wp_create_nonce('wafconfigfixmodphp'),
6269
  ), $wafMenuURL);
6270
 
6271
+ echo '<div id="wafConfigNeedsFixedNotice" class="fade error"><p><strong>' . __('The Wordfence Web Application Firewall needs a configuration update.', 'wordfence') . '</strong> ' .
6272
+ sprintf(
6273
+ /* translators: 1. WordPress admin panel URL. 2. Support URL. */
6274
+ __('It is not currently in extended protection mode but was configured to use an older version of PHP and may have become deactivated when PHP was updated. You may perform the configuration update automatically by <a href="%1$s">clicking here</a> or use the "Optimize the Wordfence Firewall" button on the Firewall Options page. <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="%2$s"></a>', 'wordfence'),
6275
+ $wafMenuURL,
6276
+ wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_WAF_MOD_PHP_FIX)
6277
+ ) . '</p></div>';
6278
  }
6279
  public static function wafReadOnlyNotice() {
6280
  echo '<div id="wordfenceWAFReadOnlyNotice" class="fade error"><p><strong>' . __('The Wordfence Web Application Firewall is in read-only mode.', 'wordfence') . '</strong> ' . sprintf('PHP is currently running as a command line user and to avoid file permission issues, the WAF is running in read-only mode. It will automatically resume normal operation when run normally by a web server. <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="%s"></a>', wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_WAF_READ_ONLY_WARNING)) . '</p></div>';
6286
 
6287
  $existingMsg = '';
6288
  if ($existing == 'REMOTE_ADDR') {
6289
+ $existingMsg = __('This site is currently using PHP\'s built in REMOTE_ADDR.', 'wordfence');
6290
  }
6291
  else if ($existing == 'HTTP_X_FORWARDED_FOR') {
6292
+ $existingMsg = __('This site is currently using the X-Forwarded-For HTTP header, which should only be used when the site is behind a front-end proxy that outputs this header.', 'wordfence');
6293
  }
6294
  else if ($existing == 'HTTP_X_REAL_IP') {
6295
+ $existingMsg = __('This site is currently using the X-Real-IP HTTP header, which should only be used when the site is behind a front-end proxy that outputs this header.', 'wordfence');
6296
  }
6297
  else if ($existing == 'HTTP_CF_CONNECTING_IP') {
6298
+ $existingMsg = __('This site is currently using the Cloudflare "CF-Connecting-IP" HTTP header, which should only be used when the site is behind Cloudflare.', 'wordfence');
6299
  }
6300
 
6301
  $recommendationMsg = '';
6302
  if ($recommendation == 'REMOTE_ADDR') {
6303
+ $recommendationMsg = __('For maximum security use PHP\'s built in REMOTE_ADDR.', 'wordfence');
6304
  }
6305
  else if ($recommendation == 'HTTP_X_FORWARDED_FOR') {
6306
+ $recommendationMsg = __('This site appears to be behind a front-end proxy, so using the X-Forwarded-For HTTP header will resolve to the correct IPs.', 'wordfence');
6307
  }
6308
  else if ($recommendation == 'HTTP_X_REAL_IP') {
6309
+ $recommendationMsg = __('This site appears to be behind a front-end proxy, so using the X-Real-IP HTTP header will resolve to the correct IPs.', 'wordfence');
6310
  }
6311
  else if ($recommendation == 'HTTP_CF_CONNECTING_IP') {
6312
+ $recommendationMsg = __('This site appears to be behind Cloudflare, so using the Cloudflare "CF-Connecting-IP" HTTP header will resolve to the correct IPs.', 'wordfence');
6313
+ }
6314
+ echo '<div id="wordfenceMisconfiguredHowGetIPsNotice" class="fade error"><p><strong>' .
6315
+ __('Your \'How does Wordfence get IPs\' setting is misconfigured.', 'wordfence')
6316
+ . '</strong> ' . $existingMsg . ' ' . $recommendationMsg . ' <a href="#" onclick="wordfenceExt.misconfiguredHowGetIPsChoice(\'yes\'); return false;">' .
6317
+ __('Click here to use the recommended setting', 'wordfence')
6318
+ . '</a> ' .
6319
+ __('or', 'wordfence')
6320
+ . ' <a href="' . $url . '">' .
6321
+ __('visit the options page', 'wordfence')
6322
+ . '</a> ' .
6323
+ __('to manually update it.', 'wordfence')
6324
+ . '</p><p>
6325
+ <a class="wf-btn wf-btn-default wf-btn-sm wf-dismiss-link" href="#" onclick="wordfenceExt.misconfiguredHowGetIPsChoice(\'no\'); return false;">' .
6326
+ __('Dismiss', 'wordfence')
6327
+ . '</a> <a class="wfhelp" target="_blank" rel="noopener noreferrer" href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_NOTICE_MISCONFIGURED_HOW_GET_IPS) . '"></a></p></div>';
6328
  }
6329
  public static function autoUpdateNotice(){
6330
+ echo '<div id="wordfenceAutoUpdateChoice" class="fade error"><p><strong>' .
6331
+ __('Do you want Wordfence to stay up-to-date automatically?', 'wordfence')
6332
+ . '</strong>&nbsp;&nbsp;&nbsp;<a href="#" onclick="wordfenceExt.autoUpdateChoice(\'yes\'); return false;">'.
6333
+ __('Yes, enable auto-update.', 'wordfence')
6334
+ . '</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href="#" onclick="wordfenceExt.autoUpdateChoice(\'no\'); return false;">' .
6335
+ __('No thanks.', 'wordfence')
6336
+ . '</a></p></div>';
6337
  }
6338
  public static function admin_menus(){
6339
  if(! wfUtils::isAdmin()){ return; }
6413
  }
6414
  }
6415
 
6416
+ $message = sprintf(
6417
+ /* translators: Localized date. */
6418
+ __('The last rules update for the Wordfence Web Application Firewall was unsuccessful. The last successful update check was %s, so this site may be missing new rules added since then.', 'wordfence'),
6419
+ wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $lastChecked)
6420
+ );
6421
 
6422
  if (!$firewall->isSubDirectoryInstallation()) {
6423
  if ($nextUpdate < PHP_INT_MAX) {
6424
+ $message .= ' ' . sprintf(
6425
+ /* translators: 1. Localized date. 2. WordPress admin panel URL. */
6426
+ __('You may wait for the next automatic attempt at %1$s or try to <a href="%2$s">Manually Update</a> by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence'),
6427
+ wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $nextUpdate),
6428
+ esc_url(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#wf-option-wafRules'))
6429
+ );
6430
  }
6431
  else {
6432
+ $message .= ' ' . sprintf(/* translators: WordPress admin panel URL. */ __('You may wait for the next automatic attempt or try to <a href="%s">Manually Update</a> by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence'), esc_url(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#waf-rules-next-update')));
6433
  }
6434
  }
6435
  else {
6436
  if ($nextUpdate < PHP_INT_MAX) {
6437
+ $message .= ' ' . sprintf(/* translators: WordPress admin panel URL. */ __('You may wait for the next automatic attempt at %s or log into the parent site to manually update by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence'), wfUtils::formatLocalTime(get_option('date_format') . ' ' . get_option('time_format'), $nextUpdate));
6438
  }
6439
  else {
6440
  $message .= ' ' . __('You may wait for the next automatic attempt or log into the parent site to manually update by clicking the "Manually Refresh Rules" button below the Rules list.', 'wordfence');
6521
  }
6522
 
6523
  if (version_compare(PHP_VERSION, '8.0', '>=') && !get_user_option('wordfence_php8_nag')) {
6524
+ wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_INFO, wp_kses(__(<<<HTML
6525
  PHP 8 includes significant changes from PHP 7, which may cause unexpected bugs in plugins, themes, and WordPress itself. Wordfence is not yet officially supported on PHP 8, but will be supported in the near future. <a href="https://www.wordfence.com/blog/2020/11/php-8-what-wordpress-users-need-to-know/">Read More</a>
6526
  HTML
6527
+ , 'wordfence'), 'post')
6528
  , 'php8', array(get_current_user_id()));
6529
  update_user_option(get_current_user_id(), 'wordfence_php8_nag', 1);
6530
  }
6540
 
6541
  //These are split to allow our module plugins to insert their menu item(s) at any point in the hierarchy
6542
  public static function admin_menus_20() {
6543
+ add_submenu_page("Wordfence", __("Wordfence Dashboard", 'wordfence'), __("Dashboard", 'wordfence'), "activate_plugins", "Wordfence", 'wordfence::menu_dashboard');
6544
  }
6545
 
6546
  public static function admin_menus_30() {
6547
+ add_submenu_page("Wordfence", __("Firewall", 'wordfence'), __("Firewall", 'wordfence'), "activate_plugins", "WordfenceWAF", 'wordfence::menu_firewall');
6548
  if (wfConfig::get('displayTopLevelBlocking')) {
6549
+ add_submenu_page("Wordfence", __("Blocking", 'wordfence'), __("Blocking", 'wordfence'), "activate_plugins", "WordfenceBlocking", 'wordfence::menu_blocking');
6550
  }
6551
  }
6552
 
6553
  public static function admin_menus_40() {
6554
+ add_submenu_page("Wordfence", __("Scan", 'wordfence'), __("Scan", 'wordfence'), "activate_plugins", "WordfenceScan", 'wordfence::menu_scan');
6555
  }
6556
 
6557
  public static function admin_menus_50() {
6558
+ add_submenu_page('Wordfence', __('Tools', 'wordfence'), __('Tools', 'wordfence'), 'activate_plugins', 'WordfenceTools', 'wordfence::menu_tools');
6559
  if (wfConfig::get('displayTopLevelLiveTraffic')) {
6560
+ add_submenu_page("Wordfence", __("Live Traffic", 'wordfence'), __("Live Traffic", 'wordfence'), "activate_plugins", "WordfenceLiveTraffic", 'wordfence::menu_tools');
6561
  }
6562
  }
6563
 
6564
  public static function admin_menus_60() {
6565
  if (wfConfig::get('displayTopLevelOptions')) {
6566
+ add_submenu_page("Wordfence", __("All Options", 'wordfence'), __("All Options", 'wordfence'), "activate_plugins", "WordfenceOptions", 'wordfence::menu_options');
6567
  }
6568
  }
6569
 
6570
  public static function admin_menus_70() {
6571
+ add_submenu_page('Wordfence', __('Help', 'wordfence'), __('Help', 'wordfence'), 'activate_plugins', 'WordfenceSupport', 'wordfence::menu_support');
6572
  }
6573
 
6574
  public static function admin_menus_80() {
6575
  if (wfCentral::isSupported()) {
6576
+ add_submenu_page(null, __('Wordfence Central', 'wordfence'), __('Wordfence Central', 'wordfence'), 'activate_plugins', 'WordfenceCentral', 'wordfence::menu_wordfence_central');
6577
  }
6578
  }
6579
 
6580
  public static function admin_menus_90() {
6581
  if (wfConfig::get('isPaid')) {
6582
+ add_submenu_page("Wordfence", __("Protect More Sites", 'wordfence'), "<strong id=\"wfMenuCallout\" style=\"color: #FCB214;\">" . __("Protect More Sites", 'wordfence') . "</strong>", "activate_plugins", "WordfenceProtectMoreSites", 'wordfence::_menu_noop');
6583
  }
6584
  else {
6585
+ add_submenu_page("Wordfence", __("Upgrade To Premium", 'wordfence'), "<strong id=\"wfMenuCallout\" style=\"color: #FCB214;\">" . __("Upgrade To Premium", 'wordfence') . "</strong>", "activate_plugins", "WordfenceUpgradeToPremium", 'wordfence::_menu_noop');
6586
  }
6587
  add_filter('clean_url', 'wordfence::_patchWordfenceSubmenuCallout', 10, 3);
6588
  }
6619
  $count = count(wfNotification::notifications());
6620
  $sinceCount = count(wfNotification::notifications((int) get_user_meta(get_current_user_id(), 'wordfence-notifications', true)));
6621
  if ($sinceCount > 0) {
6622
+ $counter = '<span id="wf-notification-popover" data-toggle="popover" data-trigger="focus" data-content="' .
6623
+ esc_attr(/* translators: Number of notifications. */ _n('You have %d new Wordfence notification.', 'You have %d new Wordfence notifications.', $sinceCount, 'wordfence'))
6624
+ . '" data-container="body" data-placement="wf-bottom">&nbsp;</span>';
6625
  update_user_meta(get_current_user_id(), 'wordfence-notifications', time());
6626
  }
6627
  else {
6638
  $wp_admin_bar->add_menu( array(
6639
  'parent' => 'wordfence-menu',
6640
  'id' => 'wordfence-notifications',
6641
+ 'title' => '<div id="wordfence-notifications-display" class="wf-adminbar-submenu-title">' . __('Notifications', 'wordfence') . '</div>' . $badge,
6642
  'href' => network_admin_url('admin.php?page=Wordfence'),
6643
  ));
6644
  $wp_admin_bar->add_menu( array(
6645
  'parent' => 'wordfence-menu',
6646
  'id' => 'wordfence-javascripterror',
6647
+ 'title' => '<div id="wordfence-javascripterror-display" class="wf-adminbar-submenu-title">' . __('JavaScript Errors', 'wordfence') . '</div><div class="wf-adminbar-status wf-adminbar-status-good">&bullet;</div>',
6648
  'href' => 'javascript:void(0)',
6649
  ));
6650
  $wp_admin_bar->add_menu( array(
6651
  'parent' => 'wordfence-menu',
6652
  'id' => 'wordfence-malwareurl',
6653
+ 'title' => '<div id="wordfence-malwareurl-display' . (is_admin() ? '-skip' : '') . '" class="wf-adminbar-submenu-title">' . __('Malware URLs', 'wordfence') . '</div><div class="wf-adminbar-status wf-adminbar-status-neutral">&bullet;</div>',
6654
  'href' => network_admin_url('admin.php?page=WordfenceScan'),
6655
  ));
6656
  }
6768
  $wafMenuURL = add_query_arg(array(
6769
  'waf-nonce' => wp_create_nonce('wafconfigrebuild'),
6770
  ), $wafMenuURL);
6771
+ $storageExceptionMessage = $e->getMessage() . ' ' . sprintf(__('<a href="%s">Click here</a> to rebuild the configuration file.', 'wordfence'), esc_url($wafMenuURL));
6772
  } catch (wfWAFStorageFileException $e) {
6773
  // We don't have anywhere to write files in this scenario. Let's notify the user to update the permissions.
6774
  $wafData = array(
6779
  'isPaid' => (bool) wfConfig::get('isPaid', 0),
6780
  );
6781
  $logPath = str_replace(ABSPATH, '~/', WFWAF_LOG_PATH);
6782
+ $storageExceptionMessage = sprintf(/* translators: File path. */ __('We were unable to write to %s which the WAF uses for storage. Please update permissions on the parent directory so the web server can write to it.', 'wordfence'), $logPath);
 
6783
  } catch (wfWAFStorageEngineMySQLiException $e) {
6784
  $wafData = array(
6785
  'learningMode' => false,
6789
  'isPaid' => (bool) wfConfig::get('isPaid', 0),
6790
  );
6791
  $logPath = null;
6792
+ $storageExceptionMessage = __('An error occured when fetching the WAF configuration from the database.', 'wordfence') . ' <pre>' . esc_html($e->getMessage()) . '</pre>';
 
6793
  }
6794
 
6795
  require(dirname(__FILE__) . '/menu_options.php');
6831
  $wafMenuURL = add_query_arg(array(
6832
  'waf-nonce' => wp_create_nonce('wafconfigrebuild'),
6833
  ), $wafMenuURL);
6834
+ $storageExceptionMessage = $e->getMessage() . ' ' . sprintf(/* translators: WordPress admin panel URL. */ __('<a href="%s">Click here</a> to rebuild the configuration file.', 'wordfence'), esc_url($wafMenuURL));
6835
  } catch (wfWAFStorageFileException $e) {
6836
  // We don't have anywhere to write files in this scenario. Let's notify the user to update the permissions.
6837
  $wafData = array(
6842
  'isPaid' => (bool) wfConfig::get('isPaid', 0),
6843
  );
6844
  $logPath = str_replace(ABSPATH, '~/', WFWAF_LOG_PATH);
6845
+ $storageExceptionMessage = sprintf(/* translators: File path. */ __('We were unable to write to %s which the WAF uses for storage. Please update permissions on the parent directory so the web server can write to it.', 'wordfence'), $logPath);
 
6846
  } catch (wfWAFStorageEngineMySQLiException $e) {
6847
  $wafData = array(
6848
  'learningMode' => false,
6852
  'isPaid' => (bool) wfConfig::get('isPaid', 0),
6853
  );
6854
  $logPath = null;
6855
+ $storageExceptionMessage = __('An error occured when fetching the WAF configuration from the database.', 'wordfence') . ' <pre>' . esc_html($e->getMessage()) . '</pre>';
 
6856
  }
6857
 
6858
  if (isset($_GET['subpage']) && $_GET['subpage'] == 'waf_options') {
6873
  echo self::cachingWarning("WP Super Cache");
6874
  }
6875
  public static function cachingWarning($plugin){
6876
+ return '<div id="wordfenceConfigWarning" class="error fade"><p><strong>' .
6877
+ sprintf(/* translators: Plugin name. */ __('The Wordfence Live Traffic feature has been disabled because you have %s active which is not compatible with Wordfence Live Traffic.', 'wordfence'), $plugin)
6878
+ . '</strong> ' .
6879
+ sprintf(/* translators: 1. Plugin name. */ __('If you want to reenable Wordfence Live Traffic, you need to deactivate %1$s and then go to the Wordfence options page and reenable Live Traffic there. Wordfence does work with %1$s, however Live Traffic will be disabled and the Wordfence firewall will also count less hits per visitor because of the %1$s caching function. All other functions should work correctly.', 'wordfence'), $plugin)
6880
+ . '</p></div>';
6881
  }
6882
  public static function menu_dashboard() {
6883
  wp_enqueue_style('wordfence-select2-css');
6937
  $issueID = filter_input(INPUT_GET, 'issueID', FILTER_SANITIZE_NUMBER_INT);
6938
  $response = self::ajax_restoreFile_callback($issueID);
6939
  if (!empty($response['ok'])) {
6940
+ $result = sprintf('<p>' . /* translators: File path. */ __('The file <code>%s</code> was restored successfully.', 'wordfence') . '</p>',
6941
  esc_html(strpos($response['file'], ABSPATH) === 0 ? substr($response['file'], strlen(ABSPATH) + 1) : $response['file']));
6942
  } else if (!empty($response['cerrorMessage'])) {
6943
  $result = sprintf('<div class="wfSummaryErr">%s</div>', esc_html($response['cerrorMessage']));
6944
  } else {
6945
+ $result = '<div class="wfSummaryErr">' . __('There was an error restoring the file.', 'wordfence') . '</div>';
6946
  }
6947
  printf(<<<HTML
6948
  <br>
6949
  %s
6950
+ <p><a href="%s">%s</a></p>
6951
  HTML
6952
  ,
6953
  $result,
6954
+ esc_url(network_admin_url('admin.php?page=WordfenceScan')),
6955
+ __('Return to scan results', 'wordfence')
6956
  );
6957
  wfScanEngine::refreshScanNotification();
6958
  }
6961
  $issueID = filter_input(INPUT_GET, 'issueID', FILTER_SANITIZE_NUMBER_INT);
6962
  $response = self::ajax_deleteFile_callback($issueID);
6963
  if (!empty($response['ok'])) {
6964
+ $result = sprintf('<p>' . /* translators: File path. */ __('The file <code>%s</code> was deleted successfully.', 'wordfence') . '</p>', esc_html($response['file']));
6965
  } else if (!empty($response['errorMessage'])) {
6966
  $result = sprintf('<div class="wfSummaryErr">%s</div>', esc_html($response['errorMessage']));
6967
  } else {
6968
+ $result = '<div class="wfSummaryErr">' . __('There was an error deleting the file.', 'wordfence') . '</div>';
6969
  }
6970
  printf(<<<HTML
6971
  <br>
6972
  %s
6973
+ <p><a href="%s">%s</a></p>
6974
  HTML
6975
  ,
6976
  $result,
6977
+ esc_url(network_admin_url('admin.php?page=WordfenceScan')),
6978
+ __('Return to scan results', 'wordfence')
6979
  );
6980
  wfScanEngine::refreshScanNotification();
6981
  }
6986
  }
6987
  if($type != 'info' && $type != 'error'){ error_log("Invalid status type: $type"); return; }
6988
  if(self::$printStatus){
6989
+ echo "STATUS: $level : $type : ".esc_html($msg)."\n";
6990
  } else {
6991
  self::getLog()->addStatus($level, $type, $msg);
6992
  }
7033
 
7034
  $IPMsg = "";
7035
  if ($IP) {
7036
+ $IPMsg = sprintf(/* translators: IP address. */ __("User IP: %s\n", 'wordfence'), $IP);
7037
  $reverse = wfUtils::reverseLookup($IP);
7038
  if ($reverse) {
7039
+ $IPMsg .= sprintf(/* translators: Domain name. */ __("User hostname: %s\n", 'wordfence'), $reverse);
7040
  }
7041
  $userLoc = wfUtils::getIPGeo($IP);
7042
  if ($userLoc) {
7095
  }
7096
  wfConfig::set('lastEmailHash', time() . ':' . $hash);
7097
  foreach ($emails as $email) {
7098
+ $uniqueContent = $content . "\n\n" . sprintf(/* translators: WordPress admin panel URL. */ __('No longer an administrator for this site? Click here to stop receiving security alerts: %s', 'wordfence'), wfUtils::getSiteBaseURL() . '?_wfsf=removeAlertEmail&jwt=' . wfUtils::generateJWT(array('email' => $email)));
7099
  wp_mail($email, $subject, $uniqueContent);
7100
  }
7101
  }
7135
  $IP = trim($IP);
7136
  $user_range = new wfUserIPRange($IP);
7137
  if (!$user_range->isValidRange()) {
7138
+ throw new Exception(__("The IP you provided must be in dotted quad notation or use ranges with square brackets. e.g. 10.11.12.13 or 10.11.12.[1-50]", 'wordfence'));
7139
  }
7140
  $whites = wfConfig::get('whitelisted', '');
7141
  $arr = explode(',', $whites);
7159
 
7160
  $report = new wfActivityReport();
7161
  return $report->sendReportViaEmail($email) ?
7162
+ array('ok' => 1, 'result' => __('Test email sent successfully', 'wordfence')) :
7163
+ array('err' => __("Test email failed to send.", 'wordfence'));
7164
  }
7165
 
7166
  public static function addDashboardWidget() {
7178
  }
7179
  wp_add_dashboard_widget(
7180
  'wordfence_activity_report_widget',
7181
+ sprintf(/* translators: Localized date range. */ __('Wordfence activity in the past %s', 'wordfence'), $report_date_range),
7182
  array('wfActivityReport', 'outputDashboardWidget')
7183
  );
7184
  }
7214
  $wfIssues = new wfIssues();
7215
  $issue = $wfIssues->getIssueByID($issueID);
7216
  if (!$issue) {
7217
+ return array('errorMsg' => __("We could not find that issue in our database.", 'wordfence'));
7218
  }
7219
  $data = $issue['data'];
7220
  if (empty($data['userID'])) {
7221
+ return array('errorMsg' => __("We could not find that user in the database.", 'wordfence'));
7222
  }
7223
  $user = new WP_User($data['userID']);
7224
  if (!$user->exists()) {
7225
+ return array('errorMsg' => __("We could not find that user in the database.", 'wordfence'));
7226
  }
7227
  $userLogin = $user->user_login;
7228
  if (is_multisite() && strcasecmp($user->user_email, get_site_option('admin_email')) === 0) {
7229
+ return array('errorMsg' => __("This user's email is the network admin email. It will need to be changed before deleting this user.", 'wordfence'));
7230
  }
7231
  if (is_multisite()) {
7232
  revoke_super_admin($data['userID']);
7249
  $wfIssues = new wfIssues();
7250
  $issue = $wfIssues->getIssueByID($issueID);
7251
  if (!$issue) {
7252
+ return array('errorMsg' => __("We could not find that issue in our database.", 'wordfence'));
7253
  }
7254
  $data = $issue['data'];
7255
  if (empty($data['userID'])) {