Security Features

Understanding Security Compliance Grades

11 views Updated 12 hours ago

WebMon analyzes your website's HTTP security headers and assigns a grade based on their presence and configuration. This guide explains each header, why it matters, and how to implement it.

What Are Security Headers?

Security headers are HTTP response headers that instruct browsers how to behave when handling your site's content. They protect against common attacks like cross-site scripting (XSS), clickjacking, and data injection.

Headers We Check

Strict-Transport-Security (HSTS)

Forces browsers to only use HTTPS connections for your site. Once a browser sees this header, it will automatically convert all HTTP requests to HTTPS, even if a user types http:// in the address bar.

Why it matters: Prevents man-in-the-middle attacks and cookie hijacking over insecure connections.

Example value: max-age=31536000; includeSubDomains; preload

Implementation:

  • Apache: Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
  • Nginx: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
  • Laravel: Add to middleware or use spatie/laravel-csp package

Content-Security-Policy (CSP)

Controls which resources (scripts, styles, images, fonts) can be loaded on your page. This is the most powerful header for preventing XSS attacks.

Why it matters: Stops attackers from injecting malicious scripts, even if they find a vulnerability in your site.

Example value: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'

Common directives:

  • default-src: Fallback for other directives
  • script-src: Where JavaScript can be loaded from
  • style-src: Where CSS can be loaded from
  • img-src: Where images can be loaded from
  • connect-src: Where AJAX/WebSocket connections can go
  • frame-ancestors: Who can embed your site (replaces X-Frame-Options)

Tip: Start with a report-only policy to find issues before enforcing.

X-Frame-Options

Prevents your site from being embedded in iframes on other domains. This protects against clickjacking attacks where attackers overlay invisible frames to trick users into clicking hidden buttons.

Why it matters: Stops attackers from embedding your login page in their site to steal credentials.

Values:

  • DENY: Never allow framing
  • SAMEORIGIN: Only allow framing by same domain
  • ALLOW-FROM uri: Allow specific domain (deprecated, use CSP frame-ancestors instead)

X-Content-Type-Options

Prevents browsers from "sniffing" the content type and executing files as a different type than declared.

Why it matters: Attackers can upload files with malicious content that browsers might execute if they guess the wrong content type.

Value: nosniff (the only valid value)

Referrer-Policy

Controls how much URL information is sent when users navigate away from your site.

Why it matters: Prevents leaking sensitive URL parameters (tokens, IDs) to third-party sites.

Common values:

  • no-referrer: Never send referrer
  • same-origin: Only send referrer for same-origin requests
  • strict-origin-when-cross-origin: Send origin only for cross-origin (recommended)
  • no-referrer-when-downgrade: Don't send when going from HTTPS to HTTP

Permissions-Policy

(formerly Feature-Policy)

Limits which browser features your site can use, like camera, microphone, geolocation, and payment APIs.

Why it matters: Reduces attack surface and prevents embedded third-party content from accessing sensitive APIs.

Example value: camera=(), microphone=(), geolocation=(self), payment=()

Common features to restrict:

  • camera, microphone: Media devices
  • geolocation: User location
  • payment: Payment Request API
  • usb, bluetooth: Hardware access

X-XSS-Protection

Enables the browser's built-in XSS filter. Note: This is a legacy header and modern browsers are removing support in favor of CSP.

Value: 1; mode=block

Note: If you have a strong CSP policy, you may set this to 0 to avoid potential conflicts.

Cross-Origin-Opener-Policy (COOP)

Isolates your browsing context from other origins, preventing other sites from accessing your window object through popups.

Values: same-origin, same-origin-allow-popups, unsafe-none

Cross-Origin-Embedder-Policy (COEP)

Controls whether your page can load cross-origin resources that don't explicitly grant permission.

Values: require-corp, credentialless, unsafe-none

Cross-Origin-Resource-Policy (CORP)

Protects your resources from being loaded by other origins.

Values: same-origin, same-site, cross-origin

Understanding Grades

A+ / A / A- (Excellent)

Your site has most or all critical security headers properly configured. You are well protected against common web vulnerabilities.

B+ / B / B- (Good)

Your site has several important security headers but is missing some recommendations. Consider adding the missing headers for better protection.

C+ / C / C- (Fair)

Your site has basic security headers but is missing important ones. You should prioritize adding the missing headers.

D / F (Needs Improvement)

Your site is missing critical security headers and is vulnerable to common attacks. Immediate action is recommended.

Priority Order for Implementation

  1. Strict-Transport-Security (HSTS) - If using HTTPS
  2. X-Content-Type-Options - Easy, no configuration needed
  3. X-Frame-Options - Simple protection against clickjacking
  4. Referrer-Policy - Protects URL data leakage
  5. Content-Security-Policy - Most powerful but requires testing
  6. Permissions-Policy - Limit unnecessary browser features
  7. Cross-Origin headers (COOP, COEP, CORP) - For advanced isolation

robots.txt Check

WebMon also checks for your robots.txt file:

  • Present: Your site has crawler directives configured
  • Blocks All Crawlers: Your robots.txt prevents search engines from indexing (may be intentional for staging sites)
  • Not Found: No robots.txt file detected (search engines will crawl everything by default)

How to Run a Security Check

  1. Go to your monitor's detail page
  2. Find the "Security Compliance" card
  3. Click "Check Now" to run an analysis
  4. Review your grade and missing headers
  5. Click "Show all headers" to see the complete list

Quick Implementation Guide

For Apache (.htaccess or httpd.conf)

<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
    Header always set X-XSS-Protection "1; mode=block"
</IfModule>

For Nginx

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header X-XSS-Protection "1; mode=block" always;

For Laravel (middleware)

return $next($request)
    ->header('X-Content-Type-Options', 'nosniff')
    ->header('X-Frame-Options', 'SAMEORIGIN')
    ->header('Referrer-Policy', 'strict-origin-when-cross-origin');

For Cloudflare

Use Transform Rules to add headers, or configure in the dashboard under Security > Settings.

After making changes, use "Check Now" to verify your new grade.

Testing Your Headers

  1. Use browser Developer Tools (Network tab) to inspect response headers
  2. Online tools like securityheaders.com can analyze your site
  3. Start CSP in report-only mode to catch issues

Common Mistakes

  • Setting CSP too strict initially (breaks functionality)
  • Forgetting to include CDN domains in CSP
  • Using deprecated header values
  • Not testing on all pages (some frameworks override headers)
  • Missing the "always" directive in Nginx (headers not sent on errors)