Wordfence Security – Firewall & Malware Scan - Version 7.4.6

Version Description

  • February 12, 2020 =
  • Improvement: Enhanced the detection ability of the WAF for SQLi attacks.
  • Improvement: Updated the bundled GeoIP database.
  • Improvement: Modified some country names in the block configuration to align with those shown in Live Traffic.
  • Change: Moved the skipped files scan check to the Server State category.
  • Fix: Fixed an issue where after scrolling on the Live Traffic page, updates would no longer automatically load.
  • Fix: Modified the number of login records kept to align better with Live Traffic so they're trimmed around the same time.
Download this release

Release Info

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

Code changes from version 7.4.5 to 7.4.6

Files changed (68) hide show
  1. css/{activity-report-widget.1579191227.css → activity-report-widget.1581523568.css} +0 -0
  2. css/{diff.1579191227.css → diff.1581523568.css} +0 -0
  3. css/{dt_table.1579191227.css → dt_table.1581523568.css} +0 -0
  4. css/{fullLog.1579191227.css → fullLog.1581523568.css} +0 -0
  5. css/{iptraf.1579191227.css → iptraf.1581523568.css} +0 -0
  6. css/{jquery-ui-timepicker-addon.1579191227.css → jquery-ui-timepicker-addon.1581523568.css} +0 -0
  7. css/{jquery-ui.min.1579191227.css → jquery-ui.min.1581523568.css} +0 -0
  8. css/{jquery-ui.structure.min.1579191227.css → jquery-ui.structure.min.1581523568.css} +0 -0
  9. css/{jquery-ui.theme.min.1579191227.css → jquery-ui.theme.min.1581523568.css} +0 -0
  10. css/{main.1579191227.css → main.1581523568.css} +0 -0
  11. css/{phpinfo.1579191227.css → phpinfo.1581523568.css} +0 -0
  12. css/{wf-adminbar.1579191227.css → wf-adminbar.1581523568.css} +0 -0
  13. css/{wf-colorbox.1579191227.css → wf-colorbox.1581523568.css} +0 -0
  14. css/{wf-font-awesome.1579191227.css → wf-font-awesome.1581523568.css} +0 -0
  15. css/{wf-global.1579191227.css → wf-global.1581523568.css} +0 -0
  16. css/{wf-ionicons.1579191227.css → wf-ionicons.1581523568.css} +0 -0
  17. css/{wf-onboarding.1579191227.css → wf-onboarding.1581523568.css} +0 -0
  18. css/{wf-roboto-font.1579191227.css → wf-roboto-font.1581523568.css} +0 -0
  19. css/{wfselect2.min.1579191227.css → wfselect2.min.1581523568.css} +0 -0
  20. css/{wordfenceBox.1579191227.css → wordfenceBox.1581523568.css} +0 -0
  21. js/{Chart.bundle.min.1579191227.js → Chart.bundle.min.1581523568.js} +0 -0
  22. js/{admin.1579191227.js → admin.1581523568.js} +1 -0
  23. js/{admin.ajaxWatcher.1579191227.js → admin.ajaxWatcher.1581523568.js} +0 -0
  24. js/{admin.liveTraffic.1579191227.js → admin.liveTraffic.1581523568.js} +0 -0
  25. js/{date.1579191227.js → date.1581523568.js} +0 -0
  26. js/{jquery-ui-timepicker-addon.1579191227.js → jquery-ui-timepicker-addon.1581523568.js} +0 -0
  27. js/{jquery.colorbox-min.1579191227.js → jquery.colorbox-min.1581523568.js} +0 -0
  28. js/{jquery.colorbox.1579191227.js → jquery.colorbox.1581523568.js} +0 -0
  29. js/{jquery.dataTables.min.1579191227.js → jquery.dataTables.min.1581523568.js} +0 -0
  30. js/{jquery.qrcode.min.1579191227.js → jquery.qrcode.min.1581523568.js} +0 -0
  31. js/{jquery.tmpl.min.1579191227.js → jquery.tmpl.min.1581523568.js} +0 -0
  32. js/{jquery.tools.min.1579191227.js → jquery.tools.min.1581523568.js} +0 -0
  33. js/{knockout-3.3.0.1579191227.js → knockout-3.3.0.1581523568.js} +0 -0
  34. js/{wfdashboard.1579191227.js → wfdashboard.1581523568.js} +0 -0
  35. js/{wfdropdown.1579191227.js → wfdropdown.1581523568.js} +0 -0
  36. js/{wfglobal.1579191227.js → wfglobal.1581523568.js} +0 -0
  37. js/{wfpopover.1579191227.js → wfpopover.1581523568.js} +0 -0
  38. js/{wfselect2.min.1579191227.js → wfselect2.min.1581523568.js} +0 -0
  39. lib/GeoLite2-Country.mmdb +0 -0
  40. lib/menu_tools_livetraffic.php +5 -0
  41. lib/wfBulkCountries.php +2 -2
  42. lib/wfCredentialsController.php +1 -1
  43. lib/wfIssues.php +1 -1
  44. lib/wfScanEngine.php +2 -2
  45. lib/wordfenceClass.php +2 -2
  46. models/scanner/wfScanner.php +5 -5
  47. modules/login-security/css/{admin-global.1579191227.css → admin-global.1581523568.css} +0 -0
  48. modules/login-security/css/{admin.1579191227.css → admin.1581523568.css} +0 -0
  49. modules/login-security/css/{colorbox.1579191227.css → colorbox.1581523568.css} +0 -0
  50. modules/login-security/css/{font-awesome.1579191227.css → font-awesome.1581523568.css} +0 -0
  51. modules/login-security/css/{ionicons.1579191227.css → ionicons.1581523568.css} +0 -0
  52. modules/login-security/css/{jquery-ui-timepicker-addon.1579191227.css → jquery-ui-timepicker-addon.1581523568.css} +0 -0
  53. modules/login-security/css/{jquery-ui.min.1579191227.css → jquery-ui.min.1581523568.css} +0 -0
  54. modules/login-security/css/{jquery-ui.structure.min.1579191227.css → jquery-ui.structure.min.1581523568.css} +0 -0
  55. modules/login-security/css/{jquery-ui.theme.min.1579191227.css → jquery-ui.theme.min.1581523568.css} +0 -0
  56. modules/login-security/css/{login.1579191227.css → login.1581523568.css} +0 -0
  57. modules/login-security/js/{admin-global.1579191227.js → admin-global.1581523568.js} +0 -0
  58. modules/login-security/js/{admin.1579191227.js → admin.1581523568.js} +0 -0
  59. modules/login-security/js/{jquery-ui-timepicker-addon.1579191227.js → jquery-ui-timepicker-addon.1581523568.js} +0 -0
  60. modules/login-security/js/{jquery.colorbox.1579191227.js → jquery.colorbox.1581523568.js} +0 -0
  61. modules/login-security/js/{jquery.colorbox.min.1579191227.js → jquery.colorbox.min.1581523568.js} +0 -0
  62. modules/login-security/js/{jquery.qrcode.min.1579191227.js → jquery.qrcode.min.1581523568.js} +0 -0
  63. modules/login-security/js/{jquery.tmpl.min.1579191227.js → jquery.tmpl.min.1581523568.js} +0 -0
  64. modules/login-security/js/{login.1579191227.js → login.1581523568.js} +0 -0
  65. modules/login-security/wordfence-login-security.php +1 -1
  66. readme.txt +11 -3
  67. vendor/wordfence/wf-waf/src/lib/parser/sqli.php +978 -263
  68. wordfence.php +3 -3
css/{activity-report-widget.1579191227.css → activity-report-widget.1581523568.css} RENAMED
File without changes
css/{diff.1579191227.css → diff.1581523568.css} RENAMED
File without changes
css/{dt_table.1579191227.css → dt_table.1581523568.css} RENAMED
File without changes
css/{fullLog.1579191227.css → fullLog.1581523568.css} RENAMED
File without changes
css/{iptraf.1579191227.css → iptraf.1581523568.css} RENAMED
File without changes
css/{jquery-ui-timepicker-addon.1579191227.css → jquery-ui-timepicker-addon.1581523568.css} RENAMED
File without changes
css/{jquery-ui.min.1579191227.css → jquery-ui.min.1581523568.css} RENAMED
File without changes
css/{jquery-ui.structure.min.1579191227.css → jquery-ui.structure.min.1581523568.css} RENAMED
File without changes
css/{jquery-ui.theme.min.1579191227.css → jquery-ui.theme.min.1581523568.css} RENAMED
File without changes
css/{main.1579191227.css → main.1581523568.css} RENAMED
File without changes
css/{phpinfo.1579191227.css → phpinfo.1581523568.css} RENAMED
File without changes
css/{wf-adminbar.1579191227.css → wf-adminbar.1581523568.css} RENAMED
File without changes
css/{wf-colorbox.1579191227.css → wf-colorbox.1581523568.css} RENAMED
File without changes
css/{wf-font-awesome.1579191227.css → wf-font-awesome.1581523568.css} RENAMED
File without changes
css/{wf-global.1579191227.css → wf-global.1581523568.css} RENAMED
File without changes
css/{wf-ionicons.1579191227.css → wf-ionicons.1581523568.css} RENAMED
File without changes
css/{wf-onboarding.1579191227.css → wf-onboarding.1581523568.css} RENAMED
File without changes
css/{wf-roboto-font.1579191227.css → wf-roboto-font.1581523568.css} RENAMED
File without changes
css/{wfselect2.min.1579191227.css → wfselect2.min.1581523568.css} RENAMED
File without changes
css/{wordfenceBox.1579191227.css → wordfenceBox.1581523568.css} RENAMED
File without changes
js/{Chart.bundle.min.1579191227.js → Chart.bundle.min.1581523568.js} RENAMED
File without changes
js/{admin.1579191227.js → admin.1581523568.js} RENAMED
@@ -1197,6 +1197,7 @@
1197
  self.liveTrafficUpdatePending = false;
1198
  }, true);
1199
  }
 
1200
  },
1201
  handleLiveTrafficReturn: function(res) {
1202
  this.liveTrafficUpdatePending = false;
1197
  self.liveTrafficUpdatePending = false;
1198
  }, true);
1199
  }
1200
+ this.liveTrafficUpdatePending = false;
1201
  },
1202
  handleLiveTrafficReturn: function(res) {
1203
  this.liveTrafficUpdatePending = false;
js/{admin.ajaxWatcher.1579191227.js → admin.ajaxWatcher.1581523568.js} RENAMED
File without changes
js/{admin.liveTraffic.1579191227.js → admin.liveTraffic.1581523568.js} RENAMED
File without changes
js/{date.1579191227.js → date.1581523568.js} RENAMED
File without changes
js/{jquery-ui-timepicker-addon.1579191227.js → jquery-ui-timepicker-addon.1581523568.js} RENAMED
File without changes
js/{jquery.colorbox-min.1579191227.js → jquery.colorbox-min.1581523568.js} RENAMED
File without changes
js/{jquery.colorbox.1579191227.js → jquery.colorbox.1581523568.js} RENAMED
File without changes
js/{jquery.dataTables.min.1579191227.js → jquery.dataTables.min.1581523568.js} RENAMED
File without changes
js/{jquery.qrcode.min.1579191227.js → jquery.qrcode.min.1581523568.js} RENAMED
File without changes
js/{jquery.tmpl.min.1579191227.js → jquery.tmpl.min.1581523568.js} RENAMED
File without changes
js/{jquery.tools.min.1579191227.js → jquery.tools.min.1581523568.js} RENAMED
File without changes
js/{knockout-3.3.0.1579191227.js → knockout-3.3.0.1581523568.js} RENAMED
File without changes
js/{wfdashboard.1579191227.js → wfdashboard.1581523568.js} RENAMED
File without changes
js/{wfdropdown.1579191227.js → wfdropdown.1581523568.js} RENAMED
File without changes
js/{wfglobal.1579191227.js → wfglobal.1581523568.js} RENAMED
File without changes
js/{wfpopover.1579191227.js → wfpopover.1581523568.js} RENAMED
File without changes
js/{wfselect2.min.1579191227.js → wfselect2.min.1581523568.js} RENAMED
File without changes
lib/GeoLite2-Country.mmdb CHANGED
Binary file
lib/menu_tools_livetraffic.php CHANGED
@@ -502,6 +502,11 @@ if (!wfConfig::liveTrafficEnabled($overridden)):
502
  $('#wf-live-traffic').toggleClass('wf-live-traffic-display-expanded', isOn);
503
  });
504
  });
 
 
 
 
 
505
  });
506
  })(jQuery);
507
  </script>
502
  $('#wf-live-traffic').toggleClass('wf-live-traffic-display-expanded', isOn);
503
  });
504
  });
505
+
506
+ $(document).on('heartbeat-tick', function(heartbeat) {
507
+ WFAD.serverMicrotime = heartbeat.timeStamp / 1000;
508
+ WFAD.updateTimeAgo();
509
+ })
510
  });
511
  })(jQuery);
512
  </script>
lib/wfBulkCountries.php CHANGED
@@ -123,8 +123,8 @@ $wfBulkCountries = array(
123
  "KI" => __("Kiribati", 'wordfence'),
124
  "KM" => __("Comoros", 'wordfence'),
125
  "KN" => __("Saint Kitts and Nevis", 'wordfence'),
126
- "KP" => __("Korea, Democratic Peoples Republic of", 'wordfence'),
127
- "KR" => __("Korea, Republic of", 'wordfence'),
128
  "KW" => __("Kuwait", 'wordfence'),
129
  "KY" => __("Cayman Islands", 'wordfence'),
130
  "KZ" => __("Kazakhstan", 'wordfence'),
123
  "KI" => __("Kiribati", 'wordfence'),
124
  "KM" => __("Comoros", 'wordfence'),
125
  "KN" => __("Saint Kitts and Nevis", 'wordfence'),
126
+ "KP" => __("North Korea", 'wordfence'),
127
+ "KR" => __("South Korea", 'wordfence'),
128
  "KW" => __("Kuwait", 'wordfence'),
129
  "KY" => __("Cayman Islands", 'wordfence'),
130
  "KZ" => __("Kazakhstan", 'wordfence'),
lib/wfCredentialsController.php CHANGED
@@ -157,7 +157,7 @@ class wfCredentialsController {
157
  return false;
158
  }
159
 
160
- $result = $wpdb->get_row($wpdb->prepare("SELECT id FROM {$table_wfLogins} WHERE action = 'loginOK' AND userID = %d AND IP = %s", $id, wfUtils::inet_pton($ip)), ARRAY_A);
161
  if (is_array($result)) {
162
  return true;
163
  }
157
  return false;
158
  }
159
 
160
+ $result = $wpdb->get_row($wpdb->prepare("SELECT id FROM {$table_wfLogins} WHERE action = 'loginOK' AND userID = %d AND IP = %s LIMIT 0,1", $id, wfUtils::inet_pton($ip)), ARRAY_A);
161
  if (is_array($result)) {
162
  return true;
163
  }
lib/wfIssues.php CHANGED
@@ -84,7 +84,7 @@ class wfIssues {
84
  );
85
 
86
  public static function validIssueTypes() {
87
- return array('checkHowGetIPs', 'checkSpamIP', 'commentBadURL', 'configReadable', 'coreUnknown', 'database', 'diskSpace', 'wafStatus', 'easyPassword', 'file', 'geoipSupport', 'knownfile', 'optionBadURL', 'postBadTitle', 'postBadURL', 'publiclyAccessible', 'spamvertizeCheck', 'suspiciousAdminUsers', 'timelimit', 'wfPluginAbandoned', 'wfPluginRemoved', 'wfPluginUpgrade', 'wfPluginVulnerable', 'wfThemeUpgrade', 'wfUpgrade', 'wpscan_directoryList', 'wpscan_fullPathDiscl');
88
  }
89
 
90
  public static function statusPrep(){
84
  );
85
 
86
  public static function validIssueTypes() {
87
+ return array('checkHowGetIPs', 'checkSpamIP', 'commentBadURL', 'configReadable', 'coreUnknown', 'database', 'diskSpace', 'wafStatus', 'easyPassword', 'file', 'geoipSupport', 'knownfile', 'optionBadURL', 'postBadTitle', 'postBadURL', 'publiclyAccessible', 'spamvertizeCheck', 'suspiciousAdminUsers', 'timelimit', 'wfPluginAbandoned', 'wfPluginRemoved', 'wfPluginUpgrade', 'wfPluginVulnerable', 'wfThemeUpgrade', 'wfUpgrade', 'wpscan_directoryList', 'wpscan_fullPathDiscl', 'skippedPaths');
88
  }
89
 
90
  public static function statusPrep(){
lib/wfScanEngine.php CHANGED
@@ -825,7 +825,7 @@ class wfScanEngine {
825
  private function scan_checkSkippedFiles() {
826
  $haveIssues = wfIssues::STATUS_SECURE;
827
  $status = wfIssues::statusStart("Checking for paths skipped due to scan settings");
828
- $this->scanController->startStage(wfScanner::STAGE_MALWARE_SCAN);
829
 
830
  $paths = $this->_scannedSkippedPaths();
831
  if (!empty($paths['skipped'])) {
@@ -868,7 +868,7 @@ class wfScanEngine {
868
  }
869
 
870
  wfIssues::statusEnd($status, $haveIssues);
871
- $this->scanController->completeStage(wfScanner::STAGE_MALWARE_SCAN, $haveIssues);
872
  }
873
  private function scan_knownFiles_init(){
874
  $paths = $this->_scannedSkippedPaths();
825
  private function scan_checkSkippedFiles() {
826
  $haveIssues = wfIssues::STATUS_SECURE;
827
  $status = wfIssues::statusStart("Checking for paths skipped due to scan settings");
828
+ $this->scanController->startStage(wfScanner::STAGE_SERVER_STATE);
829
 
830
  $paths = $this->_scannedSkippedPaths();
831
  if (!empty($paths['skipped'])) {
868
  }
869
 
870
  wfIssues::statusEnd($status, $haveIssues);
871
+ $this->scanController->completeStage(wfScanner::STAGE_SERVER_STATE, $haveIssues);
872
  }
873
  private function scan_knownFiles_init(){
874
  $paths = $this->_scannedSkippedPaths();
lib/wordfenceClass.php CHANGED
@@ -281,14 +281,14 @@ class wordfence {
281
 
282
  self::trimWfHits();
283
 
284
- $maxRows = 1000; //affects stuff further down too
285
 
286
  $table_wfLogins = wfDB::networkTable('wfLogins');
287
  $count2 = $wfdb->querySingle("select count(*) as cnt from {$table_wfLogins}");
288
  if($count2 > 20000){
289
  $wfdb->truncate($table_wfLogins); //in case of Dos
290
  } else if($count2 > $maxRows){
291
- $wfdb->queryWrite("delete from {$table_wfLogins} order by ctime asc limit %d", ($count2 - 100));
292
  }
293
 
294
  $table_wfReverseCache = wfDB::networkTable('wfReverseCache');
281
 
282
  self::trimWfHits();
283
 
284
+ $maxRows = absint(wfConfig::get('liveTraf_maxRows', 2000));; //affects stuff further down too
285
 
286
  $table_wfLogins = wfDB::networkTable('wfLogins');
287
  $count2 = $wfdb->querySingle("select count(*) as cnt from {$table_wfLogins}");
288
  if($count2 > 20000){
289
  $wfdb->truncate($table_wfLogins); //in case of Dos
290
  } else if($count2 > $maxRows){
291
+ $wfdb->queryWrite("delete from {$table_wfLogins} order by ctime asc limit %d", ($count2 - $maxRows));
292
  }
293
 
294
  $table_wfReverseCache = wfDB::networkTable('wfReverseCache');
models/scanner/wfScanner.php CHANGED
@@ -498,6 +498,11 @@ class wfScanner {
498
  );
499
  break;
500
  case self::STAGE_SERVER_STATE:
 
 
 
 
 
501
  $options = array(
502
  'scansEnabled_checkHowGetIPs',
503
  'scansEnabled_diskSpace',
@@ -520,11 +525,6 @@ class wfScanner {
520
  );
521
  break;
522
  case self::STAGE_MALWARE_SCAN:
523
- if ($this->scanType() != self::SCAN_TYPE_QUICK) {
524
- $always = array(
525
- 'checkSkippedFiles',
526
- );
527
- }
528
  $options = array(
529
  'scansEnabled_malware',
530
  'scansEnabled_fileContents',
498
  );
499
  break;
500
  case self::STAGE_SERVER_STATE:
501
+ if ($this->scanType() != self::SCAN_TYPE_QUICK) {
502
+ $always = array(
503
+ 'checkSkippedFiles',
504
+ );
505
+ }
506
  $options = array(
507
  'scansEnabled_checkHowGetIPs',
508
  'scansEnabled_diskSpace',
525
  );
526
  break;
527
  case self::STAGE_MALWARE_SCAN:
 
 
 
 
 
528
  $options = array(
529
  'scansEnabled_malware',
530
  'scansEnabled_fileContents',
modules/login-security/css/{admin-global.1579191227.css → admin-global.1581523568.css} RENAMED
File without changes
modules/login-security/css/{admin.1579191227.css → admin.1581523568.css} RENAMED
File without changes
modules/login-security/css/{colorbox.1579191227.css → colorbox.1581523568.css} RENAMED
File without changes
modules/login-security/css/{font-awesome.1579191227.css → font-awesome.1581523568.css} RENAMED
File without changes
modules/login-security/css/{ionicons.1579191227.css → ionicons.1581523568.css} RENAMED
File without changes
modules/login-security/css/{jquery-ui-timepicker-addon.1579191227.css → jquery-ui-timepicker-addon.1581523568.css} RENAMED
File without changes
modules/login-security/css/{jquery-ui.min.1579191227.css → jquery-ui.min.1581523568.css} RENAMED
File without changes
modules/login-security/css/{jquery-ui.structure.min.1579191227.css → jquery-ui.structure.min.1581523568.css} RENAMED
File without changes
modules/login-security/css/{jquery-ui.theme.min.1579191227.css → jquery-ui.theme.min.1581523568.css} RENAMED
File without changes
modules/login-security/css/{login.1579191227.css → login.1581523568.css} RENAMED
File without changes
modules/login-security/js/{admin-global.1579191227.js → admin-global.1581523568.js} RENAMED
File without changes
modules/login-security/js/{admin.1579191227.js → admin.1581523568.js} RENAMED
File without changes
modules/login-security/js/{jquery-ui-timepicker-addon.1579191227.js → jquery-ui-timepicker-addon.1581523568.js} RENAMED
File without changes
modules/login-security/js/{jquery.colorbox.1579191227.js → jquery.colorbox.1581523568.js} RENAMED
File without changes
modules/login-security/js/{jquery.colorbox.min.1579191227.js → jquery.colorbox.min.1581523568.js} RENAMED
File without changes
modules/login-security/js/{jquery.qrcode.min.1579191227.js → jquery.qrcode.min.1581523568.js} RENAMED
File without changes
modules/login-security/js/{jquery.tmpl.min.1579191227.js → jquery.tmpl.min.1581523568.js} RENAMED
File without changes
modules/login-security/js/{login.1579191227.js → login.1581523568.js} RENAMED
File without changes
modules/login-security/wordfence-login-security.php CHANGED
@@ -27,7 +27,7 @@ else {
27
  define('WORDFENCE_LS_FROM_CORE', ($wfCoreActive && isset($wfCoreLoading) && $wfCoreLoading));
28
 
29
  define('WORDFENCE_LS_VERSION', '1.0.5');
30
- define('WORDFENCE_LS_BUILD_NUMBER', '1579191227');
31
 
32
  if (!defined('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES')) { define('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES', 15); }
33
 
27
  define('WORDFENCE_LS_FROM_CORE', ($wfCoreActive && isset($wfCoreLoading) && $wfCoreLoading));
28
 
29
  define('WORDFENCE_LS_VERSION', '1.0.5');
30
+ define('WORDFENCE_LS_BUILD_NUMBER', '1581523568');
31
 
32
  if (!defined('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES')) { define('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES', 15); }
33
 
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: mmaunder, wfryan, wfmatt, wfmattr
3
  Tags: security, firewall, malware scanner, web application firewall, two factor authentication, block hackers, country blocking, clean hacked site, blacklist, waf, login security
4
  Requires at least: 3.9
5
  Requires PHP: 5.3
6
- Tested up to: 5.3
7
- Stable tag: 7.4.5
8
 
9
  Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
10
 
@@ -183,8 +183,16 @@ Secure your website with Wordfence.
183
 
184
  == Changelog ==
185
 
 
 
 
 
 
 
 
 
186
  = 7.4.5 - January 15, 2020 =
187
- * Improvement: Improved WAF coverage for an Infinite WP authentication bypass vulnerability. Credit to Marc Montpas for finding a bypass.
188
 
189
  = 7.4.4 - January 14, 2020 =
190
  * Fix: Fixed a UI issue where the scan summary status marker for malware didn't always match the findings.
3
  Tags: security, firewall, malware scanner, web application firewall, two factor authentication, block hackers, country blocking, clean hacked site, blacklist, waf, login security
4
  Requires at least: 3.9
5
  Requires PHP: 5.3
6
+ Tested up to: 5.4
7
+ Stable tag: 7.4.6
8
 
9
  Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
10
 
183
 
184
  == Changelog ==
185
 
186
+ = 7.4.6 - February 12, 2020 =
187
+ * Improvement: Enhanced the detection ability of the WAF for SQLi attacks.
188
+ * Improvement: Updated the bundled GeoIP database.
189
+ * Improvement: Modified some country names in the block configuration to align with those shown in Live Traffic.
190
+ * Change: Moved the skipped files scan check to the Server State category.
191
+ * Fix: Fixed an issue where after scrolling on the Live Traffic page, updates would no longer automatically load.
192
+ * Fix: Modified the number of login records kept to align better with Live Traffic so they're trimmed around the same time.
193
+
194
  = 7.4.5 - January 15, 2020 =
195
+ * Improvement: Improved WAF coverage for an Infinite WP authentication bypass vulnerability.
196
 
197
  = 7.4.4 - January 14, 2020 =
198
  * Fix: Fixed a UI issue where the scan summary status marker for malware didn't always match the findings.
vendor/wordfence/wf-waf/src/lib/parser/sqli.php CHANGED
@@ -138,240 +138,801 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
138
  'YEAR_MONTH',
139
  );
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  private $keywords = array(
142
- 'ID',
143
- 'TIME',
144
- 'DATE',
145
- 'SQLTIME',
146
- 'ACCESSIBLE',
147
- 'ADD',
148
- 'ALL',
149
- 'ALTER',
150
- 'ANALYZE',
151
- 'AND',
152
- 'AS',
153
- 'ASC',
154
- 'ASENSITIVE',
155
- 'BEFORE',
156
- 'BETWEEN',
157
- 'BIGINT',
158
- 'BINARY',
159
- 'BLOB',
160
- 'BOTH',
161
- 'BY',
162
- 'CALL',
163
- 'CASCADE',
164
- 'CASE',
165
- 'CHANGE',
166
- 'CHAR',
167
- 'CHARACTER',
168
- 'CHECK',
169
- 'COLLATE',
170
- 'COLUMN',
171
- 'CONDITION',
172
- 'CONSTRAINT',
173
- 'CONTINUE',
174
- 'CONVERT',
175
- 'CREATE',
176
- 'CROSS',
177
- 'CURRENT_DATE',
178
- 'CURRENT_TIME',
179
- 'CURRENT_TIMESTAMP',
180
- 'CURRENT_USER',
181
- 'CURSOR',
182
- 'DATABASE',
183
- 'DATABASES',
184
- 'DAY_HOUR',
185
- 'DAY_MICROSECOND',
186
- 'DAY_MINUTE',
187
- 'DAY_SECOND',
188
- 'DEC',
189
- 'DECIMAL',
190
- 'DECLARE',
191
- 'DEFAULT',
192
- 'DELAYED',
193
- 'DELETE',
194
- 'DESC',
195
- 'DESCRIBE',
196
- 'DETERMINISTIC',
197
- 'DISTINCT',
198
- 'DISTINCTROW',
199
- 'DIV',
200
- 'DOUBLE',
201
- 'DROP',
202
- 'DUAL',
203
- 'EACH',
204
- 'ELSE',
205
- 'ELSEIF',
206
- 'ENCLOSED',
207
- 'ESCAPED',
208
- 'EXISTS',
209
- 'EXIT',
210
- 'EXPLAIN',
211
- 'FALSE',
212
- 'FETCH',
213
- 'FLOAT',
214
- 'FLOAT4',
215
- 'FLOAT8',
216
- 'FOR',
217
- 'FORCE',
218
- 'FOREIGN',
219
- 'FROM',
220
- 'FULLTEXT',
221
- 'GRANT',
222
- 'GROUP',
223
- 'HAVING',
224
- 'HIGH_PRIORITY',
225
- 'HOUR_MICROSECOND',
226
- 'HOUR_MINUTE',
227
- 'HOUR_SECOND',
228
- 'IF',
229
- 'IGNORE',
230
- 'IN',
231
- 'INDEX',
232
- 'INFILE',
233
- 'INNER',
234
- 'INOUT',
235
- 'INSENSITIVE',
236
- 'INSERT',
237
- 'INT',
238
- 'INT1',
239
- 'INT2',
240
- 'INT3',
241
- 'INT4',
242
- 'INT8',
243
- 'INTEGER',
244
- 'INTERVAL',
245
- 'INTO',
246
- 'IS',
247
- 'ITERATE',
248
- 'JOIN',
249
- 'KEY',
250
- 'KEYS',
251
- 'KILL',
252
- 'LEADING',
253
- 'LEAVE',
254
- 'LEFT',
255
- 'LIKE',
256
- 'LIMIT',
257
- 'LINEAR',
258
- 'LINES',
259
- 'LOAD',
260
- 'LOCALTIME',
261
- 'LOCALTIMESTAMP',
262
- 'LOCK',
263
- 'LONG',
264
- 'LONGBLOB',
265
- 'LONGTEXT',
266
- 'LOOP',
267
- 'LOW_PRIORITY',
268
- 'MASTER_SSL_VERIFY_SERVER_CERT',
269
- 'MATCH',
270
- 'MEDIUMBLOB',
271
- 'MEDIUMINT',
272
- 'MEDIUMTEXT',
273
- 'MIDDLEINT',
274
- 'MINUTE_MICROSECOND',
275
- 'MINUTE_SECOND',
276
- 'MOD',
277
- 'MODIFIES',
278
- 'NATURAL',
279
- 'NOT',
280
- 'NO_WRITE_TO_BINLOG',
281
- 'NULL',
282
- 'NUMERIC',
283
- 'ON',
284
- 'OPTIMIZE',
285
- 'OPTION',
286
- 'OPTIONALLY',
287
- 'OR',
288
- 'ORDER',
289
- 'OUT',
290
- 'OUTER',
291
- 'OUTFILE',
292
- 'PRECISION',
293
- 'PRIMARY',
294
- 'PROCEDURE',
295
- 'PURGE',
296
- 'RANGE',
297
- 'READ',
298
- 'READS',
299
- 'READ_WRITE',
300
- 'REAL',
301
- 'REFERENCES',
302
- 'REGEXP',
303
- 'RELEASE',
304
- 'RENAME',
305
- 'REPEAT',
306
- 'REPLACE',
307
- 'REQUIRE',
308
- 'RESTRICT',
309
- 'RETURN',
310
- 'REVOKE',
311
- 'RIGHT',
312
- 'RLIKE',
313
- 'SCHEMA',
314
- 'SCHEMAS',
315
- 'SECOND_MICROSECOND',
316
- 'SELECT',
317
- 'SENSITIVE',
318
- 'SEPARATOR',
319
- 'SET',
320
- 'SHOW',
321
- 'SMALLINT',
322
- 'SPATIAL',
323
- 'SPECIFIC',
324
- 'SQL',
325
- 'SQLEXCEPTION',
326
- 'SQLSTATE',
327
- 'SQLWARNING',
328
- 'SQL_BIG_RESULT',
329
- 'SQL_CALC_FOUND_ROWS',
330
- 'SQL_SMALL_RESULT',
331
- 'SSL',
332
- 'STARTING',
333
- 'STRAIGHT_JOIN',
334
- 'TABLE',
335
- 'TERMINATED',
336
- 'THEN',
337
- 'TINYBLOB',
338
- 'TINYINT',
339
- 'TINYTEXT',
340
- 'TO',
341
- 'TRAILING',
342
- 'TRIGGER',
343
- 'TRUE',
344
- 'UNDO',
345
- 'UNION',
346
- 'UNIQUE',
347
- 'UNLOCK',
348
- 'UNSIGNED',
349
- 'UPDATE',
350
- 'USAGE',
351
- 'USE',
352
- 'USING',
353
- 'UTC_DATE',
354
- 'UTC_TIME',
355
- 'UTC_TIMESTAMP',
356
- 'VALUES',
357
- 'VARBINARY',
358
- 'VARCHAR',
359
- 'VARCHARACTER',
360
- 'VARYING',
361
- 'WHEN',
362
- 'WHERE',
363
- 'WHILE',
364
- 'WITH',
365
- 'WRITE',
366
- 'XOR',
367
- 'YEAR_MONTH',
368
- 'ZEROFILL',
369
- 'ACCESSIBLE',
370
- 'LINEAR',
371
- 'MASTER_SSL_VERIFY_SERVER_CERT',
372
- 'RANGE',
373
- 'READ_ONLY',
374
- 'READ_WRITE',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  );
376
 
377
  private $numberFunctions = array(
@@ -1181,6 +1742,15 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1181
  }
1182
  $this->index = $savePoint;
1183
 
 
 
 
 
 
 
 
 
 
1184
  $nextToken = $this->nextToken();
1185
  if ($nextToken) {
1186
  switch ($nextToken->getType()) {
@@ -1188,7 +1758,8 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1188
  case wfWAFSQLiLexer::BINARY_NUMBER_LITERAL:
1189
  case wfWAFSQLiLexer::HEX_NUMBER_LITERAL:
1190
  case wfWAFSQLiLexer::REAL_NUMBER_LITERAL:
1191
- return true;
 
1192
  // Allow concatenation: 'test' 'test' is valid
1193
  case wfWAFSQLiLexer::DOUBLE_STRING_LITERAL:
1194
  case wfWAFSQLiLexer::SINGLE_STRING_LITERAL:
@@ -1200,15 +1771,32 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1200
  $savePoint = $this->index;
1201
  }
1202
  $this->index = $savePoint;
1203
- return true;
 
1204
 
1205
  case wfWAFSQLiLexer::UNQUOTED_IDENTIFIER:
1206
  if ($nextToken->getLowerCaseValue() === 'null') {
1207
- return true;
1208
  }
1209
  break;
1210
  }
1211
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1212
  $this->index = $startIndex;
1213
  return false;
1214
  }
@@ -1256,6 +1844,7 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1256
  if ($this->parseExpression() &&
1257
  $this->isIdentifierWithValue($this->nextToken(), 'as') &&
1258
  $this->parseCastDataType() &&
 
1259
  $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::CLOSE_PARENTHESIS)
1260
  ) {
1261
  return true;
@@ -1267,6 +1856,7 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1267
  $savePoint = $this->index;
1268
  if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::COMMA) &&
1269
  $this->parseCastDataType() &&
 
1270
  $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::CLOSE_PARENTHESIS)
1271
  ) {
1272
  return true;
@@ -1275,6 +1865,7 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1275
  $savePoint = $this->index;
1276
  if ($this->isIdentifierWithValue($this->nextToken(), 'using') &&
1277
  $this->parseTranscodingName() &&
 
1278
  $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::CLOSE_PARENTHESIS)
1279
  ) {
1280
  return true;
@@ -1283,6 +1874,77 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1283
  }
1284
  break;
1285
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1286
  default:
1287
  $savePoint = $this->index;
1288
  if (in_array($functionToken->getUpperCaseValue(), $this->groupFunctions)) {
@@ -1301,7 +1963,15 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1301
  $this->index = $savePoint;
1302
 
1303
  while ($this->parseExpression()) {
1304
- if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::COMMA)) {
 
 
 
 
 
 
 
 
1305
  continue;
1306
  }
1307
  $this->index--;
@@ -1338,8 +2008,14 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1338
  switch ($token->getLowerCaseValue()) {
1339
  case 'binary':
1340
  case 'char':
 
 
 
1341
  $savePoint = $this->index;
1342
- if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::INTEGER_LITERAL)) {
 
 
 
1343
  return true;
1344
  }
1345
  $this->index = $savePoint;
@@ -1352,20 +2028,30 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1352
 
1353
  case 'signed':
1354
  case 'unsigned':
1355
- if (!$this->isIdentifierWithValue($this->nextToken(), 'integer')) {
 
 
 
1356
  $this->index--;
1357
  }
1358
  return true;
1359
 
1360
  case 'decimal':
1361
  $savePoint = $this->index;
1362
- while ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::INTEGER_LITERAL)) {
1363
- if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::COMMA)) {
1364
- continue;
 
 
 
 
 
 
 
 
1365
  }
1366
- $this->index--;
1367
- return true;
1368
  }
 
1369
  $this->index = $savePoint;
1370
  return true;
1371
  }
@@ -1378,12 +2064,24 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1378
  $savePoint = $this->index;
1379
  $token = $this->nextToken();
1380
  if ($token && $token->getType() === wfWAFSQLiLexer::UNQUOTED_IDENTIFIER) {
1381
- return false;
1382
  }
1383
  $this->index = $savePoint;
1384
  return false;
1385
  }
1386
 
 
 
 
 
 
 
 
 
 
 
 
 
1387
  private function parseVariable() {
1388
  $nextToken = $this->nextToken();
1389
  if ($nextToken && $nextToken->getType() === wfWAFSQLiLexer::VARIABLE) {
@@ -1760,9 +2458,7 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1760
  private function parsePartitionName() {
1761
  $startPoint = $this->index;
1762
  $token = $this->nextToken();
1763
- if ($this->isTokenOfType($token, wfWAFSQLiLexer::QUOTED_IDENTIFIER) ||
1764
- $this->isValidNonKeywordIdentifier($token)
1765
- ) {
1766
  return true;
1767
  }
1768
  $this->index = $startPoint;
@@ -1884,20 +2580,19 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1884
  private function parseTableSpec() {
1885
  $savePoint = $this->index;
1886
  if ($this->isTokenOfType($this->nextToken(), array(
1887
- wfWAFSQLiLexer::UNQUOTED_IDENTIFIER,
1888
- wfWAFSQLiLexer::QUOTED_IDENTIFIER,
1889
- ))
 
 
 
 
 
1890
  ) {
1891
- $savePoint = $this->index;
1892
- if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::DOT) &&
1893
- $this->isTokenOfType($this->nextToken(), array(
1894
- wfWAFSQLiLexer::UNQUOTED_IDENTIFIER,
1895
- wfWAFSQLiLexer::QUOTED_IDENTIFIER,
1896
- ))
1897
- ) {
1898
- return true;
1899
- }
1900
- $this->index = $savePoint;
1901
  return true;
1902
  }
1903
  $this->index = $savePoint;
@@ -1913,7 +2608,7 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
1913
  if ($this->isIdentifierWithValue($token, 'as')) {
1914
  $token = $this->nextToken();
1915
  }
1916
- if ($this->isValidNonKeywordIdentifier($token)) {
1917
  return true;
1918
  }
1919
  $this->index = $savePoint;
@@ -2051,7 +2746,7 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
2051
  private function parseIndexName() {
2052
  $startPoint = $this->index;
2053
  $token = $this->nextToken();
2054
- if ($this->isValidNonKeywordIdentifier($token)) {
2055
  return true;
2056
  }
2057
  $this->index = $startPoint;
@@ -2620,6 +3315,15 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
2620
  in_array($token->getUpperCaseValue(), $this->keywords);
2621
  }
2622
 
 
 
 
 
 
 
 
 
 
2623
  /**
2624
  * @param wfWAFLexerToken $token
2625
  * @return bool
@@ -2631,6 +3335,17 @@ class wfWAFSQLiParser extends wfWAFBaseParser {
2631
  );
2632
  }
2633
 
 
 
 
 
 
 
 
 
 
 
 
2634
  /**
2635
  * @param wfWAFLexerToken $token
2636
  * @return bool
138
  'YEAR_MONTH',
139
  );
140
 
141
+ private $reservedWords = array(
142
+ "_FILENAME",
143
+ "ACCESSIBLE",
144
+ "ADD",
145
+ "ALL",
146
+ "ALTER",
147
+ "ANALYZE",
148
+ "AND",
149
+ "AS",
150
+ "ASC",
151
+ "ASENSITIVE",
152
+ "BEFORE",
153
+ "BETWEEN",
154
+ "BIGINT",
155
+ "BINARY",
156
+ "BLOB",
157
+ "BOTH",
158
+ "BY",
159
+ "CALL",
160
+ "CASCADE",
161
+ "CASE",
162
+ "CHANGE",
163
+ "CHAR",
164
+ "CHARACTER",
165
+ "CHECK",
166
+ "COLLATE",
167
+ "COLUMN",
168
+ "CONDITION",
169
+ "CONSTRAINT",
170
+ "CONTINUE",
171
+ "CONVERT",
172
+ "CREATE",
173
+ "CROSS",
174
+ "CURRENT_DATE",
175
+ "CURRENT_TIME",
176
+ "CURRENT_TIMESTAMP",
177
+ "CURRENT_USER",
178
+ "CURSOR",
179
+ "DATABASE",
180
+ "DATABASES",
181
+ "DAY_HOUR",
182
+ "DAY_MICROSECOND",
183
+ "DAY_MINUTE",
184
+ "DAY_SECOND",
185
+ "DEC",
186
+ "DECIMAL",
187
+ "DECLARE",
188
+ "DEFAULT",
189
+ "DELAYED",
190
+ "DELETE",
191
+ "DESC",
192
+ "DESCRIBE",
193
+ "DETERMINISTIC",
194
+ "DISTINCT",
195
+ "DISTINCTROW",
196
+ "DIV",
197
+ "DOUBLE",
198
+ "DROP",
199
+ // "DUAL", // works as a table name ???
200
+ "EACH",
201
+ "ELSE",
202
+ "ELSEIF",
203
+ "ENCLOSED",
204
+ "ESCAPED",
205
+ "EXISTS",
206
+ "EXIT",
207
+ "EXPLAIN",
208
+ "FALSE",
209
+ "FETCH",
210
+ "FLOAT",
211
+ "FLOAT4",
212
+ "FLOAT8",
213
+ "FOR",
214
+ "FORCE",
215
+ "FOREIGN",
216
+ "FROM",
217
+ "FULLTEXT",
218
+ "GRANT",
219
+ "GROUP",
220
+ "HAVING",
221
+ "HIGH_PRIORITY",
222
+ "HOUR_MICROSECOND",
223
+ "HOUR_MINUTE",
224
+ "HOUR_SECOND",
225
+ "IF",
226
+ "IGNORE",
227
+ "IN",
228
+ "INDEX",
229
+ "INFILE",
230
+ "INNER",
231
+ "INOUT",
232
+ "INSENSITIVE",
233
+ "INSERT",
234
+ "INT",
235
+ "INT1",
236
+ "INT2",
237
+ "INT3",
238
+ "INT4",
239
+ "INT8",
240
+ "INTEGER",
241
+ "INTERVAL",
242
+ "INTO",
243
+ "IS",
244
+ "ITERATE",
245
+ "JOIN",
246
+ "KEY",
247
+ "KEYS",
248
+ "KILL",
249
+ "LEADING",
250
+ "LEAVE",
251
+ "LEFT",
252
+ "LIKE",
253
+ "LIMIT",
254
+ "LINEAR",
255
+ "LINES",
256
+ "LOAD",
257
+ "LOCALTIME",
258
+ "LOCALTIMESTAMP",
259
+ "LOCK",
260
+ "LONG",
261
+ "LONGBLOB",
262
+ "LONGTEXT",
263
+ "LOOP",
264
+ "LOW_PRIORITY",
265
+ "MASTER_SSL_VERIFY_SERVER_CERT",
266
+ "MATCH",
267
+ "MAXVALUE",
268
+ "MEDIUMBLOB",
269
+ "MEDIUMINT",
270
+ "MEDIUMTEXT",
271
+ "MIDDLEINT",
272
+ "MINUTE_MICROSECOND",
273
+ "MINUTE_SECOND",
274
+ "MOD",
275
+ "MODIFIES",
276
+ "NATURAL",
277
+ "NOT",
278
+ "NO_WRITE_TO_BINLOG",
279
+ "NULL",
280
+ "NUMERIC",
281
+ "ON",
282
+ "OPTIMIZE",
283
+ "OPTION",
284
+ "OPTIONALLY",
285
+ "OR",
286
+ "ORDER",
287
+ "OUT",
288
+ "OUTER",
289
+ "OUTFILE",
290
+ "PRECISION",
291
+ "PRIMARY",
292
+ "PROCEDURE",
293
+ "PURGE",
294
+ "RANGE",
295
+ "READ",
296
+ "READS",
297
+ "READ_WRITE",
298
+ "REAL",
299
+ "REFERENCES",
300
+ "REGEXP",
301
+ "RELEASE",
302
+ "RENAME",
303
+ "REPEAT",
304
+ "REPLACE",
305
+ "REQUIRE",
306
+ "RESIGNAL",
307
+ "RESTRICT",
308
+ "RETURN",
309
+ "REVOKE",
310
+ "RIGHT",
311
+ "RLIKE",
312
+ "SCHEMA",
313
+ "SCHEMAS",
314
+ "SECOND_MICROSECOND",
315
+ "SELECT",
316
+ "SENSITIVE",
317
+ "SEPARATOR",
318
+ "SET",
319
+ "SHOW",
320
+ "SIGNAL",
321
+ "SMALLINT",
322
+ "SPATIAL",
323
+ "SPECIFIC",
324
+ "SQL",
325
+ "SQLEXCEPTION",
326
+ "SQLSTATE",
327
+ "SQLWARNING",
328
+ "SQL_BIG_RESULT",
329
+ "SQL_CALC_FOUND_ROWS",
330
+ "SQL_SMALL_RESULT",
331
+ "SSL",
332
+ "STARTING",
333
+ "STRAIGHT_JOIN",
334
+ "TABLE",
335
+ "TERMINATED",
336
+ "THEN",
337
+ "TINYBLOB",
338
+ "TINYINT",
339
+ "TINYTEXT",
340
+ "TO",
341
+ "TRAILING",
342
+ "TRIGGER",
343
+ "TRUE",
344
+ "UNDO",
345
+ "UNION",
346
+ "UNIQUE",
347
+ "UNLOCK",
348
+ "UNSIGNED",
349
+ "UPDATE",
350
+ "USAGE",
351
+ "USE",
352
+ "USING",
353
+ "UTC_DATE",
354
+ "UTC_TIME",
355
+ "UTC_TIMESTAMP",
356
+ "VALUES",
357
+ "VARBINARY",
358
+ "VARCHAR",
359
+ "VARCHARACTER",
360
+ "VARYING",
361
+ "WHEN",
362
+ "WHERE",
363
+ "WHILE",
364
+ "WITH",
365
+ "WRITE",
366
+ "XOR",
367
+ "YEAR_MONTH",
368
+ "ZEROFILL",
369
+ );
370
  private $keywords = array(
371
+ "ACCESSIBLE",
372
+ "ACTION",
373
+ "ADD",
374
+ "AFTER",
375
+ "AGAINST",
376
+ "AGGREGATE",
377
+ "ALGORITHM",
378
+ "ALL",
379
+ "ALTER",
380
+ "ANALYZE",
381
+ "AND",
382
+ "ANY",
383
+ "AS",
384
+ "ASC",
385
+ "ASCII",
386
+ "ASENSITIVE",
387
+ "AT",
388
+ "AUTHORS",
389
+ "AUTOEXTEND_SIZE",
390
+ "AUTO_INCREMENT",
391
+ "AVG",
392
+ "AVG_ROW_LENGTH",
393
+ "BACKUP",
394
+ "BEFORE",
395
+ "BEGIN",
396
+ "BETWEEN",
397
+ "BIGINT",
398
+ "BINARY",
399
+ "BINLOG",
400
+ "BIT",
401
+ "BLOB",
402
+ "BLOCK",
403
+ "BOOL",
404
+ "BOOLEAN",
405
+ "BOTH",
406
+ "BTREE",
407
+ "BY",
408
+ "BYTE",
409
+ "CACHE",
410
+ "CALL",
411
+ "CASCADE",
412
+ "CASCADED",
413
+ "CASE",
414
+ "CATALOG_NAME",
415
+ "CHAIN",
416
+ "CHANGE",
417
+ "CHANGED",
418
+ "CHAR",
419
+ "CHARACTER",
420
+ "CHARSET",
421
+ "CHECK",
422
+ "CHECKSUM",
423
+ "CIPHER",
424
+ "CLASS_ORIGIN",
425
+ "CLIENT",
426
+ "CLOSE",
427
+ "COALESCE",
428
+ "CODE",
429
+ "COLLATE",
430
+ "COLLATION",
431
+ "COLUMN",
432
+ "COLUMNS",
433
+ "COLUMN_NAME",
434
+ "COMMENT",
435
+ "COMMIT",
436
+ "COMMITTED",
437
+ "COMPACT",
438
+ "COMPLETION",
439
+ "COMPRESSED",
440
+ "CONCURRENT",
441
+ "CONDITION",
442
+ "CONNECTION",
443
+ "CONSISTENT",
444
+ "CONSTRAINT",
445
+ "CONSTRAINT_CATALOG",
446
+ "CONSTRAINT_NAME",
447
+ "CONSTRAINT_SCHEMA",
448
+ "CONTAINS",
449
+ "CONTEXT",
450
+ "CONTINUE",
451
+ "CONTRIBUTORS",
452
+ "CONVERT",
453
+ "CPU",
454
+ "CREATE",
455
+ "CROSS",
456
+ "CUBE",
457
+ "CURRENT_DATE",
458
+ "CURRENT_TIME",
459
+ "CURRENT_TIMESTAMP",
460
+ "CURRENT_USER",
461
+ "CURSOR",
462
+ "CURSOR_NAME",
463
+ "DATA",
464
+ "DATABASE",
465
+ "DATABASES",
466
+ "DATAFILE",
467
+ "DATE",
468
+ "DATETIME",
469
+ "DAY",
470
+ "DAY_HOUR",
471
+ "DAY_MICROSECOND",
472
+ "DAY_MINUTE",
473
+ "DAY_SECOND",
474
+ "DEALLOCATE",
475
+ "DEC",
476
+ "DECIMAL",
477
+ "DECLARE",
478
+ "DEFAULT",
479
+ "DEFINER",
480
+ "DELAYED",
481
+ "DELAY_KEY_WRITE",
482
+ "DELETE",
483
+ "DESC",
484
+ "DESCRIBE",
485
+ "DES_KEY_FILE",
486
+ "DETERMINISTIC",
487
+ "DIRECTORY",
488
+ "DISABLE",
489
+ "DISCARD",
490
+ "DISK",
491
+ "DISTINCT",
492
+ "DISTINCTROW",
493
+ "DIV",
494
+ "DO",
495
+ "DOUBLE",
496
+ "DROP",
497
+ "DUAL",
498
+ "DUMPFILE",
499
+ "DUPLICATE",
500
+ "DYNAMIC",
501
+ "EACH",
502
+ "ELSE",
503
+ "ELSEIF",
504
+ "ENABLE",
505
+ "ENCLOSED",
506
+ "END",
507
+ "ENDS",
508
+ "ENGINE",
509
+ "ENGINES",
510
+ "ENUM",
511
+ "ERROR",
512
+ "ERRORS",
513
+ "ESCAPE",
514
+ "ESCAPED",
515
+ "EVENT",
516
+ "EVENTS",
517
+ "EVERY",
518
+ "EXECUTE",
519
+ "EXISTS",
520
+ "EXIT",
521
+ "EXPANSION",
522
+ "EXPLAIN",
523
+ "EXTENDED",
524
+ "EXTENT_SIZE",
525
+ "FALSE",
526
+ "FAST",
527
+ "FAULTS",
528
+ "FETCH",
529
+ "FIELDS",
530
+ "FILE",
531
+ "FIRST",
532
+ "FIXED",
533
+ "FLOAT",
534
+ "FLOAT4",
535
+ "FLOAT8",
536
+ "FLUSH",
537
+ "FOR",
538
+ "FORCE",
539
+ "FOREIGN",
540
+ "FOUND",
541
+ "FRAC_SECOND",
542
+ "FROM",
543
+ "FULL",
544
+ "FULLTEXT",
545
+ "FUNCTION",
546
+ "GENERAL",
547
+ "GEOMETRY",
548
+ "GEOMETRYCOLLECTION",
549
+ "GET_FORMAT",
550
+ "GLOBAL",
551
+ "GRANT",
552
+ "GRANTS",
553
+ "GROUP",
554
+ "HANDLER",
555
+ "HASH",
556
+ "HAVING",
557
+ "HELP",
558
+ "HIGH_PRIORITY",
559
+ "HOST",
560
+ "HOSTS",
561
+ "HOUR",
562
+ "HOUR_MICROSECOND",
563
+ "HOUR_MINUTE",
564
+ "HOUR_SECOND",
565
+ "IDENTIFIED",
566
+ "IF",
567
+ "IGNORE",
568
+ "IGNORE_SERVER_IDS",
569
+ "IMPORT",
570
+ "IN",
571
+ "INDEX",
572
+ "INDEXES",
573
+ "INFILE",
574
+ "INITIAL_SIZE",
575
+ "INNER",
576
+ "INNOBASE",
577
+ "INNODB",
578
+ "INOUT",
579
+ "INSENSITIVE",
580
+ "INSERT",
581
+ "INSERT_METHOD",
582
+ "INSTALL",
583
+ "INT",
584
+ "INT1",
585
+ "INT2",
586
+ "INT3",
587
+ "INT4",
588
+ "INT8",
589
+ "INTEGER",
590
+ "INTERVAL",
591
+ "INTO",
592
+ "INVOKER",
593
+ "IO",
594
+ "IO_THREAD",
595
+ "IPC",
596
+ "IS",
597
+ "ISOLATION",
598
+ "ISSUER",
599
+ "ITERATE",
600
+ "JOIN",
601
+ "KEY",
602
+ "KEYS",
603
+ "KEY_BLOCK_SIZE",
604
+ "KILL",
605
+ "LANGUAGE",
606
+ "LAST",
607
+ "LEADING",
608
+ "LEAVE",
609
+ "LEAVES",
610
+ "LEFT",
611
+ "LESS",
612
+ "LEVEL",
613
+ "LIKE",
614
+ "LIMIT",
615
+ "LINEAR",
616
+ "LINES",
617
+ "LINESTRING",
618
+ "LIST",
619
+ "LOAD",
620
+ "LOCAL",
621
+ "LOCALTIME",
622
+ "LOCALTIMESTAMP",
623
+ "LOCK",
624
+ "LOCKS",
625
+ "LOGFILE",
626
+ "LOGS",
627
+ "LONG",
628
+ "LONGBLOB",
629
+ "LONGTEXT",
630
+ "LOOP",
631
+ "LOW_PRIORITY",
632
+ "MASTER",
633
+ "MASTER_CONNECT_RETRY",
634
+ "MASTER_HEARTBEAT_PERIOD",
635
+ "MASTER_HOST",
636
+ "MASTER_LOG_FILE",
637
+ "MASTER_LOG_POS",
638
+ "MASTER_PASSWORD",
639
+ "MASTER_PORT",
640
+ "MASTER_SERVER_ID",
641
+ "MASTER_SSL",
642
+ "MASTER_SSL_CA",
643
+ "MASTER_SSL_CAPATH",
644
+ "MASTER_SSL_CERT",
645
+ "MASTER_SSL_CIPHER",
646
+ "MASTER_SSL_KEY",
647
+ "MASTER_SSL_VERIFY_SERVER_CERT",
648
+ "MASTER_USER",
649
+ "MATCH",
650
+ "MAXVALUE",
651
+ "MAX_CONNECTIONS_PER_HOUR",
652
+ "MAX_QUERIES_PER_HOUR",
653
+ "MAX_ROWS",
654
+ "MAX_SIZE",
655
+ "MAX_UPDATES_PER_HOUR",
656
+ "MAX_USER_CONNECTIONS",
657
+ "MEDIUM",
658
+ "MEDIUMBLOB",
659
+ "MEDIUMINT",
660
+ "MEDIUMTEXT",
661
+ "MEMORY",
662
+ "MERGE",
663
+ "MESSAGE_TEXT",
664
+ "MICROSECOND",
665
+ "MIDDLEINT",
666
+ "MIGRATE",
667
+ "MINUTE",
668
+ "MINUTE_MICROSECOND",
669
+ "MINUTE_SECOND",
670
+ "MIN_ROWS",
671
+ "MOD",
672
+ "MODE",
673
+ "MODIFIES",
674
+ "MODIFY",
675
+ "MONTH",
676
+ "MULTILINESTRING",
677
+ "MULTIPOINT",
678
+ "MULTIPOLYGON",
679
+ "MUTEX",
680
+ "MYSQL_ERRNO",
681
+ "NAME",
682
+ "NAMES",
683
+ "NATIONAL",
684
+ "NATURAL",
685
+ "NCHAR",
686
+ "NDB",
687
+ "NDBCLUSTER",
688
+ "NEW",
689
+ "NEXT",
690
+ "NO",
691
+ "NODEGROUP",
692
+ "NONE",
693
+ "NOT",
694
+ "NO_WAIT",
695
+ "NO_WRITE_TO_BINLOG",
696
+ "NULL",
697
+ "NUMERIC",
698
+ "NVARCHAR",
699
+ "OFFSET",
700
+ "OLD_PASSWORD",
701
+ "ON",
702
+ "ONE",
703
+ "ONE_SHOT",
704
+ "OPEN",
705
+ "OPTIMIZE",
706
+ "OPTION",
707
+ "OPTIONALLY",
708
+ "OPTIONS",
709
+ "OR",
710
+ "ORDER",
711
+ "OUT",
712
+ "OUTER",
713
+ "OUTFILE",
714
+ "OWNER",
715
+ "PACK_KEYS",
716
+ "PAGE",
717
+ "PARSER",
718
+ "PARTIAL",
719
+ "PARTITION",
720
+ "PARTITIONING",
721
+ "PARTITIONS",
722
+ "PASSWORD",
723
+ "PHASE",
724
+ "PLUGIN",
725
+ "PLUGINS",
726
+ "POINT",
727
+ "POLYGON",
728
+ "PORT",
729
+ "PRECISION",
730
+ "PREPARE",
731
+ "PRESERVE",
732
+ "PREV",
733
+ "PRIMARY",
734
+ "PRIVILEGES",
735
+ "PROCEDURE",
736
+ "PROCESSLIST",
737
+ "PROFILE",
738
+ "PROFILES",
739
+ "PROXY",
740
+ "PURGE",
741
+ "QUARTER",
742
+ "QUERY",
743
+ "QUICK",
744
+ "RANGE",
745
+ "READ",
746
+ "READS",
747
+ "READ_ONLY",
748
+ "READ_WRITE",
749
+ "REAL",
750
+ "REBUILD",
751
+ "RECOVER",
752
+ "REDOFILE",
753
+ "REDO_BUFFER_SIZE",
754
+ "REDUNDANT",
755
+ "REFERENCES",
756
+ "REGEXP",
757
+ "RELAY",
758
+ "RELAYLOG",
759
+ "RELAY_LOG_FILE",
760
+ "RELAY_LOG_POS",
761
+ "RELAY_THREAD",
762
+ "RELEASE",
763
+ "RELOAD",
764
+ "REMOVE",
765
+ "RENAME",
766
+ "REORGANIZE",
767
+ "REPAIR",
768
+ "REPEAT",
769
+ "REPEATABLE",
770
+ "REPLACE",
771
+ "REPLICATION",
772
+ "REQUIRE",
773
+ "RESET",
774
+ "RESIGNAL",
775
+ "RESTORE",
776
+ "RESTRICT",
777
+ "RESUME",
778
+ "RETURN",
779
+ "RETURNS",
780
+ "REVOKE",
781
+ "RIGHT",
782
+ "RLIKE",
783
+ "ROLLBACK",
784
+ "ROLLUP",
785
+ "ROUTINE",
786
+ "ROW",
787
+ "ROWS",
788
+ "ROW_FORMAT",
789
+ "RTREE",
790
+ "SAVEPOINT",
791
+ "SCHEDULE",
792
+ "SCHEMA",
793
+ "SCHEMAS",
794
+ "SCHEMA_NAME",
795
+ "SECOND",
796
+ "SECOND_MICROSECOND",
797
+ "SECURITY",
798
+ "SELECT",
799
+ "SENSITIVE",
800
+ "SEPARATOR",
801
+ "SERIAL",
802
+ "SERIALIZABLE",
803
+ "SERVER",
804
+ "SESSION",
805
+ "SET",
806
+ "SHARE",
807
+ "SHOW",
808
+ "SHUTDOWN",
809
+ "SIGNAL",
810
+ "SIGNED",
811
+ "SIMPLE",
812
+ "SLAVE",
813
+ "SLOW",
814
+ "SMALLINT",
815
+ "SNAPSHOT",
816
+ "SOCKET",
817
+ "SOME",
818
+ "SONAME",
819
+ "SOUNDS",
820
+ "SOURCE",
821
+ "SPATIAL",
822
+ "SPECIFIC",
823
+ "SQL",
824
+ "SQLEXCEPTION",
825
+ "SQLSTATE",
826
+ "SQLWARNING",
827
+ "SQL_BIG_RESULT",
828
+ "SQL_BUFFER_RESULT",
829
+ "SQL_CACHE",
830
+ "SQL_CALC_FOUND_ROWS",
831
+ "SQL_NO_CACHE",
832
+ "SQL_SMALL_RESULT",
833
+ "SQL_THREAD",
834
+ "SQL_TSI_DAY",
835
+ "SQL_TSI_FRAC_SECOND",
836
+ "SQL_TSI_HOUR",
837
+ "SQL_TSI_MINUTE",
838
+ "SQL_TSI_MONTH",
839
+ "SQL_TSI_QUARTER",
840
+ "SQL_TSI_SECOND",
841
+ "SQL_TSI_WEEK",
842
+ "SQL_TSI_YEAR",
843
+ "SSL",
844
+ "START",
845
+ "STARTING",
846
+ "STARTS",
847
+ "STATUS",
848
+ "STOP",
849
+ "STORAGE",
850
+ "STRAIGHT_JOIN",
851
+ "STRING",
852
+ "SUBCLASS_ORIGIN",
853
+ "SUBJECT",
854
+ "SUBPARTITION",
855
+ "SUBPARTITIONS",
856
+ "SUPER",
857
+ "SUSPEND",
858
+ "SWAPS",
859
+ "SWITCHES",
860
+ "TABLE",
861
+ "TABLES",
862
+ "TABLESPACE",
863
+ "TABLE_CHECKSUM",
864
+ "TABLE_NAME",
865
+ "TEMPORARY",
866
+ "TEMPTABLE",
867
+ "TERMINATED",
868
+ "TEXT",
869
+ "THAN",
870
+ "THEN",
871
+ "TIME",
872
+ "TIMESTAMP",
873
+ "TIMESTAMPADD",
874
+ "TIMESTAMPDIFF",
875
+ "TINYBLOB",
876
+ "TINYINT",
877
+ "TINYTEXT",
878
+ "TO",
879
+ "TRAILING",
880
+ "TRANSACTION",
881
+ "TRIGGER",
882
+ "TRIGGERS",
883
+ "TRUE",
884
+ "TRUNCATE",
885
+ "TYPE",
886
+ "TYPES",
887
+ "UNCOMMITTED",
888
+ "UNDEFINED",
889
+ "UNDO",
890
+ "UNDOFILE",
891
+ "UNDO_BUFFER_SIZE",
892
+ "UNICODE",
893
+ "UNINSTALL",
894
+ "UNION",
895
+ "UNIQUE",
896
+ "UNKNOWN",
897
+ "UNLOCK",
898
+ "UNSIGNED",
899
+ "UNTIL",
900
+ "UPDATE",
901
+ "UPGRADE",
902
+ "USAGE",
903
+ "USE",
904
+ "USER",
905
+ "USER_RESOURCES",
906
+ "USE_FRM",
907
+ "USING",
908
+ "UTC_DATE",
909
+ "UTC_TIME",
910
+ "UTC_TIMESTAMP",
911
+ "VALUE",
912
+ "VALUES",
913
+ "VARBINARY",
914
+ "VARCHAR",
915
+ "VARCHARACTER",
916
+ "VARIABLES",
917
+ "VARYING",
918
+ "VIEW",
919
+ "WAIT",
920
+ "WARNINGS",
921
+ "WEEK",
922
+ "WHEN",
923
+ "WHERE",
924
+ "WHILE",
925
+ "WITH",
926
+ "WORK",
927
+ "WRAPPER",
928
+ "WRITE",
929
+ "X509",
930
+ "XA",
931
+ "XML",
932
+ "XOR",
933
+ "YEAR",
934
+ "YEAR_MONTH",
935
+ "ZEROFILL",
936
  );
937
 
938
  private $numberFunctions = array(
1742
  }
1743
  $this->index = $savePoint;
1744
 
1745
+ // Check if this is a Character Set Introducer
1746
+ $nextToken = $this->nextToken();
1747
+ $hasCharacterSetIntroducer = $this->isTokenOfType($nextToken, wfWAFSQLiLexer::UNQUOTED_IDENTIFIER) &&
1748
+ substr($nextToken->getValue(), 0, 1) === '_';
1749
+ if (!$hasCharacterSetIntroducer) {
1750
+ $this->index--;
1751
+ }
1752
+
1753
+ $validLiteral = false;
1754
  $nextToken = $this->nextToken();
1755
  if ($nextToken) {
1756
  switch ($nextToken->getType()) {
1758
  case wfWAFSQLiLexer::BINARY_NUMBER_LITERAL:
1759
  case wfWAFSQLiLexer::HEX_NUMBER_LITERAL:
1760
  case wfWAFSQLiLexer::REAL_NUMBER_LITERAL:
1761
+ $validLiteral = true;
1762
+ break;
1763
  // Allow concatenation: 'test' 'test' is valid
1764
  case wfWAFSQLiLexer::DOUBLE_STRING_LITERAL:
1765
  case wfWAFSQLiLexer::SINGLE_STRING_LITERAL:
1771
  $savePoint = $this->index;
1772
  }
1773
  $this->index = $savePoint;
1774
+ $validLiteral = true;
1775
+ break;
1776
 
1777
  case wfWAFSQLiLexer::UNQUOTED_IDENTIFIER:
1778
  if ($nextToken->getLowerCaseValue() === 'null') {
1779
+ $validLiteral = true;
1780
  }
1781
  break;
1782
  }
1783
  }
1784
+
1785
+
1786
+ if ($validLiteral) {
1787
+ if ($hasCharacterSetIntroducer) {
1788
+ // Check for and parse collation
1789
+ $savePoint = $this->index;
1790
+ $hasCollation = $this->isIdentifierWithValue($this->nextToken(), 'collation') &&
1791
+ $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::UNQUOTED_IDENTIFIER);
1792
+ if (!$hasCollation) {
1793
+ $this->index = $savePoint;
1794
+ }
1795
+ }
1796
+
1797
+ return true;
1798
+ }
1799
+
1800
  $this->index = $startIndex;
1801
  return false;
1802
  }
1844
  if ($this->parseExpression() &&
1845
  $this->isIdentifierWithValue($this->nextToken(), 'as') &&
1846
  $this->parseCastDataType() &&
1847
+ $this->parseOptionalCharacterSet() &&
1848
  $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::CLOSE_PARENTHESIS)
1849
  ) {
1850
  return true;
1856
  $savePoint = $this->index;
1857
  if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::COMMA) &&
1858
  $this->parseCastDataType() &&
1859
+ $this->parseOptionalCharacterSet() &&
1860
  $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::CLOSE_PARENTHESIS)
1861
  ) {
1862
  return true;
1865
  $savePoint = $this->index;
1866
  if ($this->isIdentifierWithValue($this->nextToken(), 'using') &&
1867
  $this->parseTranscodingName() &&
1868
+ $this->parseOptionalCharacterSet() &&
1869
  $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::CLOSE_PARENTHESIS)
1870
  ) {
1871
  return true;
1874
  }
1875
  break;
1876
 
1877
+ case 'trim':
1878
+ if (!$this->isIdentifierWithValue($this->nextToken(), array(
1879
+ 'leading',
1880
+ 'both',
1881
+ 'trailing',
1882
+ ))) {
1883
+ $this->index--;
1884
+ }
1885
+
1886
+ while ($this->parseExpression()) {
1887
+ $nextToken = $this->nextToken();
1888
+ if (
1889
+ $this->isTokenOfType($nextToken, wfWAFSQLiLexer::COMMA) ||
1890
+ $this->isIdentifierWithValue($nextToken, array(
1891
+ 'from',
1892
+ 'for',
1893
+ 'in',
1894
+ ))
1895
+ ) {
1896
+ continue;
1897
+ }
1898
+ $this->index--;
1899
+ break;
1900
+ }
1901
+
1902
+ if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::CLOSE_PARENTHESIS)) {
1903
+ return true;
1904
+ }
1905
+ break;
1906
+
1907
+ case 'weight_string':
1908
+ if ($this->parseExpression()) {
1909
+ $savePoint = $this->index;
1910
+ if (!(
1911
+ $this->isIdentifierWithValue($this->nextToken(), 'as') &&
1912
+ $this->parseCastDataType() &&
1913
+ $this->parseOptionalCharacterSet()
1914
+ )) {
1915
+ $this->index = $savePoint;
1916
+ }
1917
+
1918
+ if ($this->isIdentifierWithValue($this->nextToken(), 'level')) {
1919
+ while ($this->parseExpression()) {
1920
+ $nextToken = $this->nextToken();
1921
+ if (
1922
+ $this->isTokenOfType($nextToken, wfWAFSQLiLexer::COMMA) ||
1923
+ $this->isTokenOfType($nextToken, wfWAFSQLiLexer::MINUS)
1924
+ ) {
1925
+ continue;
1926
+ }
1927
+ $this->index--;
1928
+ break;
1929
+ }
1930
+ while ($this->isIdentifierWithValue($this->nextToken(), array(
1931
+ 'asc',
1932
+ 'desc',
1933
+ 'reverse',
1934
+ ))) {
1935
+ continue;
1936
+ }
1937
+ $this->index--;
1938
+ } else {
1939
+ $this->index--;
1940
+ }
1941
+ }
1942
+
1943
+ if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::CLOSE_PARENTHESIS)) {
1944
+ return true;
1945
+ }
1946
+ break;
1947
+
1948
  default:
1949
  $savePoint = $this->index;
1950
  if (in_array($functionToken->getUpperCaseValue(), $this->groupFunctions)) {
1963
  $this->index = $savePoint;
1964
 
1965
  while ($this->parseExpression()) {
1966
+ $nextToken = $this->nextToken();
1967
+ if (
1968
+ $this->isTokenOfType($nextToken, wfWAFSQLiLexer::COMMA) ||
1969
+ $this->isIdentifierWithValue($nextToken, array(
1970
+ 'from',
1971
+ 'for',
1972
+ 'in',
1973
+ ))
1974
+ ) {
1975
  continue;
1976
  }
1977
  $this->index--;
2008
  switch ($token->getLowerCaseValue()) {
2009
  case 'binary':
2010
  case 'char':
2011
+ case 'nchar':
2012
+ case 'varchar':
2013
+ case 'character':
2014
  $savePoint = $this->index;
2015
+ if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::OPEN_PARENTHESIS) &&
2016
+ $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::INTEGER_LITERAL) &&
2017
+ $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::CLOSE_PARENTHESIS)
2018
+ ) {
2019
  return true;
2020
  }
2021
  $this->index = $savePoint;
2028
 
2029
  case 'signed':
2030
  case 'unsigned':
2031
+ if (!$this->isIdentifierWithValue($this->nextToken(), array(
2032
+ 'int',
2033
+ 'integer',
2034
+ ))) {
2035
  $this->index--;
2036
  }
2037
  return true;
2038
 
2039
  case 'decimal':
2040
  $savePoint = $this->index;
2041
+ if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::OPEN_PARENTHESIS) &&
2042
+ $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::INTEGER_LITERAL)) {
2043
+
2044
+ $savePoint2 = $this->index;
2045
+ if (!($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::COMMA) &&
2046
+ $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::INTEGER_LITERAL)
2047
+ )) {
2048
+ $this->index = $savePoint2;
2049
+ }
2050
+ if ($this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::CLOSE_PARENTHESIS)) {
2051
+ return true;
2052
  }
 
 
2053
  }
2054
+
2055
  $this->index = $savePoint;
2056
  return true;
2057
  }
2064
  $savePoint = $this->index;
2065
  $token = $this->nextToken();
2066
  if ($token && $token->getType() === wfWAFSQLiLexer::UNQUOTED_IDENTIFIER) {
2067
+ return true;
2068
  }
2069
  $this->index = $savePoint;
2070
  return false;
2071
  }
2072
 
2073
+ private function parseOptionalCharacterSet() {
2074
+ $savePoint = $this->index;
2075
+ if (!(
2076
+ $this->nextToken()->getLowerCaseValue() === 'character' &&
2077
+ $this->nextToken()->getLowerCaseValue() === 'set' &&
2078
+ $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::UNQUOTED_IDENTIFIER)
2079
+ )) {
2080
+ $this->index = $savePoint;
2081
+ }
2082
+ return true;
2083
+ }
2084
+
2085
  private function parseVariable() {
2086
  $nextToken = $this->nextToken();
2087
  if ($nextToken && $nextToken->getType() === wfWAFSQLiLexer::VARIABLE) {
2458
  private function parsePartitionName() {
2459
  $startPoint = $this->index;
2460
  $token = $this->nextToken();
2461
+ if ($this->isValidNonReservedWordIdentifier($token)) {
 
 
2462
  return true;
2463
  }
2464
  $this->index = $startPoint;
2580
  private function parseTableSpec() {
2581
  $savePoint = $this->index;
2582
  if ($this->isTokenOfType($this->nextToken(), array(
2583
+ wfWAFSQLiLexer::UNQUOTED_IDENTIFIER,
2584
+ wfWAFSQLiLexer::QUOTED_IDENTIFIER,
2585
+ )) &&
2586
+ $this->isTokenOfType($this->nextToken(), wfWAFSQLiLexer::DOT) &&
2587
+ $this->isTokenOfType($this->nextToken(), array(
2588
+ wfWAFSQLiLexer::UNQUOTED_IDENTIFIER,
2589
+ wfWAFSQLiLexer::QUOTED_IDENTIFIER,
2590
+ ))
2591
  ) {
2592
+ return true;
2593
+ }
2594
+ $this->index = $savePoint;
2595
+ if ($this->isValidNonReservedWordIdentifier($this->nextToken())) {
 
 
 
 
 
 
2596
  return true;
2597
  }
2598
  $this->index = $savePoint;
2608
  if ($this->isIdentifierWithValue($token, 'as')) {
2609
  $token = $this->nextToken();
2610
  }
2611
+ if ($this->isValidNonReservedWordIdentifier($token)) {
2612
  return true;
2613
  }
2614
  $this->index = $savePoint;
2746
  private function parseIndexName() {
2747
  $startPoint = $this->index;
2748
  $token = $this->nextToken();
2749
+ if ($this->isValidNonReservedWordIdentifier($token)) {
2750
  return true;
2751
  }
2752
  $this->index = $startPoint;
3315
  in_array($token->getUpperCaseValue(), $this->keywords);
3316
  }
3317
 
3318
+ /**
3319
+ * @param wfWAFLexerToken $token
3320
+ * @return bool
3321
+ */
3322
+ private function isReservedWordToken($token) {
3323
+ return $token && $token->getType() === wfWAFSQLiLexer::UNQUOTED_IDENTIFIER &&
3324
+ in_array($token->getUpperCaseValue(), $this->reservedWords);
3325
+ }
3326
+
3327
  /**
3328
  * @param wfWAFLexerToken $token
3329
  * @return bool
3335
  );
3336
  }
3337
 
3338
+ /**
3339
+ * @param wfWAFLexerToken $token
3340
+ * @return bool
3341
+ */
3342
+ private function isValidNonReservedWordIdentifier($token) {
3343
+ return $token && (
3344
+ $token->getType() === wfWAFSQLiLexer::QUOTED_IDENTIFIER ||
3345
+ ($token->getType() === wfWAFSQLiLexer::UNQUOTED_IDENTIFIER && !$this->isReservedWordToken($token))
3346
+ );
3347
+ }
3348
+
3349
  /**
3350
  * @param wfWAFLexerToken $token
3351
  * @return bool
wordfence.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Wordfence Security
4
  Plugin URI: http://www.wordfence.com/
5
  Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
6
  Author: Wordfence
7
- Version: 7.4.5
8
  Author URI: http://www.wordfence.com/
9
  Network: true
10
  */
@@ -15,8 +15,8 @@ if(defined('WP_INSTALLING') && WP_INSTALLING){
15
  if (!defined('ABSPATH')) {
16
  exit;
17
  }
18
- define('WORDFENCE_VERSION', '7.4.5');
19
- define('WORDFENCE_BUILD_NUMBER', '1579191227');
20
  define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
21
  basename(dirname(__FILE__)) . '/' . basename(__FILE__));
22
 
4
  Plugin URI: http://www.wordfence.com/
5
  Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
6
  Author: Wordfence
7
+ Version: 7.4.6
8
  Author URI: http://www.wordfence.com/
9
  Network: true
10
  */
15
  if (!defined('ABSPATH')) {
16
  exit;
17
  }
18
+ define('WORDFENCE_VERSION', '7.4.6');
19
+ define('WORDFENCE_BUILD_NUMBER', '1581523568');
20
  define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
21
  basename(dirname(__FILE__)) . '/' . basename(__FILE__));
22