Version Description
Download this release
Release Info
Developer | paultgoodchild |
Plugin | Shield Security for WordPress |
Version | 15.1.7 |
Comparing to | |
See all releases |
Code changes from version 15.1.6 to 15.1.7
- cl.json +14 -0
- icwp-wpsf.php +1 -1
- plugin-spec.php +3 -3
- plugin.json +3 -3
- readme.txt +1 -1
- resources/css/plugin.css +7 -0
- resources/js/shield/audit_trail.js +0 -2
- resources/js/shield/scantables.js +4 -2
- src/lib/src/Modules/AuditTrail/Lib/LogTable/BuildAuditTableData.php +3 -3
- src/lib/src/Modules/AuditTrail/ModCon.php +1 -1
- src/lib/src/Modules/Base/Databases.php +0 -3
- src/lib/src/Modules/Events/Lib/EventsService.php +13 -4
- src/lib/src/Modules/HackGuard/Lib/ScanTables/BuildScanTableData.php +122 -0
- src/lib/src/Modules/HackGuard/Lib/ScanTables/BuildSearchPanesData.php +78 -0
- src/lib/src/Modules/HackGuard/Lib/ScanTables/DelegateAjaxHandler.php +6 -6
- src/lib/src/Modules/HackGuard/Lib/ScanTables/Modals/BuildInfo.php +6 -6
- src/lib/src/Modules/HackGuard/Lib/ScanTables/Modals/ScanItemView.php +1 -1
- src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/BaseLoadTableData.php +166 -0
- src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/BaseLoadTableDataPluginTheme.php +54 -0
- src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/LoadTableDataMalware.php +77 -0
- src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/LoadTableDataPlugin.php +28 -0
- src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/LoadTableDataTheme.php +28 -0
- src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/LoadTableDataWordpress.php +67 -0
- src/lib/src/Modules/HackGuard/ModCon.php +3 -6
- src/lib/src/Modules/HackGuard/Render/ScanResults/SectionPlugins.php +5 -5
- src/lib/src/Modules/HackGuard/Render/ScanResults/SectionThemes.php +5 -6
- src/lib/src/Modules/HackGuard/Scan/Controller/Base.php +1 -1
- src/lib/src/Modules/HackGuard/Scan/Results/Counts.php +0 -1
- src/lib/src/Modules/HackGuard/Scan/Results/Retrieve.php +64 -42
- src/lib/src/Modules/HackGuard/Scan/ScansController.php +1 -2
- src/lib/src/Modules/IPs/WpCli/Add.php +11 -13
- src/lib/src/Modules/IPs/WpCli/Base.php +20 -0
- src/lib/src/Modules/IPs/WpCli/BaseAddRemove.php +1 -3
- src/lib/src/Modules/IPs/WpCli/Enumerate.php +24 -18
- src/lib/src/Modules/IPs/WpCli/Remove.php +11 -15
- src/lib/src/Modules/License/Processor.php +1 -1
- src/lib/src/Modules/Plugin/Lib/PluginTelemetry.php +5 -2
- src/lib/src/Modules/Traffic/Lib/TrafficTable/BuildTrafficTableData.php +3 -3
- src/lib/src/Tables/DataTables/Build/Scans/BaseForScan.php +37 -15
- src/lib/src/Tables/DataTables/Build/Scans/ForMalware.php +15 -3
- src/lib/src/Tables/DataTables/LoadData/BaseBuildTableData.php +9 -9
- src/lib/src/Tables/Render/WpCliTable/AuditTrail.php +1 -1
cl.json
CHANGED
@@ -100,6 +100,20 @@
|
|
100 |
"type": "fixed"
|
101 |
}
|
102 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
}
|
104 |
]
|
105 |
},
|
100 |
"type": "fixed"
|
101 |
}
|
102 |
]
|
103 |
+
},
|
104 |
+
{
|
105 |
+
"version": "7",
|
106 |
+
"released_at": 1658226200,
|
107 |
+
"items": [
|
108 |
+
{
|
109 |
+
"title": "Eliminate errors and slow processing when displaying scan results pages for large datasets.",
|
110 |
+
"type": "improved"
|
111 |
+
},
|
112 |
+
{
|
113 |
+
"title": "Bug when specifying a particular list when adding/removing an IP address using WP-CLI.",
|
114 |
+
"type": "fixed"
|
115 |
+
}
|
116 |
+
]
|
117 |
}
|
118 |
]
|
119 |
},
|
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: 15.1.
|
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: 15.1.7
|
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": "15.1.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "202207.
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"text_domain": "wp-simple-firewall",
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "15.1.7",
|
4 |
+
"release_timestamp": 1658663000,
|
5 |
+
"build": "202207.2401",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"text_domain": "wp-simple-firewall",
|
plugin.json
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "15.1.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "202207.
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"text_domain": "wp-simple-firewall",
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "15.1.7",
|
4 |
+
"release_timestamp": 1658663000,
|
5 |
+
"build": "202207.2401",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"text_domain": "wp-simple-firewall",
|
readme.txt
CHANGED
@@ -8,7 +8,7 @@ Requires at least: 3.7
|
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 6.0
|
11 |
-
Stable tag: 15.1.
|
12 |
|
13 |
Bad Bots Are Your #1 Security Risk. Malware is a symptom of poor security, not the cause. Discover the advantage of powerful security over marketing.
|
14 |
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 6.0
|
11 |
+
Stable tag: 15.1.7
|
12 |
|
13 |
Bad Bots Are Your #1 Security Risk. Malware is a symptom of poor security, not the cause. Discover the advantage of powerful security over marketing.
|
14 |
|
resources/css/plugin.css
CHANGED
@@ -1150,4 +1150,11 @@ button.bs-placeholder {
|
|
1150 |
}
|
1151 |
#ShieldGeneralPurposeDialog .card-header {
|
1152 |
background: transparent;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1153 |
}
|
1150 |
}
|
1151 |
#ShieldGeneralPurposeDialog .card-header {
|
1152 |
background: transparent;
|
1153 |
+
}
|
1154 |
+
td.status {
|
1155 |
+
min-width: 150px;
|
1156 |
+
}
|
1157 |
+
td.status ul,
|
1158 |
+
td.mal_details ul {
|
1159 |
+
padding-left: 0;
|
1160 |
}
|
resources/js/shield/audit_trail.js
CHANGED
@@ -141,8 +141,6 @@
|
|
141 |
iCWP_WPSF_BodyOverlay.show();
|
142 |
let reqData = base.getBaseAjaxData();
|
143 |
reqData.sub_action = 'retrieve_table_data';
|
144 |
-
reqData.type = base.options.type;
|
145 |
-
reqData.file = base.options.file;
|
146 |
reqData.table_data = data;
|
147 |
$.post( ajaxurl, reqData, function ( response ) {
|
148 |
if ( response.success ) {
|
141 |
iCWP_WPSF_BodyOverlay.show();
|
142 |
let reqData = base.getBaseAjaxData();
|
143 |
reqData.sub_action = 'retrieve_table_data';
|
|
|
|
|
144 |
reqData.table_data = data;
|
145 |
$.post( ajaxurl, reqData, function ( response ) {
|
146 |
if ( response.success ) {
|
resources/js/shield/scantables.js
CHANGED
@@ -204,14 +204,16 @@
|
|
204 |
this.$table = this.$el.DataTable(
|
205 |
$.extend( base.options.datatables_init,
|
206 |
{
|
|
|
207 |
ajax: function ( data, callback, settings ) {
|
208 |
let reqData = base.getBaseAjaxData();
|
209 |
reqData.sub_action = 'retrieve_table_data';
|
210 |
reqData.type = base.options.type;
|
211 |
reqData.file = base.options.file;
|
|
|
212 |
$.post( ajaxurl, reqData, function ( response ) {
|
213 |
if ( response.success ) {
|
214 |
-
callback( response.data.
|
215 |
}
|
216 |
else {
|
217 |
let msg = 'Communications error with site.';
|
@@ -226,7 +228,7 @@
|
|
226 |
select: {
|
227 |
style: 'multi'
|
228 |
},
|
229 |
-
dom: '
|
230 |
buttons: [
|
231 |
{
|
232 |
text: 'Reload',
|
204 |
this.$table = this.$el.DataTable(
|
205 |
$.extend( base.options.datatables_init,
|
206 |
{
|
207 |
+
serverSide: true,
|
208 |
ajax: function ( data, callback, settings ) {
|
209 |
let reqData = base.getBaseAjaxData();
|
210 |
reqData.sub_action = 'retrieve_table_data';
|
211 |
reqData.type = base.options.type;
|
212 |
reqData.file = base.options.file;
|
213 |
+
reqData.table_data = data;
|
214 |
$.post( ajaxurl, reqData, function ( response ) {
|
215 |
if ( response.success ) {
|
216 |
+
callback( response.data.datatable_data );
|
217 |
}
|
218 |
else {
|
219 |
let msg = 'Communications error with site.';
|
228 |
select: {
|
229 |
style: 'multi'
|
230 |
},
|
231 |
+
dom: 'Brpftip',
|
232 |
buttons: [
|
233 |
{
|
234 |
text: 'Reload',
|
src/lib/src/Modules/AuditTrail/Lib/LogTable/BuildAuditTableData.php
CHANGED
@@ -17,8 +17,8 @@ class BuildAuditTableData extends BaseBuildTableData {
|
|
17 |
*/
|
18 |
private $log;
|
19 |
|
20 |
-
protected function
|
21 |
-
return $this->
|
22 |
}
|
23 |
|
24 |
protected function getSearchPanesData() :array {
|
@@ -30,7 +30,7 @@ class BuildAuditTableData extends BaseBuildTableData {
|
|
30 |
/**
|
31 |
* @param LogRecord[] $records
|
32 |
*/
|
33 |
-
protected function
|
34 |
return array_values( array_map(
|
35 |
function ( $log ) {
|
36 |
$this->log = $log;
|
17 |
*/
|
18 |
private $log;
|
19 |
|
20 |
+
protected function loadRecordsWithDirectQuery() :array {
|
21 |
+
return $this->loadRecordsWithSearch();
|
22 |
}
|
23 |
|
24 |
protected function getSearchPanesData() :array {
|
30 |
/**
|
31 |
* @param LogRecord[] $records
|
32 |
*/
|
33 |
+
protected function buildTableRowsFromRawRecords( array $records ) :array {
|
34 |
return array_values( array_map(
|
35 |
function ( $log ) {
|
36 |
$this->log = $log;
|
src/lib/src/Modules/AuditTrail/ModCon.php
CHANGED
@@ -80,7 +80,7 @@ class ModCon extends BaseShield\ModCon {
|
|
80 |
array_filter( // Get all logs entries pertaining to this user:
|
81 |
( new Shield\Modules\AuditTrail\Lib\LogTable\BuildAuditTableData() )
|
82 |
->setMod( $this )
|
83 |
-
->
|
84 |
function ( $log ) use ( $user ) {
|
85 |
$keep = $log[ 'user_id' ] === $user->ID;
|
86 |
if ( !$keep ) {
|
80 |
array_filter( // Get all logs entries pertaining to this user:
|
81 |
( new Shield\Modules\AuditTrail\Lib\LogTable\BuildAuditTableData() )
|
82 |
->setMod( $this )
|
83 |
+
->loadForRecords(),
|
84 |
function ( $log ) use ( $user ) {
|
85 |
$keep = $log[ 'user_id' ] === $user->ID;
|
86 |
if ( !$keep ) {
|
src/lib/src/Modules/Base/Databases.php
CHANGED
@@ -57,9 +57,6 @@ class Databases {
|
|
57 |
$dbDef[ 'table_prefix' ] = $this->getCon()->getPluginPrefix( '_' );
|
58 |
/** @var Core\Databases\Base\Handler|mixed $dbh */
|
59 |
$dbh = new $dbClass( $dbDef );
|
60 |
-
if ( $this->getCon()->flags[ 'db_bypass_ready_check_cache' ] ?? false ) {
|
61 |
-
$dbh->bypassReadyCheckCache();
|
62 |
-
}
|
63 |
$dbh->execute();
|
64 |
|
65 |
$this->dbHandlers[ $dbKey ] = $dbh;
|
57 |
$dbDef[ 'table_prefix' ] = $this->getCon()->getPluginPrefix( '_' );
|
58 |
/** @var Core\Databases\Base\Handler|mixed $dbh */
|
59 |
$dbh = new $dbClass( $dbDef );
|
|
|
|
|
|
|
60 |
$dbh->execute();
|
61 |
|
62 |
$this->dbHandlers[ $dbKey ] = $dbh;
|
src/lib/src/Modules/Events/Lib/EventsService.php
CHANGED
@@ -101,10 +101,19 @@ class EventsService {
|
|
101 |
}
|
102 |
|
103 |
public function getEventStrings( string $eventKey ) :array {
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
}
|
109 |
|
110 |
/**
|
101 |
}
|
102 |
|
103 |
public function getEventStrings( string $eventKey ) :array {
|
104 |
+
$eventStrings = [];
|
105 |
+
|
106 |
+
if ( $this->eventExists( $eventKey ) ) {
|
107 |
+
$eventStrings = $this->getCon()
|
108 |
+
->getModule( $this->getEventDef( $eventKey )[ 'module' ] )
|
109 |
+
->getStrings()
|
110 |
+
->getEventStrings()[ $eventKey ] ?? $eventStrings;
|
111 |
+
}
|
112 |
+
else {
|
113 |
+
error_log( sprintf( 'An event %s does not exist.', $eventKey ) );
|
114 |
+
}
|
115 |
+
|
116 |
+
return $eventStrings;
|
117 |
}
|
118 |
|
119 |
/**
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/BuildScanTableData.php
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\DB\LogRecord;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\Build\Scans\BaseForScan;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Tables\DataTables\LoadData\BaseBuildTableData;
|
8 |
+
use FernleafSystems\Wordpress\Services\Services;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @property string $type
|
12 |
+
* @property string $file
|
13 |
+
*/
|
14 |
+
class BuildScanTableData extends BaseBuildTableData {
|
15 |
+
|
16 |
+
protected function loadRecordsWithSearch() :array {
|
17 |
+
return $this->loadRecordsWithDirectQuery();
|
18 |
+
}
|
19 |
+
|
20 |
+
protected function getSearchPanesData() :array {
|
21 |
+
return [];
|
22 |
+
/*
|
23 |
+
return ( new BuildSearchPanesData() )
|
24 |
+
->setMod( $this->getMod() )
|
25 |
+
->build();
|
26 |
+
*/
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @param LogRecord[] $records
|
31 |
+
*/
|
32 |
+
protected function buildTableRowsFromRawRecords( array $records ) :array {
|
33 |
+
return array_values( $records );
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* The Wheres need to align with the structure of the Query called from getRecords()
|
38 |
+
*/
|
39 |
+
protected function buildWheresFromSearchParams() :array {
|
40 |
+
$wheres = [];
|
41 |
+
if ( !empty( $this->table_data[ 'searchPanes' ] ) ) {
|
42 |
+
foreach ( array_filter( $this->table_data[ 'searchPanes' ] ) as $column => $selected ) {
|
43 |
+
switch ( $column ) {
|
44 |
+
case 'event':
|
45 |
+
if ( count( $selected ) > 1 ) {
|
46 |
+
$wheres[] = sprintf( 'log.event_slug IN (`%s`)', implode( '`,`', $selected ) );
|
47 |
+
}
|
48 |
+
else {
|
49 |
+
$wheres[] = sprintf( "log.event_slug='%s'", array_pop( $selected ) );
|
50 |
+
}
|
51 |
+
break;
|
52 |
+
case 'ip':
|
53 |
+
$wheres[] = sprintf( "ips.ip=INET6_ATON('%s')", array_pop( $selected ) );
|
54 |
+
break;
|
55 |
+
default:
|
56 |
+
break;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
}
|
60 |
+
return $wheres;
|
61 |
+
}
|
62 |
+
|
63 |
+
protected function countTotalRecords() :int {
|
64 |
+
return $this->getRecordsLoader()->countAll();
|
65 |
+
}
|
66 |
+
|
67 |
+
protected function countTotalRecordsFiltered() :int {
|
68 |
+
$loader = $this->getRecordsLoader();
|
69 |
+
$loader->wheres = $this->buildWheresFromSearchParams();
|
70 |
+
return $loader->countAll();
|
71 |
+
}
|
72 |
+
|
73 |
+
protected function getSearchableColumns() :array {
|
74 |
+
// Use the DataTables definition builder to locate searchable columns
|
75 |
+
return array_filter( array_map(
|
76 |
+
function ( $column ) {
|
77 |
+
return ( $column[ 'searchable' ] ?? false ) ? $column[ 'data' ] : '';
|
78 |
+
},
|
79 |
+
( new BaseForScan() )
|
80 |
+
->setMod( $this->getMod() )
|
81 |
+
->buildRaw()[ 'columns' ]
|
82 |
+
) );
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* @return array[]
|
87 |
+
*/
|
88 |
+
protected function getRecords( array $wheres = [], int $offset = 0, int $limit = 0 ) :array {
|
89 |
+
$loader = $this->getRecordsLoader();
|
90 |
+
$loader->wheres = $wheres;
|
91 |
+
$loader->limit = $limit;
|
92 |
+
$loader->offset = $offset;
|
93 |
+
return $loader->run();
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* @return TableData\BaseLoadTableData
|
98 |
+
*/
|
99 |
+
protected function getRecordsLoader() {
|
100 |
+
switch ( $this->type ) {
|
101 |
+
case 'plugin':
|
102 |
+
$loader = new TableData\LoadTableDataPlugin( Services::WpPlugins()->getPluginAsVo( $this->file ) );
|
103 |
+
break;
|
104 |
+
case 'theme':
|
105 |
+
$loader = new TableData\LoadTableDataTheme( Services::WpThemes()->getThemeAsVo( $this->file ) );
|
106 |
+
break;
|
107 |
+
case 'malware':
|
108 |
+
$loader = new TableData\LoadTableDataMalware();
|
109 |
+
break;
|
110 |
+
case 'wordpress':
|
111 |
+
default:
|
112 |
+
$loader = new TableData\LoadTableDataWordpress();
|
113 |
+
break;
|
114 |
+
}
|
115 |
+
|
116 |
+
$loader->order_dir = $this->getOrderDirection();
|
117 |
+
$loader->order_by = $this->order_by;
|
118 |
+
$loader->search_text = preg_replace( '#[^/a-z\d_-]#i', '', (string)$this->table_data[ 'search' ][ 'value' ] ?? '' );
|
119 |
+
|
120 |
+
return $loader->setMod( $this->getMod() );
|
121 |
+
}
|
122 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/BuildSearchPanesData.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class BuildSearchPanesData {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
public function build() :array {
|
14 |
+
return [
|
15 |
+
'options' => [
|
16 |
+
'file_type' => $this->buildForFileTypes(),
|
17 |
+
'status' => $this->buildForFileStatus(),
|
18 |
+
]
|
19 |
+
];
|
20 |
+
}
|
21 |
+
|
22 |
+
private function buildForFileTypes() :array {
|
23 |
+
$exts = [];
|
24 |
+
foreach ( $this->runQueryForFileTypes() as $item ) {
|
25 |
+
$item = $item[ 'item_id' ] ?? '';
|
26 |
+
if ( !empty( $item ) && strpos( $item, '.' ) > 0 ) {
|
27 |
+
$ext = explode( '.', $item )[ 1 ];
|
28 |
+
if ( empty( $exts[ $ext ] ) ) {
|
29 |
+
$exts[ $ext ] = [
|
30 |
+
'label' => strtoupper( $ext ),
|
31 |
+
'value' => $ext,
|
32 |
+
];
|
33 |
+
}
|
34 |
+
}
|
35 |
+
}
|
36 |
+
return array_values( $exts );
|
37 |
+
}
|
38 |
+
|
39 |
+
private function buildForFileStatus() :array {
|
40 |
+
return [
|
41 |
+
[
|
42 |
+
'label' => __( 'Malware', 'wp-simple-firewall' ),
|
43 |
+
'value' => 'is_mal',
|
44 |
+
],
|
45 |
+
[
|
46 |
+
'label' => __( 'Unrecognised', 'wp-simple-firewall' ),
|
47 |
+
'value' => 'is_unrecognised',
|
48 |
+
],
|
49 |
+
[
|
50 |
+
'label' => __( 'Modified From Original', 'wp-simple-firewall' ),
|
51 |
+
'value' => 'is_checksumfail',
|
52 |
+
],
|
53 |
+
[
|
54 |
+
'label' => __( 'Missing', 'wp-simple-firewall' ),
|
55 |
+
'value' => 'is_missing',
|
56 |
+
],
|
57 |
+
];
|
58 |
+
}
|
59 |
+
|
60 |
+
private function runQueryForFileTypes() :array {
|
61 |
+
/** @var ModCon $mod */
|
62 |
+
$mod = $this->getMod();
|
63 |
+
$results = Services::WpDb()->selectCustom(
|
64 |
+
sprintf( "SELECT DISTINCT `ri`.`item_id`
|
65 |
+
FROM `%s` as `ri`
|
66 |
+
WHERE `ri`.`item_type`='f'
|
67 |
+
AND `ri`.`ignored_at`=0
|
68 |
+
AND `ri`.`auto_filtered_at`!=0
|
69 |
+
AND `ri`.`item_repaired_at`=0
|
70 |
+
AND `ri`.`item_deleted_at`=0
|
71 |
+
AND `ri`.`deleted_at`=0
|
72 |
+
",
|
73 |
+
$mod->getDbH_ResultItems()->getTableSchema()->table
|
74 |
+
)
|
75 |
+
);
|
76 |
+
return is_array( $results ) ? $results : [];
|
77 |
+
}
|
78 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/DelegateAjaxHandler.php
CHANGED
@@ -151,13 +151,13 @@ class DelegateAjaxHandler {
|
|
151 |
*/
|
152 |
private function retrieveTableData() :array {
|
153 |
$req = Services::Request();
|
|
|
|
|
|
|
|
|
154 |
return [
|
155 |
-
'success'
|
156 |
-
'
|
157 |
-
'data' => array_values( ( new LoadRawTableData() )
|
158 |
-
->setMod( $this->getMod() )
|
159 |
-
->loadFor( $req->post( 'type' ), $req->post( 'file' ) ) )
|
160 |
-
],
|
161 |
];
|
162 |
}
|
163 |
}
|
151 |
*/
|
152 |
private function retrieveTableData() :array {
|
153 |
$req = Services::Request();
|
154 |
+
$builder = ( new BuildScanTableData() )->setMod( $this->getMod() );
|
155 |
+
$builder->table_data = (array)$req->post( 'table_data', [] );
|
156 |
+
$builder->type = (string)$req->post( 'type', '' );
|
157 |
+
$builder->file = (string)$req->post( 'file', '' );
|
158 |
return [
|
159 |
+
'success' => true,
|
160 |
+
'datatable_data' => $builder->build(),
|
|
|
|
|
|
|
|
|
161 |
];
|
162 |
}
|
163 |
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/Modals/BuildInfo.php
CHANGED
@@ -74,28 +74,28 @@ class BuildInfo {
|
|
74 |
}
|
75 |
elseif ( $item->is_in_plugin ) {
|
76 |
if ( $item->is_unrecognised ) {
|
77 |
-
$description[] = __( "It's located
|
78 |
}
|
79 |
else {
|
80 |
-
$description[] = __( "It's located in a WordPress plugin directory, and is a recognised
|
81 |
}
|
82 |
}
|
83 |
elseif ( $item->is_in_theme ) {
|
84 |
if ( $item->is_unrecognised ) {
|
85 |
-
$description[] = __( "It's located in a WordPress theme directory, but it's not recognised as an official file.", 'wp-simple-firewall' );
|
86 |
}
|
87 |
else {
|
88 |
-
$description[] = __( "It's located in a WordPress theme directory, and is a recognised
|
89 |
}
|
90 |
}
|
91 |
if ( $item->is_checksumfail ) {
|
92 |
-
$description[] = __( '
|
93 |
}
|
94 |
if ( $item->is_mal ) {
|
95 |
$description[] = __( 'Contents could potentially contain malicious PHP malware.', 'wp-simple-firewall' );
|
96 |
$description[] = sprintf( __( 'The false positive score of this file is %s.', 'wp-simple-firewall' ),
|
97 |
sprintf( '<code>%s</code>', $item->mal_fp_confidence ) );
|
98 |
-
$description[] = __( "The lower the score the less we know about the file
|
99 |
}
|
100 |
|
101 |
return $description;
|
74 |
}
|
75 |
elseif ( $item->is_in_plugin ) {
|
76 |
if ( $item->is_unrecognised ) {
|
77 |
+
$description[] = __( "It's located inside a WordPress plugin directory, but it's not recognised as an official file for that plugin version.", 'wp-simple-firewall' );
|
78 |
}
|
79 |
else {
|
80 |
+
$description[] = __( "It's located in a WordPress plugin directory, and is a recognised as a valid file for that plugin version.", 'wp-simple-firewall' );
|
81 |
}
|
82 |
}
|
83 |
elseif ( $item->is_in_theme ) {
|
84 |
if ( $item->is_unrecognised ) {
|
85 |
+
$description[] = __( "It's located in a WordPress theme directory, but it's not recognised as an official file for that theme version.", 'wp-simple-firewall' );
|
86 |
}
|
87 |
else {
|
88 |
+
$description[] = __( "It's located in a WordPress theme directory, and is a recognised as a valid file for that theme version.", 'wp-simple-firewall' );
|
89 |
}
|
90 |
}
|
91 |
if ( $item->is_checksumfail ) {
|
92 |
+
$description[] = __( 'File contents have been modified when compared against the official release for that version.', 'wp-simple-firewall' );
|
93 |
}
|
94 |
if ( $item->is_mal ) {
|
95 |
$description[] = __( 'Contents could potentially contain malicious PHP malware.', 'wp-simple-firewall' );
|
96 |
$description[] = sprintf( __( 'The false positive score of this file is %s.', 'wp-simple-firewall' ),
|
97 |
sprintf( '<code>%s</code>', $item->mal_fp_confidence ) );
|
98 |
+
$description[] = __( "The lower the score the less we know about the file or the more likely it contains malicious code.", 'wp-simple-firewall' );
|
99 |
}
|
100 |
|
101 |
return $description;
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/Modals/ScanItemView.php
CHANGED
@@ -140,7 +140,7 @@ class ScanItemView {
|
|
140 |
|
141 |
$FS = Services::WpFs();
|
142 |
if ( empty( $originalFileDownload ) || !$FS->isFile($originalFileDownload)) {
|
143 |
-
throw new \Exception( '
|
144 |
}
|
145 |
|
146 |
$conv = new ConvertLineEndings();
|
140 |
|
141 |
$FS = Services::WpFs();
|
142 |
if ( empty( $originalFileDownload ) || !$FS->isFile($originalFileDownload)) {
|
143 |
+
throw new \Exception( "A File Diff can't be created as there is no original/official file available for us to compare with." );
|
144 |
}
|
145 |
|
146 |
$conv = new ConvertLineEndings();
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/BaseLoadTableData.php
ADDED
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\TableData;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller\Afs;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Results\Retrieve;
|
9 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Tool\FormatBytes;
|
10 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
11 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
12 |
+
use FernleafSystems\Wordpress\Services\Services;
|
13 |
+
use FernleafSystems\Wordpress\Services\Utilities\File\Paths;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @property int $limit
|
17 |
+
* @property int $offset
|
18 |
+
* @property string[] $wheres
|
19 |
+
* @property string $order_by
|
20 |
+
* @property string $order_dir
|
21 |
+
* @property string $search_text
|
22 |
+
*/
|
23 |
+
abstract class BaseLoadTableData extends DynPropertiesClass {
|
24 |
+
|
25 |
+
use ModConsumer;
|
26 |
+
|
27 |
+
abstract public function run() :array;
|
28 |
+
|
29 |
+
public function countAll() :int {
|
30 |
+
return $this->getRecordRetriever()->count();
|
31 |
+
}
|
32 |
+
|
33 |
+
protected function getRecordRetriever() :Retrieve {
|
34 |
+
/** @var ModCon $mod */
|
35 |
+
$mod = $this->getMod();
|
36 |
+
$retriever = ( new Retrieve() )
|
37 |
+
->setMod( $this->getMod() )
|
38 |
+
->setScanController( $mod->getScanCon( Afs::SCAN_SLUG ) );
|
39 |
+
$retriever->limit = $this->limit;
|
40 |
+
$retriever->offset = $this->offset;
|
41 |
+
|
42 |
+
if ( !empty( $this->order_by ) ) {
|
43 |
+
switch ( $this->order_by ) {
|
44 |
+
case 'created_at':
|
45 |
+
$by = '`ri`.`created_at`';
|
46 |
+
break;
|
47 |
+
case 'file':
|
48 |
+
$by = '`ri`.`item_id`';
|
49 |
+
break;
|
50 |
+
default:
|
51 |
+
$by = null;
|
52 |
+
break;
|
53 |
+
}
|
54 |
+
|
55 |
+
$retriever->order_by = $by;
|
56 |
+
if ( !empty( $by ) && in_array( strtoupper( (string)$this->order_dir ), [ 'ASC', 'DESC' ] ) ) {
|
57 |
+
$retriever->order_dir = $this->order_dir;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
if ( !empty( $this->search_text ) ) {
|
62 |
+
$wheres = $this->wheres ?? [];
|
63 |
+
$wheres[] = sprintf( "`ri`.`item_id` LIKE '%%%s%%'", $this->search_text );
|
64 |
+
$retriever->wheres = $wheres;
|
65 |
+
}
|
66 |
+
|
67 |
+
return $retriever;
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* @param Scans\Base\ResultItem $item
|
72 |
+
* @throws \Exception
|
73 |
+
*/
|
74 |
+
protected function getActions( string $status, $item ) :array {
|
75 |
+
$con = $this->getCon();
|
76 |
+
/** @var ModCon $mod */
|
77 |
+
$mod = $this->getMod();
|
78 |
+
$actionHandler = $mod->getScanCon( $item->VO->scan )
|
79 |
+
->getItemActionHandler()
|
80 |
+
->setScanItem( $item );
|
81 |
+
|
82 |
+
$actions = [];
|
83 |
+
|
84 |
+
$defaultButtonClasses = [
|
85 |
+
'btn',
|
86 |
+
'action',
|
87 |
+
];
|
88 |
+
|
89 |
+
if ( !empty( $item->path_fragment ) ) {
|
90 |
+
$actions[] = sprintf( '<button class="action view-file btn-dark %s" title="%s" data-rid="%s">%s</button>',
|
91 |
+
implode( ' ', $defaultButtonClasses ),
|
92 |
+
__( 'View File Details', 'wp-simple-firewall' ),
|
93 |
+
$item->VO->scanresult_id,
|
94 |
+
$con->svgs->raw( 'bootstrap/zoom-in.svg' )
|
95 |
+
);
|
96 |
+
}
|
97 |
+
|
98 |
+
if ( in_array( $status, [ 'unrecognised', 'malware' ] ) ) {
|
99 |
+
$actions[] = sprintf( '<button class="btn-danger delete %s" title="%s" data-rid="%s">%s</button>',
|
100 |
+
implode( ' ', $defaultButtonClasses ),
|
101 |
+
__( 'Delete', 'wp-simple-firewall' ),
|
102 |
+
$item->VO->scanresult_id,
|
103 |
+
$con->svgs->raw( 'bootstrap/x-square.svg' )
|
104 |
+
);
|
105 |
+
}
|
106 |
+
|
107 |
+
try {
|
108 |
+
if ( in_array( $status, [ 'modified', 'missing', 'malware' ] )
|
109 |
+
&& $actionHandler->getRepairHandler()->canRepairItem() ) {
|
110 |
+
$actions[] = sprintf( '<button class="btn-warning repair %s" title="%s" data-rid="%s">%s</button>',
|
111 |
+
implode( ' ', $defaultButtonClasses ),
|
112 |
+
__( 'Repair', 'wp-simple-firewall' ),
|
113 |
+
$item->VO->scanresult_id,
|
114 |
+
$con->svgs->raw( 'bootstrap/tools.svg' )
|
115 |
+
);
|
116 |
+
}
|
117 |
+
}
|
118 |
+
catch ( \Exception $e ) {
|
119 |
+
}
|
120 |
+
|
121 |
+
$actions[] = sprintf( '<button class="btn-light ignore %s" title="%s" data-rid="%s">%s</button>',
|
122 |
+
implode( ' ', $defaultButtonClasses ),
|
123 |
+
__( 'Ignore', 'wp-simple-firewall' ),
|
124 |
+
$item->VO->scanresult_id,
|
125 |
+
$con->svgs->raw( 'bootstrap/eye-slash-fill.svg' )
|
126 |
+
);
|
127 |
+
|
128 |
+
return $actions;
|
129 |
+
}
|
130 |
+
|
131 |
+
protected function getColumnContent_File( Scans\Afs\ResultItem $item ) :string {
|
132 |
+
return sprintf( '<div>%s</div>', $this->getColumnContent_FileAsHref( $item ) );
|
133 |
+
}
|
134 |
+
|
135 |
+
protected function getColumnContent_FileStatus( Scans\Afs\ResultItem $item, string $status ) :string {
|
136 |
+
$content = $status;
|
137 |
+
|
138 |
+
$FS = Services::WpFs();
|
139 |
+
if ( $FS->isFile( $item->path_full ) ) {
|
140 |
+
$carbon = Services::Request()->carbon( true );
|
141 |
+
$content = sprintf( '%s<ul style="list-style: square inside"><li>%s</li></ul>',
|
142 |
+
$status,
|
143 |
+
implode( '</li><li>', [
|
144 |
+
sprintf( '%s: %s', __( 'Modified', 'wp-simple-firewall' ),
|
145 |
+
$carbon->setTimestamp( $FS->getModifiedTime( $item->path_full ) )
|
146 |
+
->diffForHumans()
|
147 |
+
),
|
148 |
+
sprintf( '%s: %s', __( 'Size', 'wp-simple-firewall' ),
|
149 |
+
FormatBytes::Format( $FS->getFileSize( $item->path_full ) )
|
150 |
+
),
|
151 |
+
sprintf( '%s: %s', __( 'Type', 'wp-simple-firewall' ), strtoupper( Paths::Ext( $item->path_full ) ) )
|
152 |
+
] )
|
153 |
+
);
|
154 |
+
}
|
155 |
+
|
156 |
+
return $content;
|
157 |
+
}
|
158 |
+
|
159 |
+
protected function getColumnContent_FileAsHref( Scans\Afs\ResultItem $item ) :string {
|
160 |
+
return sprintf( '<a href="#" title="%s" class="action view-file" data-rid="%s">%s</a>',
|
161 |
+
__( 'View File Contents', 'wp-simple-firewall' ),
|
162 |
+
$item->VO->scanresult_id,
|
163 |
+
$item->path_fragment
|
164 |
+
);
|
165 |
+
}
|
166 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/BaseLoadTableDataPluginTheme.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\TableData;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class BaseLoadTableDataPluginTheme extends BaseLoadTableData {
|
9 |
+
|
10 |
+
public function run() :array {
|
11 |
+
$RS = $this->getRecordRetriever()->retrieveLatest();
|
12 |
+
try {
|
13 |
+
$files = array_map(
|
14 |
+
function ( $item ) {
|
15 |
+
/** @var Scans\Afs\ResultItem $item */
|
16 |
+
$data = $item->getRawData();
|
17 |
+
$data[ 'rid' ] = $item->VO->scanresult_id;
|
18 |
+
$data[ 'file' ] = $item->path_fragment;
|
19 |
+
$data[ 'created_at' ] = $item->VO->created_at;
|
20 |
+
$data[ 'detected_since' ] = Services::Request()
|
21 |
+
->carbon( true )
|
22 |
+
->setTimestamp( $item->VO->created_at )
|
23 |
+
->diffForHumans();
|
24 |
+
|
25 |
+
if ( $item->is_checksumfail ) {
|
26 |
+
$data[ 'status_slug' ] = 'modified';
|
27 |
+
$data[ 'status' ] = __( 'Modified', 'wp-simple-firewall' );
|
28 |
+
}
|
29 |
+
elseif ( $item->is_missing ) {
|
30 |
+
$data[ 'status_slug' ] = 'missing';
|
31 |
+
$data[ 'status' ] = __( 'Missing', 'wp-simple-firewall' );
|
32 |
+
}
|
33 |
+
else {
|
34 |
+
$data[ 'status_slug' ] = 'unrecognised';
|
35 |
+
$data[ 'status' ] = __( 'Unrecognised', 'wp-simple-firewall' );
|
36 |
+
}
|
37 |
+
$data[ 'status' ] = $this->getColumnContent_FileStatus( $item, $data[ 'status' ] );
|
38 |
+
|
39 |
+
$data[ 'file_as_href' ] = $this->getColumnContent_File( $item );
|
40 |
+
|
41 |
+
$data[ 'file_type' ] = strtoupper( Services::Data()->getExtension( $item->path_full ) );
|
42 |
+
$data[ 'actions' ] = implode( ' ', $this->getActions( $data[ 'status_slug' ], $item ) );
|
43 |
+
return $data;
|
44 |
+
},
|
45 |
+
$RS->getItems()
|
46 |
+
);
|
47 |
+
}
|
48 |
+
catch ( \Exception $e ) {
|
49 |
+
$files = [];
|
50 |
+
}
|
51 |
+
|
52 |
+
return $files;
|
53 |
+
}
|
54 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/LoadTableDataMalware.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\TableData;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Results\Retrieve;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class LoadTableDataMalware extends BaseLoadTableData {
|
10 |
+
|
11 |
+
public function run() :array {
|
12 |
+
$RS = $this->getRecordRetriever()->retrieveLatest();
|
13 |
+
try {
|
14 |
+
$files = array_map(
|
15 |
+
function ( $item ) {
|
16 |
+
/** @var Scans\Afs\ResultItem $item */
|
17 |
+
$data = $item->getRawData();
|
18 |
+
|
19 |
+
$data[ 'rid' ] = $item->VO->scanresult_id;
|
20 |
+
$data[ 'file' ] = $item->path_fragment;
|
21 |
+
$data[ 'created_at' ] = $item->VO->created_at;
|
22 |
+
$data[ 'detected_since' ] = Services::Request()
|
23 |
+
->carbon( true )
|
24 |
+
->setTimestamp( $item->VO->created_at )
|
25 |
+
->diffForHumans();
|
26 |
+
|
27 |
+
$data[ 'file_as_href' ] = $this->getColumnContent_File( $item );
|
28 |
+
|
29 |
+
$data[ 'status_slug' ] = 'malware';
|
30 |
+
$data[ 'status' ] = $this->getColumnContent_FileStatus( $item, __( 'Malware', 'wp-simple-firewall' ) );
|
31 |
+
|
32 |
+
$data[ 'line_numbers' ] = implode( ', ', array_map(
|
33 |
+
function ( $line ) {
|
34 |
+
return $line + 1; // because lines start at ZERO
|
35 |
+
},
|
36 |
+
array_keys( $item->mal_fp_lines )
|
37 |
+
) );
|
38 |
+
$data[ 'mal_sig' ] = sprintf( '<code style="white-space: nowrap">%s</code>', esc_html( $item->mal_sig ) );
|
39 |
+
$data[ 'file_type' ] = strtoupper( Services::Data()->getExtension( $item->path_full ) );
|
40 |
+
$data[ 'actions' ] = implode( ' ', $this->getActions( $data[ 'status_slug' ], $item ) );
|
41 |
+
$data[ 'mal_details' ] = $this->getColumnContent_MalwareDetails(
|
42 |
+
$data[ 'line_numbers' ],
|
43 |
+
(int)$item->mal_fp_confidence,
|
44 |
+
$data[ 'mal_sig' ]
|
45 |
+
);
|
46 |
+
|
47 |
+
return $data;
|
48 |
+
},
|
49 |
+
$RS->getMalware()->getItems()
|
50 |
+
);
|
51 |
+
}
|
52 |
+
catch ( \Exception $e ) {
|
53 |
+
$files = [];
|
54 |
+
}
|
55 |
+
|
56 |
+
return $files;
|
57 |
+
}
|
58 |
+
|
59 |
+
protected function getColumnContent_MalwareDetails( string $lines, int $confidence, string $sig ) :string {
|
60 |
+
return sprintf( '<ul style="list-style: square inside"><li>%s</li></ul>',
|
61 |
+
implode( '</li><li>', [
|
62 |
+
sprintf( '%s: %s', __( 'Line Numbers' ), $lines ),
|
63 |
+
sprintf( '%s: %s', __( 'False Positive Confidence' ), $confidence ),
|
64 |
+
sprintf( '%s: %s', __( 'Pattern Detected' ), $sig ),
|
65 |
+
] )
|
66 |
+
);
|
67 |
+
}
|
68 |
+
|
69 |
+
protected function getRecordRetriever() :Retrieve {
|
70 |
+
$retriever = parent::getRecordRetriever();
|
71 |
+
$retriever->wheres = array_merge( [
|
72 |
+
"`rim`.`meta_key`='is_mal'",
|
73 |
+
"`rim`.`meta_value`=1",
|
74 |
+
], $retriever->wheres ?? [] );
|
75 |
+
return $retriever;
|
76 |
+
}
|
77 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/LoadTableDataPlugin.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\TableData;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Results\Retrieve;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
+
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
|
8 |
+
|
9 |
+
class LoadTableDataPlugin extends BaseLoadTableDataPluginTheme {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var WpPluginVo
|
13 |
+
*/
|
14 |
+
private $plugin;
|
15 |
+
|
16 |
+
public function __construct( WpPluginVo $plugin ) {
|
17 |
+
$this->plugin = $plugin;
|
18 |
+
}
|
19 |
+
|
20 |
+
protected function getRecordRetriever() :Retrieve {
|
21 |
+
$retriever = parent::getRecordRetriever();
|
22 |
+
$retriever->wheres = array_merge( [
|
23 |
+
"`rim`.`meta_key`='ptg_slug'",
|
24 |
+
sprintf( "`rim`.`meta_value`='%s'", $this->plugin->file ),
|
25 |
+
], $retriever->wheres ?? [] );
|
26 |
+
return $retriever;
|
27 |
+
}
|
28 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/LoadTableDataTheme.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\TableData;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Results\Retrieve;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
+
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpThemeVo;
|
8 |
+
|
9 |
+
class LoadTableDataTheme extends BaseLoadTableDataPluginTheme {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var WpThemeVo
|
13 |
+
*/
|
14 |
+
private $theme;
|
15 |
+
|
16 |
+
public function __construct( WpThemeVo $theme ) {
|
17 |
+
$this->theme = $theme;
|
18 |
+
}
|
19 |
+
|
20 |
+
protected function getRecordRetriever() :Retrieve {
|
21 |
+
$retriever = parent::getRecordRetriever();
|
22 |
+
$retriever->wheres = array_merge( [
|
23 |
+
"`rim`.`meta_key`='ptg_slug'",
|
24 |
+
sprintf( "`rim`.`meta_value`='%s'", $this->theme->stylesheet ),
|
25 |
+
], $retriever->wheres ?? [] );
|
26 |
+
return $retriever;
|
27 |
+
}
|
28 |
+
}
|
src/lib/src/Modules/HackGuard/Lib/ScanTables/TableData/LoadTableDataWordpress.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\TableData;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Results\Retrieve;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller\Afs;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
9 |
+
use FernleafSystems\Wordpress\Services\Services;
|
10 |
+
|
11 |
+
class LoadTableDataWordpress extends BaseLoadTableData {
|
12 |
+
|
13 |
+
public function run() :array {
|
14 |
+
$RS = $this->getRecordRetriever()->retrieveLatest();
|
15 |
+
try {
|
16 |
+
$files = array_map(
|
17 |
+
function ( $item ) {
|
18 |
+
/** @var Scans\Afs\ResultItem $item */
|
19 |
+
$data = $item->getRawData();
|
20 |
+
|
21 |
+
$data[ 'rid' ] = $item->VO->scanresult_id;
|
22 |
+
$data[ 'file' ] = $item->path_fragment;
|
23 |
+
$data[ 'created_at' ] = $item->VO->created_at;
|
24 |
+
$data[ 'detected_since' ] = Services::Request()
|
25 |
+
->carbon( true )
|
26 |
+
->setTimestamp( $item->VO->created_at )
|
27 |
+
->diffForHumans();
|
28 |
+
|
29 |
+
$data[ 'file_as_href' ] = $this->getColumnContent_File( $item );
|
30 |
+
|
31 |
+
if ( $item->is_checksumfail ) {
|
32 |
+
$data[ 'status_slug' ] = 'modified';
|
33 |
+
$data[ 'status' ] = __( 'Modified', 'wp-simple-firewall' );
|
34 |
+
}
|
35 |
+
elseif ( $item->is_missing ) {
|
36 |
+
$data[ 'status_slug' ] = 'missing';
|
37 |
+
$data[ 'status' ] = __( 'Missing', 'wp-simple-firewall' );
|
38 |
+
}
|
39 |
+
else {
|
40 |
+
$data[ 'status_slug' ] = 'unrecognised';
|
41 |
+
$data[ 'status' ] = __( 'Unrecognised', 'wp-simple-firewall' );
|
42 |
+
}
|
43 |
+
$data[ 'status' ] = $this->getColumnContent_FileStatus( $item, $data[ 'status' ] );
|
44 |
+
|
45 |
+
$data[ 'file_type' ] = strtoupper( Services::Data()->getExtension( $item->path_full ) );
|
46 |
+
$data[ 'actions' ] = implode( ' ', $this->getActions( $data[ 'status_slug' ], $item ) );
|
47 |
+
return $data;
|
48 |
+
},
|
49 |
+
$RS->getWordpressCore()->getItems()
|
50 |
+
);
|
51 |
+
}
|
52 |
+
catch ( \Exception $e ) {
|
53 |
+
$files = [];
|
54 |
+
}
|
55 |
+
|
56 |
+
return $files;
|
57 |
+
}
|
58 |
+
|
59 |
+
protected function getRecordRetriever() :Retrieve {
|
60 |
+
$retriever = parent::getRecordRetriever();
|
61 |
+
$retriever->wheres = array_merge( [
|
62 |
+
"`rim`.`meta_key`='is_in_core'",
|
63 |
+
"`rim`.`meta_value`=1",
|
64 |
+
], $retriever->wheres ?? [] );
|
65 |
+
return $retriever;
|
66 |
+
}
|
67 |
+
}
|
src/lib/src/Modules/HackGuard/ModCon.php
CHANGED
@@ -35,24 +35,21 @@ class ModCon extends BaseShield\ModCon {
|
|
35 |
|
36 |
public function getFileLocker() :Lib\FileLocker\FileLockerController {
|
37 |
if ( !isset( $this->oFileLocker ) ) {
|
38 |
-
$this->oFileLocker = ( new Lib\FileLocker\FileLockerController() )
|
39 |
-
->setMod( $this );
|
40 |
}
|
41 |
return $this->oFileLocker;
|
42 |
}
|
43 |
|
44 |
public function getScansCon() :Scan\ScansController {
|
45 |
if ( !isset( $this->scanCon ) ) {
|
46 |
-
$this->scanCon = ( new Scan\ScansController() )
|
47 |
-
->setMod( $this );
|
48 |
}
|
49 |
return $this->scanCon;
|
50 |
}
|
51 |
|
52 |
public function getScanQueueController() :Scan\Queue\Controller {
|
53 |
if ( !isset( $this->scanQueueCon ) ) {
|
54 |
-
$this->scanQueueCon = ( new Scan\Queue\Controller() )
|
55 |
-
->setMod( $this );
|
56 |
}
|
57 |
return $this->scanQueueCon;
|
58 |
}
|
35 |
|
36 |
public function getFileLocker() :Lib\FileLocker\FileLockerController {
|
37 |
if ( !isset( $this->oFileLocker ) ) {
|
38 |
+
$this->oFileLocker = ( new Lib\FileLocker\FileLockerController() )->setMod( $this );
|
|
|
39 |
}
|
40 |
return $this->oFileLocker;
|
41 |
}
|
42 |
|
43 |
public function getScansCon() :Scan\ScansController {
|
44 |
if ( !isset( $this->scanCon ) ) {
|
45 |
+
$this->scanCon = ( new Scan\ScansController() )->setMod( $this );
|
|
|
46 |
}
|
47 |
return $this->scanCon;
|
48 |
}
|
49 |
|
50 |
public function getScanQueueController() :Scan\Queue\Controller {
|
51 |
if ( !isset( $this->scanQueueCon ) ) {
|
52 |
+
$this->scanQueueCon = ( new Scan\Queue\Controller() )->setMod( $this );
|
|
|
53 |
}
|
54 |
return $this->scanQueueCon;
|
55 |
}
|
src/lib/src/Modules/HackGuard/Render/ScanResults/SectionPlugins.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\
|
6 |
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
use FernleafSystems\Wordpress\Services\Utilities\Assets\DetectInstallationDate;
|
@@ -84,9 +84,9 @@ class SectionPlugins extends SectionPluginThemesBase {
|
|
84 |
$carbon = Services::Request()->carbon();
|
85 |
|
86 |
$abandoned = $this->getAbandoned()->getItemForSlug( $plugin->file );
|
87 |
-
$
|
88 |
->setMod( $this->getMod() )
|
89 |
-
->
|
90 |
|
91 |
$vulnerabilities = $this->getVulnerabilities()->getItemsForSlug( $plugin->file );
|
92 |
|
@@ -95,7 +95,7 @@ class SectionPlugins extends SectionPluginThemesBase {
|
|
95 |
|
96 |
$flags = [
|
97 |
'has_update' => $plugin->hasUpdate(),
|
98 |
-
'has_guard_files' =>
|
99 |
'is_abandoned' => !empty( $abandoned ),
|
100 |
'is_active' => $plugin->active,
|
101 |
'is_vulnerable' => !empty( $vulnerabilities ),
|
@@ -140,7 +140,7 @@ class SectionPlugins extends SectionPluginThemesBase {
|
|
140 |
'flags' => $flags,
|
141 |
'vars' => [
|
142 |
'abandoned_rid' => empty( $abandoned ) ? -1 : $abandoned->VO->scanresult_id,
|
143 |
-
'count_items' =>
|
144 |
+ ( empty( $abandoned ) ? 0 : 1 )
|
145 |
],
|
146 |
];
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\TableData\LoadTableDataPlugin;
|
6 |
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
use FernleafSystems\Wordpress\Services\Utilities\Assets\DetectInstallationDate;
|
84 |
$carbon = Services::Request()->carbon();
|
85 |
|
86 |
$abandoned = $this->getAbandoned()->getItemForSlug( $plugin->file );
|
87 |
+
$countGuardFiles = ( new LoadTableDataPlugin( $plugin ) )
|
88 |
->setMod( $this->getMod() )
|
89 |
+
->countAll();
|
90 |
|
91 |
$vulnerabilities = $this->getVulnerabilities()->getItemsForSlug( $plugin->file );
|
92 |
|
95 |
|
96 |
$flags = [
|
97 |
'has_update' => $plugin->hasUpdate(),
|
98 |
+
'has_guard_files' => $countGuardFiles > 0,
|
99 |
'is_abandoned' => !empty( $abandoned ),
|
100 |
'is_active' => $plugin->active,
|
101 |
'is_vulnerable' => !empty( $vulnerabilities ),
|
140 |
'flags' => $flags,
|
141 |
'vars' => [
|
142 |
'abandoned_rid' => empty( $abandoned ) ? -1 : $abandoned->VO->scanresult_id,
|
143 |
+
'count_items' => $countGuardFiles + count( $vulnerabilities )
|
144 |
+ ( empty( $abandoned ) ? 0 : 1 )
|
145 |
],
|
146 |
];
|
src/lib/src/Modules/HackGuard/Render/ScanResults/SectionThemes.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpThemeVo;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
@@ -85,16 +85,16 @@ class SectionThemes extends SectionPluginThemesBase {
|
|
85 |
$carbon = Services::Request()->carbon();
|
86 |
|
87 |
$abandoned = $this->getAbandoned()->getItemForSlug( $theme->stylesheet );
|
88 |
-
$
|
89 |
->setMod( $this->getMod() )
|
90 |
-
->
|
91 |
|
92 |
$vulnerabilities = $this->getVulnerabilities()->getItemsForSlug( $theme->stylesheet );
|
93 |
|
94 |
$flags = [
|
95 |
'has_update' => $theme->hasUpdate(),
|
96 |
'is_abandoned' => !empty( $abandoned ),
|
97 |
-
'has_guard_files' =>
|
98 |
'is_active' => $theme->active || $theme->is_parent,
|
99 |
'is_ignored' => $theme->active || $theme->is_parent,
|
100 |
'is_vulnerable' => !empty( $vulnerabilities ),
|
@@ -173,8 +173,7 @@ class SectionThemes extends SectionPluginThemesBase {
|
|
173 |
],
|
174 |
'flags' => $flags,
|
175 |
'vars' => [
|
176 |
-
'count_items' => count( $
|
177 |
-
+ ( empty( $abandoned ) ? 0 : 1 )
|
178 |
],
|
179 |
];
|
180 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Render\ScanResults;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\ScanTables\TableData\LoadTableDataTheme;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
7 |
use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpThemeVo;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
85 |
$carbon = Services::Request()->carbon();
|
86 |
|
87 |
$abandoned = $this->getAbandoned()->getItemForSlug( $theme->stylesheet );
|
88 |
+
$countGuardFiles = ( new LoadTableDataTheme( $theme ) )
|
89 |
->setMod( $this->getMod() )
|
90 |
+
->countAll();
|
91 |
|
92 |
$vulnerabilities = $this->getVulnerabilities()->getItemsForSlug( $theme->stylesheet );
|
93 |
|
94 |
$flags = [
|
95 |
'has_update' => $theme->hasUpdate(),
|
96 |
'is_abandoned' => !empty( $abandoned ),
|
97 |
+
'has_guard_files' => $countGuardFiles > 0,
|
98 |
'is_active' => $theme->active || $theme->is_parent,
|
99 |
'is_ignored' => $theme->active || $theme->is_parent,
|
100 |
'is_vulnerable' => !empty( $vulnerabilities ),
|
173 |
],
|
174 |
'flags' => $flags,
|
175 |
'vars' => [
|
176 |
+
'count_items' => $countGuardFiles + count( $vulnerabilities ) + ( empty( $abandoned ) ? 0 : 1 )
|
|
|
177 |
],
|
178 |
];
|
179 |
}
|
src/lib/src/Modules/HackGuard/Scan/Controller/Base.php
CHANGED
@@ -131,7 +131,7 @@ abstract class Base extends ExecOnceModConsumer {
|
|
131 |
$this->latestResults = ( new HackGuard\Scan\Results\Retrieve() )
|
132 |
->setMod( $this->getMod() )
|
133 |
->setScanController( $this )
|
134 |
-
->retrieveLatest(
|
135 |
}
|
136 |
catch ( \Exception $e ) {
|
137 |
}
|
131 |
$this->latestResults = ( new HackGuard\Scan\Results\Retrieve() )
|
132 |
->setMod( $this->getMod() )
|
133 |
->setScanController( $this )
|
134 |
+
->retrieveLatest();
|
135 |
}
|
136 |
catch ( \Exception $e ) {
|
137 |
}
|
src/lib/src/Modules/HackGuard/Scan/Results/Counts.php
CHANGED
@@ -64,7 +64,6 @@ class Counts {
|
|
64 |
case 'theme_files':
|
65 |
$count = $resultsRetrieve->setAdditionalWheres( [ "`rim`.`meta_key`='is_in_theme'", ] )->count();
|
66 |
break;
|
67 |
-
|
68 |
case 'abandoned':
|
69 |
$count = $resultsRetrieve
|
70 |
->setScanController( $mod->getScanCon( Apc::SCAN_SLUG ) )
|
64 |
case 'theme_files':
|
65 |
$count = $resultsRetrieve->setAdditionalWheres( [ "`rim`.`meta_key`='is_in_theme'", ] )->count();
|
66 |
break;
|
|
|
67 |
case 'abandoned':
|
68 |
$count = $resultsRetrieve
|
69 |
->setScanController( $mod->getScanCon( Apc::SCAN_SLUG ) )
|
src/lib/src/Modules/HackGuard/Scan/Results/Retrieve.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Results;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\DB\{
|
7 |
ResultItemMeta as ResultItemMetaDB,
|
@@ -14,7 +15,14 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
|
|
14 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultsSet;
|
15 |
use FernleafSystems\Wordpress\Services\Services;
|
16 |
|
17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
use ModConsumer;
|
20 |
use ScanControllerConsumer;
|
@@ -46,14 +54,11 @@ class Retrieve {
|
|
46 |
$this->setScanController( $mod->getScanCon( $scan ) );
|
47 |
|
48 |
$raw = Services::WpDb()->selectCustom(
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
],
|
55 |
-
$this->getAdditionalWheres()
|
56 |
-
) ) )
|
57 |
)
|
58 |
);
|
59 |
$rawResults = empty( $raw ) ? [] : $raw;
|
@@ -75,19 +80,14 @@ class Retrieve {
|
|
75 |
$latestID = $this->getLatestScanID();
|
76 |
if ( $latestID >= 0 ) {
|
77 |
$raw = Services::WpDb()->selectCustom(
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
],
|
84 |
-
$this->getAdditionalWheres()
|
85 |
-
) ) )
|
86 |
)
|
87 |
);
|
88 |
-
|
89 |
-
$results = $raw;
|
90 |
-
}
|
91 |
}
|
92 |
}
|
93 |
|
@@ -121,14 +121,13 @@ class Retrieve {
|
|
121 |
/**
|
122 |
* @return Scans\Afs\ResultsSet|Scans\Apc\ResultsSet|Scans\Wpv\ResultsSet
|
123 |
*/
|
124 |
-
public function retrieveLatest(
|
125 |
|
126 |
$latestID = $this->getLatestScanID();
|
127 |
if ( $latestID >= 0 ) {
|
128 |
$results = $this
|
129 |
->setAdditionalWheres( [
|
130 |
sprintf( "`sr`.`scan_ref`=%s", $latestID ),
|
131 |
-
$includeIgnored ? '' : "`ri`.ignored_at = 0",
|
132 |
"`ri`.`item_repaired_at`=0",
|
133 |
"`ri`.`item_deleted_at`=0"
|
134 |
] )
|
@@ -145,24 +144,38 @@ class Retrieve {
|
|
145 |
* @return Scans\Base\ResultsSet
|
146 |
*/
|
147 |
public function retrieve() {
|
148 |
-
$results = [];
|
149 |
$raw = Services::WpDb()->selectCustom(
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
],
|
157 |
-
$this->getAdditionalWheres()
|
158 |
-
) ) )
|
159 |
)
|
160 |
);
|
161 |
-
|
162 |
-
|
163 |
-
}
|
164 |
|
165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
}
|
167 |
|
168 |
public function count() :int {
|
@@ -180,7 +193,8 @@ class Retrieve {
|
|
180 |
"`ri`.`item_deleted_at`=0",
|
181 |
"`ri`.`deleted_at`=0"
|
182 |
],
|
183 |
-
$this->getAdditionalWheres()
|
|
|
184 |
) ) )
|
185 |
)
|
186 |
);
|
@@ -263,7 +277,7 @@ class Retrieve {
|
|
263 |
return empty( $latest ) ? -1 : $latest->id;
|
264 |
}
|
265 |
|
266 |
-
private function getBaseQuery() :string {
|
267 |
/** @var ModCon $mod */
|
268 |
$mod = $this->getMod();
|
269 |
return sprintf( "SELECT %%s
|
@@ -272,11 +286,19 @@ class Retrieve {
|
|
272 |
ON `sr`.scan_ref = `scans`.id
|
273 |
INNER JOIN `%s` as `ri`
|
274 |
ON `sr`.resultitem_ref = `ri`.id
|
|
|
275 |
WHERE %%s
|
276 |
-
|
|
|
|
|
277 |
$mod->getDbH_ScanResults()->getTableSchema()->table,
|
278 |
$mod->getDbH_Scans()->getTableSchema()->table,
|
279 |
-
$mod->getDbH_ResultItems()->getTableSchema()->table
|
|
|
|
|
|
|
|
|
|
|
280 |
);
|
281 |
}
|
282 |
|
@@ -325,8 +347,8 @@ class Retrieve {
|
|
325 |
return is_array( $this->additionalWheres ) ? $this->additionalWheres : [];
|
326 |
}
|
327 |
|
328 |
-
public function setAdditionalWheres( array $wheres ) {
|
329 |
-
$this->additionalWheres = $wheres;
|
330 |
return $this;
|
331 |
}
|
332 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Results;
|
4 |
|
5 |
+
use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\DB\{
|
8 |
ResultItemMeta as ResultItemMetaDB,
|
15 |
use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\ResultsSet;
|
16 |
use FernleafSystems\Wordpress\Services\Services;
|
17 |
|
18 |
+
/**
|
19 |
+
* @property int $limit
|
20 |
+
* @property int $offset
|
21 |
+
* @property string[] $wheres
|
22 |
+
* @property string $order_by
|
23 |
+
* @property string $order_dir
|
24 |
+
*/
|
25 |
+
class Retrieve extends DynPropertiesClass {
|
26 |
|
27 |
use ModConsumer;
|
28 |
use ScanControllerConsumer;
|
54 |
$this->setScanController( $mod->getScanCon( $scan ) );
|
55 |
|
56 |
$raw = Services::WpDb()->selectCustom(
|
57 |
+
$this->buildQuery(
|
58 |
+
$this->standardSelectFields(),
|
59 |
+
[
|
60 |
+
sprintf( "`sr`.`id`=%s", $scanResultID )
|
61 |
+
]
|
|
|
|
|
|
|
62 |
)
|
63 |
);
|
64 |
$rawResults = empty( $raw ) ? [] : $raw;
|
80 |
$latestID = $this->getLatestScanID();
|
81 |
if ( $latestID >= 0 ) {
|
82 |
$raw = Services::WpDb()->selectCustom(
|
83 |
+
$this->buildQuery(
|
84 |
+
$this->standardSelectFields(),
|
85 |
+
[
|
86 |
+
sprintf( "`sr`.`id` IN (%s)", implode( ',', $IDs ) )
|
87 |
+
]
|
|
|
|
|
|
|
88 |
)
|
89 |
);
|
90 |
+
$results = empty( $raw ) ? [] : $raw;
|
|
|
|
|
91 |
}
|
92 |
}
|
93 |
|
121 |
/**
|
122 |
* @return Scans\Afs\ResultsSet|Scans\Apc\ResultsSet|Scans\Wpv\ResultsSet
|
123 |
*/
|
124 |
+
public function retrieveLatest() {
|
125 |
|
126 |
$latestID = $this->getLatestScanID();
|
127 |
if ( $latestID >= 0 ) {
|
128 |
$results = $this
|
129 |
->setAdditionalWheres( [
|
130 |
sprintf( "`sr`.`scan_ref`=%s", $latestID ),
|
|
|
131 |
"`ri`.`item_repaired_at`=0",
|
132 |
"`ri`.`item_deleted_at`=0"
|
133 |
] )
|
144 |
* @return Scans\Base\ResultsSet
|
145 |
*/
|
146 |
public function retrieve() {
|
|
|
147 |
$raw = Services::WpDb()->selectCustom(
|
148 |
+
$this->buildQuery(
|
149 |
+
$this->standardSelectFields(),
|
150 |
+
[
|
151 |
+
"`ri`.`auto_filtered_at`=0",
|
152 |
+
"`ri`.`deleted_at`=0"
|
153 |
+
]
|
|
|
|
|
|
|
154 |
)
|
155 |
);
|
156 |
+
return $this->convertToResultsSet( empty( $raw ) ? [] : $raw );
|
157 |
+
}
|
|
|
158 |
|
159 |
+
public function buildQuery( array $selectFields, array $wheres ) :string {
|
160 |
+
$hasResultMeta = false;
|
161 |
+
|
162 |
+
$wheres = array_filter( array_merge(
|
163 |
+
$wheres,
|
164 |
+
$this->getAdditionalWheres(),
|
165 |
+
is_array( $this->wheres ) ? $this->wheres : []
|
166 |
+
) );
|
167 |
+
|
168 |
+
foreach ( $wheres as $where ) {
|
169 |
+
if ( strpos( $where, '`rim`' ) !== false ) {
|
170 |
+
$hasResultMeta = true;
|
171 |
+
break;
|
172 |
+
}
|
173 |
+
}
|
174 |
+
return sprintf(
|
175 |
+
$this->getBaseQuery( $hasResultMeta ),
|
176 |
+
implode( ',', $selectFields ),
|
177 |
+
implode( ' AND ', $wheres )
|
178 |
+
);
|
179 |
}
|
180 |
|
181 |
public function count() :int {
|
193 |
"`ri`.`item_deleted_at`=0",
|
194 |
"`ri`.`deleted_at`=0"
|
195 |
],
|
196 |
+
$this->getAdditionalWheres(),
|
197 |
+
is_array( $this->wheres ) ? $this->wheres : []
|
198 |
) ) )
|
199 |
)
|
200 |
);
|
277 |
return empty( $latest ) ? -1 : $latest->id;
|
278 |
}
|
279 |
|
280 |
+
private function getBaseQuery( bool $joinWithResultMeta = false ) :string {
|
281 |
/** @var ModCon $mod */
|
282 |
$mod = $this->getMod();
|
283 |
return sprintf( "SELECT %%s
|
286 |
ON `sr`.scan_ref = `scans`.id
|
287 |
INNER JOIN `%s` as `ri`
|
288 |
ON `sr`.resultitem_ref = `ri`.id
|
289 |
+
%s
|
290 |
WHERE %%s
|
291 |
+
%s
|
292 |
+
%s
|
293 |
+
%s;",
|
294 |
$mod->getDbH_ScanResults()->getTableSchema()->table,
|
295 |
$mod->getDbH_Scans()->getTableSchema()->table,
|
296 |
+
$mod->getDbH_ResultItems()->getTableSchema()->table,
|
297 |
+
$joinWithResultMeta ? sprintf( 'INNER JOIN `%s` as `rim` ON `rim`.`ri_ref` = `ri`.id',
|
298 |
+
$mod->getDbH_ResultItemMeta()->getTableSchema()->table ) : '',
|
299 |
+
empty( $this->order_by ) ? 'ORDER BY `sr`.`id` ASC' : sprintf( 'ORDER BY %s %s', $this->order_by, $this->order_dir ),
|
300 |
+
empty( $this->limit ) ? '' : sprintf( 'LIMIT %s', (int)$this->limit ),
|
301 |
+
empty( $this->offset ) ? '' : sprintf( 'OFFSET %s', (int)$this->offset )
|
302 |
);
|
303 |
}
|
304 |
|
347 |
return is_array( $this->additionalWheres ) ? $this->additionalWheres : [];
|
348 |
}
|
349 |
|
350 |
+
public function setAdditionalWheres( array $wheres, bool $merge = false ) {
|
351 |
+
$this->additionalWheres = $merge ? array_merge( $this->getAdditionalWheres(), $wheres ) : $wheres;
|
352 |
return $this;
|
353 |
}
|
354 |
}
|
src/lib/src/Modules/HackGuard/Scan/ScansController.php
CHANGED
@@ -75,8 +75,7 @@ class ScansController extends ExecOnceModConsumer {
|
|
75 |
|
76 |
public function getScanResultsCount() :Results\Counts {
|
77 |
if ( !isset( $this->scanResultsStatus ) ) {
|
78 |
-
$this->scanResultsStatus = ( new Results\Counts() )
|
79 |
-
->setMod( $this->getMod() );
|
80 |
}
|
81 |
return $this->scanResultsStatus;
|
82 |
}
|
75 |
|
76 |
public function getScanResultsCount() :Results\Counts {
|
77 |
if ( !isset( $this->scanResultsStatus ) ) {
|
78 |
+
$this->scanResultsStatus = ( new Results\Counts() )->setMod( $this->getMod() );
|
|
|
79 |
}
|
80 |
return $this->scanResultsStatus;
|
81 |
}
|
src/lib/src/Modules/IPs/WpCli/Add.php
CHANGED
@@ -28,26 +28,24 @@ class Add extends BaseAddRemove {
|
|
28 |
}
|
29 |
|
30 |
/**
|
31 |
-
* @param array $null
|
32 |
-
* @param array $args
|
33 |
* @throws WP_CLI\ExitException
|
34 |
*/
|
35 |
public function cmdIpAdd( array $null, array $args ) {
|
36 |
-
|
37 |
-
$adder = ( new Ops\AddIp() )
|
38 |
-
->setMod( $this->getMod() )
|
39 |
-
->setIP( $args[ 'ip' ] );
|
40 |
try {
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
47 |
}
|
48 |
catch ( \Exception $e ) {
|
49 |
WP_CLI::error( $e->getMessage() );
|
50 |
}
|
51 |
-
WP_CLI::success( __( 'IP address added successfully.', 'wp-simple-firewall' ) );
|
52 |
}
|
53 |
}
|
28 |
}
|
29 |
|
30 |
/**
|
|
|
|
|
31 |
* @throws WP_CLI\ExitException
|
32 |
*/
|
33 |
public function cmdIpAdd( array $null, array $args ) {
|
|
|
|
|
|
|
|
|
34 |
try {
|
35 |
+
$this->checkList( $args[ 'list' ] );
|
36 |
+
|
37 |
+
$adder = ( new Ops\AddIp() )
|
38 |
+
->setMod( $this->getMod() )
|
39 |
+
->setIP( $args[ 'ip' ] );
|
40 |
+
|
41 |
+
in_array( $args[ 'list' ], [ 'white', 'bypass' ] ) ?
|
42 |
+
$adder->toManualWhitelist( $args[ 'label' ] ?? '' )
|
43 |
+
: $adder->toManualBlacklist( $args[ 'label' ] ?? '' );
|
44 |
+
|
45 |
+
WP_CLI::success( __( 'IP address added successfully.', 'wp-simple-firewall' ) );
|
46 |
}
|
47 |
catch ( \Exception $e ) {
|
48 |
WP_CLI::error( $e->getMessage() );
|
49 |
}
|
|
|
50 |
}
|
51 |
}
|
src/lib/src/Modules/IPs/WpCli/Base.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\WpCli;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\WpCli\BaseWpCliCmd;
|
6 |
+
|
7 |
+
class Base extends BaseWpCliCmd {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @throws \Exception
|
11 |
+
*/
|
12 |
+
protected function checkList( string $list ) {
|
13 |
+
if ( !in_array( $list, [ 'white', 'bypass', 'black', 'block' ] ) ) {
|
14 |
+
throw new \Exception( sprintf( '%s %s',
|
15 |
+
sprintf( __( "'%s' is an unsupported IP list.", 'wp-simple-firewall' ), $list ),
|
16 |
+
sprintf( __( 'Please use one of %s.', 'wp-simple-firewall' ), "'bypass' or 'white'; 'block' or 'black'" )
|
17 |
+
) );
|
18 |
+
}
|
19 |
+
}
|
20 |
+
}
|
src/lib/src/Modules/IPs/WpCli/BaseAddRemove.php
CHANGED
@@ -2,9 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\WpCli;
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
class BaseAddRemove extends BaseWpCliCmd {
|
8 |
|
9 |
/**
|
10 |
* @return array[]
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\WpCli;
|
4 |
|
5 |
+
class BaseAddRemove extends Base {
|
|
|
|
|
6 |
|
7 |
/**
|
8 |
* @return array[]
|
src/lib/src/Modules/IPs/WpCli/Enumerate.php
CHANGED
@@ -2,12 +2,11 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\WpCli;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\WpCli\BaseWpCliCmd;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
|
8 |
use WP_CLI;
|
9 |
|
10 |
-
class Enumerate extends
|
11 |
|
12 |
/**
|
13 |
* @throws \Exception
|
@@ -32,24 +31,31 @@ class Enumerate extends BaseWpCliCmd {
|
|
32 |
] ) );
|
33 |
}
|
34 |
|
35 |
-
public function cmdPrint( $null, $
|
36 |
/** @var ModCon $mod */
|
37 |
$mod = $this->getMod();
|
38 |
|
39 |
-
|
40 |
-
->
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
55 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\WpCli;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
|
7 |
use WP_CLI;
|
8 |
|
9 |
+
class Enumerate extends Base {
|
10 |
|
11 |
/**
|
12 |
* @throws \Exception
|
31 |
] ) );
|
32 |
}
|
33 |
|
34 |
+
public function cmdPrint( array $null, array $args ) {
|
35 |
/** @var ModCon $mod */
|
36 |
$mod = $this->getMod();
|
37 |
|
38 |
+
try {
|
39 |
+
$this->checkList( $args[ 'list' ] );
|
40 |
+
|
41 |
+
$retriever = ( new Ops\RetrieveIpsForLists() )
|
42 |
+
->setDbHandler( $mod->getDbHandler_IPs() );
|
43 |
+
|
44 |
+
$IPs = array_map(
|
45 |
+
function ( $ip ) {
|
46 |
+
return [ 'IP' => $ip, ];
|
47 |
+
},
|
48 |
+
in_array( $args[ 'list' ], [ 'white', 'bypass' ] ) ? $retriever->white() : $retriever->black()
|
49 |
+
);
|
50 |
+
|
51 |
+
WP_CLI\Utils\format_items(
|
52 |
+
'table',
|
53 |
+
$IPs,
|
54 |
+
[ 'IP' ]
|
55 |
+
);
|
56 |
+
}
|
57 |
+
catch ( \Exception $e ) {
|
58 |
+
WP_CLI::error( $e->getMessage() );
|
59 |
+
}
|
60 |
}
|
61 |
}
|
src/lib/src/Modules/IPs/WpCli/Remove.php
CHANGED
@@ -20,26 +20,22 @@ class Remove extends BaseAddRemove {
|
|
20 |
}
|
21 |
|
22 |
/**
|
23 |
-
* @param array $null
|
24 |
-
* @param array $args
|
25 |
* @throws WP_CLI\ExitException
|
26 |
*/
|
27 |
public function cmdIpRemove( array $null, array $args ) {
|
28 |
-
|
29 |
-
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
$
|
|
|
|
|
36 |
}
|
37 |
-
|
38 |
-
|
39 |
}
|
40 |
-
|
41 |
-
$success ?
|
42 |
-
WP_CLI::success( __( 'IP address removed successfully.', 'wp-simple-firewall' ) )
|
43 |
-
: WP_CLI::error( __( "IP address couldn't be removed. (It may not be on this list)", 'wp-simple-firewall' ) );
|
44 |
}
|
45 |
}
|
20 |
}
|
21 |
|
22 |
/**
|
|
|
|
|
23 |
* @throws WP_CLI\ExitException
|
24 |
*/
|
25 |
public function cmdIpRemove( array $null, array $args ) {
|
26 |
+
try {
|
27 |
+
$this->checkList( $args[ 'list' ] );
|
28 |
|
29 |
+
$del = ( new IPs\Lib\Ops\DeleteIp() )
|
30 |
+
->setMod( $this->getMod() )
|
31 |
+
->setIP( $args[ 'ip' ] );
|
32 |
+
|
33 |
+
( in_array( $args[ 'list' ], [ 'white', 'bypass' ] ) ? $del->fromWhiteList() : $del->fromBlacklist() ) ?
|
34 |
+
WP_CLI::success( __( 'IP address removed successfully.', 'wp-simple-firewall' ) )
|
35 |
+
: WP_CLI::error( __( "IP address couldn't be removed. (It may not be on this list)", 'wp-simple-firewall' ) );
|
36 |
}
|
37 |
+
catch ( \Exception $e ) {
|
38 |
+
WP_CLI::error( $e->getMessage() );
|
39 |
}
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
}
|
src/lib/src/Modules/License/Processor.php
CHANGED
@@ -11,7 +11,7 @@ class Processor extends BaseShield\Processor {
|
|
11 |
$mod = $this->getMod();
|
12 |
$mod->getLicenseHandler()->execute();
|
13 |
( new Lib\PluginNameSuffix() )
|
14 |
-
->setMod( $
|
15 |
->execute();
|
16 |
}
|
17 |
}
|
11 |
$mod = $this->getMod();
|
12 |
$mod->getLicenseHandler()->execute();
|
13 |
( new Lib\PluginNameSuffix() )
|
14 |
+
->setMod( $mod )
|
15 |
->execute();
|
16 |
}
|
17 |
}
|
src/lib/src/Modules/Plugin/Lib/PluginTelemetry.php
CHANGED
@@ -135,15 +135,18 @@ class PluginTelemetry extends ExecOnceModConsumer {
|
|
135 |
}
|
136 |
|
137 |
private function getBaseTrackingData() :array {
|
|
|
138 |
$WP = Services::WpGeneral();
|
139 |
$WPP = Services::WpPlugins();
|
140 |
return [
|
141 |
'env' => [
|
142 |
-
'slug' => $
|
|
|
143 |
'unique_site_hash' => sha1( network_home_url( '/' ) ),
|
144 |
'php' => Services::Data()->getPhpVersionCleaned(),
|
145 |
'wordpress' => $WP->getVersion(),
|
146 |
-
'version' => $
|
|
|
147 |
'is_wpms' => $WP->isMultisite() ? 1 : 0,
|
148 |
'is_cp' => $WP->isClassicPress() ? 1 : 0,
|
149 |
'ssl' => is_ssl() ? 1 : 0,
|
135 |
}
|
136 |
|
137 |
private function getBaseTrackingData() :array {
|
138 |
+
$con = $this->getCon();
|
139 |
$WP = Services::WpGeneral();
|
140 |
$WPP = Services::WpPlugins();
|
141 |
return [
|
142 |
'env' => [
|
143 |
+
'slug' => $con->getPluginSlug(),
|
144 |
+
'installation_id' => $con->getSiteInstallationId(),
|
145 |
'unique_site_hash' => sha1( network_home_url( '/' ) ),
|
146 |
'php' => Services::Data()->getPhpVersionCleaned(),
|
147 |
'wordpress' => $WP->getVersion(),
|
148 |
+
'version' => $con->getVersion(),
|
149 |
+
'plugin_version' => $con->getVersion(),
|
150 |
'is_wpms' => $WP->isMultisite() ? 1 : 0,
|
151 |
'is_cp' => $WP->isClassicPress() ? 1 : 0,
|
152 |
'ssl' => is_ssl() ? 1 : 0,
|
src/lib/src/Modules/Traffic/Lib/TrafficTable/BuildTrafficTableData.php
CHANGED
@@ -32,8 +32,8 @@ class BuildTrafficTableData extends BaseBuildTableData {
|
|
32 |
|
33 |
private $ipInfo = [];
|
34 |
|
35 |
-
protected function
|
36 |
-
return $this->
|
37 |
}
|
38 |
|
39 |
protected function getSearchPanesData() :array {
|
@@ -45,7 +45,7 @@ class BuildTrafficTableData extends BaseBuildTableData {
|
|
45 |
/**
|
46 |
* @param LogRecord[] $records
|
47 |
*/
|
48 |
-
protected function
|
49 |
$this->users = [ 0 => __( 'No', 'wp-simple-firewall' ) ];
|
50 |
|
51 |
return array_values( array_filter( array_map(
|
32 |
|
33 |
private $ipInfo = [];
|
34 |
|
35 |
+
protected function loadRecordsWithSearch() :array {
|
36 |
+
return $this->loadRecordsWithDirectQuery();
|
37 |
}
|
38 |
|
39 |
protected function getSearchPanesData() :array {
|
45 |
/**
|
46 |
* @param LogRecord[] $records
|
47 |
*/
|
48 |
+
protected function buildTableRowsFromRawRecords( array $records ) :array {
|
49 |
$this->users = [ 0 => __( 'No', 'wp-simple-firewall' ) ];
|
50 |
|
51 |
return array_values( array_filter( array_map(
|
src/lib/src/Tables/DataTables/Build/Scans/BaseForScan.php
CHANGED
@@ -30,6 +30,9 @@ class BaseForScan extends Base {
|
|
30 |
'orderable' => true,
|
31 |
'searchable' => false,
|
32 |
'visible' => false,
|
|
|
|
|
|
|
33 |
],
|
34 |
'file' => [
|
35 |
'data' => 'file',
|
@@ -38,41 +41,59 @@ class BaseForScan extends Base {
|
|
38 |
'orderable' => true,
|
39 |
'searchable' => true,
|
40 |
'visible' => true,
|
|
|
|
|
|
|
41 |
],
|
42 |
'file_as_href' => [
|
43 |
-
'data' =>
|
|
|
|
|
|
|
44 |
'title' => __( 'File' ),
|
45 |
'className' => 'file_as_href',
|
46 |
'orderable' => true,
|
47 |
'searchable' => true,
|
48 |
'visible' => true,
|
|
|
|
|
|
|
49 |
],
|
50 |
'file_type' => [
|
51 |
'data' => 'file_type',
|
52 |
'title' => __( 'Type' ),
|
53 |
'className' => 'file_type',
|
54 |
-
'orderable' =>
|
55 |
-
'searchable' =>
|
56 |
-
'visible' =>
|
|
|
|
|
|
|
57 |
],
|
58 |
'status' => [
|
59 |
'data' => 'status',
|
60 |
'title' => __( 'Status' ),
|
61 |
'className' => 'status',
|
62 |
-
'orderable' =>
|
63 |
'searchable' => false,
|
64 |
'visible' => true,
|
|
|
|
|
|
|
65 |
],
|
66 |
'detected' => [
|
67 |
'data' => [
|
68 |
'_' => 'detected_since',
|
69 |
-
'sort' => '
|
70 |
],
|
71 |
'title' => __( 'Detected' ),
|
72 |
'className' => 'detected',
|
73 |
'orderable' => true,
|
74 |
'searchable' => false,
|
75 |
'visible' => true,
|
|
|
|
|
|
|
76 |
],
|
77 |
'actions' => [
|
78 |
'data' => 'actions',
|
@@ -81,14 +102,20 @@ class BaseForScan extends Base {
|
|
81 |
'orderable' => false,
|
82 |
'searchable' => false,
|
83 |
'visible' => true,
|
|
|
|
|
|
|
84 |
],
|
85 |
'mal_fp_confidence' => [
|
86 |
'data' => 'mal_fp_confidence',
|
87 |
'title' => __( 'False Positive Confidence' ),
|
88 |
'className' => 'mal_fp_confidence',
|
89 |
-
'orderable' =>
|
90 |
'searchable' => false,
|
91 |
'visible' => true,
|
|
|
|
|
|
|
92 |
],
|
93 |
'line_numbers' => [
|
94 |
'data' => 'line_numbers',
|
@@ -97,14 +124,9 @@ class BaseForScan extends Base {
|
|
97 |
'orderable' => false,
|
98 |
'searchable' => false,
|
99 |
'visible' => true,
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
'title' => __( 'Pattern Detected' ),
|
104 |
-
'className' => 'mal_sig',
|
105 |
-
'orderable' => false,
|
106 |
-
'searchable' => true,
|
107 |
-
'visible' => true,
|
108 |
],
|
109 |
];
|
110 |
}
|
30 |
'orderable' => true,
|
31 |
'searchable' => false,
|
32 |
'visible' => false,
|
33 |
+
'searchPanes' => [
|
34 |
+
'show' => false
|
35 |
+
],
|
36 |
],
|
37 |
'file' => [
|
38 |
'data' => 'file',
|
41 |
'orderable' => true,
|
42 |
'searchable' => true,
|
43 |
'visible' => true,
|
44 |
+
'searchPanes' => [
|
45 |
+
'show' => false
|
46 |
+
],
|
47 |
],
|
48 |
'file_as_href' => [
|
49 |
+
'data' => [
|
50 |
+
'_' => 'file_as_href',
|
51 |
+
'sort' => 'file',
|
52 |
+
],
|
53 |
'title' => __( 'File' ),
|
54 |
'className' => 'file_as_href',
|
55 |
'orderable' => true,
|
56 |
'searchable' => true,
|
57 |
'visible' => true,
|
58 |
+
'searchPanes' => [
|
59 |
+
'show' => false
|
60 |
+
],
|
61 |
],
|
62 |
'file_type' => [
|
63 |
'data' => 'file_type',
|
64 |
'title' => __( 'Type' ),
|
65 |
'className' => 'file_type',
|
66 |
+
'orderable' => false,
|
67 |
+
'searchable' => false,
|
68 |
+
'visible' => false,
|
69 |
+
'searchPanes' => [
|
70 |
+
'show' => true
|
71 |
+
],
|
72 |
],
|
73 |
'status' => [
|
74 |
'data' => 'status',
|
75 |
'title' => __( 'Status' ),
|
76 |
'className' => 'status',
|
77 |
+
'orderable' => false,
|
78 |
'searchable' => false,
|
79 |
'visible' => true,
|
80 |
+
'searchPanes' => [
|
81 |
+
'show' => true
|
82 |
+
],
|
83 |
],
|
84 |
'detected' => [
|
85 |
'data' => [
|
86 |
'_' => 'detected_since',
|
87 |
+
'sort' => 'created_at',
|
88 |
],
|
89 |
'title' => __( 'Detected' ),
|
90 |
'className' => 'detected',
|
91 |
'orderable' => true,
|
92 |
'searchable' => false,
|
93 |
'visible' => true,
|
94 |
+
'searchPanes' => [
|
95 |
+
'show' => false
|
96 |
+
],
|
97 |
],
|
98 |
'actions' => [
|
99 |
'data' => 'actions',
|
102 |
'orderable' => false,
|
103 |
'searchable' => false,
|
104 |
'visible' => true,
|
105 |
+
'searchPanes' => [
|
106 |
+
'show' => false
|
107 |
+
],
|
108 |
],
|
109 |
'mal_fp_confidence' => [
|
110 |
'data' => 'mal_fp_confidence',
|
111 |
'title' => __( 'False Positive Confidence' ),
|
112 |
'className' => 'mal_fp_confidence',
|
113 |
+
'orderable' => false,
|
114 |
'searchable' => false,
|
115 |
'visible' => true,
|
116 |
+
'searchPanes' => [
|
117 |
+
'show' => false
|
118 |
+
],
|
119 |
],
|
120 |
'line_numbers' => [
|
121 |
'data' => 'line_numbers',
|
124 |
'orderable' => false,
|
125 |
'searchable' => false,
|
126 |
'visible' => true,
|
127 |
+
'searchPanes' => [
|
128 |
+
'show' => false
|
129 |
+
],
|
|
|
|
|
|
|
|
|
|
|
130 |
],
|
131 |
];
|
132 |
}
|
src/lib/src/Tables/DataTables/Build/Scans/ForMalware.php
CHANGED
@@ -14,6 +14,7 @@ class ForMalware extends BaseForScan {
|
|
14 |
'mal_fp_confidence',
|
15 |
'line_numbers',
|
16 |
'mal_sig',
|
|
|
17 |
'detected',
|
18 |
'actions',
|
19 |
];
|
@@ -27,7 +28,7 @@ class ForMalware extends BaseForScan {
|
|
27 |
'className' => 'mal_fp_confidence',
|
28 |
'orderable' => true,
|
29 |
'searchable' => false,
|
30 |
-
'visible' =>
|
31 |
];
|
32 |
$colDefs[ 'line_numbers' ] = [
|
33 |
'data' => 'line_numbers',
|
@@ -35,14 +36,25 @@ class ForMalware extends BaseForScan {
|
|
35 |
'className' => 'line_numbers',
|
36 |
'orderable' => false,
|
37 |
'searchable' => false,
|
38 |
-
'visible' =>
|
39 |
];
|
40 |
$colDefs[ 'mal_sig' ] = [
|
41 |
'data' => 'mal_sig',
|
42 |
'title' => __( 'Pattern Detected' ),
|
43 |
'className' => 'mal_sig',
|
44 |
'orderable' => false,
|
45 |
-
'searchable' =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
'visible' => true,
|
47 |
];
|
48 |
return $colDefs;
|
14 |
'mal_fp_confidence',
|
15 |
'line_numbers',
|
16 |
'mal_sig',
|
17 |
+
'mal_details',
|
18 |
'detected',
|
19 |
'actions',
|
20 |
];
|
28 |
'className' => 'mal_fp_confidence',
|
29 |
'orderable' => true,
|
30 |
'searchable' => false,
|
31 |
+
'visible' => false,
|
32 |
];
|
33 |
$colDefs[ 'line_numbers' ] = [
|
34 |
'data' => 'line_numbers',
|
36 |
'className' => 'line_numbers',
|
37 |
'orderable' => false,
|
38 |
'searchable' => false,
|
39 |
+
'visible' => false,
|
40 |
];
|
41 |
$colDefs[ 'mal_sig' ] = [
|
42 |
'data' => 'mal_sig',
|
43 |
'title' => __( 'Pattern Detected' ),
|
44 |
'className' => 'mal_sig',
|
45 |
'orderable' => false,
|
46 |
+
'searchable' => false,
|
47 |
+
'visible' => false,
|
48 |
+
'searchPanes' => [
|
49 |
+
'show' => false
|
50 |
+
],
|
51 |
+
];
|
52 |
+
$colDefs[ 'mal_details' ] = [
|
53 |
+
'data' => 'mal_details',
|
54 |
+
'title' => __( 'Malware Details' ),
|
55 |
+
'className' => 'mal_details',
|
56 |
+
'orderable' => false,
|
57 |
+
'searchable' => false,
|
58 |
'visible' => true,
|
59 |
];
|
60 |
return $colDefs;
|
src/lib/src/Tables/DataTables/LoadData/BaseBuildTableData.php
CHANGED
@@ -17,7 +17,7 @@ abstract class BaseBuildTableData extends DynPropertiesClass {
|
|
17 |
|
18 |
public function build() :array {
|
19 |
return [
|
20 |
-
'data' => $this->
|
21 |
'recordsTotal' => $this->countTotalRecords(),
|
22 |
'recordsFiltered' => $this->countTotalRecordsFiltered(),
|
23 |
'searchPanes' => $this->getSearchPanesData(),
|
@@ -28,22 +28,22 @@ abstract class BaseBuildTableData extends DynPropertiesClass {
|
|
28 |
return [];
|
29 |
}
|
30 |
|
31 |
-
public function
|
32 |
if ( empty( $this->table_data[ 'search' ][ 'value' ] ) ) {
|
33 |
-
return $this->
|
34 |
}
|
35 |
else {
|
36 |
-
return $this->
|
37 |
}
|
38 |
}
|
39 |
|
40 |
-
protected function
|
41 |
-
return $this->
|
42 |
$this->getRecords( $this->buildWheresFromSearchParams(), (int)$this->table_data[ 'start' ], (int)$this->table_data[ 'length' ] )
|
43 |
);
|
44 |
}
|
45 |
|
46 |
-
protected function
|
47 |
$start = (int)$this->table_data[ 'start' ];
|
48 |
$length = (int)$this->table_data[ 'length' ];
|
49 |
$search = (string)$this->table_data[ 'search' ][ 'value' ] ?? '';
|
@@ -57,7 +57,7 @@ abstract class BaseBuildTableData extends DynPropertiesClass {
|
|
57 |
$page = 0;
|
58 |
$pageLength = 100;
|
59 |
do {
|
60 |
-
$interimResults = $this->
|
61 |
$this->getRecords( $wheres, $page*$pageLength, $pageLength )
|
62 |
);
|
63 |
// no more table results to process, so go with what we have.
|
@@ -129,7 +129,7 @@ abstract class BaseBuildTableData extends DynPropertiesClass {
|
|
129 |
|
130 |
abstract protected function countTotalRecordsFiltered() :int;
|
131 |
|
132 |
-
abstract protected function
|
133 |
|
134 |
protected function getColumnContent_Date( int $ts ) :string {
|
135 |
return sprintf( '%s<br /><small>%s</small>',
|
17 |
|
18 |
public function build() :array {
|
19 |
return [
|
20 |
+
'data' => $this->loadForRecords(),
|
21 |
'recordsTotal' => $this->countTotalRecords(),
|
22 |
'recordsFiltered' => $this->countTotalRecordsFiltered(),
|
23 |
'searchPanes' => $this->getSearchPanesData(),
|
28 |
return [];
|
29 |
}
|
30 |
|
31 |
+
public function loadForRecords() :array {
|
32 |
if ( empty( $this->table_data[ 'search' ][ 'value' ] ) ) {
|
33 |
+
return $this->loadRecordsWithDirectQuery();
|
34 |
}
|
35 |
else {
|
36 |
+
return $this->loadRecordsWithSearch();
|
37 |
}
|
38 |
}
|
39 |
|
40 |
+
protected function loadRecordsWithDirectQuery() :array {
|
41 |
+
return $this->buildTableRowsFromRawRecords(
|
42 |
$this->getRecords( $this->buildWheresFromSearchParams(), (int)$this->table_data[ 'start' ], (int)$this->table_data[ 'length' ] )
|
43 |
);
|
44 |
}
|
45 |
|
46 |
+
protected function loadRecordsWithSearch() :array {
|
47 |
$start = (int)$this->table_data[ 'start' ];
|
48 |
$length = (int)$this->table_data[ 'length' ];
|
49 |
$search = (string)$this->table_data[ 'search' ][ 'value' ] ?? '';
|
57 |
$page = 0;
|
58 |
$pageLength = 100;
|
59 |
do {
|
60 |
+
$interimResults = $this->buildTableRowsFromRawRecords(
|
61 |
$this->getRecords( $wheres, $page*$pageLength, $pageLength )
|
62 |
);
|
63 |
// no more table results to process, so go with what we have.
|
129 |
|
130 |
abstract protected function countTotalRecordsFiltered() :int;
|
131 |
|
132 |
+
abstract protected function buildTableRowsFromRawRecords( array $records ) :array;
|
133 |
|
134 |
protected function getColumnContent_Date( int $ts ) :string {
|
135 |
return sprintf( '%s<br /><small>%s</small>',
|
src/lib/src/Tables/Render/WpCliTable/AuditTrail.php
CHANGED
@@ -12,7 +12,7 @@ class AuditTrail {
|
|
12 |
public function render() {
|
13 |
$rows = ( new BuildAuditTableData() )
|
14 |
->setMod( $this->getMod() )
|
15 |
-
->
|
16 |
|
17 |
\WP_CLI\Utils\format_items(
|
18 |
'table',
|
12 |
public function render() {
|
13 |
$rows = ( new BuildAuditTableData() )
|
14 |
->setMod( $this->getMod() )
|
15 |
+
->loadForRecords();
|
16 |
|
17 |
\WP_CLI\Utils\format_items(
|
18 |
'table',
|