PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.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 / component / security-tweaks / class-disable-file-editor.php

class-disable-file-editor.php in Defender Security – Malware Scanner, Login Security & Firewall 6.3.0, at src/component/security-tweaks/class-disable-file-editor.php

215 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Responsible for enabling or disabling the file editor in WordPress.
4 *
5 * @package WP_Defender\Component\Security_Tweaks
6 */
7
8 namespace WP_Defender\Component\Security_Tweaks;
9
10 use WP_Error;
11 use WP_Defender\Component\Security_Tweaks\Servers\Server;
12 use WP_Defender\Component\Security_Tweak as Security_Tweak_Component;
13
14 /**
15 * Handles the implementation of the disable-file-editor security tweak.
16 */
17 class Disable_File_Editor extends Abstract_Security_Tweaks {
18
19
20 /**
21 * Slug identifier for the component.
22 *
23 * @var string
24 */
25 public string $slug = 'disable-file-editor';
26
27 /**
28 * Check whether the issue has been resolved or not.
29 *
30 * @return bool
31 */
32 public function check() {
33 if ( defined( 'DISALLOW_FILE_EDIT' ) && true === constant( 'DISALLOW_FILE_EDIT' ) ) {
34 return true;
35 }
36
37 return false;
38 }
39
40 /**
41 * Get pattern for DISALLOW_FILE_EDIT.
42 *
43 * @return string
44 */
45 private function get_file_edit_pattern() {
46 return "/^define\(\s*['|\"]DISALLOW_FILE_EDIT['|\"],(.*)\)/";
47 }
48
49 /**
50 * Set data in wp-config.php.
51 *
52 * @param bool $value The value to set for DISALLOW_FILE_EDIT.
53 *
54 * @return bool|WP_Error
55 */
56 private function set_file_edit_data( $value ) {
57 $sec_tweak_component = new Security_Tweak_Component();
58 $obj_file = 'flywheel' === Server::get_current_server()
59 ? $sec_tweak_component->advanced_check_file()
60 : $sec_tweak_component->file();
61 if ( false === $obj_file ) {
62 return new WP_Error(
63 'defender_file_not_writable',
64 esc_html__( 'The file wp-config.php is not writable', 'defender-security' )
65 );
66 } elseif ( is_numeric( $obj_file ) ) {
67 return new WP_Error(
68 'defender_file_not_writable',
69 $sec_tweak_component->show_hosting_notice( 'DISALLOW_FILE_EDIT' )
70 );
71 }
72
73 $file_edit = 'DISALLOW_FILE_EDIT';
74 $value = $value ? 'true' : 'false';
75 $pattern = $this->get_file_edit_pattern();
76 $hook_line_pattern = $sec_tweak_component->get_hook_line_pattern();
77 $file_edit_line = "define( '{$file_edit}', {$value} ); // Added by Defender";
78 $lines = array();
79 $line_found = false;
80 $hook_line_no = null;
81
82 foreach ( $obj_file as $line ) {
83 if ( ! $line_found && preg_match( $pattern, $line ) ) {
84 // If this is revert request and the changes is not made by us throw error.
85 if ( 'true' === $value && ! preg_match(
86 "/^define\(\s*['|\"]{$file_edit}['|\"],(.*)\);\s*\/\/\s*Added\s*by\s*Defender.?.*/i",
87 $line
88 )
89 ) {
90 return new WP_Error(
91 'defender_file_not_writable',
92 $sec_tweak_component->show_hosting_notice_with_code( $file_edit, $file_edit_line )
93 );
94 }
95
96 $lines[] = $file_edit_line;
97 $line_found = true;
98 continue;
99 }
100
101 // If there is no match, keep reference of `hook_line_no` so that we can insert data there as needed.
102 if ( ! $line_found && preg_match( $hook_line_pattern, $line ) ) {
103 $hook_line_no = $obj_file->key();
104 $lines[ $hook_line_no + 1 ] = trim( $line );
105 continue;
106 }
107
108 $lines[] = trim( $line );
109 }
110
111 // There is no match, so set DISALLOW_FILE_EDIT data just before the hook line ei: `$table_prefix`.
112 if ( ! $line_found && ! is_null( $hook_line_no ) ) {
113 $line_found = true;
114 $lines[ $hook_line_no ] = $file_edit_line;
115 ksort( $lines );
116 }
117
118 return $line_found
119 ? $sec_tweak_component->write( $lines )
120 : new WP_Error(
121 'defender_line_not_found',
122 esc_html__( 'Error writing to file.', 'defender-security' ),
123 404
124 );
125 }
126
127 /**
128 * Allow file editor.
129 *
130 * @return bool|WP_Error
131 */
132 private function allow_file_editor() {
133 return $this->set_file_edit_data( false );
134 }
135
136 /**
137 * Prevent file editor.
138 *
139 * @return bool|WP_Error
140 */
141 private function prevent_file_editor() {
142 return $this->set_file_edit_data( true );
143 }
144
145 /**
146 * Here is the code for processing, if the return is true, we add it to resolve list, WP_Error if any error.
147 *
148 * @return bool|WP_Error
149 */
150 public function process() {
151 return $this->prevent_file_editor();
152 }
153
154 /**
155 * This is for un-do stuff that has be done in @process.
156 *
157 * @return bool|WP_Error
158 */
159 public function revert() {
160 return $this->allow_file_editor();
161 }
162
163 /**
164 * Define the DISALLOW_FILE_EDIT constant, so we can hide the editor page.
165 *
166 * @return bool Always returns true.
167 */
168 public function shield_up() {
169 return true;
170 }
171
172 /**
173 * Retrieve the tweak's label.
174 *
175 * @return string
176 */
177 public function get_label(): string {
178 return esc_html__( 'Turn off file editor', 'defender-security' );
179 }
180
181 /**
182 * Get the error reason.
183 *
184 * @return string
185 */
186 public function get_error_reason(): string {
187 return wp_kses(
188 __( '<strong>File editor is turned on</strong> and may allow malicious code changes.', 'defender-security' ),
189 array(
190 'strong' => array(),
191 )
192 );
193 }
194
195 /**
196 * Return a summary data of this tweak.
197 *
198 * @return array
199 */
200 public function to_array(): array {
201 return array(
202 'slug' => $this->slug,
203 'title' => $this->get_label(),
204 'errorReason' => $this->get_error_reason(),
205 'successReason' => wp_strip_all_tags( __( 'File editor is turned off.', 'defender-security' ) ),
206 'misc' => array(
207 'show_revert_button' => true,
208 'show_action_button' => true,
209 ),
210 'bulk_description' => wp_strip_all_tags( __( 'WordPress includes a built-in file editor for theme and plugin files. Turn off file editor to help prevent unauthorized code changes if an attacker gains access.', 'defender-security' ) ),
211 'bulk_title' => wp_strip_all_tags( __( 'File Editor', 'defender-security' ) ),
212 );
213 }
214 }
215