Shield Security for WordPress - Version 12.0.1

Version Description

Download this release

Release Info

Developer paultgoodchild
Plugin Icon 128x128 Shield Security for WordPress
Version 12.0.1
Comparing to
See all releases

Code changes from version 12.0.0 to 12.0.1

Files changed (77) hide show
  1. cl.json +8 -0
  2. config/audit_trail.json +1 -1
  3. config/deprecated/audit_trail.php +1 -1
  4. config/deprecated/hack_protect.php +3 -2
  5. config/deprecated/ips.php +124 -0
  6. config/hack_protect.json +3 -2
  7. config/ips.json +124 -0
  8. icwp-wpsf.php +1 -1
  9. plugin-spec.php +5 -4
  10. plugin.json +5 -4
  11. readme.txt +2 -2
  12. src/lib/src/Databases/Base/Update.php +11 -6
  13. src/lib/src/Databases/BotSignals/Common.php +15 -9
  14. src/lib/src/Databases/BotSignals/Handler.php +0 -3
  15. src/lib/src/Databases/BotSignals/Select.php +0 -10
  16. src/lib/src/Databases/IPs/Delete.php +1 -1
  17. src/lib/src/Databases/Scanner/Common.php +14 -7
  18. src/lib/src/Logging/Processors/RequestMetaProcessor.php +2 -2
  19. src/lib/src/Modules/AuditTrail/DB/LoadLogs.php +13 -2
  20. src/lib/src/Modules/AuditTrail/Lib/AuditWriter.php +0 -6
  21. src/lib/src/Modules/AuditTrail/Lib/LogHandlers/LocalDbWriter.php +9 -6
  22. src/lib/src/Modules/AuditTrail/Lib/LogTable/LoadRawTableData.php +5 -19
  23. src/lib/src/Modules/Base/Processor.php +0 -1
  24. src/lib/src/Modules/Data/DB/IPs/IPRecords.php +21 -11
  25. src/lib/src/Modules/Data/DB/IPs/Ops/Common.php +3 -7
  26. src/lib/src/Modules/Data/DB/ReqLogs/LoadLogs.php +1 -1
  27. src/lib/src/Modules/GeoIp/Lookup.php +4 -0
  28. src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/Diff.php +9 -7
  29. src/lib/src/Modules/HackGuard/Lib/Reports/ScanRepairs.php +1 -1
  30. src/lib/src/Modules/HackGuard/Scan/Controller/Base.php +19 -3
  31. src/lib/src/Modules/HackGuard/Scan/Results/ResultsDelete.php +49 -23
  32. src/lib/src/Modules/HackGuard/Scan/Results/ResultsStore.php +39 -3
  33. src/lib/src/Modules/HackGuard/Scan/Results/ResultsUpdate.php +26 -18
  34. src/lib/src/Modules/IPs/DB/BotSignal/BotSignalRecord.php +11 -0
  35. src/lib/src/Modules/IPs/DB/BotSignal/LoadBotSignalRecords.php +41 -0
  36. src/lib/src/Modules/IPs/DB/BotSignal/Ops/Common.php +10 -0
  37. src/lib/src/Modules/IPs/DB/BotSignal/Ops/Delete.php +10 -0
  38. src/lib/src/Modules/IPs/DB/BotSignal/Ops/Handler.php +9 -0
  39. src/lib/src/Modules/IPs/DB/BotSignal/Ops/Insert.php +9 -0
  40. src/lib/src/Modules/IPs/DB/BotSignal/Ops/Record.php +35 -0
  41. src/lib/src/Modules/IPs/DB/BotSignal/Ops/Select.php +11 -0
  42. src/lib/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php +77 -44
  43. src/lib/src/Modules/IPs/Lib/Bots/Calculator/BaseBuildScores.php +7 -11
  44. src/lib/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php +5 -2
  45. src/lib/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php +21 -1
  46. src/lib/src/Modules/IPs/Lib/Bots/ShieldNET/BuildData.php +35 -16
  47. src/lib/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php +0 -7
  48. src/lib/src/Modules/IPs/Lib/OffenseTracker.php +2 -5
  49. src/lib/src/Modules/IPs/Lib/Ops/ConvertLegacy.php +97 -0
  50. src/lib/src/Modules/IPs/ModCon.php +23 -2
  51. src/lib/src/Modules/IPs/Upgrade.php +6 -0
  52. src/lib/src/Modules/Insights/ModCon.php +2 -1
  53. src/lib/src/Modules/Lockdown/Processor.php +15 -10
  54. src/lib/src/Modules/Plugin/Debug.php +13 -5
  55. src/lib/src/Modules/Plugin/Insights/DashboardCards.php +1 -1
  56. src/lib/src/Modules/Plugin/Lib/Debug/Collate.php +1 -1
  57. src/lib/src/Modules/Sessions/Processor.php +14 -14
  58. src/lib/src/Modules/Traffic/Lib/TrafficTable/LoadRawTableData.php +1 -1
  59. src/lib/src/Scans/Base/DiffResultForStorage.php +10 -10
  60. src/lib/src/Scans/Base/FileResultItem.php +4 -0
  61. src/lib/src/Scans/Base/Utilities/BaseRepair.php +0 -4
  62. src/lib/src/Scans/Base/Utilities/IgnoreItem.php +42 -0
  63. src/lib/src/Scans/Base/Utilities/ItemActionHandler.php +12 -15
  64. src/lib/src/Scans/Mal/ResultItem.php +0 -4
  65. src/lib/src/Scans/Ptg/ResultItem.php +0 -3
  66. src/lib/src/Scans/Ufc/ResultItem.php +0 -3
  67. src/lib/src/Scans/Wcf/ResultItem.php +0 -4
  68. src/lib/src/Tables/DataTables/LoadData/BaseLoadTableData.php +18 -5
  69. src/lib/vendor/composer/autoload_classmap.php +11 -1
  70. src/lib/vendor/composer/autoload_static.php +11 -1
  71. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/BaseQuery.php +12 -0
  72. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php +7 -1
  73. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/FilterByIP.php +23 -0
  74. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/Select_IPTable.php +0 -24
  75. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php +1 -1
  76. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Retrieve.php +9 -0
  77. templates/twig/notices/new-audit-trail.twig +1 -6
cl.json CHANGED
@@ -78,6 +78,14 @@
78
  "The Traffic Log feature now also uses the improved table UI for faster processing and better search."
79
  ]
80
  },
 
 
 
 
 
 
 
 
81
  {
82
  "type": "changed",
83
  "pro_only": false,
78
  "The Traffic Log feature now also uses the improved table UI for faster processing and better search."
79
  ]
80
  },
81
+ {
82
+ "type": "improved",
83
+ "pro_only": false,
84
+ "title": "Scanning Improvements and Fixes",
85
+ "description": [
86
+ "Based on customer feedback we've made some adjustments and fixes to the scans and results processing."
87
+ ]
88
+ },
89
  {
90
  "type": "changed",
91
  "pro_only": false,
config/audit_trail.json CHANGED
@@ -27,7 +27,7 @@
27
  "source_mod_page": "audit-redirect",
28
  "target_mod_page": "insights",
29
  "query_args": {
30
- "inav": "audit"
31
  }
32
  }
33
  ],
27
  "source_mod_page": "audit-redirect",
28
  "target_mod_page": "insights",
29
  "query_args": {
30
+ "inav": "audit_trail"
31
  }
32
  }
33
  ],
config/deprecated/audit_trail.php CHANGED
@@ -27,7 +27,7 @@
27
  "source_mod_page": "audit-redirect",
28
  "target_mod_page": "insights",
29
  "query_args": {
30
- "inav": "audit"
31
  }
32
  }
33
  ],
27
  "source_mod_page": "audit-redirect",
28
  "target_mod_page": "insights",
29
  "query_args": {
30
+ "inav": "audit_trail"
31
  }
32
  }
33
  ],
config/deprecated/hack_protect.php CHANGED
@@ -508,8 +508,9 @@
508
  "severity": "int(3) NOT NULL DEFAULT 1 COMMENT 'Severity'"
509
  },
510
  "cols_timestamps": {
511
- "ignored_at": "Scan Result Ignored",
512
- "notified_at": "Scan Notifiation Sent"
 
513
  }
514
  },
515
  "db_table_scanq": {
508
  "severity": "int(3) NOT NULL DEFAULT 1 COMMENT 'Severity'"
509
  },
510
  "cols_timestamps": {
511
+ "ignored_at": "Scan Result Ignored",
512
+ "notified_at": "Scan Notifiation Sent",
513
+ "attempt_repair_at": "Attempted Repair At"
514
  }
515
  },
516
  "db_table_scanq": {
config/deprecated/ips.php CHANGED
@@ -569,6 +569,13 @@
569
  "transferable": false,
570
  "type": "array",
571
  "default": []
 
 
 
 
 
 
 
572
  }
573
  ],
574
  "definitions": {
@@ -584,6 +591,123 @@
584
  "woff",
585
  "woff2"
586
  ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
587
  "db_classes": {
588
  "botsignals": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\BotSignals\\Handler",
589
  "ip_lists": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
569
  "transferable": false,
570
  "type": "array",
571
  "default": []
572
+ },
573
+ {
574
+ "key": "legacy_db_deleted_at",
575
+ "section": "section_non_ui",
576
+ "transferable": false,
577
+ "type": "integer",
578
+ "default": ""
579
  }
580
  ],
581
  "definitions": {
591
  "woff",
592
  "woff2"
593
  ],
594
+ "db_handler_classes": {
595
+ "botsignal": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Handler"
596
+ },
597
+ "db_table_botsignal": {
598
+ "autoexpire": 0,
599
+ "slug": "botsignal",
600
+ "has_updated_at": true,
601
+ "col_older_than": "updated_at",
602
+ "cols_custom": {
603
+ "ip_ref": {
604
+ "macro_type": "foreign_key_id",
605
+ "foreign_key": {
606
+ "ref_table": "icwp_wpsf_ips"
607
+ }
608
+ },
609
+ "notbot_at": {
610
+ "macro_type": "timestamp",
611
+ "comment": "NotBot"
612
+ },
613
+ "frontpage_at": {
614
+ "macro_type": "timestamp",
615
+ "comment": "Any Frontend Page Loaded"
616
+ },
617
+ "loginpage_at": {
618
+ "macro_type": "timestamp",
619
+ "comment": "Login Page Loaded"
620
+ },
621
+ "bt404_at": {
622
+ "macro_type": "timestamp",
623
+ "comment": "BotTrack 404"
624
+ },
625
+ "btfake_at": {
626
+ "macro_type": "timestamp",
627
+ "comment": "BotTrack FakeWebCrawler"
628
+ },
629
+ "btcheese_at": {
630
+ "macro_type": "timestamp",
631
+ "comment": "BotTrack LinkCheese"
632
+ },
633
+ "btloginfail_at": {
634
+ "macro_type": "timestamp",
635
+ "comment": "BotTrack LoginFailed"
636
+ },
637
+ "btua_at": {
638
+ "macro_type": "timestamp",
639
+ "comment": "BotTrack Useragent Fail"
640
+ },
641
+ "btxml_at": {
642
+ "macro_type": "timestamp",
643
+ "comment": "BotTrack XMLRPC Access"
644
+ },
645
+ "btlogininvalid_at": {
646
+ "macro_type": "timestamp",
647
+ "comment": "BotTrack LoginInvalid"
648
+ },
649
+ "btinvalidscript_at": {
650
+ "macro_type": "timestamp",
651
+ "comment": "BotTrack InvalidScript"
652
+ },
653
+ "cooldown_at": {
654
+ "macro_type": "timestamp",
655
+ "comment": "Cooldown Triggered"
656
+ },
657
+ "humanspam_at": {
658
+ "macro_type": "timestamp",
659
+ "comment": "Comment Marked As Human SPAM"
660
+ },
661
+ "markspam_at": {
662
+ "macro_type": "timestamp",
663
+ "comment": "Mark Comment As SPAM"
664
+ },
665
+ "unmarkspam_at": {
666
+ "macro_type": "timestamp",
667
+ "comment": "Unmark Comment As SPAM"
668
+ },
669
+ "captchapass_at": {
670
+ "macro_type": "timestamp",
671
+ "comment": "Captcha Passed"
672
+ },
673
+ "captchafail_at": {
674
+ "macro_type": "timestamp",
675
+ "comment": "Captcha Failed"
676
+ },
677
+ "auth_at": {
678
+ "macro_type": "timestamp",
679
+ "comment": "Successful Login"
680
+ },
681
+ "firewall_at": {
682
+ "macro_type": "timestamp",
683
+ "comment": "Triggered Firewall"
684
+ },
685
+ "ratelimit_at": {
686
+ "macro_type": "timestamp",
687
+ "comment": "Rate Limit Exceeded"
688
+ },
689
+ "offense_at": {
690
+ "macro_type": "timestamp",
691
+ "comment": "Last Offense"
692
+ },
693
+ "blocked_at": {
694
+ "macro_type": "timestamp",
695
+ "comment": "Last Block"
696
+ },
697
+ "unblocked_at": {
698
+ "macro_type": "timestamp",
699
+ "comment": "Unblocked"
700
+ },
701
+ "bypass_at": {
702
+ "macro_type": "timestamp",
703
+ "comment": "Bypass"
704
+ },
705
+ "snsent_at": {
706
+ "macro_type": "timestamp",
707
+ "comment": "Sent To ShieldNET"
708
+ }
709
+ }
710
+ },
711
  "db_classes": {
712
  "botsignals": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\BotSignals\\Handler",
713
  "ip_lists": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
config/hack_protect.json CHANGED
@@ -508,8 +508,9 @@
508
  "severity": "int(3) NOT NULL DEFAULT 1 COMMENT 'Severity'"
509
  },
510
  "cols_timestamps": {
511
- "ignored_at": "Scan Result Ignored",
512
- "notified_at": "Scan Notifiation Sent"
 
513
  }
514
  },
515
  "db_table_scanq": {
508
  "severity": "int(3) NOT NULL DEFAULT 1 COMMENT 'Severity'"
509
  },
510
  "cols_timestamps": {
511
+ "ignored_at": "Scan Result Ignored",
512
+ "notified_at": "Scan Notifiation Sent",
513
+ "attempt_repair_at": "Attempted Repair At"
514
  }
515
  },
516
  "db_table_scanq": {
config/ips.json CHANGED
@@ -569,6 +569,13 @@
569
  "transferable": false,
570
  "type": "array",
571
  "default": []
 
 
 
 
 
 
 
572
  }
573
  ],
574
  "definitions": {
@@ -584,6 +591,123 @@
584
  "woff",
585
  "woff2"
586
  ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
587
  "db_classes": {
588
  "botsignals": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\BotSignals\\Handler",
589
  "ip_lists": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
569
  "transferable": false,
570
  "type": "array",
571
  "default": []
572
+ },
573
+ {
574
+ "key": "legacy_db_deleted_at",
575
+ "section": "section_non_ui",
576
+ "transferable": false,
577
+ "type": "integer",
578
+ "default": ""
579
  }
580
  ],
581
  "definitions": {
591
  "woff",
592
  "woff2"
593
  ],
594
+ "db_handler_classes": {
595
+ "botsignal": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Handler"
596
+ },
597
+ "db_table_botsignal": {
598
+ "autoexpire": 0,
599
+ "slug": "botsignal",
600
+ "has_updated_at": true,
601
+ "col_older_than": "updated_at",
602
+ "cols_custom": {
603
+ "ip_ref": {
604
+ "macro_type": "foreign_key_id",
605
+ "foreign_key": {
606
+ "ref_table": "icwp_wpsf_ips"
607
+ }
608
+ },
609
+ "notbot_at": {
610
+ "macro_type": "timestamp",
611
+ "comment": "NotBot"
612
+ },
613
+ "frontpage_at": {
614
+ "macro_type": "timestamp",
615
+ "comment": "Any Frontend Page Loaded"
616
+ },
617
+ "loginpage_at": {
618
+ "macro_type": "timestamp",
619
+ "comment": "Login Page Loaded"
620
+ },
621
+ "bt404_at": {
622
+ "macro_type": "timestamp",
623
+ "comment": "BotTrack 404"
624
+ },
625
+ "btfake_at": {
626
+ "macro_type": "timestamp",
627
+ "comment": "BotTrack FakeWebCrawler"
628
+ },
629
+ "btcheese_at": {
630
+ "macro_type": "timestamp",
631
+ "comment": "BotTrack LinkCheese"
632
+ },
633
+ "btloginfail_at": {
634
+ "macro_type": "timestamp",
635
+ "comment": "BotTrack LoginFailed"
636
+ },
637
+ "btua_at": {
638
+ "macro_type": "timestamp",
639
+ "comment": "BotTrack Useragent Fail"
640
+ },
641
+ "btxml_at": {
642
+ "macro_type": "timestamp",
643
+ "comment": "BotTrack XMLRPC Access"
644
+ },
645
+ "btlogininvalid_at": {
646
+ "macro_type": "timestamp",
647
+ "comment": "BotTrack LoginInvalid"
648
+ },
649
+ "btinvalidscript_at": {
650
+ "macro_type": "timestamp",
651
+ "comment": "BotTrack InvalidScript"
652
+ },
653
+ "cooldown_at": {
654
+ "macro_type": "timestamp",
655
+ "comment": "Cooldown Triggered"
656
+ },
657
+ "humanspam_at": {
658
+ "macro_type": "timestamp",
659
+ "comment": "Comment Marked As Human SPAM"
660
+ },
661
+ "markspam_at": {
662
+ "macro_type": "timestamp",
663
+ "comment": "Mark Comment As SPAM"
664
+ },
665
+ "unmarkspam_at": {
666
+ "macro_type": "timestamp",
667
+ "comment": "Unmark Comment As SPAM"
668
+ },
669
+ "captchapass_at": {
670
+ "macro_type": "timestamp",
671
+ "comment": "Captcha Passed"
672
+ },
673
+ "captchafail_at": {
674
+ "macro_type": "timestamp",
675
+ "comment": "Captcha Failed"
676
+ },
677
+ "auth_at": {
678
+ "macro_type": "timestamp",
679
+ "comment": "Successful Login"
680
+ },
681
+ "firewall_at": {
682
+ "macro_type": "timestamp",
683
+ "comment": "Triggered Firewall"
684
+ },
685
+ "ratelimit_at": {
686
+ "macro_type": "timestamp",
687
+ "comment": "Rate Limit Exceeded"
688
+ },
689
+ "offense_at": {
690
+ "macro_type": "timestamp",
691
+ "comment": "Last Offense"
692
+ },
693
+ "blocked_at": {
694
+ "macro_type": "timestamp",
695
+ "comment": "Last Block"
696
+ },
697
+ "unblocked_at": {
698
+ "macro_type": "timestamp",
699
+ "comment": "Unblocked"
700
+ },
701
+ "bypass_at": {
702
+ "macro_type": "timestamp",
703
+ "comment": "Bypass"
704
+ },
705
+ "snsent_at": {
706
+ "macro_type": "timestamp",
707
+ "comment": "Sent To ShieldNET"
708
+ }
709
+ }
710
+ },
711
  "db_classes": {
712
  "botsignals": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\BotSignals\\Handler",
713
  "ip_lists": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
icwp-wpsf.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Shield Security
4
  * Plugin URI: https://shsec.io/2f
5
  * Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
6
- * Version: 12.0.0
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: Shield Security
3
  * Plugin Name: Shield Security
4
  * Plugin URI: https://shsec.io/2f
5
  * Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
6
+ * Version: 12.0.1
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: Shield Security
plugin-spec.php CHANGED
@@ -1,8 +1,8 @@
1
  {
2
  "properties": {
3
- "version": "12.0.0",
4
- "release_timestamp": 1631783098,
5
- "build": "202109.1601",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "human_name": "Shield Security",
@@ -446,7 +446,8 @@
446
  "10.1.0",
447
  "10.2.1",
448
  "11.2.0",
449
- "12.0.0"
 
450
  ],
451
  "action_links": {
452
  "remove": null,
1
  {
2
  "properties": {
3
+ "version": "12.0.1",
4
+ "release_timestamp": 1632214137,
5
+ "build": "202109.2101",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "human_name": "Shield Security",
446
  "10.1.0",
447
  "10.2.1",
448
  "11.2.0",
449
+ "12.0.0",
450
+ "12.0.1"
451
  ],
452
  "action_links": {
453
  "remove": null,
plugin.json CHANGED
@@ -1,8 +1,8 @@
1
  {
2
  "properties": {
3
- "version": "12.0.0",
4
- "release_timestamp": 1631783098,
5
- "build": "202109.1601",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "human_name": "Shield Security",
@@ -446,7 +446,8 @@
446
  "10.1.0",
447
  "10.2.1",
448
  "11.2.0",
449
- "12.0.0"
 
450
  ],
451
  "action_links": {
452
  "remove": null,
1
  {
2
  "properties": {
3
+ "version": "12.0.1",
4
+ "release_timestamp": 1632214137,
5
+ "build": "202109.2101",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "human_name": "Shield Security",
446
  "10.1.0",
447
  "10.2.1",
448
  "11.2.0",
449
+ "12.0.0",
450
+ "12.0.1"
451
  ],
452
  "action_links": {
453
  "remove": null,
readme.txt CHANGED
@@ -8,13 +8,13 @@ Requires at least: 3.7
8
  Requires PHP: 7.0
9
  Recommended PHP: 7.4
10
  Tested up to: 5.8
11
- Stable tag: 12.0.0
12
 
13
  No-Nonsense Security Hardening that protects WordPress against hackers, malicious bots, and spammers (no captchas!). Now with exclusive ShieldNET Technology.
14
 
15
  == Description ==
16
 
17
- **No-Nonsense, No-Hype. Just Security Protection**. Shield is the only NO-nonsense security solution that defends and protects your WordPress sites against hackers and malicious bots, of all types. With our exclusive, *no-need-for-captcha* security technology you can limit login attempts, block brute force attacks and prevent 100% bot comment SPAM.
18
 
19
  **Performance is critical**. Shield Security automatically blocks bad IP addresses while optimising performance so your WordPress site never slows down because of bloated security, with large IP lookup tables .
20
 
8
  Requires PHP: 7.0
9
  Recommended PHP: 7.4
10
  Tested up to: 5.8
11
+ Stable tag: 12.0.1
12
 
13
  No-Nonsense Security Hardening that protects WordPress against hackers, malicious bots, and spammers (no captchas!). Now with exclusive ShieldNET Technology.
14
 
15
  == Description ==
16
 
17
+ **No-Nonsense, No-Hype. Just Good Security Protection**. Shield is the only NO-nonsense security solution that defends and protects your WordPress sites against hackers and malicious bots, of all types. With our exclusive, *no-need-for-captcha* security technology you can limit login attempts, block brute force attacks and prevent 100% bot comment SPAM.
18
 
19
  **Performance is critical**. Shield Security automatically blocks bad IP addresses while optimising performance so your WordPress site never slows down because of bloated security, with large IP lookup tables .
20
 
src/lib/src/Databases/Base/Update.php CHANGED
@@ -25,6 +25,10 @@ class Update extends Insert {
25
  return is_array( $this->aUpdateWheres ) ? $this->aUpdateWheres : [];
26
  }
27
 
 
 
 
 
28
  /**
29
  * @param array $data
30
  * @return $this
@@ -71,7 +75,8 @@ class Update extends Insert {
71
  $success = true;
72
  }
73
  else {
74
- if ( $this->getDbH()->getTableSchema()->hasColumn( 'updated_at' ) && !isset( $updateData[ 'updated_at' ] ) ) {
 
75
  $updateData[ 'updated_at' ] = Services::Request()->ts();
76
  }
77
  if ( $this->updateById( $entry->id, $updateData ) ) {
@@ -102,10 +107,10 @@ class Update extends Insert {
102
 
103
  public function query() {
104
  return (bool)Services::WpDb()
105
- ->updateRowsFromTableWhere(
106
- $this->getDbH()->getTable(),
107
- $this->getUpdateData(),
108
- $this->getUpdateWheres()
109
- );
110
  }
111
  }
25
  return is_array( $this->aUpdateWheres ) ? $this->aUpdateWheres : [];
26
  }
27
 
28
+ public function setSoftDeleted() {
29
+ return $this->setUpdateData( [ 'deleted_at' => Services::Request()->ts() ] );
30
+ }
31
+
32
  /**
33
  * @param array $data
34
  * @return $this
75
  $success = true;
76
  }
77
  else {
78
+ if ( $this->getDbH()->getTableSchema()->hasColumn( 'updated_at' )
79
+ && !isset( $updateData[ 'updated_at' ] ) ) {
80
  $updateData[ 'updated_at' ] = Services::Request()->ts();
81
  }
82
  if ( $this->updateById( $entry->id, $updateData ) ) {
107
 
108
  public function query() {
109
  return (bool)Services::WpDb()
110
+ ->updateRowsFromTableWhere(
111
+ $this->getDbH()->getTable(),
112
+ $this->getUpdateData(),
113
+ $this->getUpdateWheres()
114
+ );
115
  }
116
  }
src/lib/src/Databases/BotSignals/Common.php CHANGED
@@ -2,22 +2,28 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals;
4
 
 
 
5
  trait Common {
6
 
7
  /**
8
- * Will test whether the Binary IP can be converted back before applying filter.
9
- * @param mixed $binaryIp - IP has already been converted using inet_pton
10
  * @return $this
11
  */
12
- public function filterByIP( $binaryIp ) {
13
- if ( inet_ntop( $binaryIp ) !== false ) {
14
- $this->addWhereEquals( 'ip', $binaryIp );
 
 
 
 
15
  }
16
- return $this;
17
- }
18
 
19
- public function filterByIPHuman( string $ip ) {
20
- return $this->filterByIP( inet_pton( $ip ) );
 
 
21
  }
22
 
23
  /**
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals;
4
 
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
  trait Common {
8
 
9
  /**
10
+ * COPIED FROM PLUGIN CORE
11
+ * @param string $ip
12
  * @return $this
13
  */
14
+ public function filterByIPHuman( string $ip ) {
15
+ $rightSide = null;
16
+ if ( empty( $ip ) ) {
17
+ $rightSide = "''";
18
+ }
19
+ elseif ( Services::IP()->isValidIp( $ip ) || Services::IP()->isValidIp( inet_ntop( $ip ) ) ) {
20
+ $rightSide = sprintf( "INET6_ATON('%s')", Services::IP()->isValidIp( $ip ) ? $ip : inet_ntop( $ip ) );
21
  }
 
 
22
 
23
+ if ( !empty( $rightSide ) ) {
24
+ $this->addRawWhere( [ 'ip', '=', $rightSide ] );
25
+ }
26
+ return $this;
27
  }
28
 
29
  /**
src/lib/src/Databases/BotSignals/Handler.php CHANGED
@@ -4,7 +4,4 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals;
4
 
5
  class Handler extends \FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\Handler {
6
 
7
- public function autoCleanDb() {
8
- $this->tableCleanExpired( (int)$this->getTableSchema()->autoexpire );
9
- }
10
  }
4
 
5
  class Handler extends \FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\Handler {
6
 
 
 
 
7
  }
src/lib/src/Databases/BotSignals/Select.php CHANGED
@@ -8,14 +8,4 @@ class Select extends Base\Select {
8
 
9
  use Common;
10
  use Base\Traits\Select_IPTable;
11
-
12
- /**
13
- * @param string $ip
14
- * @return EntryVO
15
- */
16
- public function byIp( string $ip ) {
17
- return $this->filterByIP( inet_pton( $ip ) )
18
- ->setResultsAsVo( true )
19
- ->first();
20
- }
21
  }
8
 
9
  use Common;
10
  use Base\Traits\Select_IPTable;
 
 
 
 
 
 
 
 
 
 
11
  }
src/lib/src/Databases/IPs/Delete.php CHANGED
@@ -33,6 +33,6 @@ class Delete extends Base\Delete {
33
  $this->filterByIp( $sIp )
34
  ->filterByBlacklist();
35
  }
36
- return $this->hasWheres() ? $this->query() : false;
37
  }
38
  }
33
  $this->filterByIp( $sIp )
34
  ->filterByBlacklist();
35
  }
36
+ return $this->hasWheres() && $this->query();
37
  }
38
  }
src/lib/src/Databases/Scanner/Common.php CHANGED
@@ -7,22 +7,22 @@ use FernleafSystems\Wordpress\Services\Services;
7
  trait Common {
8
 
9
  /**
10
- * @param string $sHash
11
  * @return $this
12
  */
13
- public function filterByHash( $sHash ) {
14
- if ( !empty( $sHash ) ) {
15
- $this->filterByHashes( [ $sHash ] );
16
  }
17
  return $this;
18
  }
19
 
20
  /**
21
- * @param string[] $aHashes
22
  * @return $this
23
  */
24
- public function filterByHashes( $aHashes ) {
25
- return $this->addWhereIn( 'hash', $aHashes );
26
  }
27
 
28
  /**
@@ -39,6 +39,13 @@ trait Common {
39
  return $this->addWhereEquals( 'ignored_at', 0 );
40
  }
41
 
 
 
 
 
 
 
 
42
  /**
43
  * @return $this
44
  */
7
  trait Common {
8
 
9
  /**
10
+ * @param string $hash
11
  * @return $this
12
  */
13
+ public function filterByHash( string $hash ) {
14
+ if ( !empty( $hash ) ) {
15
+ $this->addWhereEquals( 'hash', $hash );
16
  }
17
  return $this;
18
  }
19
 
20
  /**
21
+ * @param string[] $hashes
22
  * @return $this
23
  */
24
+ public function filterByHashes( $hashes ) {
25
+ return $this->addWhereIn( 'hash', $hashes );
26
  }
27
 
28
  /**
39
  return $this->addWhereEquals( 'ignored_at', 0 );
40
  }
41
 
42
+ /**
43
+ * @return $this
44
+ */
45
+ public function filterByNoRepairAttempted() {
46
+ return $this->addWhereEquals( 'attempt_repair_at', 0 );
47
+ }
48
+
49
  /**
50
  * @return $this
51
  */
src/lib/src/Logging/Processors/RequestMetaProcessor.php CHANGED
@@ -18,7 +18,7 @@ class RequestMetaProcessor implements ProcessorInterface {
18
  $req = Services::Request();
19
  $leadingPath = Services::WpGeneral()->isMultisite_SubdomainInstall() ? $req->getHost() : '';
20
 
21
- $record[ 'extra' ][ 'meta_request' ] = array_filter( [
22
  'ip' => $isWpCli ? '' : (string)Services::IP()->getRequestIp(),
23
  'rid' => Services::Request()->getID( true, 10 ),
24
  'ts' => microtime( true ),
@@ -26,7 +26,7 @@ class RequestMetaProcessor implements ProcessorInterface {
26
  'verb' => $isWpCli ? '' : strtoupper( $req->getMethod() ),
27
  'path' => $isWpCli ? '' : ( $leadingPath.$req->getPath().( empty( $_GET ) ? '' : '?'.http_build_query( $_GET ) ) ),
28
  'code' => $isWpCli ? '' : http_response_code(),
29
- ] );
30
 
31
  return $record;
32
  }
18
  $req = Services::Request();
19
  $leadingPath = Services::WpGeneral()->isMultisite_SubdomainInstall() ? $req->getHost() : '';
20
 
21
+ $record[ 'extra' ][ 'meta_request' ] = [
22
  'ip' => $isWpCli ? '' : (string)Services::IP()->getRequestIp(),
23
  'rid' => Services::Request()->getID( true, 10 ),
24
  'ts' => microtime( true ),
26
  'verb' => $isWpCli ? '' : strtoupper( $req->getMethod() ),
27
  'path' => $isWpCli ? '' : ( $leadingPath.$req->getPath().( empty( $_GET ) ? '' : '?'.http_build_query( $_GET ) ) ),
28
  'code' => $isWpCli ? '' : http_response_code(),
29
+ ];
30
 
31
  return $record;
32
  }
src/lib/src/Modules/AuditTrail/DB/LoadLogs.php CHANGED
@@ -9,9 +9,12 @@ use FernleafSystems\Wordpress\Services\Services;
9
 
10
  class LoadLogs {
11
 
 
12
  use ModConsumer;
13
  use IpAddressConsumer;
14
 
 
 
15
  /**
16
  * @return LogRecord[]
17
  */
@@ -76,13 +79,21 @@ class LoadLogs {
76
  %s
77
  LEFT JOIN `%s` as `meta`
78
  ON log.id = `meta`.log_ref
79
- ORDER BY log.updated_at DESC;',
 
 
80
  $mod->getDbH_Logs()->getTableSchema()->table,
81
  $this->getCon()->getModule_Data()->getDbH_ReqLogs()->getTableSchema()->table,
82
  $this->getCon()->getModule_Data()->getDbH_IPs()->getTableSchema()->table,
83
  empty( $this->getIP() ) ? '' : sprintf( "AND ips.ip=INET6_ATON('%s')", $this->getIP() ),
84
- $mod->getDbH_Meta()->getTableSchema()->table
 
85
  )
86
  );
87
  }
 
 
 
 
 
88
  }
9
 
10
  class LoadLogs {
11
 
12
+ const DEFAULT_LIMIT = 10000;
13
  use ModConsumer;
14
  use IpAddressConsumer;
15
 
16
+ private $limit = null;
17
+
18
  /**
19
  * @return LogRecord[]
20
  */
79
  %s
80
  LEFT JOIN `%s` as `meta`
81
  ON log.id = `meta`.log_ref
82
+ ORDER BY log.updated_at DESC
83
+ %s
84
+ ',
85
  $mod->getDbH_Logs()->getTableSchema()->table,
86
  $this->getCon()->getModule_Data()->getDbH_ReqLogs()->getTableSchema()->table,
87
  $this->getCon()->getModule_Data()->getDbH_IPs()->getTableSchema()->table,
88
  empty( $this->getIP() ) ? '' : sprintf( "AND ips.ip=INET6_ATON('%s')", $this->getIP() ),
89
+ $mod->getDbH_Meta()->getTableSchema()->table,
90
+ ( $this->limit === 0 ) ? '' : sprintf( 'LIMIT %s', is_null( $this->limit ) ? self::DEFAULT_LIMIT : $this->limit )
91
  )
92
  );
93
  }
94
+
95
+ public function setLimit( int $limit ) {
96
+ $this->limit = $limit;
97
+ return $this;
98
+ }
99
  }
src/lib/src/Modules/AuditTrail/Lib/AuditWriter.php CHANGED
@@ -52,12 +52,6 @@ class AuditWriter extends EventsListener {
52
  }
53
 
54
  protected function onShutdown() {
55
- if ( !$this->getCon()->plugin_deleting ) {
56
- ( new Commit() )
57
- ->setDbHandler( $this->getDbHandler() )
58
- ->commitAudits( $this->getLogs() );
59
- $this->setLogs();
60
- }
61
  }
62
 
63
  /**
52
  }
53
 
54
  protected function onShutdown() {
 
 
 
 
 
 
55
  }
56
 
57
  /**
src/lib/src/Modules/AuditTrail/Lib/LogHandlers/LocalDbWriter.php CHANGED
@@ -79,11 +79,14 @@ class LocalDbWriter extends AbstractProcessingHandler {
79
  ->id;
80
  /** @var ReqLogs\Ops\Select $reqSelector */
81
  $reqSelector = $modData->getDbH_ReqLogs()->getQuerySelector();
82
- $reqIDs = array_map( function ( $rawRecord ) {
83
- return $rawRecord->id;
84
- }, (array)$reqSelector->filterByIP( $ipRecordID )
85
- ->setColumnsToSelect( [ 'id' ] )
86
- ->queryWithResult() );
 
 
 
87
 
88
  /** @var Logs\Ops\Select $select */
89
  $select = $mod->getDbH_Logs()->getQuerySelector();
@@ -124,7 +127,7 @@ class LocalDbWriter extends AbstractProcessingHandler {
124
 
125
  $ipRecordID = ( new IPRecords() )
126
  ->setMod( $this->getCon()->getModule_Data() )
127
- ->loadIP( $this->log[ 'extra' ][ 'meta_request' ][ 'ip' ] )
128
  ->id;
129
  $record->req_ref = ( new ReqLogs\RequestRecords() )
130
  ->setMod( $this->getCon()->getModule_Data() )
79
  ->id;
80
  /** @var ReqLogs\Ops\Select $reqSelector */
81
  $reqSelector = $modData->getDbH_ReqLogs()->getQuerySelector();
82
+ $reqIDs = array_map(
83
+ function ( $rawRecord ) {
84
+ return $rawRecord->id;
85
+ },
86
+ (array)$reqSelector->filterByIP( $ipRecordID )
87
+ ->setColumnsToSelect( [ 'id' ] )
88
+ ->queryWithResult()
89
+ );
90
 
91
  /** @var Logs\Ops\Select $select */
92
  $select = $mod->getDbH_Logs()->getQuerySelector();
127
 
128
  $ipRecordID = ( new IPRecords() )
129
  ->setMod( $this->getCon()->getModule_Data() )
130
+ ->loadIP( $this->log[ 'extra' ][ 'meta_request' ][ 'ip' ] ?? '' )
131
  ->id;
132
  $record->req_ref = ( new ReqLogs\RequestRecords() )
133
  ->setMod( $this->getCon()->getModule_Data() )
src/lib/src/Modules/AuditTrail/Lib/LogTable/LoadRawTableData.php CHANGED
@@ -7,12 +7,10 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\DB\LogRecord;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\Lib\AuditMessageBuilder;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\Lib\Ops\ConvertLegacy;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Traffic;
10
- use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
11
  use FernleafSystems\Wordpress\Services\Services;
12
 
13
- class LoadRawTableData {
14
-
15
- use ModConsumer;
16
 
17
  /**
18
  * @var LogRecord
@@ -38,7 +36,7 @@ class LoadRawTableData {
38
  $data[ 'rid' ] = $this->log->rid ?? __( 'Unknown', 'wp-simple-firewall' );
39
  $data[ 'ip_linked' ] = $this->getColumnContent_RequestDetails();
40
  $data[ 'event' ] = $srvEvents->getEventName( $log->event_slug );
41
- $data[ 'created_since' ] = $this->getColumnContent_Date();
42
  $data[ 'message' ] = $this->getColumnContent_Message();
43
  $data[ 'user' ] = $this->getColumnContent_User();
44
  $data[ 'user_id' ] = $this->getColumnContent_UserID();
@@ -58,6 +56,7 @@ class LoadRawTableData {
58
  return array_filter(
59
  ( new LoadLogs() )
60
  ->setMod( $this->getCon()->getModule_AuditTrail() )
 
61
  ->run(),
62
  function ( $logRecord ) {
63
  return $this->getCon()->loadEventsService()->eventExists( $logRecord->event_slug );
@@ -66,20 +65,7 @@ class LoadRawTableData {
66
  }
67
 
68
  private function getColumnContent_RequestDetails() :string {
69
- return sprintf( '<h6><a href="%s" target="_blank">%s</a></h6>',
70
- $this->getCon()->getModule_Insights()->getUrl_IpAnalysis( $this->log->ip ),
71
- $this->log->ip
72
- );
73
- }
74
-
75
- private function getColumnContent_Date() :string {
76
- return sprintf( '%s<br /><small>%s</small>',
77
- Services::Request()
78
- ->carbon( true )
79
- ->setTimestamp( $this->log->created_at )
80
- ->diffForHumans(),
81
- Services::WpGeneral()->getTimeStringForDisplay( $this->log->created_at )
82
- );
83
  }
84
 
85
  private function getColumnContent_UserID() :string {
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\Lib\AuditMessageBuilder;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\Lib\Ops\ConvertLegacy;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Traffic;
10
+ use FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\LoadData\BaseLoadTableData;
11
  use FernleafSystems\Wordpress\Services\Services;
12
 
13
+ class LoadRawTableData extends BaseLoadTableData {
 
 
14
 
15
  /**
16
  * @var LogRecord
36
  $data[ 'rid' ] = $this->log->rid ?? __( 'Unknown', 'wp-simple-firewall' );
37
  $data[ 'ip_linked' ] = $this->getColumnContent_RequestDetails();
38
  $data[ 'event' ] = $srvEvents->getEventName( $log->event_slug );
39
+ $data[ 'created_since' ] = $this->getColumnContent_Date( $this->log->created_at );
40
  $data[ 'message' ] = $this->getColumnContent_Message();
41
  $data[ 'user' ] = $this->getColumnContent_User();
42
  $data[ 'user_id' ] = $this->getColumnContent_UserID();
56
  return array_filter(
57
  ( new LoadLogs() )
58
  ->setMod( $this->getCon()->getModule_AuditTrail() )
59
+ ->setLimit( (int)Services::Request()->post( 'record_limit', 10000 ) )
60
  ->run(),
61
  function ( $logRecord ) {
62
  return $this->getCon()->loadEventsService()->eventExists( $logRecord->event_slug );
65
  }
66
 
67
  private function getColumnContent_RequestDetails() :string {
68
+ return sprintf( '<h6>%s</h6>', $this->getIpAnalysisLink( (string)$this->log->ip ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  }
70
 
71
  private function getColumnContent_UserID() :string {
src/lib/src/Modules/Base/Processor.php CHANGED
@@ -18,7 +18,6 @@ abstract class Processor {
18
  $this->setMod( $mod );
19
  add_action( 'init', [ $this, 'onWpInit' ], $this->getWpHookPriority( 'init' ) );
20
  add_action( 'wp_loaded', [ $this, 'onWpLoaded' ], $this->getWpHookPriority( 'wp_loaded' ) );
21
- add_action( $mod->prefix( 'plugin_shutdown' ), [ $this, 'onModuleShutdown' ] );
22
  $this->setupCronHooks();
23
  }
24
 
18
  $this->setMod( $mod );
19
  add_action( 'init', [ $this, 'onWpInit' ], $this->getWpHookPriority( 'init' ) );
20
  add_action( 'wp_loaded', [ $this, 'onWpLoaded' ], $this->getWpHookPriority( 'wp_loaded' ) );
 
21
  $this->setupCronHooks();
22
  }
23
 
src/lib/src/Modules/Data/DB/IPs/IPRecords.php CHANGED
@@ -9,20 +9,30 @@ class IPRecords {
9
 
10
  use ModConsumer;
11
 
 
 
12
  public function loadIP( string $ip, bool $autoCreate = true ) :Ops\Record {
13
- /** @var ModCon $mod */
14
- $mod = $this->getMod();
15
- $dbh = $mod->getDbH_IPs();
16
- /** @var Ops\Select $select */
17
- $select = $dbh->getQuerySelector();
18
- $record = $select->filterByIPHuman( $ip )->first();
19
 
20
- if ( empty( $record ) && $autoCreate && $this->addIP( $ip ) ) {
21
- $record = $this->loadIP( $ip, false );
22
  }
23
-
24
- if ( empty( $record ) ) {
25
- throw new \Exception( 'IP Record unavailable' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
27
 
28
  return $record;
9
 
10
  use ModConsumer;
11
 
12
+ private static $ips = [];
13
+
14
  public function loadIP( string $ip, bool $autoCreate = true ) :Ops\Record {
 
 
 
 
 
 
15
 
16
+ if ( !empty( self::$ips[ $ip ] ) ) {
17
+ $record = self::$ips[ $ip ];
18
  }
19
+ else {
20
+ /** @var ModCon $mod */
21
+ $mod = $this->getMod();
22
+ $dbh = $mod->getDbH_IPs();
23
+ /** @var Ops\Select $select */
24
+ $select = $dbh->getQuerySelector();
25
+ $record = $select->filterByIPHuman( $ip )->first();
26
+
27
+ if ( empty( $record ) && $autoCreate && $this->addIP( $ip ) ) {
28
+ $record = $this->loadIP( $ip, false );
29
+ }
30
+
31
+ if ( empty( $record ) ) {
32
+ throw new \Exception( 'IP Record unavailable' );
33
+ }
34
+
35
+ self::$ips[ $ip ] = $record;
36
  }
37
 
38
  return $record;
src/lib/src/Modules/Data/DB/IPs/Ops/Common.php CHANGED
@@ -2,13 +2,9 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Data\DB\IPs\Ops;
4
 
5
- trait Common {
6
 
7
- public function filterByIP( string $ip ) {
8
- return $this->addWhereEquals( 'ip', $ip );
9
- }
10
 
11
- public function filterByIPHuman( string $ip ) :self {
12
- return $this->filterByIP( inet_pton( $ip ) );
13
- }
14
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Data\DB\IPs\Ops;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Core\Databases\Base\Traits\FilterByIP;
6
 
7
+ trait Common {
 
 
8
 
9
+ use FilterByIP;
 
 
10
  }
src/lib/src/Modules/Data/DB/ReqLogs/LoadLogs.php CHANGED
@@ -40,7 +40,7 @@ class LoadLogs {
40
  ON req.ip_ref = ips.id
41
  ORDER BY `req`.created_at DESC;',
42
  $mod->getDbH_ReqLogs()->getTableSchema()->table,
43
- empty( $ip ) ? '' : sprintf( "WHERE `ips`.ip==INET6_ATON('%s')", $ip ),
44
  $this->getCon()->getModule_Data()->getDbH_IPs()->getTableSchema()->table
45
  )
46
  );
40
  ON req.ip_ref = ips.id
41
  ORDER BY `req`.created_at DESC;',
42
  $mod->getDbH_ReqLogs()->getTableSchema()->table,
43
+ empty( $ip ) ? '' : sprintf( "WHERE `ips`.ip=INET6_ATON('%s')", $ip ),
44
  $this->getCon()->getModule_Data()->getDbH_IPs()->getTableSchema()->table
45
  )
46
  );
src/lib/src/Modules/GeoIp/Lookup.php CHANGED
@@ -25,6 +25,10 @@ class Lookup {
25
  }
26
 
27
  try {
 
 
 
 
28
  $ipRecord = ( new IPRecords() )
29
  ->setMod( $this->getCon()->getModule_Data() )
30
  ->loadIP( $this->getIP(), true );
25
  }
26
 
27
  try {
28
+ if ( empty( $ip ) || !Services::IP()->isValidIp_PublicRemote( $ip ) ) {
29
+ throw new \Exception( 'Not a valid public IP address' );
30
+ }
31
+
32
  $ipRecord = ( new IPRecords() )
33
  ->setMod( $this->getCon()->getModule_Data() )
34
  ->loadIP( $this->getIP(), true );
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/Diff.php CHANGED
@@ -35,15 +35,17 @@ class Diff extends BaseOps {
35
 
36
  /**
37
  * The WP Diff is empty if the only difference is white space
38
- * @since v10.3 always use WP Hashes DIFF
39
- *
40
- * $diff = $this->useWpDiff( $original, $current );
41
- * if ( empty( $diff ) ) {
42
- * $this->useWpHashes( $original, $current );
43
- * }
44
  */
 
 
 
 
 
 
45
 
46
- return $this->useWpHashes( $original, $current );
47
  }
48
 
49
  /**
35
 
36
  /**
37
  * The WP Diff is empty if the only difference is white space
38
+ * @since 10.3 - always use WP Hashes DIFF
39
+ * @since 12.0 - use WPHashes and fallback to WP Diff
 
 
 
 
40
  */
41
+ try {
42
+ $diff = $this->useWpHashes( $original, $current );
43
+ }
44
+ catch ( \Exception $e ) {
45
+ $diff = $this->useWpDiff( $original, $current );
46
+ }
47
 
48
+ return $diff;
49
  }
50
 
51
  /**
src/lib/src/Modules/HackGuard/Lib/Reports/ScanRepairs.php CHANGED
@@ -85,7 +85,7 @@ class ScanRepairs extends BaseReporter {
85
  'hrefs' => [
86
  'audit_trail' => $this->getCon()
87
  ->getModule_Insights()
88
- ->getUrl_SubInsightsPage( 'audit' ),
89
  ],
90
  ]
91
  );
85
  'hrefs' => [
86
  'audit_trail' => $this->getCon()
87
  ->getModule_Insights()
88
+ ->getUrl_SubInsightsPage( 'audit_trail' ),
89
  ],
90
  ]
91
  );
src/lib/src/Modules/HackGuard/Scan/Controller/Base.php CHANGED
@@ -67,9 +67,24 @@ abstract class Base extends ExecOnceModConsumer {
67
  $results->removeItemByHash( $item->hash );
68
  }
69
  }
70
- ( new HackGuard\Scan\Results\ResultsDelete() )
71
- ->setScanController( $this )
72
- ->delete( $results );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
74
 
75
  public function createFileDownloadLink( int $recordID ) :string {
@@ -114,6 +129,7 @@ abstract class Base extends ExecOnceModConsumer {
114
  /** @var Databases\Scanner\Select $sel */
115
  $sel = $this->getScanResultsDbHandler()->getQuerySelector();
116
  $sel->filterByScan( $this->getSlug() )
 
117
  ->filterByNotIgnored();
118
  return ( new HackGuard\Scan\Results\ConvertBetweenTypes() )
119
  ->setScanController( $this )
67
  $results->removeItemByHash( $item->hash );
68
  }
69
  }
70
+ try {
71
+ ( new HackGuard\Scan\Results\ResultsDelete() )
72
+ ->setScanController( $this )
73
+ ->delete( $results, true );
74
+ }
75
+ catch ( \Exception $e ) {
76
+ }
77
+
78
+ $this->cleanStalesDeletedResults();
79
+ }
80
+
81
+ public function cleanStalesDeletedResults() {
82
+ /** @var Databases\Scanner\Delete $deleter */
83
+ $deleter = $this->getScanResultsDbHandler()->getQueryDeleter();
84
+ $deleter->addWhere( 'deleted_at', 0, '>' )
85
+ ->addWhereOlderThan( Services::Request()->carbon()->subMonths( 1 )->timestamp, 'deleted_at' )
86
+ ->filterByScan( $this->getSlug() )
87
+ ->query();
88
  }
89
 
90
  public function createFileDownloadLink( int $recordID ) :string {
129
  /** @var Databases\Scanner\Select $sel */
130
  $sel = $this->getScanResultsDbHandler()->getQuerySelector();
131
  $sel->filterByScan( $this->getSlug() )
132
+ ->filterByNoRepairAttempted()
133
  ->filterByNotIgnored();
134
  return ( new HackGuard\Scan\Results\ConvertBetweenTypes() )
135
  ->setScanController( $this )
src/lib/src/Modules/HackGuard/Scan/Results/ResultsDelete.php CHANGED
@@ -15,39 +15,65 @@ class ResultsDelete {
15
  use ScanControllerConsumer;
16
 
17
  /**
18
- * @param Scans\Base\ResultsSet $oResultsToDelete
 
19
  * @return bool
 
20
  */
21
- public function delete( $oResultsToDelete ) {
22
- $aHashes = array_map(
23
- function ( $oItem ) {
24
- /** @var Scans\Base\ResultItem $oItem */
25
- return $oItem->hash;
 
 
 
26
  },
27
- $oResultsToDelete->getAllItems()
28
- );
29
-
30
- $bSuccess = true;
31
- if ( !empty( $aHashes ) ) {
32
- /** @var Databases\Scanner\Delete $oDel */
33
- $oDel = $this->getScanController()
34
- ->getScanResultsDbHandler()
35
- ->getQueryDeleter();
36
- $bSuccess = $oDel->filterByHashes( $aHashes )
37
- ->query();
 
 
 
 
38
  }
39
- return $bSuccess;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  }
41
 
42
  /**
43
  * @return $this
44
  */
45
  public function deleteAllForScan() {
46
- /** @var Databases\Scanner\Delete $oDel */
47
- $oDel = $this->getScanController()
48
- ->getScanResultsDbHandler()
49
- ->getQueryDeleter();
50
- $oDel->forScan( $this->getScanController()->getSlug() );
51
  return $this;
52
  }
53
  }
15
  use ScanControllerConsumer;
16
 
17
  /**
18
+ * @param Scans\Base\ResultsSet $resultsToDelete
19
+ * @param bool $softDelete
20
  * @return bool
21
+ * @throws \Exception
22
  */
23
+ public function delete( $resultsToDelete, bool $softDelete = true ) {
24
+ if ( !$resultsToDelete->hasItems() ) {
25
+ throw new \Exception( 'No items' );
26
+ }
27
+
28
+ $hashes = array_filter( array_map(
29
+ function ( $item ) {
30
+ return (string)$item->hash;
31
  },
32
+ $resultsToDelete->getAllItems()
33
+ ) );
34
+
35
+ $success = true;
36
+ if ( !empty( $hashes ) ) {
37
+ if ( $softDelete ) {
38
+ $success = $this->softDelete( $hashes );
39
+ }
40
+ else {
41
+ /** @var Databases\Scanner\Delete $deleter */
42
+ $deleter = $this->getScanController()
43
+ ->getScanResultsDbHandler()
44
+ ->getQueryDeleter();
45
+ $success = $deleter->filterByHashes( $hashes )->query();
46
+ }
47
  }
48
+ return $success;
49
+ }
50
+
51
+ protected function softDelete( array $hashes ) :bool {
52
+ /** @var Databases\Scanner\Update $updater */
53
+ $updater = $this->getScanController()
54
+ ->getScanResultsDbHandler()
55
+ ->getQueryUpdater();
56
+ // This is an inefficient hack for multiple soft-deletes until we rewrite a custom SQL updater
57
+ foreach ( $hashes as $hash ) {
58
+ $updater->setSoftDeleted()
59
+ ->setUpdateWheres( [
60
+ 'hash' => $hash
61
+ ] )
62
+ ->query();
63
+ }
64
+
65
+ return true;
66
  }
67
 
68
  /**
69
  * @return $this
70
  */
71
  public function deleteAllForScan() {
72
+ /** @var Databases\Scanner\Delete $deleter */
73
+ $deleter = $this->getScanController()
74
+ ->getScanResultsDbHandler()
75
+ ->getQueryDeleter();
76
+ $deleter->forScan( $this->getScanController()->getSlug() );
77
  return $this;
78
  }
79
  }
src/lib/src/Modules/HackGuard/Scan/Results/ResultsStore.php CHANGED
@@ -16,17 +16,53 @@ class ResultsStore {
16
 
17
  /**
18
  * @param Scans\Base\ResultsSet $resultsToStore
 
19
  */
20
  public function store( $resultsToStore ) {
 
 
 
 
21
  $scanCon = $this->getScanController();
22
- $inserter = $scanCon->getScanResultsDbHandler()
23
- ->getQueryInserter();
24
  $VOs = ( new ConvertBetweenTypes() )
25
  ->setScanController( $scanCon )
26
  ->fromResultsToVOs( $resultsToStore );
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  foreach ( $VOs as $vo ) {
29
- $inserter->insert( $vo );
30
  }
31
  }
32
  }
16
 
17
  /**
18
  * @param Scans\Base\ResultsSet $resultsToStore
19
+ * @throws \Exception
20
  */
21
  public function store( $resultsToStore ) {
22
+ if ( !$resultsToStore->hasItems() ) {
23
+ throw new \Exception( 'No items' );
24
+ }
25
+
26
  $scanCon = $this->getScanController();
27
+ $dbh = $scanCon->getScanResultsDbHandler();
28
+
29
  $VOs = ( new ConvertBetweenTypes() )
30
  ->setScanController( $scanCon )
31
  ->fromResultsToVOs( $resultsToStore );
32
 
33
+ // Try to find all older, but deleted results.
34
+ /** @var Databases\Scanner\Select $selector */
35
+ $selector = $dbh->getQuerySelector();
36
+ /** @var Databases\Scanner\EntryVO[] $existing */
37
+ $existing = $selector->filterByScan( $scanCon->getSlug() )
38
+ ->filterByHashes( array_keys( $VOs ) )
39
+ ->setIncludeSoftDeleted( true )
40
+ ->query();
41
+
42
+ if ( !empty( $existing ) ) {
43
+ foreach ( $existing as $existingRecord ) {
44
+ foreach ( $VOs as $vo ) {
45
+ if ( $existingRecord->hash === $vo->hash ) {
46
+
47
+ $updateData = $vo->getRawData();
48
+ $updateData[ 'deleted_at' ] = 0;
49
+
50
+ $dbh->getQueryUpdater()
51
+ ->setUpdateWheres( [
52
+ 'scan' => $scanCon->getSlug(),
53
+ 'hash' => $existingRecord->hash,
54
+ ] )
55
+ ->setUpdateData( $updateData )
56
+ ->query();
57
+ unset( $VOs[ $vo->hash ] );
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
  foreach ( $VOs as $vo ) {
65
+ $dbh->getQueryInserter()->insert( $vo );
66
  }
67
  }
68
  }
src/lib/src/Modules/HackGuard/Scan/Results/ResultsUpdate.php CHANGED
@@ -27,27 +27,35 @@ class ResultsUpdate {
27
 
28
  $itemsToDelete = ( new Scans\Base\DiffResultForStorage() )->diff( $existing, $newCopy );
29
 
30
- ( new ResultsDelete() )
31
- ->setScanController( $scanCon )
32
- ->delete( $itemsToDelete );
 
 
 
 
33
 
34
- ( new ResultsStore() )
35
- ->setScanController( $scanCon )
36
- ->store( $newCopy );
37
-
38
- $updater = $scanCon->getScanResultsDbHandler()->getQueryUpdater();
39
- /** @var Databases\Scanner\EntryVO $vo */
40
- $converter = ( new ConvertBetweenTypes() )->setScanController( $scanCon );
41
- foreach ( $converter->fromResultsToVOs( $existing ) as $vo ) {
42
- $updater->reset()
43
- ->setUpdateData( $vo->getRawData() )
44
- ->setUpdateWheres(
45
- [
 
 
 
46
  'scan' => $scanCon->getSlug(),
47
  'hash' => $vo->hash,
48
- ]
49
- )
50
- ->query();
 
51
  }
52
  }
53
  }
27
 
28
  $itemsToDelete = ( new Scans\Base\DiffResultForStorage() )->diff( $existing, $newCopy );
29
 
30
+ try {
31
+ ( new ResultsDelete() )
32
+ ->setScanController( $scanCon )
33
+ ->delete( $itemsToDelete );
34
+ }
35
+ catch ( \Exception $e ) {
36
+ }
37
 
38
+ try {
39
+ ( new ResultsStore() )
40
+ ->setScanController( $scanCon )
41
+ ->store( $newCopy );
42
+ }
43
+ catch ( \Exception $e ) {
44
+ }
45
+
46
+ if ( $existing->hasItems() ) {
47
+ $updater = $scanCon->getScanResultsDbHandler()->getQueryUpdater();
48
+ /** @var Databases\Scanner\EntryVO $vo */
49
+ $converter = ( new ConvertBetweenTypes() )->setScanController( $scanCon );
50
+ foreach ( $converter->fromResultsToVOs( $existing ) as $vo ) {
51
+ $updater->reset()
52
+ ->setUpdateWheres( [
53
  'scan' => $scanCon->getSlug(),
54
  'hash' => $vo->hash,
55
+ ] )
56
+ ->setUpdateData( $vo->getRawData() )
57
+ ->query();
58
+ }
59
  }
60
  }
61
  }
src/lib/src/Modules/IPs/DB/BotSignal/BotSignalRecord.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal;
4
+
5
+ /**
6
+ * NOT a true DB Model
7
+ * @property string $ip
8
+ */
9
+ class BotSignalRecord extends Ops\Record {
10
+
11
+ }
src/lib/src/Modules/IPs/DB/BotSignal/LoadBotSignalRecords.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components\IpAddressConsumer;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
8
+ use FernleafSystems\Wordpress\Services\Services;
9
+
10
+ class LoadBotSignalRecords {
11
+
12
+ use ModConsumer;
13
+ use IpAddressConsumer;
14
+
15
+ public function loadRecord() :BotSignalRecord {
16
+ $raw = $this->selectRaw();
17
+ if ( empty( $raw ) ) {
18
+ throw new \Exception( 'No record' );
19
+ }
20
+ return ( new BotSignalRecord() )->applyFromArray( $raw );
21
+ }
22
+
23
+ private function selectRaw() :array {
24
+ /** @var ModCon $mod */
25
+ $mod = $this->getMod();
26
+ $raw = Services::WpDb()->selectRow(
27
+ sprintf( "SELECT ips.ip, bs.*
28
+ FROM `%s` as bs
29
+ INNER JOIN `%s` as ips
30
+ ON `ips`.id = `bs`.ip_ref
31
+ AND `ips`.`ip`=INET6_ATON('%s')
32
+ ORDER BY `bs`.updated_at DESC
33
+ LIMIT 1;",
34
+ $mod->getDbH_BotSignal()->getTableSchema()->table,
35
+ $this->getCon()->getModule_Data()->getDbH_IPs()->getTableSchema()->table,
36
+ $this->getIP()
37
+ )
38
+ );
39
+ return is_array( $raw ) ? $raw : [];
40
+ }
41
+ }
src/lib/src/Modules/IPs/DB/BotSignal/Ops/Common.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal\Ops;
4
+
5
+ trait Common {
6
+
7
+ public function filterByIP( int $ipRef ) {
8
+ return $this->addWhereEquals( 'ip_ref', $ipRef );
9
+ }
10
+ }
src/lib/src/Modules/IPs/DB/BotSignal/Ops/Delete.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal\Ops;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
6
+
7
+ class Delete extends Base\Delete {
8
+
9
+ use Common;
10
+ }
src/lib/src/Modules/IPs/DB/BotSignal/Ops/Handler.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal\Ops;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
6
+
7
+ class Handler extends Base\Handler {
8
+
9
+ }
src/lib/src/Modules/IPs/DB/BotSignal/Ops/Insert.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal\Ops;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
6
+
7
+ class Insert extends Base\Insert {
8
+
9
+ }
src/lib/src/Modules/IPs/DB/BotSignal/Ops/Record.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal\Ops;
4
+
5
+ /**
6
+ * @property int $ip_ref
7
+ * @property int $notbot_at
8
+ * @property int $frontpage_at
9
+ * @property int $loginpage_at
10
+ * @property int $bt404_at
11
+ * @property int $btcheese_at
12
+ * @property int $btfake_at
13
+ * @property int $btinvalidscript_at
14
+ * @property int $btloginfail_at
15
+ * @property int $btlogininvalid_at
16
+ * @property int $btua_at
17
+ * @property int $btxml_at
18
+ * @property int $cooldown_at
19
+ * @property int $auth_at
20
+ * @property int $offense_at
21
+ * @property int $blocked_at
22
+ * @property int $unblocked_at
23
+ * @property int $bypass_at
24
+ * @property int $humanspam_at
25
+ * @property int $markspam_at
26
+ * @property int $unmarkspam_at
27
+ * @property int $captchapass_at
28
+ * @property int $captchafail_at
29
+ * @property int $ratelimit_at
30
+ * @property int $updated_at
31
+ * @property int $snsent_at
32
+ */
33
+ class Record extends \FernleafSystems\Wordpress\Plugin\Core\Databases\Base\Record {
34
+
35
+ }
src/lib/src/Modules/IPs/DB/BotSignal/Ops/Select.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal\Ops;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\Traits\Select_IPTable;
7
+
8
+ class Select extends Base\Select {
9
+
10
+ use Common;
11
+ }
src/lib/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php CHANGED
@@ -2,12 +2,16 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots;
4
 
5
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\EntryVO;
6
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\Select;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Databases\Session;
 
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components\IpAddressConsumer;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops\LookupIpOnList;
10
- use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
 
 
 
 
 
11
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
12
  use FernleafSystems\Wordpress\Services\Services;
13
 
@@ -19,43 +23,61 @@ class BotSignalsRecord {
19
  public function delete() :bool {
20
  /** @var ModCon $mod */
21
  $mod = $this->getMod();
22
- /** @var Select $select */
23
- $select = $mod->getDbHandler_BotSignals()->getQueryDeleter();
24
- return $select->filterByIPHuman( $this->getIP() )->query();
25
  }
26
 
27
- public function retrieve( bool $storeOnLoad = true ) :EntryVO {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  /** @var ModCon $mod */
29
  $mod = $this->getMod();
30
 
31
- $e = $this->dbLoad();
32
- if ( !$e instanceof EntryVO ) {
33
- $e = new EntryVO();
34
- $e->ip = $this->getIP();
35
  }
36
 
37
  $ipOnList = ( new LookupIpOnList() )
38
  ->setDbHandler( $mod->getDbHandler_IPs() )
39
- ->setIP( $e->ip )
40
  ->lookupIp();
41
 
42
  if ( !empty( $ipOnList ) ) {
43
- if ( empty( $e->bypass_at ) && $ipOnList->list === $mod::LIST_MANUAL_WHITE ) {
44
- $e->bypass_at = $ipOnList->created_at;
45
  }
46
- if ( empty( $e->offense_at ) && $ipOnList->list === $mod::LIST_AUTO_BLACK ) {
47
- $e->offense_at = $ipOnList->last_access_at;
48
  }
49
- $e->blocked_at = $ipOnList->blocked_at;
50
  }
51
 
52
- if ( empty( $e->notbot_at ) && Services::IP()->getRequestIp() === $this->getIP() ) {
53
- $e->notbot_at = $mod->getBotSignalsController()
54
  ->getHandlerNotBot()
55
  ->hasCookie() ? Services::Request()->ts() : 0;
56
  }
57
 
58
- if ( empty( $e->auth_at ) ) {
59
  $dbhSessions = $this->getCon()
60
  ->getModule_Sessions()
61
  ->getDbHandler_Sessions();
@@ -64,43 +86,48 @@ class BotSignalsRecord {
64
  $session = $selector->setIncludeSoftDeleted( true )
65
  ->filterByIp( $this->getIP() )
66
  ->first();
67
- $e->auth_at = empty( $session ) ? 0 : $session->created_at;
68
  }
69
 
70
  if ( $storeOnLoad ) {
71
- $this->store( $e );
72
  }
73
 
74
- return $e;
75
  }
76
 
77
  /**
78
- * @return EntryVO|null
79
  */
80
  private function dbLoad() {
81
- /** @var ModCon $mod */
82
- $mod = $this->getMod();
83
- /** @var Select $select */
84
- $select = $mod->getDbHandler_BotSignals()->getQuerySelector();
85
- /** @var EntryVO $record */
86
- return $select->filterByIPHuman( $this->getIP() )->first();
 
 
 
 
 
87
  }
88
 
89
- public function store( EntryVO $entry ) :bool {
90
  /** @var ModCon $mod */
91
  $mod = $this->getMod();
92
 
93
- if ( empty( $entry->id ) ) {
94
- $success = $mod->getDbHandler_BotSignals()
95
  ->getQueryInserter()
96
- ->insert( $entry );
97
  }
98
  else {
99
- $data = $entry->getRawData();
100
  $data[ 'updated_at' ] = Services::Request()->ts();
101
- $success = $mod->getDbHandler_BotSignals()
102
  ->getQueryUpdater()
103
- ->updateById( $entry->id, $data );
104
  }
105
  return $success;
106
  }
@@ -108,22 +135,28 @@ class BotSignalsRecord {
108
  /**
109
  * @param string $field
110
  * @param int|null $ts
111
- * @return EntryVO
112
  * @throws \LogicException
113
  */
114
- public function updateSignalField( string $field, $ts = null ) :EntryVO {
115
  /** @var ModCon $mod */
116
  $mod = $this->getMod();
117
 
118
- if ( !$mod->getDbHandler_BotSignals()->getTableSchema()->hasColumn( $field ) ) {
119
  throw new \LogicException( sprintf( '"%s" is not a valid column on Bot Signals', $field ) );
120
  }
121
 
122
- $entry = $this->retrieve( false ); // false as we're going to store it anyway
123
- $entry->{$field} = is_null( $ts ) ? Services::Request()->ts() : $ts;
124
 
125
- $this->store( $entry );
 
 
 
126
 
127
- return $entry;
 
 
 
128
  }
129
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots;
4
 
 
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Databases\Session;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Data\DB\IPs;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components\IpAddressConsumer;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops\LookupIpOnList;
9
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\{
10
+ DB\BotSignal\BotSignalRecord,
11
+ DB\BotSignal\LoadBotSignalRecords,
12
+ ModCon,
13
+ DB\BotSignal
14
+ };
15
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
16
  use FernleafSystems\Wordpress\Services\Services;
17
 
23
  public function delete() :bool {
24
  /** @var ModCon $mod */
25
  $mod = $this->getMod();
26
+ /** @var BotSignal\Ops\Select $select */
27
+ $select = $mod->getDbH_BotSignal()->getQueryDeleter();
28
+ return $select->filterByIP( $this->getIPRecord()->id )->query();
29
  }
30
 
31
+ public function retrieveNotBotAt() :int {
32
+ /** @var ModCon $mod */
33
+ $mod = $this->getMod();
34
+ return (int)Services::WpDb()->getVar(
35
+ sprintf( "SELECT bs.notbot_at
36
+ FROM `%s` as bs
37
+ INNER JOIN `%s` as ips
38
+ ON `ips`.id = `bs`.ip_ref
39
+ AND `ips`.`ip`=INET6_ATON('%s')
40
+ ORDER BY `bs`.updated_at DESC
41
+ LIMIT 1;",
42
+ $mod->getDbH_BotSignal()->getTableSchema()->table,
43
+ $this->getCon()->getModule_Data()->getDbH_IPs()->getTableSchema()->table,
44
+ $this->getIP()
45
+ )
46
+ );
47
+ }
48
+
49
+ public function retrieve( bool $storeOnLoad = true ) :BotSignalRecord {
50
  /** @var ModCon $mod */
51
  $mod = $this->getMod();
52
 
53
+ $r = $this->dbLoad();
54
+ if ( empty( $r ) ) {
55
+ $r = new BotSignalRecord();
56
+ $r->ip_ref = $this->getIPRecord()->id;
57
  }
58
 
59
  $ipOnList = ( new LookupIpOnList() )
60
  ->setDbHandler( $mod->getDbHandler_IPs() )
61
+ ->setIP( $this->getIP() )
62
  ->lookupIp();
63
 
64
  if ( !empty( $ipOnList ) ) {
65
+ if ( empty( $r->bypass_at ) && $ipOnList->list === $mod::LIST_MANUAL_WHITE ) {
66
+ $r->bypass_at = $ipOnList->created_at;
67
  }
68
+ if ( empty( $r->offense_at ) && $ipOnList->list === $mod::LIST_AUTO_BLACK ) {
69
+ $r->offense_at = $ipOnList->last_access_at;
70
  }
71
+ $r->blocked_at = $ipOnList->blocked_at;
72
  }
73
 
74
+ if ( empty( $r->notbot_at ) && Services::IP()->getRequestIp() === $this->getIP() ) {
75
+ $r->notbot_at = $mod->getBotSignalsController()
76
  ->getHandlerNotBot()
77
  ->hasCookie() ? Services::Request()->ts() : 0;
78
  }
79
 
80
+ if ( empty( $r->auth_at ) ) {
81
  $dbhSessions = $this->getCon()
82
  ->getModule_Sessions()
83
  ->getDbHandler_Sessions();
86
  $session = $selector->setIncludeSoftDeleted( true )
87
  ->filterByIp( $this->getIP() )
88
  ->first();
89
+ $r->auth_at = empty( $session ) ? 0 : $session->created_at;
90
  }
91
 
92
  if ( $storeOnLoad ) {
93
+ $this->store( $r );
94
  }
95
 
96
+ return $r;
97
  }
98
 
99
  /**
100
+ * @return BotSignal\BotSignalRecord|null
101
  */
102
  private function dbLoad() {
103
+ try {
104
+ $record = ( new LoadBotSignalRecords() )
105
+ ->setMod( $this->getMod() )
106
+ ->setIP( $this->getIP() )
107
+ ->loadRecord();
108
+ }
109
+ catch ( \Exception $e ) {
110
+ $record = null;
111
+ }
112
+
113
+ return $record;
114
  }
115
 
116
+ public function store( BotSignalRecord $record ) :bool {
117
  /** @var ModCon $mod */
118
  $mod = $this->getMod();
119
 
120
+ if ( empty( $record->id ) ) {
121
+ $success = $mod->getDbH_BotSignal()
122
  ->getQueryInserter()
123
+ ->insert( $record );
124
  }
125
  else {
126
+ $data = $record->getRawData();
127
  $data[ 'updated_at' ] = Services::Request()->ts();
128
+ $success = $mod->getDbH_BotSignal()
129
  ->getQueryUpdater()
130
+ ->updateById( $record->id, $data );
131
  }
132
  return $success;
133
  }
135
  /**
136
  * @param string $field
137
  * @param int|null $ts
138
+ * @return BotSignalRecord
139
  * @throws \LogicException
140
  */
141
+ public function updateSignalField( string $field, $ts = null ) :BotSignalRecord {
142
  /** @var ModCon $mod */
143
  $mod = $this->getMod();
144
 
145
+ if ( !$mod->getDbH_BotSignal()->getTableSchema()->hasColumn( $field ) ) {
146
  throw new \LogicException( sprintf( '"%s" is not a valid column on Bot Signals', $field ) );
147
  }
148
 
149
+ $record = $this->retrieve( false ); // false as we're going to store it anyway
150
+ $record->{$field} = is_null( $ts ) ? Services::Request()->ts() : $ts;
151
 
152
+ $this->store( $record );
153
+
154
+ return $record;
155
+ }
156
 
157
+ private function getIPRecord() :IPs\Ops\Record {
158
+ return ( new IPs\IPRecords() )
159
+ ->setMod( $this->getCon()->getModule_Data() )
160
+ ->loadIP( $this->getIP(), true );
161
  }
162
  }
src/lib/src/Modules/IPs/Lib/Bots/Calculator/BaseBuildScores.php CHANGED
@@ -2,15 +2,14 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\Calculator;
4
 
5
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\EntryVoConsumer;
6
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\EntryVO;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
  use FernleafSystems\Wordpress\Services\Services;
9
  use FernleafSystems\Wordpress\Services\Utilities\Net\IpID;
10
 
11
  abstract class BaseBuildScores {
12
 
13
- use EntryVoConsumer;
14
  use ModConsumer;
15
 
16
  abstract public function build() :array;
@@ -37,15 +36,16 @@ abstract class BaseBuildScores {
37
  }
38
 
39
  protected function getAllFields( $filterForMethods = false ) :array {
40
- $botSignalDBH = shield_security_get_plugin()->getController()
41
- ->getModule_IPs()
42
- ->getDbHandler_BotSignals();
43
  $fields = array_map(
44
  function ( $col ) {
45
  return str_replace( '_at', '', $col );
46
  },
47
  array_filter(
48
- $botSignalDBH->getTableSchema()->getColumnNames(),
 
 
 
 
49
  function ( $col ) {
50
  return preg_match( '#_at$#', $col ) &&
51
  !in_array( $col, [ 'snsent_at', 'updated_at', 'deleted_at' ] );
@@ -61,8 +61,4 @@ abstract class BaseBuildScores {
61
 
62
  return $fields;
63
  }
64
-
65
- protected function getRecord() :EntryVO {
66
- return $this->getEntryVO();
67
- }
68
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\Calculator;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Core\Databases\Common\RecordConsumer;
 
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
7
  use FernleafSystems\Wordpress\Services\Services;
8
  use FernleafSystems\Wordpress\Services\Utilities\Net\IpID;
9
 
10
  abstract class BaseBuildScores {
11
 
12
+ use RecordConsumer;
13
  use ModConsumer;
14
 
15
  abstract public function build() :array;
36
  }
37
 
38
  protected function getAllFields( $filterForMethods = false ) :array {
 
 
 
39
  $fields = array_map(
40
  function ( $col ) {
41
  return str_replace( '_at', '', $col );
42
  },
43
  array_filter(
44
+ $this->getCon()
45
+ ->getModule_IPs()
46
+ ->getDbH_BotSignal()
47
+ ->getTableSchema()
48
+ ->getColumnNames(),
49
  function ( $col ) {
50
  return preg_match( '#_at$#', $col ) &&
51
  !in_array( $col, [ 'snsent_at', 'updated_at', 'deleted_at' ] );
61
 
62
  return $fields;
63
  }
 
 
 
 
64
  }
src/lib/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php CHANGED
@@ -4,6 +4,8 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\Calculato
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\EntryVO;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components\IpAddressConsumer;
 
 
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\BotSignalsRecord;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
9
  use FernleafSystems\Wordpress\Services\Services;
@@ -17,7 +19,7 @@ class CalculateVisitorBotScores {
17
 
18
  public function scores() :array {
19
  $this->scores = ( new BuildScores() )
20
- ->setEntryVO( $this->loadEntry() )
21
  ->setMod( $this->getMod() )
22
  ->build();
23
  return $this->getActiveScores();
@@ -40,11 +42,12 @@ class CalculateVisitorBotScores {
40
  );
41
  }
42
 
43
- private function loadEntry() :EntryVO {
44
  $ip = $this->getIP();
45
  if ( empty( $ip ) ) {
46
  $ip = Services::IP()->getRequestIp();
47
  }
 
48
  try {
49
  $entry = ( new BotSignalsRecord() )
50
  ->setMod( $this->getMod() )
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\EntryVO;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components\IpAddressConsumer;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal\BotSignalRecord;
8
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal\LoadBotSignalRecords;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\BotSignalsRecord;
10
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
11
  use FernleafSystems\Wordpress\Services\Services;
19
 
20
  public function scores() :array {
21
  $this->scores = ( new BuildScores() )
22
+ ->setRecord( $this->loadRecord() )
23
  ->setMod( $this->getMod() )
24
  ->build();
25
  return $this->getActiveScores();
42
  );
43
  }
44
 
45
+ private function loadRecord() :BotSignalRecord {
46
  $ip = $this->getIP();
47
  if ( empty( $ip ) ) {
48
  $ip = Services::IP()->getRequestIp();
49
  }
50
+
51
  try {
52
  $entry = ( new BotSignalsRecord() )
53
  ->setMod( $this->getMod() )
src/lib/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php CHANGED
@@ -12,10 +12,30 @@ class InsertNotBotJs extends ExecOnceModConsumer {
12
  protected function canRun() :bool {
13
  $req = Services::Request();
14
  return $req->query( 'force_notbot' ) == 1
 
15
  || ( $req->ts() - ( new BotSignalsRecord() )
16
  ->setMod( $this->getMod() )
17
  ->setIP( Services::IP()->getRequestIp() )
18
- ->retrieve()->notbot_at ) > MINUTE_IN_SECONDS*45;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  }
20
 
21
  protected function run() {
12
  protected function canRun() :bool {
13
  $req = Services::Request();
14
  return $req->query( 'force_notbot' ) == 1
15
+ || $this->isForcedForOptimisationPlugins()
16
  || ( $req->ts() - ( new BotSignalsRecord() )
17
  ->setMod( $this->getMod() )
18
  ->setIP( Services::IP()->getRequestIp() )
19
+ ->retrieveNotBotAt() ) > MINUTE_IN_SECONDS*45;
20
+ }
21
+
22
+ /**
23
+ * Looks for the presence of certain caching plugins and forces notbot to load.
24
+ */
25
+ private function isForcedForOptimisationPlugins() :bool {
26
+ return (bool)apply_filters(
27
+ 'shield/notbot_force_load',
28
+ !empty( array_intersect(
29
+ array_map( 'basename', Services::WpPlugins()->getActivePlugins() ),
30
+ [
31
+ 'wpFastestCache.php',
32
+ 'wp-cache.php', // Super Cache
33
+ 'wp-hummingbird.php',
34
+ 'sg-cachepress.php',
35
+ 'autoptimize.php',
36
+ ]
37
+ ) ) > 0
38
+ );
39
  }
40
 
41
  protected function run() {
src/lib/src/Modules/IPs/Lib/Bots/ShieldNET/BuildData.php CHANGED
@@ -2,8 +2,7 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\ShieldNET;
4
 
5
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\EntryVO;
6
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\Select;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
9
  use FernleafSystems\Wordpress\Services\Services;
@@ -15,9 +14,9 @@ class BuildData {
15
 
16
  public function build( bool $quiet = false ) :array {
17
 
18
- $recordsToSend = $this->getRecords();
19
  if ( !$quiet ) {
20
- $this->markRecordsAsSent( $recordsToSend );
21
  }
22
 
23
  $records = array_filter( array_map(
@@ -48,7 +47,7 @@ class BuildData {
48
 
49
  return $record;
50
  },
51
- $recordsToSend
52
  ) );
53
 
54
  // We order with preference towards IPs with more signals.
@@ -80,7 +79,7 @@ class BuildData {
80
  }
81
 
82
  /**
83
- * @param EntryVO[] $records
84
  */
85
  private function markRecordsAsSent( array $records ) {
86
  if ( !empty( $records ) ) {
@@ -89,7 +88,7 @@ class BuildData {
89
  Services::WpDb()
90
  ->doSql(
91
  sprintf( 'UPDATE `%s` SET `snsent_at`=%s WHERE `id` in (%s);',
92
- $mod->getDbHandler_BotSignals()->getTableSchema()->table,
93
  Services::Request()->ts(),
94
  implode( ',', array_map( function ( $record ) {
95
  return $record->id;
@@ -101,18 +100,38 @@ class BuildData {
101
 
102
  /**
103
  * Optimised to ensure that only signals are sent if they've been updated since the last SNAPI-Send
104
- * @return EntryVO[]
105
  */
106
  private function getRecords() :array {
107
  /** @var ModCon $mod */
108
  $mod = $this->getMod();
109
- /** @var Select $select */
110
- $select = $mod->getDbHandler_BotSignals()->getQuerySelector();
111
- $records = $select->setLimit( 200 )
112
- ->setOrderBy( 'updated_at', 'DESC' )
113
- ->addWhereNotIn( 'ip', array_map( 'inet_pton', Services::IP()->getServerPublicIPs() ) )
114
- ->addWhereCompareColumns( 'updated_at', 'snsent_at', '>' )
115
- ->query();
116
- return is_array( $records ) ? $records : [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  }
118
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\ShieldNET;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal;
 
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
  use FernleafSystems\Wordpress\Services\Services;
14
 
15
  public function build( bool $quiet = false ) :array {
16
 
17
+ $records = $this->getRecords();
18
  if ( !$quiet ) {
19
+ $this->markRecordsAsSent( $records );
20
  }
21
 
22
  $records = array_filter( array_map(
47
 
48
  return $record;
49
  },
50
+ $records
51
  ) );
52
 
53
  // We order with preference towards IPs with more signals.
79
  }
80
 
81
  /**
82
+ * @param BotSignal\BotSignalRecord[] $records
83
  */
84
  private function markRecordsAsSent( array $records ) {
85
  if ( !empty( $records ) ) {
88
  Services::WpDb()
89
  ->doSql(
90
  sprintf( 'UPDATE `%s` SET `snsent_at`=%s WHERE `id` in (%s);',
91
+ $mod->getDbH_BotSignal()->getTableSchema()->table,
92
  Services::Request()->ts(),
93
  implode( ',', array_map( function ( $record ) {
94
  return $record->id;
100
 
101
  /**
102
  * Optimised to ensure that only signals are sent if they've been updated since the last SNAPI-Send
103
+ * @return BotSignal\BotSignalRecord[]
104
  */
105
  private function getRecords() :array {
106
  /** @var ModCon $mod */
107
  $mod = $this->getMod();
108
+
109
+ $serverIPs = array_map(
110
+ function ( $ip ) {
111
+ return sprintf( "INET6_ATON('%s')", $ip );
112
+ },
113
+ is_array( Services::IP()->getServerPublicIPs() ) ? Services::IP()->getServerPublicIPs() : []
114
+ );
115
+
116
+ $records = Services::WpDb()->selectCustom(
117
+ sprintf( "SELECT ips.ip, bs.*
118
+ FROM `%s` as bs
119
+ INNER JOIN `%s` as ips
120
+ ON `ips`.id = `bs`.ip_ref
121
+ %s
122
+ ORDER BY `bs`.`updated_at` DESC
123
+ LIMIT 200;",
124
+ $mod->getDbH_BotSignal()->getTableSchema()->table,
125
+ $this->getCon()->getModule_Data()->getDbH_IPs()->getTableSchema()->table,
126
+ empty( $serverIPs ) ? '' : sprintf( "AND `ips`.`ip` NOT IN (%s)", implode( ",", $serverIPs ) )
127
+ )
128
+ );
129
+
130
+ return array_map(
131
+ function ( $record ) {
132
+ return ( new BotSignal\BotSignalRecord() )->applyFromArray( $record );
133
+ },
134
+ is_array( $records ) ? $records : []
135
+ );
136
  }
137
  }
src/lib/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php CHANGED
@@ -34,13 +34,6 @@ class FindAllPluginIps {
34
  ->getQuerySelector();
35
  $ips = array_merge( $ips, $sel->getDistinctForColumn( 'ip' ) );
36
 
37
- // Bot Signal
38
- /** @var Databases\BotSignals\Select $sel */
39
- $sel = $con->getModule_IPs()
40
- ->getDbHandler_BotSignals()
41
- ->getQuerySelector();
42
- $ips = array_merge( $ips, $sel->getDistinctIps() );
43
-
44
  return IpListSort::Sort( array_unique( $ips ) );
45
  }
46
  }
34
  ->getQuerySelector();
35
  $ips = array_merge( $ips, $sel->getDistinctForColumn( 'ip' ) );
36
 
 
 
 
 
 
 
 
37
  return IpListSort::Sort( array_unique( $ips ) );
38
  }
39
  }
src/lib/src/Modules/IPs/Lib/OffenseTracker.php CHANGED
@@ -23,17 +23,14 @@ class OffenseTracker extends EventsListener {
23
  */
24
  protected function captureEvent( string $evt, $meta = [], $def = [] ) {
25
  if ( !empty( $def[ 'offense' ] ) && empty( $meta[ 'suppress_offense' ] ) ) {
26
- $this->incrementCount( (int)( $meta[ 'offense_count' ] ?? 1) );
27
  if ( !empty( $meta[ 'block' ] ) ) {
28
  $this->setIsBlocked( true );
29
  }
30
  }
31
  }
32
 
33
- /**
34
- * @return bool
35
- */
36
- public function hasVisitorOffended() {
37
  return $this->isBlocked() || $this->getOffenseCount() > 0;
38
  }
39
 
23
  */
24
  protected function captureEvent( string $evt, $meta = [], $def = [] ) {
25
  if ( !empty( $def[ 'offense' ] ) && empty( $meta[ 'suppress_offense' ] ) ) {
26
+ $this->incrementCount( (int)( $meta[ 'offense_count' ] ?? 1 ) );
27
  if ( !empty( $meta[ 'block' ] ) ) {
28
  $this->setIsBlocked( true );
29
  }
30
  }
31
  }
32
 
33
+ public function hasVisitorOffended() :bool {
 
 
 
34
  return $this->isBlocked() || $this->getOffenseCount() > 0;
35
  }
36
 
src/lib/src/Modules/IPs/Lib/Ops/ConvertLegacy.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Data\DB\IPs\IPRecords;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
8
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\DB\BotSignal;
9
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
10
+ use FernleafSystems\Wordpress\Services\Services;
11
+
12
+ class ConvertLegacy {
13
+
14
+ use ModConsumer;
15
+
16
+ public function run() {
17
+ /** @var ModCon $mod */
18
+ $mod = $this->getMod();
19
+ $opts = $this->getOptions();
20
+
21
+ if ( empty( $opts->getOpt( 'legacy_db_deleted_at' ) ) ) {
22
+ $this->convert();
23
+ $dbh = $mod->getDbHandler_BotSignals();
24
+ if ( $dbh->getQuerySelector()->count() === 0 ) {
25
+ $opts->setOpt( 'legacy_db_deleted_at', Services::Request()->ts() );
26
+ $dbh->tableDelete();
27
+ }
28
+ }
29
+ }
30
+
31
+ private function convert() {
32
+ /** @var ModCon $mod */
33
+ $mod = $this->getMod();
34
+ $dbh = $mod->getDbHandler_BotSignals();
35
+
36
+ $toDelete = [];
37
+
38
+ /** @var BotSignals\EntryVO $entry */
39
+ foreach ( $dbh->getIterator() as $entry ) {
40
+
41
+ try {
42
+ $this->createPrimaryLogRecord( $entry );
43
+ }
44
+ catch ( \Exception $e ) {
45
+ }
46
+ finally {
47
+ $toDelete[] = $entry->id;
48
+ }
49
+ }
50
+
51
+ if ( !empty( $toDelete ) ) {
52
+ $dbh->getQueryDeleter()
53
+ ->addWhereIn( 'in', $toDelete )
54
+ ->query();
55
+ }
56
+ }
57
+
58
+ /**
59
+ * @param BotSignals\EntryVO $entry
60
+ * @return bool
61
+ * @throws \Exception
62
+ */
63
+ protected function createPrimaryLogRecord( BotSignals\EntryVO $entry ) :bool {
64
+ /** @var ModCon $mod */
65
+ $mod = $this->getMod();
66
+ $dbh = $mod->getDbH_BotSignal();
67
+
68
+ if ( empty( $entry->ip ) ) {
69
+ throw new \Exception( 'No IP' );
70
+ }
71
+
72
+ $ipRecord = ( new IPRecords() )
73
+ ->setMod( $this->getCon()->getModule_Data() )
74
+ ->loadIP( $entry->ip );
75
+ unset( $entry->ip );
76
+
77
+ /** @var BotSignal\Ops\Select $selector */
78
+ $selector = $dbh->getQuerySelector();
79
+ if ( $selector->filterByIP( $ipRecord->id )->count() > 0 ) {
80
+ throw new \Exception( 'Record already exists' );
81
+ }
82
+
83
+ /** @var BotSignal\Ops\Record $record */
84
+ $record = $dbh->getRecord()->applyFromArray( $entry->getRawData() );
85
+ unset( $record->id );
86
+ $record->ip_ref = $ipRecord->id;
87
+
88
+ $success = $mod->getDbH_BotSignal()
89
+ ->getQueryInserter()
90
+ ->insert( $record );
91
+ if ( !$success ) {
92
+ throw new \Exception( 'Failed to insert' );
93
+ }
94
+
95
+ return true;
96
+ }
97
+ }
src/lib/src/Modules/IPs/ModCon.php CHANGED
@@ -43,8 +43,12 @@ class ModCon extends BaseShield\ModCon {
43
  return $this->oBlacklistHandler;
44
  }
45
 
46
- public function getDbHandler_BotSignals() :Shield\Databases\BotSignals\Handler {
47
- return $this->getDbH( 'botsignals' );
 
 
 
 
48
  }
49
 
50
  public function getDbHandler_IPs() :Shield\Databases\IPs\Handler {
@@ -154,4 +158,21 @@ class ModCon extends BaseShield\ModCon {
154
  }
155
  return $text;
156
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
43
  return $this->oBlacklistHandler;
44
  }
45
 
46
+ protected function doPostConstruction() {
47
+ $this->getDbH_BotSignal();
48
+ }
49
+
50
+ public function getDbH_BotSignal() :DB\BotSignal\Ops\Handler {
51
+ return $this->getDbHandler()->loadDbH( 'botsignal' );
52
  }
53
 
54
  public function getDbHandler_IPs() :Shield\Databases\IPs\Handler {
158
  }
159
  return $text;
160
  }
161
+
162
+ /**
163
+ * @deprecated 12.0
164
+ */
165
+ protected function cleanupDatabases() {
166
+ $dbhIPs = $this->getDbHandler_IPs();
167
+ if ( $dbhIPs->isReady() ) {
168
+ $dbhIPs->autoCleanDb();
169
+ }
170
+ }
171
+
172
+ /**
173
+ * @deprecated 12.0
174
+ */
175
+ public function getDbHandler_BotSignals() :Shield\Databases\BotSignals\Handler {
176
+ return $this->getDbH( 'botsignals' );
177
+ }
178
  }
src/lib/src/Modules/IPs/Upgrade.php CHANGED
@@ -7,6 +7,12 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
7
 
8
  class Upgrade extends Base\Upgrade {
9
 
 
 
 
 
 
 
10
  protected function upgrade_1010() {
11
  /** @var ModCon $mod */
12
  $mod = $this->getMod();
7
 
8
  class Upgrade extends Base\Upgrade {
9
 
10
+ protected function upgrade_1201() {
11
+ ( new Lib\Ops\ConvertLegacy() )
12
+ ->setMod( $this->getMod() )
13
+ ->run();
14
+ }
15
+
16
  protected function upgrade_1010() {
17
  /** @var ModCon $mod */
18
  $mod = $this->getMod();
src/lib/src/Modules/Insights/ModCon.php CHANGED
@@ -149,8 +149,9 @@ class ModCon extends BaseShield\ModCon {
149
  case 'users':
150
  case 'stats':
151
 
 
152
  if ( in_array( $inav, [ 'scans_results', 'scans_run' ] ) ) {
153
- $enq[ Enqueue::JS ][] = 'shield-scans';
154
  }
155
  elseif ( $inav == 'ips' ) {
156
  $enq[ Enqueue::JS ][] = 'shield/ipanalyse';
149
  case 'users':
150
  case 'stats':
151
 
152
+ $enq[ Enqueue::JS ][] = 'shield/tables';
153
  if ( in_array( $inav, [ 'scans_results', 'scans_run' ] ) ) {
154
+ $enq[ Enqueue::JS ][] = 'shield/scans';
155
  }
156
  elseif ( $inav == 'ips' ) {
157
  $enq[ Enqueue::JS ][] = 'shield/ipanalyse';
src/lib/src/Modules/Lockdown/Processor.php CHANGED
@@ -7,6 +7,8 @@ use FernleafSystems\Wordpress\Services\Services;
7
 
8
  class Processor extends BaseShield\Processor {
9
 
 
 
10
  protected function run() {
11
  /** @var Options $opts */
12
  $opts = $this->getOptions();
@@ -45,17 +47,17 @@ class Processor extends BaseShield\Processor {
45
 
46
  add_filter( 'user_has_cap',
47
  /**
48
- * @param array $aAllCaps
49
  * @param array $cap
50
- * @param array $aArgs
51
  * @return array
52
  */
53
- function ( $aAllCaps, $cap, $aArgs ) {
54
- $sRequestedCapability = $aArgs[ 0 ];
55
- if ( in_array( $sRequestedCapability, [ 'edit_themes', 'edit_plugins', 'edit_files' ] ) ) {
56
- $aAllCaps[ $sRequestedCapability ] = false;
57
  }
58
- return $aAllCaps;
59
  },
60
  PHP_INT_MAX, 3
61
  );
@@ -77,7 +79,10 @@ class Processor extends BaseShield\Processor {
77
  * @return array|false
78
  */
79
  public function disableXmlrpc() {
80
- $this->getCon()->fireEvent( 'block_xml' );
 
 
 
81
  return ( current_filter() == 'xmlrpc_enabled' ) ? false : [];
82
  }
83
 
@@ -110,9 +115,9 @@ class Processor extends BaseShield\Processor {
110
  public function disableAnonymousRestApi( $mStatus ) {
111
  /** @var ModCon $mod */
112
  $mod = $this->getMod();
113
- $oWpRest = Services::Rest();
114
 
115
- $namespace = $oWpRest->getNamespace();
116
  if ( !empty( $namespace ) && $mStatus !== true && !is_wp_error( $mStatus )
117
  && !$mod->isPermittedAnonRestApiNamespace( $namespace ) ) {
118
 
7
 
8
  class Processor extends BaseShield\Processor {
9
 
10
+ private $xmlProcessed = false;
11
+
12
  protected function run() {
13
  /** @var Options $opts */
14
  $opts = $this->getOptions();
47
 
48
  add_filter( 'user_has_cap',
49
  /**
50
+ * @param array $allCaps
51
  * @param array $cap
52
+ * @param array $args
53
  * @return array
54
  */
55
+ function ( $allCaps, $cap, $args ) {
56
+ $requestedCapability = $args[ 0 ];
57
+ if ( in_array( $requestedCapability, [ 'edit_themes', 'edit_plugins', 'edit_files' ] ) ) {
58
+ $allCaps[ $requestedCapability ] = false;
59
  }
60
+ return $allCaps;
61
  },
62
  PHP_INT_MAX, 3
63
  );
79
  * @return array|false
80
  */
81
  public function disableXmlrpc() {
82
+ if ( !$this->xmlProcessed ) {
83
+ $this->xmlProcessed = true;
84
+ $this->getCon()->fireEvent( 'block_xml' );
85
+ }
86
  return ( current_filter() == 'xmlrpc_enabled' ) ? false : [];
87
  }
88
 
115
  public function disableAnonymousRestApi( $mStatus ) {
116
  /** @var ModCon $mod */
117
  $mod = $this->getMod();
118
+ $WPRest = Services::Rest();
119
 
120
+ $namespace = $WPRest->getNamespace();
121
  if ( !empty( $namespace ) && $mStatus !== true && !is_wp_error( $mStatus )
122
  && !$mod->isPermittedAnonRestApiNamespace( $namespace ) ) {
123
 
src/lib/src/Modules/Plugin/Debug.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules;
 
6
  use FernleafSystems\Wordpress\Plugin\Shield\Tests\RunTests;
7
 
8
  class Debug extends Modules\Base\Debug {
@@ -12,13 +13,20 @@ class Debug extends Modules\Base\Debug {
12
  die( 'finish' );
13
  }
14
 
 
 
 
 
 
 
 
15
  private function getIpRefs() {
16
  $ipRefs = $this->getCon()
17
- ->getModule_Data()
18
- ->getDbH_ReqLogs()
19
- ->getQuerySelector()
20
- ->getDistinctForColumn( 'ip_ref' );
21
- var_dump($ipRefs);
22
  }
23
 
24
  private function tests() {
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\ShieldNET\BuildData;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Tests\RunTests;
8
 
9
  class Debug extends Modules\Base\Debug {
13
  die( 'finish' );
14
  }
15
 
16
+ private function testbotsignals() {
17
+ $r = ( new BuildData() )
18
+ ->setMod( $this->getCon()->getModule_IPs() )
19
+ ->build( true );
20
+ var_dump( $r );
21
+ }
22
+
23
  private function getIpRefs() {
24
  $ipRefs = $this->getCon()
25
+ ->getModule_Data()
26
+ ->getDbH_ReqLogs()
27
+ ->getQuerySelector()
28
+ ->getDistinctForColumn( 'ip_ref' );
29
+ var_dump( $ipRefs );
30
  }
31
 
32
  private function tests() {
src/lib/src/Modules/Plugin/Insights/DashboardCards.php CHANGED
@@ -217,7 +217,7 @@ class DashboardCards {
217
  'actions' => [
218
  [
219
  'text' => __( "View Audit Log", 'wp-simple-firewall' ),
220
- 'href' => $modInsights->getUrl_SubInsightsPage( 'audit' ),
221
  ],
222
  [
223
  'text' => __( "Audit Trail Settings", 'wp-simple-firewall' ),
217
  'actions' => [
218
  [
219
  'text' => __( "View Audit Log", 'wp-simple-firewall' ),
220
+ 'href' => $modInsights->getUrl_SubInsightsPage( 'audit_trail' ),
221
  ],
222
  [
223
  'text' => __( "Audit Trail Settings", 'wp-simple-firewall' ),
src/lib/src/Modules/Plugin/Lib/Debug/Collate.php CHANGED
@@ -179,7 +179,7 @@ class Collate {
179
  sprintf( '%s (rows: ~%s)', 'Ready', $dbh->getQuerySelector()->count() )
180
  : 'Missing';
181
 
182
- $dbh = $con->getModule_IPs()->getDbHandler_BotSignals();
183
  $data[ 'DB Table: Bot Signals' ] = $dbh->isReady() ?
184
  sprintf( '%s (rows: ~%s)', 'Ready', $dbh->getQuerySelector()->count() )
185
  : 'Missing';
179
  sprintf( '%s (rows: ~%s)', 'Ready', $dbh->getQuerySelector()->count() )
180
  : 'Missing';
181
 
182
+ $dbh = $con->getModule_IPs()->getDbH_BotSignal();
183
  $data[ 'DB Table: Bot Signals' ] = $dbh->isReady() ?
184
  sprintf( '%s (rows: ~%s)', 'Ready', $dbh->getQuerySelector()->count() )
185
  : 'Missing';
src/lib/src/Modules/Sessions/Processor.php CHANGED
@@ -42,25 +42,18 @@ class Processor extends BaseShield\Processor {
42
  }
43
 
44
  public function onWpLoaded() {
45
- if ( Services::WpUsers()->isUserLoggedIn() && !Services::Rest()->isRest() ) {
46
- $this->autoAddSession();
47
- }
48
- }
49
-
50
- public function onModuleShutdown() {
51
  /** @var ModCon $mod */
52
  $mod = $this->getMod();
53
 
54
- if ( !Services::Rest()->isRest() && !$this->getCon()->plugin_deleting ) {
55
- $session = $mod->getSessionCon()->getCurrent();
56
- if ( $session instanceof Session\EntryVO ) {
57
- /** @var Session\Update $update */
58
- $update = $mod->getDbHandler_Sessions()->getQueryUpdater();
59
- $update->updateLastActivity( $session );
60
- }
61
  }
62
 
63
- parent::onModuleShutdown();
 
 
 
 
64
  }
65
 
66
  private function autoAddSession() {
@@ -101,4 +94,11 @@ class Processor extends BaseShield\Processor {
101
  protected function getHookPriority() :int {
102
  return 100;
103
  }
 
 
 
 
 
 
 
104
  }
42
  }
43
 
44
  public function onWpLoaded() {
 
 
 
 
 
 
45
  /** @var ModCon $mod */
46
  $mod = $this->getMod();
47
 
48
+ if ( Services::WpUsers()->isUserLoggedIn() && !Services::Rest()->isRest() ) {
49
+ $this->autoAddSession();
 
 
 
 
 
50
  }
51
 
52
+ if ( $mod->getSessionCon()->hasSession() ) {
53
+ /** @var Session\Update $update */
54
+ $update = $mod->getDbHandler_Sessions()->getQueryUpdater();
55
+ $update->updateLastActivity( $mod->getSessionCon()->getCurrent() );
56
+ }
57
  }
58
 
59
  private function autoAddSession() {
94
  protected function getHookPriority() :int {
95
  return 100;
96
  }
97
+
98
+ /**
99
+ * @deprecated 12.0
100
+ */
101
+ public function onModuleShutdown() {
102
+ parent::onModuleShutdown();
103
+ }
104
  }
src/lib/src/Modules/Traffic/Lib/TrafficTable/LoadRawTableData.php CHANGED
@@ -155,7 +155,7 @@ class LoadRawTableData extends BaseLoadTableData {
155
  private function getColumnContent_Page() :string {
156
  list( $preQuery, $query ) = explode( '?', $this->log->meta[ 'path' ].'?', 2 );
157
  return strtoupper( $this->log->meta[ 'verb' ] ).': <code>'.$preQuery
158
- .( empty( $query ) ? '' : '?<br/>'.$query ).'</code>';
159
  }
160
 
161
  private function getIpInfo( string $ip ) {
155
  private function getColumnContent_Page() :string {
156
  list( $preQuery, $query ) = explode( '?', $this->log->meta[ 'path' ].'?', 2 );
157
  return strtoupper( $this->log->meta[ 'verb' ] ).': <code>'.$preQuery
158
+ .( empty( $query ) ? '' : '?<br/>'.rtrim( $query, '?' ) ).'</code>';
159
  }
160
 
161
  private function getIpInfo( string $ip ) {
src/lib/src/Scans/Base/DiffResultForStorage.php CHANGED
@@ -12,28 +12,28 @@ class DiffResultForStorage {
12
 
13
  /**
14
  * The Existing set will be updated to reflect the new current status of the scan
15
- * @param ResultsSet $oExistingRes - will be updated with all items to DB Update
16
- * @param ResultsSet $oNewResults - will be adjusted with all item to DB Insert
17
  * @return ResultsSet - A results set of all out-of-date records that need to be deleted.
18
  */
19
- public function diff( $oExistingRes, $oNewResults ) {
20
 
21
  $toDelete = new ResultsSet();
22
  $merger = new Scans\Base\BaseMergeItems();
23
 
24
  // 1 Remove items in EXISTING that are not in NEW
25
- foreach ( $oExistingRes->getAllItems() as $oExistItem ) {
26
- if ( !$oNewResults->getItemExists( $oExistItem->hash ) ) {
27
- $oExistingRes->removeItemByHash( $oExistItem->hash );
28
  $toDelete->addItem( $oExistItem );
29
  }
30
  }
31
 
32
  // 2 Merge NEW items into Existing items
33
- foreach ( $oNewResults->getAllItems() as $oNewItem ) {
34
- if ( $oExistingRes->getItemExists( $oNewItem->hash ) ) {
35
- $merger->mergeItemTo( $oExistingRes->getItemByHash( $oNewItem->hash ), $oNewItem );
36
- $oNewResults->removeItemByHash( $oNewItem->hash );
37
  }
38
  }
39
 
12
 
13
  /**
14
  * The Existing set will be updated to reflect the new current status of the scan
15
+ * @param ResultsSet $existingResults - will be updated with all items to DB Update
16
+ * @param ResultsSet $newResults - will be adjusted with all item to DB Insert
17
  * @return ResultsSet - A results set of all out-of-date records that need to be deleted.
18
  */
19
+ public function diff( $existingResults, $newResults ) {
20
 
21
  $toDelete = new ResultsSet();
22
  $merger = new Scans\Base\BaseMergeItems();
23
 
24
  // 1 Remove items in EXISTING that are not in NEW
25
+ foreach ( $existingResults->getAllItems() as $oExistItem ) {
26
+ if ( !$newResults->getItemExists( $oExistItem->hash ) ) {
27
+ $existingResults->removeItemByHash( $oExistItem->hash );
28
  $toDelete->addItem( $oExistItem );
29
  }
30
  }
31
 
32
  // 2 Merge NEW items into Existing items
33
+ foreach ( $newResults->getAllItems() as $oNewItem ) {
34
+ if ( $existingResults->getItemExists( $oNewItem->hash ) ) {
35
+ $merger->mergeItemTo( $existingResults->getItemByHash( $oNewItem->hash ), $oNewItem );
36
+ $newResults->removeItemByHash( $oNewItem->hash );
37
  }
38
  }
39
 
src/lib/src/Scans/Base/FileResultItem.php CHANGED
@@ -10,6 +10,10 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
10
  */
11
  class FileResultItem extends ResultItem {
12
 
 
 
 
 
13
  public function getDescriptionForAudit() :string {
14
  return $this->path_full;
15
  }
10
  */
11
  class FileResultItem extends ResultItem {
12
 
13
+ public function generateHash() :string {
14
+ return md5( $this->path_full );
15
+ }
16
+
17
  public function getDescriptionForAudit() :string {
18
  return $this->path_full;
19
  }
src/lib/src/Scans/Base/Utilities/BaseRepair.php CHANGED
@@ -5,10 +5,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Utilities;
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultItem;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanItemConsumer;
7
 
8
- /**
9
- * Class BaseRepair
10
- * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Base
11
- */
12
  abstract class BaseRepair {
13
 
14
  use ScanItemConsumer;
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultItem;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanItemConsumer;
7
 
 
 
 
 
8
  abstract class BaseRepair {
9
 
10
  use ScanItemConsumer;
src/lib/src/Scans/Base/Utilities/IgnoreItem.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Utilities;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
+ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanItemConsumer;
9
+ use FernleafSystems\Wordpress\Services\Services;
10
+
11
+ class IgnoreItem {
12
+
13
+ use ModConsumer;
14
+ use ScanItemConsumer;
15
+
16
+ /**
17
+ * @return bool
18
+ * @throws \Exception
19
+ */
20
+ public function ignore() :bool {
21
+ if ( empty( $this->getScanItem()->VO ) ) {
22
+ throw new \Exception( 'Item could not be found to ignore.' );
23
+ }
24
+
25
+ /** @var HackGuard\ModCon $mod */
26
+ $mod = $this->getMod();
27
+ $updated = $mod->getDbHandler_ScanResults()
28
+ ->getQueryUpdater()
29
+ ->setUpdateWheres( [
30
+ 'hash' => $this->getScanItem()->generateHash()
31
+ ] )
32
+ ->setUpdateData( [
33
+ 'ignored_at' => Services::Request()->ts()
34
+ ] )
35
+ ->query();
36
+ if ( !$updated ) {
37
+ throw new \Exception( 'Item could not be ignored at this time.' );
38
+ }
39
+
40
+ return true;
41
+ }
42
+ }
src/lib/src/Scans/Base/Utilities/ItemActionHandler.php CHANGED
@@ -7,6 +7,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultItem;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanItemConsumer;
 
10
 
11
  abstract class ItemActionHandler {
12
 
@@ -62,19 +63,10 @@ abstract class ItemActionHandler {
62
  * @throws \Exception
63
  */
64
  public function ignore() {
65
- if ( empty( $this->getScanItem()->VO ) ) {
66
- throw new \Exception( 'Item could not be found to ignore.' );
67
- }
68
-
69
- /** @var HackGuard\ModCon $mod */
70
- $mod = $this->getMod();
71
- /** @var Scanner\Update $updater */
72
- $updater = $mod->getDbHandler_ScanResults()->getQueryUpdater();
73
- if ( !$updater->setIgnored( $this->getScanItem()->VO ) ) {
74
- throw new \Exception( 'Item could not be ignored at this time.' );
75
- }
76
-
77
- return true;
78
  }
79
 
80
  /**
@@ -110,14 +102,19 @@ abstract class ItemActionHandler {
110
 
111
  $this->fireRepairEvent();
112
 
 
 
113
  if ( $item->repaired ) {
114
- /** @var HackGuard\ModCon $mod */
115
- $mod = $this->getMod();
116
  /** @var Scanner\Delete $deleter */
117
  $mod->getDbHandler_ScanResults()
118
  ->getQueryDeleter()
119
  ->deleteById( $item->VO->id );
120
  }
 
 
 
 
 
121
 
122
  return $item->repaired;
123
  }
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultItem;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanItemConsumer;
10
+ use FernleafSystems\Wordpress\Services\Services;
11
 
12
  abstract class ItemActionHandler {
13
 
63
  * @throws \Exception
64
  */
65
  public function ignore() {
66
+ return ( new IgnoreItem() )
67
+ ->setMod( $this->getMod() )
68
+ ->setScanItem( $this->getScanItem() )
69
+ ->ignore();
 
 
 
 
 
 
 
 
 
70
  }
71
 
72
  /**
102
 
103
  $this->fireRepairEvent();
104
 
105
+ /** @var HackGuard\ModCon $mod */
106
+ $mod = $this->getMod();
107
  if ( $item->repaired ) {
 
 
108
  /** @var Scanner\Delete $deleter */
109
  $mod->getDbHandler_ScanResults()
110
  ->getQueryDeleter()
111
  ->deleteById( $item->VO->id );
112
  }
113
+ else {
114
+ $mod->getDbHandler_ScanResults()
115
+ ->getQueryUpdater()
116
+ ->updateById( $item->VO->id, [ 'attempt_repair_at' => Services::Request()->ts() ] );
117
+ }
118
 
119
  return $item->repaired;
120
  }
src/lib/src/Scans/Mal/ResultItem.php CHANGED
@@ -12,10 +12,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
12
  */
13
  class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
14
 
15
- public function generateHash() :string {
16
- return md5( $this->path_full );
17
- }
18
-
19
  public function isReady() :bool {
20
  return !empty( $this->path_full ) && !empty( $this->md5_file_wp ) && !empty( $this->path_fragment );
21
  }
12
  */
13
  class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
14
 
 
 
 
 
15
  public function isReady() :bool {
16
  return !empty( $this->path_full ) && !empty( $this->md5_file_wp ) && !empty( $this->path_fragment );
17
  }
src/lib/src/Scans/Ptg/ResultItem.php CHANGED
@@ -13,7 +13,4 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
13
  */
14
  class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
15
 
16
- public function generateHash() :string {
17
- return md5( $this->path_full );
18
- }
19
  }
13
  */
14
  class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
15
 
 
 
 
16
  }
src/lib/src/Scans/Ufc/ResultItem.php CHANGED
@@ -4,7 +4,4 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc;
4
 
5
  class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
6
 
7
- public function generateHash() :string {
8
- return md5( $this->path_full );
9
- }
10
  }
4
 
5
  class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
6
 
 
 
 
7
  }
src/lib/src/Scans/Wcf/ResultItem.php CHANGED
@@ -11,10 +11,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf;
11
  */
12
  class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
13
 
14
- public function generateHash() :string {
15
- return md5( $this->path_full );
16
- }
17
-
18
  public function isReady() :bool {
19
  return !empty( $this->path_full ) && !empty( $this->md5_file_wp ) && !empty( $this->path_fragment );
20
  }
11
  */
12
  class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\FileResultItem {
13
 
 
 
 
 
14
  public function isReady() :bool {
15
  return !empty( $this->path_full ) && !empty( $this->md5_file_wp ) && !empty( $this->path_fragment );
16
  }
src/lib/src/Tables/DataTables/LoadData/BaseLoadTableData.php CHANGED
@@ -21,11 +21,24 @@ class BaseLoadTableData {
21
 
22
  protected function getIpAnalysisLink( string $ip ) :string {
23
  $srvIP = Services::IP();
24
- return sprintf( '<a href="%s" target="_blank" title="%s" class="ip-whois">%s</a>',
25
- $srvIP->isValidIpRange( $ip ) ? $srvIP->getIpWhoisLookup( $ip ) :
 
 
 
 
 
 
 
 
26
  $this->getCon()->getModule_Insights()->getUrl_IpAnalysis( $ip ),
27
- __( 'IP Analysis' ),
28
- $ip
29
- );
 
 
 
 
 
30
  }
31
  }
21
 
22
  protected function getIpAnalysisLink( string $ip ) :string {
23
  $srvIP = Services::IP();
24
+
25
+ if ( $srvIP->isValidIpRange( $ip ) ) {
26
+ $content = sprintf( '<a href="%s" target="_blank" title="%s">%s</a>',
27
+ $srvIP->getIpWhoisLookup( $ip ),
28
+ __( 'IP Analysis', 'wp-simple-firewall' ),
29
+ $ip
30
+ );
31
+ }
32
+ elseif ( Services::IP()->isValidIp( $ip ) ) {
33
+ $content = sprintf( '<a href="%s" target="_blank" title="%s">%s</a>',
34
  $this->getCon()->getModule_Insights()->getUrl_IpAnalysis( $ip ),
35
+ __( 'IP Analysis', 'wp-simple-firewall' ),
36
+ $ip
37
+ );
38
+ }
39
+ else {
40
+ $content = __( 'IP Unavailable', 'wp-simple-firewall' );
41
+ }
42
+ return $content;
43
  }
44
  }
src/lib/vendor/composer/autoload_classmap.php CHANGED
@@ -38,7 +38,7 @@ return array(
38
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Insert' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Insert.php',
39
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Record' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php',
40
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Select' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php',
41
- 'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Traits\\Select_IPTable' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/Select_IPTable.php',
42
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Update' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php',
43
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\AlignTableWithSchema' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php',
44
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\BuildColumnFromDef' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php',
@@ -481,6 +481,14 @@ return array(
481
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryIpBlock' => $baseDir . '/src/Modules/IPs/Components/QueryIpBlock.php',
482
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryRemainingOffenses' => $baseDir . '/src/Modules/IPs/Components/QueryRemainingOffenses.php',
483
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => $baseDir . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
 
 
 
 
 
 
 
 
484
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Insights\\OverviewCards' => $baseDir . '/src/Modules/IPs/Insights/OverviewCards.php',
485
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\AutoUnblock' => $baseDir . '/src/Modules/IPs/Lib/AutoUnblock.php',
486
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlacklistHandler' => $baseDir . '/src/Modules/IPs/Lib/BlacklistHandler.php',
@@ -501,6 +509,7 @@ return array(
501
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
502
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => $baseDir . '/src/Modules/IPs/Lib/OffenseTracker.php',
503
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\AddIp' => $baseDir . '/src/Modules/IPs/Lib/Ops/AddIp.php',
 
504
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\DeleteIp' => $baseDir . '/src/Modules/IPs/Lib/Ops/DeleteIp.php',
505
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\LookupIpOnList' => $baseDir . '/src/Modules/IPs/Lib/Ops/LookupIpOnList.php',
506
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\RetrieveIpsForLists' => $baseDir . '/src/Modules/IPs/Lib/Ops/RetrieveIpsForLists.php',
@@ -813,6 +822,7 @@ return array(
813
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultItem' => $baseDir . '/src/Scans/Base/ResultItem.php',
814
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultsSet' => $baseDir . '/src/Scans/Base/ResultsSet.php',
815
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BaseRepair' => $baseDir . '/src/Scans/Base/Utilities/BaseRepair.php',
 
816
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Base/Utilities/ItemActionHandler.php',
817
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandlerAssets' => $baseDir . '/src/Scans/Base/Utilities/ItemActionHandlerAssets.php',
818
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Common\\ScanActionConsumer' => $baseDir . '/src/Scans/Common/ScanActionConsumer.php',
38
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Insert' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Insert.php',
39
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Record' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php',
40
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Select' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php',
41
+ 'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Traits\\FilterByIP' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/FilterByIP.php',
42
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Update' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php',
43
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\AlignTableWithSchema' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php',
44
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\BuildColumnFromDef' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php',
481
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryIpBlock' => $baseDir . '/src/Modules/IPs/Components/QueryIpBlock.php',
482
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryRemainingOffenses' => $baseDir . '/src/Modules/IPs/Components/QueryRemainingOffenses.php',
483
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => $baseDir . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
484
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\BotSignalRecord' => $baseDir . '/src/Modules/IPs/DB/BotSignal/BotSignalRecord.php',
485
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\LoadBotSignalRecords' => $baseDir . '/src/Modules/IPs/DB/BotSignal/LoadBotSignalRecords.php',
486
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Common' => $baseDir . '/src/Modules/IPs/DB/BotSignal/Ops/Common.php',
487
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Delete' => $baseDir . '/src/Modules/IPs/DB/BotSignal/Ops/Delete.php',
488
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Handler' => $baseDir . '/src/Modules/IPs/DB/BotSignal/Ops/Handler.php',
489
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Insert' => $baseDir . '/src/Modules/IPs/DB/BotSignal/Ops/Insert.php',
490
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Record' => $baseDir . '/src/Modules/IPs/DB/BotSignal/Ops/Record.php',
491
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Select' => $baseDir . '/src/Modules/IPs/DB/BotSignal/Ops/Select.php',
492
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Insights\\OverviewCards' => $baseDir . '/src/Modules/IPs/Insights/OverviewCards.php',
493
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\AutoUnblock' => $baseDir . '/src/Modules/IPs/Lib/AutoUnblock.php',
494
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlacklistHandler' => $baseDir . '/src/Modules/IPs/Lib/BlacklistHandler.php',
509
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
510
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => $baseDir . '/src/Modules/IPs/Lib/OffenseTracker.php',
511
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\AddIp' => $baseDir . '/src/Modules/IPs/Lib/Ops/AddIp.php',
512
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\ConvertLegacy' => $baseDir . '/src/Modules/IPs/Lib/Ops/ConvertLegacy.php',
513
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\DeleteIp' => $baseDir . '/src/Modules/IPs/Lib/Ops/DeleteIp.php',
514
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\LookupIpOnList' => $baseDir . '/src/Modules/IPs/Lib/Ops/LookupIpOnList.php',
515
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\RetrieveIpsForLists' => $baseDir . '/src/Modules/IPs/Lib/Ops/RetrieveIpsForLists.php',
822
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultItem' => $baseDir . '/src/Scans/Base/ResultItem.php',
823
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultsSet' => $baseDir . '/src/Scans/Base/ResultsSet.php',
824
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BaseRepair' => $baseDir . '/src/Scans/Base/Utilities/BaseRepair.php',
825
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\IgnoreItem' => $baseDir . '/src/Scans/Base/Utilities/IgnoreItem.php',
826
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Base/Utilities/ItemActionHandler.php',
827
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandlerAssets' => $baseDir . '/src/Scans/Base/Utilities/ItemActionHandlerAssets.php',
828
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Common\\ScanActionConsumer' => $baseDir . '/src/Scans/Common/ScanActionConsumer.php',
src/lib/vendor/composer/autoload_static.php CHANGED
@@ -224,7 +224,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
224
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Insert' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Insert.php',
225
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Record' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php',
226
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Select' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php',
227
- 'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Traits\\Select_IPTable' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/Select_IPTable.php',
228
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Update' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php',
229
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\AlignTableWithSchema' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php',
230
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\BuildColumnFromDef' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php',
@@ -667,6 +667,14 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
667
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryIpBlock' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/QueryIpBlock.php',
668
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryRemainingOffenses' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/QueryRemainingOffenses.php',
669
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
 
 
 
 
 
 
 
 
670
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Insights\\OverviewCards' => __DIR__ . '/../..' . '/src/Modules/IPs/Insights/OverviewCards.php',
671
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\AutoUnblock' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/AutoUnblock.php',
672
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlacklistHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/BlacklistHandler.php',
@@ -687,6 +695,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
687
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
688
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/OffenseTracker.php',
689
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\AddIp' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/AddIp.php',
 
690
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\DeleteIp' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/DeleteIp.php',
691
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\LookupIpOnList' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/LookupIpOnList.php',
692
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\RetrieveIpsForLists' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/RetrieveIpsForLists.php',
@@ -999,6 +1008,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
999
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Base/ResultItem.php',
1000
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Base/ResultsSet.php',
1001
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BaseRepair' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/BaseRepair.php',
 
1002
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/ItemActionHandler.php',
1003
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandlerAssets' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/ItemActionHandlerAssets.php',
1004
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Common\\ScanActionConsumer' => __DIR__ . '/../..' . '/src/Scans/Common/ScanActionConsumer.php',
224
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Insert' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Insert.php',
225
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Record' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php',
226
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Select' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php',
227
+ 'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Traits\\FilterByIP' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/FilterByIP.php',
228
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Update' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php',
229
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\AlignTableWithSchema' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php',
230
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\BuildColumnFromDef' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php',
667
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryIpBlock' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/QueryIpBlock.php',
668
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\QueryRemainingOffenses' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/QueryRemainingOffenses.php',
669
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
670
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\BotSignalRecord' => __DIR__ . '/../..' . '/src/Modules/IPs/DB/BotSignal/BotSignalRecord.php',
671
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\LoadBotSignalRecords' => __DIR__ . '/../..' . '/src/Modules/IPs/DB/BotSignal/LoadBotSignalRecords.php',
672
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Common' => __DIR__ . '/../..' . '/src/Modules/IPs/DB/BotSignal/Ops/Common.php',
673
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Delete' => __DIR__ . '/../..' . '/src/Modules/IPs/DB/BotSignal/Ops/Delete.php',
674
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Handler' => __DIR__ . '/../..' . '/src/Modules/IPs/DB/BotSignal/Ops/Handler.php',
675
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Insert' => __DIR__ . '/../..' . '/src/Modules/IPs/DB/BotSignal/Ops/Insert.php',
676
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Record' => __DIR__ . '/../..' . '/src/Modules/IPs/DB/BotSignal/Ops/Record.php',
677
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\DB\\BotSignal\\Ops\\Select' => __DIR__ . '/../..' . '/src/Modules/IPs/DB/BotSignal/Ops/Select.php',
678
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Insights\\OverviewCards' => __DIR__ . '/../..' . '/src/Modules/IPs/Insights/OverviewCards.php',
679
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\AutoUnblock' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/AutoUnblock.php',
680
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\BlacklistHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/BlacklistHandler.php',
695
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
696
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/OffenseTracker.php',
697
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\AddIp' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/AddIp.php',
698
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\ConvertLegacy' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/ConvertLegacy.php',
699
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\DeleteIp' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/DeleteIp.php',
700
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\LookupIpOnList' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/LookupIpOnList.php',
701
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Ops\\RetrieveIpsForLists' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Ops/RetrieveIpsForLists.php',
1008
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Base/ResultItem.php',
1009
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Base/ResultsSet.php',
1010
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\BaseRepair' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/BaseRepair.php',
1011
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\IgnoreItem' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/IgnoreItem.php',
1012
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/ItemActionHandler.php',
1013
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Base\\Utilities\\ItemActionHandlerAssets' => __DIR__ . '/../..' . '/src/Scans/Base/Utilities/ItemActionHandlerAssets.php',
1014
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Common\\ScanActionConsumer' => __DIR__ . '/../..' . '/src/Scans/Common/ScanActionConsumer.php',
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/BaseQuery.php CHANGED
@@ -134,6 +134,18 @@ abstract class BaseQuery {
134
  return $this;
135
  }
136
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  /**
138
  * @param string $column
139
  * @param string $like
134
  return $this;
135
  }
136
 
137
+ /**
138
+ * @param string $column
139
+ * @param array $values
140
+ * @return $this
141
+ */
142
+ public function addWhereNotIn( string $column, array $values ) {
143
+ if ( !empty( $values ) ) {
144
+ $this->addWhere( $column, $values, 'NOT IN' );
145
+ }
146
+ return $this;
147
+ }
148
+
149
  /**
150
  * @param string $column
151
  * @param string $like
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php CHANGED
@@ -30,7 +30,10 @@ class Record extends DynPropertiesClass {
30
  switch ( $key ) {
31
 
32
  case 'ip':
33
- $value = inet_ntop( $value );
 
 
 
34
  break;
35
 
36
  case 'meta':
@@ -67,6 +70,9 @@ class Record extends DynPropertiesClass {
67
 
68
  case 'ip':
69
  $value = inet_pton( $value );
 
 
 
70
  break;
71
 
72
  case 'meta':
30
  switch ( $key ) {
31
 
32
  case 'ip':
33
+ if ( !empty( $value ) ) {
34
+ $value = inet_ntop( $value );
35
+ }
36
+ $value = (string)$value;
37
  break;
38
 
39
  case 'meta':
70
 
71
  case 'ip':
72
  $value = inet_pton( $value );
73
+ if ( empty( $value ) ) {
74
+ $value = '';
75
+ }
76
  break;
77
 
78
  case 'meta':
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/FilterByIP.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base\Traits;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ trait FilterByIP {
8
+
9
+ public function filterByIPHuman( string $ip ) :self {
10
+ $rightSide = null;
11
+ if ( empty( $ip ) ) {
12
+ $rightSide = "''";
13
+ }
14
+ elseif ( Services::IP()->isValidIp( $ip ) || Services::IP()->isValidIp( inet_ntop( $ip ) ) ) {
15
+ $rightSide = sprintf( "INET6_ATON('%s')", Services::IP()->isValidIp( $ip ) ? $ip : inet_ntop( $ip ) );
16
+ }
17
+
18
+ if ( !empty( $rightSide ) ) {
19
+ $this->addRawWhere( [ '`ip`', '=', $rightSide ] );
20
+ }
21
+ return $this;
22
+ }
23
+ }
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/Select_IPTable.php DELETED
@@ -1,24 +0,0 @@
1
- <?php declare( strict_types=1 );
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base\Traits;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Core\Utilities\Tool\IpListSort;
6
-
7
- trait Select_IPTable {
8
-
9
- /**
10
- * @return string[]
11
- */
12
- public function getDistinctIps() :array {
13
- $ips = $this->getDistinctForColumn( 'ip' );
14
- if ( $this->getDbH()->getTableSchema()->is_ip_binary ) {
15
- $ips = array_map(
16
- function ( $binaryIP ) {
17
- return inet_ntop( $binaryIP );
18
- },
19
- $ips
20
- );
21
- }
22
- return IpListSort::Sort( $ips );
23
- }
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php CHANGED
@@ -118,7 +118,7 @@ abstract class ApiBase {
118
 
119
  $url = add_query_arg( $this->getQueryData(), $this->getApiUrl() );
120
  $sig = md5( $url );
121
-
122
  if ( $this->isUseQueryCache() && isset( self::$QueryCache[ $sig ] ) ) {
123
  $response = self::$QueryCache[ $sig ];
124
  }
118
 
119
  $url = add_query_arg( $this->getQueryData(), $this->getApiUrl() );
120
  $sig = md5( $url );
121
+ error_log( $url );
122
  if ( $this->isUseQueryCache() && isset( self::$QueryCache[ $sig ] ) ) {
123
  $response = self::$QueryCache[ $sig ];
124
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Retrieve.php CHANGED
@@ -40,6 +40,15 @@ class Retrieve extends Base {
40
  return $this->query();
41
  }
42
 
 
 
 
 
 
 
 
 
 
43
  /**
44
  * @param string $sFullPath
45
  * @param string $sLine
40
  return $this->query();
41
  }
42
 
43
+ /**
44
+ * @return array|null - null on failure
45
+ */
46
+ protected function fireRequestDecodeResponse() {
47
+ $sResponse = $this->fireRequest();
48
+ error_log( 'HTTP: '.$sResponse );
49
+ return empty( $sResponse ) ? null : json_decode( $sResponse, true );
50
+ }
51
+
52
  /**
53
  * @param string $sFullPath
54
  * @param string $sLine
templates/twig/notices/new-audit-trail.twig CHANGED
@@ -1,6 +1 @@
1
- {% extends "/notices/base-info.twig" %}
2
-
3
- {% block notice_body %}
4
- {{ parent() }}
5
- <p><a href=""></a></p>
6
- {% endblock %}
1
+ {% extends "/notices/base-info.twig" %}