# Site Health Check for Security Headers

> Adds a Site Health test that loads your homepage and reports which common security headers (HSTS, CSP, nosniff, framing, referrer and permissions policies) are missing.

- Type: PHP
- Runs: Admin only
- Category: [Security](https://wpide.com/library/category/security/)
- Tags: site-health, headers, audit
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/sec-headers-site-health/

## Code

```php
add_filter( 'site_status_tests', function ( $tests ) {
    $tests['direct']['wpide_security_headers'] = array(
        'label' => 'Security headers',
        'test'  => function () {
            $headers = get_transient( 'wpide_sh_headers' );

            if ( false === $headers ) {
                $response = wp_remote_get( home_url( '/' ), array( 'timeout' => 8, 'redirection' => 2, 'sslverify' => apply_filters( 'https_local_ssl_verify', false ) ) );
                $headers  = is_wp_error( $response ) ? array() : array_change_key_case( wp_remote_retrieve_headers( $response )->getAll(), CASE_LOWER );
                set_transient( 'wpide_sh_headers', $headers, 12 * HOUR_IN_SECONDS );
            }

            $wanted = array(
                'x-content-type-options'  => 'X-Content-Type-Options',
                'referrer-policy'         => 'Referrer-Policy',
                'permissions-policy'      => 'Permissions-Policy',
                'content-security-policy' => 'Content-Security-Policy',
            );
            if ( is_ssl() || 0 === strpos( home_url(), 'https:' ) ) {
                $wanted['strict-transport-security'] = 'Strict-Transport-Security';
            }

            $missing = array();
            foreach ( $wanted as $key => $label ) {
                if ( empty( $headers[ $key ] ) && ! ( 'content-security-policy' === $key && ! empty( $headers['content-security-policy-report-only'] ) ) ) {
                    $missing[] = $label;
                }
            }
            $csp = isset( $headers['content-security-policy'] ) ? implode( ' ', (array) $headers['content-security-policy'] ) : '';
            if ( empty( $headers['x-frame-options'] ) && false === strpos( $csp, 'frame-ancestors' ) ) {
                $missing[] = 'X-Frame-Options (or CSP frame-ancestors)';
            }

            return array(
                'label'       => $missing ? 'Some security headers are missing' : 'Security headers are in place',
                'status'      => $missing ? 'recommended' : 'good',
                'badge'       => array( 'label' => 'Security', 'color' => 'blue' ),
                'description' => $missing
                    ? '<p>' . esc_html( 'Your homepage does not send: ' . implode( ', ', $missing ) . '.' ) . '</p>'
                    : '<p>Your homepage sends the common security headers.</p>',
                'test'        => 'wpide_security_headers',
            );
        },
    );

    return $tests;
} );
```

## Notes

The result is cached for 12 hours; headers added by your server or CDN are detected too.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Site Health Check for Security Headers" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
