PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.0.1
Defender Security – Malware Scanner, Login Security & Firewall v3.0.1
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / behavior / scan / malware-deep-scan.php

malware-deep-scan.php in Defender Security – Malware Scanner, Login Security & Firewall 3.0.1, at src/behavior/scan/malware-deep-scan.php

166 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WP_Defender\Behavior\Scan;
4
5 use Calotes\Component\Behavior;
6 use PHP_CodeSniffer\Config;
7 use PHP_CodeSniffer\Exceptions\TokenizerException;
8 use PHP_CodeSniffer\Tokenizers\PHP;
9 use WP_Defender\Component\Scan\Tokens;
10 use WP_Defender\Traits\IO;
11
12 /**
13 * We need to verify the result to avoid false positive.
14 *
15 * Class Malware_Deep_Scan
16 * @package WP_Defender\Behavior\Scan
17 */
18 class Malware_Deep_Scan extends Behavior {
19 use IO;
20
21 /**
22 * @param $file
23 * @param $rules
24 * @param $quick_found
25 *
26 * @return bool|array
27 */
28 public function do_deep_scan( $file, $rules, $quick_found ) {
29 $this->load_phpcodesniffer_needed();
30 if ( ! defined( 'PHP_CODESNIFFER_VERBOSITY' ) ) {
31 define( 'PHP_CODESNIFFER_VERBOSITY', 0 );
32 }
33 if ( ! defined( 'PHP_CODESNIFFER_CBF' ) ) {
34 define( 'PHP_CODESNIFFER_CBF', false );
35 }
36 $content = file_get_contents( $file );
37 try {
38 $parser = new PHP( $content, $this->make_phpsniff_config(), PHP_EOL );
39 Tokens::$tokens = $parser->getTokens();
40 foreach ( $quick_found as &$item ) {
41 if ( ! isset( $item['catches'] ) || ! is_array( $item['catches'] ) ) {
42 continue;
43 }
44 foreach ( $item['catches'] as &$catch ) {
45 $offset = $catch['offset'];
46 $catch['line'] = Tokens::get_line_from_offset( $content, $offset );
47 $catch['mapper'] = Tokens::get_offsets_map( Tokens::get_tokens_by_line( $catch['line'] ) );
48 $code = Tokens::formatter( Tokens::get_tokens_by_line( $catch['line'] ) );
49 $tokens = Tokens::get_tokens_by_line( $catch['line'] );
50 foreach ( $tokens as $k => $token ) {
51 if ( in_array( $token['code'], [
52 T_DOC_COMMENT_WHITESPACE,
53 T_DOC_COMMENT_STAR,
54 T_DOC_COMMENT_WHITESPACE,
55 T_DOC_COMMENT_STRING
56 ] ) ) {
57 unset( $tokens[ $k ] );
58 }
59 }
60 $tokens = array_filter( $tokens );
61 if ( empty( $tokens ) ) {
62 // This mean the catch is comment, do nothing.
63 return false;
64 }
65 unset( $catch['text'] );
66 //$catch['code'] = $code;
67 }
68 }
69
70 return $quick_found;
71 } catch ( TokenizerException $e ) {
72 $this->log( $e->getMessage() );
73 }
74
75 return false;
76 }
77
78 private function load_phpcodesniffer_needed() {
79 $ds = DIRECTORY_SEPARATOR;
80 $vendor_path = defender_path( 'src/extra/php-codesniffer-php-token' );
81 if ( ! class_exists( \PHP_CodeSniffer\Util\Tokens::class ) ) {
82 require_once $vendor_path . $ds . 'Util' . $ds . 'Tokens.php';
83 }
84 if ( ! class_exists( \PHP_CodeSniffer\Util\Common::class ) ) {
85 require_once $vendor_path . $ds . 'Util' . $ds . 'Common.php';
86 }
87
88 if ( ! class_exists( \PHP_CodeSniffer\Tokenizers\Tokenizer::class ) ) {
89 require_once $vendor_path . $ds . 'Tokenizers' . $ds . 'Tokenizer.php';
90 }
91
92 if ( ! class_exists( \PHP_CodeSniffer\Tokenizers\PHP::class ) ) {
93 require_once $vendor_path . $ds . 'Tokenizers' . $ds . 'PHP.php';
94 }
95
96 if ( ! class_exists( \PHP_CodeSniffer\Tokenizers\Comment::class ) ) {
97 require_once $vendor_path . $ds . 'Tokenizers' . $ds . 'Comment.php';
98 }
99
100 if ( ! class_exists( \PHP_CodeSniffer\Util\Standards::class ) ) {
101 require_once $vendor_path . $ds . 'Util' . $ds . 'Standards.php';
102 }
103
104 if ( ! class_exists( \PHP_CodeSniffer\Exceptions\RuntimeException::class ) ) {
105 require_once $vendor_path . $ds . 'Exceptions' . $ds . 'RuntimeException.php';
106 }
107
108 if ( ! class_exists( \PHP_CodeSniffer\Exceptions\DeepExitException::class ) ) {
109 require_once $vendor_path . $ds . 'Exceptions' . $ds . 'DeepExitException.php';
110 }
111
112 if ( ! class_exists( \PHP_CodeSniffer\Config::class ) ) {
113 require_once $vendor_path . $ds . 'Config.php';
114 }
115 }
116
117 /**
118 * @return Config
119 */
120 private function make_phpsniff_config() {
121 $config = new \stdClass();
122 $config->files = [];
123 $config->standards = [ 'PEAR' ];
124 $config->verbosity = 0;
125 $config->interactive = false;
126 $config->cache = false;
127 $config->cacheFile = null;
128 $config->colors = false;
129 $config->explain = false;
130 $config->local = false;
131 $config->showSources = true;
132 $config->showProgress = false;
133 $config->quiet = false;
134 $config->annotations = true;
135 $config->parallel = 1;
136 $config->tabWidth = 0;
137 $config->encoding = 'utf-8';
138 $config->extensions = [
139 'php' => 'PHP',
140 'inc' => 'PHP',
141 'js' => 'JS',
142 'css' => 'CSS',
143 ];
144 $config->sniffs = [];
145 $config->exclude = [];
146 $config->ignored = [];
147 $config->reportFile = null;
148 $config->generator = null;
149 $config->filter = null;
150 $config->bootstrap = [];
151 $config->basepath = null;
152 $config->reports = [ 'full' => null ];
153 $config->reportWidth = 'auto';
154 $config->errorSeverity = 5;
155 $config->warningSeverity = 5;
156 $config->recordErrors = true;
157 $config->suffix = '';
158 $config->stdin = true;
159 $config->stdinContent = null;
160 $config->stdinPath = null;
161 $config->unknown = [];
162
163 return $config;
164 }
165 }
166