Skip to content

Nginx CSP Integration

Add CSP headers to your Nginx configuration.

  • Nginx 1.7.5+ (for add_header support)
  • Access to nginx.conf or site configuration

Add to your server or location block:

# Report-only mode (recommended to start)
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; report-uri https://your-ingest-code.ingest.us.headerhawk.com/r" always;

Reload Nginx:

Terminal window
sudo nginx -t && sudo nginx -s reload

Once you’ve tuned your policy using the reports, switch to enforcement:

add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; report-uri https://your-ingest-code.ingest.us.headerhawk.com/r" always;
server {
listen 443 ssl http2;
server_name example.com;
# CSP Header - keep the value on one line (see "One Line Per Header" below)
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https://api.example.com; report-uri https://your-ingest-code.ingest.us.headerhawk.com/r" always;
# Other security headers
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
location / {
# Your config...
}
}

Include always to send headers for all response codes (including errors):

add_header Content-Security-Policy "..." always;

Do not split a policy across lines inside the quotes. nginx -t accepts it, but nginx sends the line breaks as part of the header value, and a line break is not allowed in an HTTP/2 header: Chromium refuses the whole response with ERR_HTTP2_PROTOCOL_ERROR, so the page does not load at all. Keep each add_header value on a single line, however long.

Different policies for different paths:

location /admin {
add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;
}
location /public {
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'" always;
}
  1. Check Nginx config: sudo nginx -t
  2. Verify the always parameter is included
  3. Check if a proxy is stripping headers

If you see duplicate CSP headers, check parent blocks. You may need to consolidate headers in one location.

Test your configuration:

Terminal window
curl -I https://your-site.com | grep -i content-security-policy