owner->raw_data; $file = $data['file']; $file_created_at = @filemtime( $file ); if ( $file_created_at ) { $file_created_at = $this->format_date_time( $file_created_at ); } else { $file_created_at = 'n/a'; } $file_size = @filesize( $file ); if ( ! $file_size ) { $file_size = 'n/a'; } else { $file_size = $this->format_bytes_into_readable( $file_size ); } return array( 'id' => $this->owner->id, 'type' => Scan_Item::TYPE_SUSPICIOUS, 'file_name' => pathinfo( $file, PATHINFO_BASENAME ), 'full_path' => $file, 'date_added' => $file_created_at, 'size' => $file_size, 'short_desc' => __( 'Suspicious function found', 'wpdef' ), ); } /** * @return array */ public function ignore() { $scan = Scan::get_last(); $scan->ignore_issue( $this->owner->id ); return array( 'message' => __( 'The suspicious file has been successfully ignored.', 'wpdef' ), ); } /** * @return array */ public function unignore() { $scan = Scan::get_last(); $scan->unignore_issue( $this->owner->id ); return array( 'message' => __( 'The suspicious file has been successfully restored.', 'wpdef' ), ); } /** * Delete the file, or whole folder. * * @return array|\WP_Error */ public function delete() { $data = $this->owner->raw_data; $scan = Scan::get_last(); $path = $data['file']; /** * If the path inside theme or plugin folder, then we remove the whole plugin/theme for prevent fatal error. * If the path is to wp-config, we can't delete it. */ if ( defender_wp_config_path() === $path ) { return new \WP_Error( Error_Code::INVALID, __( 'wp-config.php can\'t be removed. Please remove the suspicious code manually.', 'wpdef' ) ); } // If it's not relative path, which mean it is something lay on wp-content folder, we can delete it. if ( file_exists( $path ) ) { if ( ! @unlink( $path ) ) { return new \WP_Error( Error_Code::NOT_WRITEABLE, __( 'Defender doesn\'t have enough permission to remove this file', 'wpdef' ) ); } } $scan->remove_issue( $this->owner->id ); $this->log( sprintf( '%s is deleted', $path ), 'scan.log' ); return array( 'message' => __( 'This item has been permanently removed', 'wpdef' ), ); } protected function is_active_plugin( $file_path ) { $path_data = explode( DIRECTORY_SEPARATOR, plugin_basename( $file_path ) ); if ( ! empty( $path_data ) ) { $plugin_slug = $path_data[0]; } else { return false; } $active = false; foreach ( $this->get_plugins() as $slug => $data ) { if ( $plugin_slug === $slug || 0 === strpos( $slug, $plugin_slug ) ) { $active = is_multisite() ? is_plugin_active_for_network( $slug ) : is_plugin_active( $slug ); break; } } return $active; } /** * Return the source code depending on the type of the issue. * * @return array */ public function pull_src() { $data = $this->owner->raw_data; $active = false; $type_src = ''; if ( ! file_exists( $data['file'] ) ) { return array( 'origin' => '', 'mapper' => array(), 'active' => $active, 'type_src' => $type_src, ); } if ( false !== stripos( $data['file'], WP_PLUGIN_DIR ) ) { $active = $this->is_active_plugin( $data['file'] ); $type_src = 'plugin'; } $markers = array(); foreach ( $data as $item ) { if ( isset( $item['catches'] ) ) { foreach ( $item['catches'] as $catch ) { $markers = array_merge( $markers, $catch['mapper'] ); } } } wp_send_json_success( array( 'origin' => file_get_contents( $data['file'] ), 'mapper' => $markers, 'active' => $active, 'type_src' => $type_src, ) ); } }