Score:1

How to override Nginx response headers in PHP

eg flag

I want to apply a default CSP header in nginx - basically a catch all. However, I also want to be able to override the CSP header via PHP in certain scripts. So far I've been unable to find a way to do this and the result is I get 2 headers - the first from PHP and the second from Nginx, with the last header taking preference over the first.

In nginx I have:

add_header Content-Security-Policy "default-src 'self';";

Then there's a catch for the PHP files:

location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
        fastcgi_pass 127.0.0.1:9000;
        include fastcgi_params;
        fastcgi_param HTTP_PROXY "";
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_intercept_errors on;
        fastcgi_connect_timeout         300; 
        fastcgi_send_timeout           3600; 
        fastcgi_read_timeout           3600;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
    }

I've tried playing around with fastcgi_param to see if I can get the header back from PHP and only add_header if not set, as well as trying:

    if ($http_content_security_policy = "") {
        add_header Content-Security-Policy "default-src 'self';";
    }

But so far not winning. I assume it's a timing or access issue in Nginx in terms of the PHP header values? Any help is appreciated.

Note: I'm using Azure web apps, so I don't think I can add any modules that aren't default for Nginx

Score:1
jp flag

The add_header directive will not generate a header if the value provided is an empty string.

You can provide various values to the add_header statement by using a map block. See map directive documentation.

The header returned by the PHP script is available as $upstream_http_content_security_policy.

So the solution is to test the value returned by the PHP script using a map block, and set the default value only if the script returns no header.

For example:

map $upstream_http_content_security_policy $csp_value {
    ""  "default-src 'self';";
}
add_header Content-Security-Policy $csp_value;

The default header for Content-Security-Policy is only inserted if the $upstream_http_content_security_policy variable is empty (meaning that the script did not provide an alternative value).

Note that the map block must be placed outside of the server block. The add_header statement can remain where you currently define it.

Praemon avatar
eg flag
Thank you for the detailed response. This worked perfectly and I have a better understanding now of the process. Much appreciated!
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.