advanced_check_file() : $sec_tweak_component->file(); if ( false === $obj_file ) { return new WP_Error( 'defender_file_not_writable', esc_html__( 'The file wp-config.php is not writable', 'defender-security' ) ); } elseif ( is_numeric( $obj_file ) ) { return new WP_Error( 'defender_file_not_writable', $sec_tweak_component->show_hosting_notice( 'DISALLOW_FILE_EDIT' ) ); } $file_edit = 'DISALLOW_FILE_EDIT'; $value = $value ? 'true' : 'false'; $pattern = $this->get_file_edit_pattern(); $hook_line_pattern = $sec_tweak_component->get_hook_line_pattern(); $file_edit_line = "define( '{$file_edit}', {$value} ); // Added by Defender"; $lines = array(); $line_found = false; $hook_line_no = null; foreach ( $obj_file as $line ) { if ( ! $line_found && preg_match( $pattern, $line ) ) { // If this is revert request and the changes is not made by us throw error. if ( 'true' === $value && ! preg_match( "/^define\(\s*['|\"]{$file_edit}['|\"],(.*)\);\s*\/\/\s*Added\s*by\s*Defender.?.*/i", $line ) ) { return new WP_Error( 'defender_file_not_writable', $sec_tweak_component->show_hosting_notice_with_code( $file_edit, $file_edit_line ) ); } $lines[] = $file_edit_line; $line_found = true; continue; } // If there is no match, keep reference of `hook_line_no` so that we can insert data there as needed. if ( ! $line_found && preg_match( $hook_line_pattern, $line ) ) { $hook_line_no = $obj_file->key(); $lines[ $hook_line_no + 1 ] = trim( $line ); continue; } $lines[] = trim( $line ); } // There is no match, so set DISALLOW_FILE_EDIT data just before the hook line ei: `$table_prefix`. if ( ! $line_found && ! is_null( $hook_line_no ) ) { $line_found = true; $lines[ $hook_line_no ] = $file_edit_line; ksort( $lines ); } return $line_found ? $sec_tweak_component->write( $lines ) : new WP_Error( 'defender_line_not_found', esc_html__( 'Error writing to file.', 'defender-security' ), 404 ); } /** * Allow file editor. * * @return bool|WP_Error */ private function allow_file_editor() { return $this->set_file_edit_data( false ); } /** * Prevent file editor. * * @return bool|WP_Error */ private function prevent_file_editor() { return $this->set_file_edit_data( true ); } /** * Here is the code for processing, if the return is true, we add it to resolve list, WP_Error if any error. * * @return bool|WP_Error */ public function process() { return $this->prevent_file_editor(); } /** * This is for un-do stuff that has be done in @process. * * @return bool|WP_Error */ public function revert() { return $this->allow_file_editor(); } /** * Define the DISALLOW_FILE_EDIT constant, so we can hide the editor page. * * @return bool Always returns true. */ public function shield_up() { return true; } /** * Retrieve the tweak's label. * * @return string */ public function get_label(): string { return esc_html__( 'Turn off file editor', 'defender-security' ); } /** * Get the error reason. * * @return string */ public function get_error_reason(): string { return wp_kses( __( 'File editor is turned on and may allow malicious code changes.', 'defender-security' ), array( 'strong' => array(), ) ); } /** * Return a summary data of this tweak. * * @return array */ public function to_array(): array { return array( 'slug' => $this->slug, 'title' => $this->get_label(), 'errorReason' => $this->get_error_reason(), 'successReason' => wp_strip_all_tags( __( 'File editor is turned off.', 'defender-security' ) ), 'misc' => array( 'show_revert_button' => true, 'show_action_button' => true, ), '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' ) ), 'bulk_title' => wp_strip_all_tags( __( 'File Editor', 'defender-security' ) ), ); } }