10, 'sslverify' => false, 'redirection' => 0, ) ); if ( is_wp_error( $response ) ) { return static::info( __( 'We couldn\'t check your security headers. This might be a temporary connection issue.', '0-day-analytics' ), array( 'error' => $response->get_error_message() ) ); } $headers = wp_remote_retrieve_headers( $response ); // Important security headers to check. $security_headers = array( 'x-frame-options' => array( 'name' => 'X-Frame-Options', 'description' => __( 'Prevents your site from being embedded in iframes on other sites (clickjacking protection).', '0-day-analytics' ), 'severity' => 'medium', ), 'x-content-type-options' => array( 'name' => 'X-Content-Type-Options', 'description' => __( 'Prevents browsers from interpreting files as a different type (MIME sniffing protection).', '0-day-analytics' ), 'severity' => 'low', ), 'x-xss-protection' => array( 'name' => 'X-XSS-Protection', 'description' => __( 'Enables the browser\'s built-in XSS filter.', '0-day-analytics' ), 'severity' => 'low', ), 'strict-transport-security' => array( 'name' => 'Strict-Transport-Security', 'description' => __( 'Forces browsers to always use HTTPS (HSTS).', '0-day-analytics' ), 'severity' => 'medium', ), 'content-security-policy' => array( 'name' => 'Content-Security-Policy', 'description' => __( 'Controls which resources can be loaded on your pages.', '0-day-analytics' ), 'severity' => 'low', ), ); $missing = array(); $present = array(); $details = array(); foreach ( $security_headers as $header_key => $header_info ) { if ( isset( $headers[ $header_key ] ) ) { $present[] = $header_info['name']; $details[ $header_info['name'] ] = $headers[ $header_key ]; } else { $missing[] = $header_info; } } $details['headers_present'] = $present; $details['headers_missing'] = array_map( function( $h ) { return $h['name']; }, $missing ); // Count missing headers by severity. $critical_missing = array_filter( $missing, function( $h ) { return 'high' === $h['severity']; } ); $medium_missing = array_filter( $missing, function( $h ) { return 'medium' === $h['severity']; } ); if ( empty( $missing ) ) { return static::pass( __( 'Your site has all the recommended security headers configured. These help protect visitors from various attacks.', '0-day-analytics' ), $details ); } if ( count( $missing ) <= 2 ) { $missing_names = implode( ', ', array_map( function( $h ) { return $h['name']; }, $missing ) ); return static::info( sprintf( /* translators: %s: list of header names */ __( 'Most security headers are configured. Missing: %s. These provide additional protection but are not critical.', '0-day-analytics' ), $missing_names ), $details ); } $missing_names = implode( ', ', array_map( function( $h ) { return $h['name']; }, array_slice( $missing, 0, 3 ) ) ); return static::warning( sprintf( /* translators: 1: number of missing headers, 2: list of header names */ __( 'Your site is missing %1$d security headers including: %2$s. These headers help protect your visitors from various attacks.', '0-day-analytics' ), count( $missing ), $missing_names ), __( 'Security headers should be added at the server level (Apache/Nginx) or using a security plugin. Contact your hosting provider or developer to add these headers.', '0-day-analytics' ), $details ); } } }