PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.1.0
Defender Security – Malware Scanner, Login Security & Firewall v3.1.0
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-item / core-integrity.php

core-integrity.php in Defender Security – Malware Scanner, Login Security & Firewall 3.1.0, at src/behavior/scan-item/core-integrity.php

210 lines 5.6 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_Item;
4
5 use Calotes\Base\File;
6 use Calotes\Component\Behavior;
7 use WP_Defender\Component\Error_Code;
8 use WP_Defender\Model\Scan;
9 use WP_Defender\Model\Scan_Item;
10 use WP_Defender\Traits\Formats;
11 use WP_Defender\Traits\IO;
12
13 class Core_Integrity extends Behavior {
14 use Formats, IO;
15
16 /**
17 * Return general data so we can output on frontend.
18 *
19 * @return array
20 */
21 public function to_array() {
22 $data = $this->owner->raw_data;
23 $file = $data['file'];
24 $file_created_at = @filemtime( $file );
25 if ( $file_created_at ) {
26 $file_created_at = $this->format_date_time( $file_created_at );
27 } else {
28 $file_created_at = 'n/a';
29 }
30 $file_size = @filesize( $file );
31 if ( ! $file_size ) {
32 $file_size = 'n/a';
33 } else {
34 $file_size = $this->format_bytes_into_readable( $file_size );
35 }
36
37 return array(
38 'id' => $this->owner->id,
39 'type' => Scan_Item::TYPE_INTEGRITY,
40 'file_name' => pathinfo( $file, PATHINFO_BASENAME ),
41 'full_path' => $file,
42 'date_added' => $file_created_at,
43 'size' => $file_size,
44 'scenario' => $data['type'],
45 'short_desc' => $this->get_short_description(),
46 );
47 }
48
49 /**
50 * We will get the origin code by looking into svn repo.
51 *
52 * @return false|string|\WP_Error
53 */
54 private function get_origin_code() {
55 global $wp_version;
56 $data = $this->owner->raw_data;
57 $file = wp_normalize_path( $data['file'] );
58 $relative_path = str_replace( wp_normalize_path( ABSPATH ), '', $file );
59 $source_file_url = "http://core.svn.wordpress.org/tags/$wp_version/" . $relative_path;
60 $ds = DIRECTORY_SEPARATOR;
61 if ( ! function_exists( 'download_url' ) ) {
62 require_once ABSPATH . 'wp-admin' . $ds . 'includes' . $ds . 'file.php';
63 }
64 $tmp = download_url( $source_file_url );
65 if ( is_wp_error( $tmp ) ) {
66 return $tmp;
67 }
68 $content = file_get_contents( $tmp );
69 @unlink( $tmp );
70
71 return $content;
72 }
73
74 /**
75 * Restore the file with its origin content.
76 *
77 * @return void|array
78 */
79 public function resolve() {
80 $data = $this->owner->raw_data;
81 if ( 'modified' !== $data['type'] ) {
82 // Should not be here unless case changed.
83 return;
84 }
85
86 $origin = $this->get_origin_code();
87 if ( false === $origin || is_wp_error( $origin ) ) {
88 return;
89 }
90
91 $path = $data['file'];
92 $ret = @file_put_contents( $path, $origin );// phpcs:ignore
93 if ( $ret ) {
94 $scan = Scan::get_last();
95 $scan->remove_issue( $this->owner->id );
96 $this->log( sprintf( '%s is deleted', $path ), 'scan.log' );
97
98 return array(
99 'message' => __( 'This item has been resolved.', 'wpdef' ),
100 );
101 } else {
102 return new \WP_Error(
103 'defender_permissions_denied',
104 __( 'Permissions Denied. Defender does not have the needed permissions to edit the file. Please change file permissions to 640 or contact your hosting provider so they could change them for you.', 'wpdef' )
105 );
106 }
107 }
108
109 /**
110 * @return array
111 */
112 public function ignore() {
113 $scan = Scan::get_last();
114 $scan->ignore_issue( $this->owner->id );
115
116 return array(
117 'message' => __( 'The suspicious file has been successfully ignored.', 'wpdef' ),
118 );
119 }
120
121 /**
122 * @return array
123 */
124 public function unignore() {
125 $scan = Scan::get_last();
126 $scan->unignore_issue( $this->owner->id );
127
128 return array(
129 'message' => __( 'The suspicious file has been successfully restored.', 'wpdef' ),
130 );
131 }
132
133 /**
134 * Delete the file or whole folder.
135 *
136 * @return array|\WP_Error
137 */
138 public function delete() {
139 $data = $this->owner->raw_data;
140 $scan = Scan::get_last();
141 if ( 'unversion' === $data['type'] && unlink( $data['file'] ) ) {
142 $scan->remove_issue( $this->owner->id );
143 $this->log( sprintf( '%s is deleted', $data['file'] ), 'scan.log' );
144
145 return array(
146 'message' => __( 'This item has been permanently removed', 'wpdef' ),
147 );
148 } elseif ( 'dir' === $data['type'] && $this->delete_dir( $data['file'] ) ) {
149 $scan->remove_issue( $this->owner->id );
150 $this->log( sprintf( '%s is deleted', $data['file'] ), 'scan.log' );
151
152 return array(
153 'message' => __( 'This item has been permanently removed', 'wpdef' ),
154 );
155 }
156
157 return new \WP_Error( Error_Code::NOT_WRITEABLE, __( 'Defender doesn\'t have enough permission to remove this file', 'wpdef' ) );
158 }
159
160 /**
161 * Return the source code depending on the type of the issue:
162 * If it is unversion, return full source,
163 * if it is dir, we return a list of files,
164 * if it is modified, we will return the current code & origin.
165 *
166 * @return array
167 */
168 public function pull_src() {
169 $data = $this->owner->raw_data;
170 if ( ! file_exists( $data['file'] ) && ! is_dir( $data['file'] ) ) {
171 return array(
172 'code' => '',
173 'origin' => '',
174 );
175 }
176 switch ( $data['type'] ) {
177 case 'unversion':
178 return array(
179 'code' => file_get_contents( $data['file'] ),
180 );
181 case 'dir':
182 $dir_tree = new File( $data['file'], true, true, array(), array(), false );
183
184 return array(
185 'code' => implode( PHP_EOL, $dir_tree->get_dir_tree() ),
186 );
187 case 'modified':
188 default:
189 return array(
190 'code' => file_get_contents( $data['file'] ),
191 'origin' => $this->get_origin_code(),
192 );
193 }
194 }
195
196 /**
197 * @return string
198 */
199 private function get_short_description() {
200 $data = $this->owner->raw_data;
201 if ( 'unversion' === $data['type'] ) {
202 return esc_html__( 'Unknown file in WordPress core', 'wpdef' );
203 } elseif ( 'dir' === $data['type'] ) {
204 return esc_html__( 'This directory does not belong to WordPress core', 'wpdef' );
205 } elseif ( 'modified' === $data['type'] ) {
206 return esc_html__( 'This WordPress core file appears modified', 'wpdef' );
207 }
208 }
209 }
210