October 2025 โข Markus
WooCommerce Security Headers Configuration Guide (2025)
Security headers are your WooCommerce store's first line of defense against web-based attacks. According to OWASP, properly configured HTTP security headers can prevent 95% of common web vulnerabilities including XSS, clickjacking, and code injection. Yet most WooCommerce stores run with minimal or no security headers, leaving them vulnerable to attacks that could have been prevented with simple configuration changes.
โ ๏ธ Important: Always test security header changes in a staging environment first. Incorrect configurations can break your site functionality.
๐ก๏ธ What Are HTTP Security Headers?
HTTP security headers are response headers that tell browsers how to behave when handling your website's content. They act as browser-level security policies that protect users even if your application has vulnerabilities.
Think of security headers as guardrails: even if a misconfiguration or vulnerable plugin introduces an XSS flaw, properly configured headers can prevent the attack from executing. This defense-in-depth approach is critical for eCommerce stores handling sensitive customer data.
๐จ Why WooCommerce Stores Need Security Headers
- PCI DSS Compliance: PCI DSS 4.0 requires merchants to implement security controls, and headers are part of best practices
- GDPR Protection: Mitigate data leakage risks โ critical for GDPR compliance
- SEO Benefits: Google's algorithm favors secure sites; security headers improve trust signals
- Prevent XSS Attacks: Content Security Policy (CSP) blocks malicious scripts from executing
- Stop Clickjacking: X-Frame-Options prevents your checkout from being embedded in malicious iframes
- Reduce Breach Costs: Headers can prevent the $4.45M average breach cost
๐ง Essential Security Headers for WooCommerce
1. Content-Security-Policy (CSP)
Purpose: Prevents XSS attacks by controlling which resources can be loaded and executed.
CSP is the most powerful security header. It creates an allowlist of trusted sources for scripts, styles, images, and other resources. Any content from non-whitelisted sources is blocked. Learn more at MDN Web Docs.
Apache Configuration (.htaccess):
# Basic CSP for WooCommerce
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com https://www.gstatic.com https://js.stripe.com https://checkout.stripe.com https://www.googletagmanager.com https://www.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://api.stripe.com https://www.google-analytics.com; frame-src https://js.stripe.com https://checkout.stripe.com; object-src 'none'; base-uri 'self'; form-action 'self';"
Nginx Configuration:
# Basic CSP for WooCommerce
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com https://www.gstatic.com https://js.stripe.com https://checkout.stripe.com https://www.googletagmanager.com https://www.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://api.stripe.com https://www.google-analytics.com; frame-src https://js.stripe.com https://checkout.stripe.com; object-src 'none'; base-uri 'self'; form-action 'self';" always;
๐ก Pro Tip: Start with CSP in report-only mode
(Content-Security-Policy-Report-Only) to identify
violations without breaking functionality. Monitor reports, adjust
your policy, then switch to enforcement mode.
2. Strict-Transport-Security (HSTS)
Purpose: Forces HTTPS connections and prevents man-in-the-middle (MITM) attacks.
HSTS tells browsers to only connect to your site via HTTPS for a specified duration. This prevents SSL stripping attacks where attackers downgrade connections to HTTP. Read the HSTS Preload specification.
Configuration:
# Apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
Parameters explained:
-
max-age=31536000โ Enforce HTTPS for 1 year (in seconds) -
includeSubDomainsโ Apply to all subdomains (use with caution) -
preloadโ Eligible for browser HSTS preload lists (submit at hstspreload.org)
3. X-Frame-Options
Purpose: Prevents clickjacking attacks by controlling iframe embedding.
Clickjacking tricks users into clicking hidden elements. For WooCommerce, this could mean unauthorized purchases or data disclosure. X-Frame-Options prevents your site from being embedded in iframes on other domains.
# Apache
Header always set X-Frame-Options "SAMEORIGIN"
# Nginx
add_header X-Frame-Options "SAMEORIGIN" always;
Options:
DENYโ Block all iframe embedding-
SAMEORIGINโ Allow embedding only on your own domain -
ALLOW-FROM https://trusted-site.comโ Deprecated, use CSPframe-ancestorsinstead
4. X-Content-Type-Options
Purpose: Prevents MIME type sniffing attacks.
Browsers sometimes "sniff" content types and execute files differently than intended. This header forces browsers to respect the declared Content-Type, preventing malicious files from being executed as scripts.
# Apache
Header always set X-Content-Type-Options "nosniff"
# Nginx
add_header X-Content-Type-Options "nosniff" always;
5. Referrer-Policy
Purpose: Controls how much referrer information is sent with requests.
The Referer header can leak sensitive information like session tokens in URLs. Referrer-Policy lets you control what data is shared with third parties.
# Apache
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Nginx
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Recommended values:
-
no-referrerโ Never send referrer (may break analytics) -
strict-origin-when-cross-originโ Send origin only on HTTPS cross-origin requests (recommended) -
same-originโ Only send to same-origin requests
6. Permissions-Policy
Purpose: Controls browser feature access (formerly Feature-Policy).
Permissions-Policy restricts access to sensitive browser features like geolocation, camera, microphone, and payment APIs. For WooCommerce, restrict unnecessary features to reduce attack surface.
# Apache
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(self)"
# Nginx
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(self)" always;
๐ Complete Security Headers Configuration
Here's a production-ready configuration combining all essential headers for WooCommerce:
Apache (.htaccess or VirtualHost):
# Content Security Policy
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com https://www.gstatic.com https://js.stripe.com https://checkout.stripe.com https://www.googletagmanager.com https://www.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://api.stripe.com https://www.google-analytics.com; frame-src https://js.stripe.com https://checkout.stripe.com; object-src 'none'; base-uri 'self'; form-action 'self';"
# Strict Transport Security
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# Prevent clickjacking
Header always set X-Frame-Options "SAMEORIGIN"
# Prevent MIME sniffing
Header always set X-Content-Type-Options "nosniff"
# Referrer Policy
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Permissions Policy
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(self)"
# Remove server information
Header always unset X-Powered-By
Header always unset Server
Nginx (server or location block):
# Content Security Policy
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com https://www.gstatic.com https://js.stripe.com https://checkout.stripe.com https://www.googletagmanager.com https://www.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://api.stripe.com https://www.google-analytics.com; frame-src https://js.stripe.com https://checkout.stripe.com; object-src 'none'; base-uri 'self'; form-action 'self';" always;
# Strict Transport Security
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Prevent clickjacking
add_header X-Frame-Options "SAMEORIGIN" always;
# Prevent MIME sniffing
add_header X-Content-Type-Options "nosniff" always;
# Referrer Policy
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Permissions Policy
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(self)" always;
# Remove server information
more_clear_headers 'Server';
more_clear_headers 'X-Powered-By';
๐งช Testing Your Security Headers
After configuration, validate your headers using these tools:
- SecurityHeaders.com โ Comprehensive header analysis with letter grades (A+ is the goal)
- Mozilla Observatory โ Detailed security scoring and recommendations
- Chrome DevTools โ Open DevTools โ Network tab โ Click any request โ Check Response Headers
-
Command Line (curl) โ
curl -I https://yourstore.com - Google CSP Evaluator โ Analyze your Content Security Policy
โ ๏ธ Common Pitfalls & Troubleshooting
1. CSP Breaking Functionality
Symptom: Inline scripts, styles, or third-party resources fail to load.
Solution:
-
Use
Content-Security-Policy-Report-Onlyduring testing -
Add nonce or hash for inline scripts:
script-src 'nonce-random123' -
Whitelist specific domains:
script-src https://cdn.example.com - Avoid
'unsafe-inline'and'unsafe-eval'when possible
2. HSTS Lockout Risk
Warning: HSTS with includeSubDomains can
lock out HTTP-only subdomains.
Solution:
- Start with a short
max-age(e.g., 300 seconds) for testing - Ensure ALL subdomains have valid SSL certificates before using
includeSubDomains - Never use
preloaduntil thoroughly tested (it's nearly irreversible)
3. Payment Gateway Conflicts
Issue: Stripe, PayPal, or other gateways may fail if not whitelisted in CSP.
Solution:
-
Stripe: Add
https://js.stripe.com https://checkout.stripe.comtoscript-srcandframe-src -
PayPal: Add
https://www.paypal.com https://www.sandbox.paypal.comtoframe-src - Check payment gateway documentation for required CSP directives
Related Security Topics
๐ Advanced: Automating Header Monitoring
Once configured, continuously monitor headers to detect configuration drift or CDN conflicts:
#!/bin/bash
# header-check.sh - Monitor security headers
DOMAIN="https://yourstore.com"
EXPECTED_HEADERS=(
"Strict-Transport-Security"
"Content-Security-Policy"
"X-Frame-Options"
"X-Content-Type-Options"
)
for header in "${EXPECTED_HEADERS[@]}"; do
if ! curl -sI "$DOMAIN" | grep -q "$header"; then
echo "โ Missing header: $header"
# Send alert (email, Slack, PagerDuty)
else
echo "โ
$header present"
fi
done
Schedule this script as a cron job or integrate with monitoring tools like UptimeRobot or Pingdom.
๐ก๏ธ Security Headers as Part of Defense-in-Depth
Security headers are essential but not sufficient alone. Implement them as part of a comprehensive security strategy:
- Layer 1: Security headers (covered in this guide)
- Layer 2: Login protection with rate limiting and 2FA
- Layer 3: Multi-factor authentication
- Layer 4: Regular penetration testing
- Layer 5: PCI DSS compliance and GDPR compliance
- Layer 6: WordPress core and plugin updates
Summary & Action Plan
Implementing security headers is a 30-minute task that provides significant protection against common web attacks. Here's your implementation checklist:
- Backup your configuration files (.htaccess or nginx config)
- Add security headers using the production-ready configs above
- Start CSP in report-only mode to identify violations
- Test thoroughly on staging environment (checkout, payment gateways, analytics)
- Validate with SecurityHeaders.com โ aim for A+ grade
- Deploy to production during low-traffic periods
- Monitor error logs for 24-48 hours after deployment
- Switch CSP to enforcement mode once violations are resolved
โ ๏ธ Critical Reminder: Security headers protect against browser-based attacks but don't address server vulnerabilities, plugin vulnerabilities, or account takeovers. For comprehensive protection, combine headers with regular security audits and professional security services.
Need Expert Security Configuration?
We implement security headers, perform comprehensive audits, and provide ongoing monitoring for WooCommerce stores.
Get Professional Security Hardening โ