Nginx – Override CSP header for specific location

nginx

I have an nginx config that includes a CSP header that is served for all requests. Now I need to override it in one particular location (that also happens to be rewritten). I'm thinking something like this:

server {
  listen 80;
  listen [::]:80;

  server_name example.com;
  root /var/www;
  index index.php;

  try_files $uri @rewrites;

  add_header Content-Security-Policy "default-src 'self' ; script-src 'self' ; style-src 'self' 'unsafe-inline' ; img-src * 'self' data: ; font-src 'self' ; media-src * 'self' ; form-action 'self'";

  location @rewrites {
    rewrite ^/special/([0-9]*) /special.php?id=$1 last;
    rewrite ^/foo/([a-z]+) /foo.php?method=$1 last;
  }

  location /special {
    add_header Content-Security-Policy "default-src 'self' ; script-src 'self' 'unsafe-inline' ; style-src 'self' 'unsafe-inline' ; img-src * 'self' data: ; font-src 'self' ; media-src * 'self' ; form-action 'self'";
  }

  location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass php;
  }
}

However, while that sets the header on any request starting with /special, it results in a 404 because it doesn't continue to the following location that maps PHP files. How should I do this?

Best Answer

Try to the see if the following works for you:

http context:

map $request_uri $csp_header {
    default "default-src 'self' ; script-src 'self' ; style-src 'self' 'unsafe-inline' ; img-src * 'self' data: ; font-src 'self' ; media-src * 'self' ; form-action 'self'";
    "~^/special" "default-src 'self' ; script-src 'self' 'unsafe-inline' ; style-src 'self' 'unsafe-inline' ; img-src * 'self' data: ; font-src 'self' ; media-src * 'self' ; form-action 'self'";
}

server context:

add_header Content-Security-Policy $csp_header;