ISP Reverse Proxy changes case of Headers causing multiple occurrences

I have installed NC 10 on a hosting site (siteground). Their configuration is an nginx proxy server in front of apache.

When I go to the Admin Panel, I get a series of messages like:

The “X-XSS-Protection” HTTP header is not configured to equal to “1; mode=block”. This is a potential security or privacy risk and we recommend adjusting this setting

Having raised a Support request with them, it appears that the headers are correct when output from Apache, but are being converted to lower case by nginx before being served to the client; so there is a header “x-xss-protection” with the required content.

Indeed there are two of them. due to “belt and braces” checking.

I have found no operational problem in my limited usage, but added unnecessary processing.

Whilst I have a lot of sympathy for the approach that says “We set them mixed case, so they shouldn’t mess with them”, this may be a sterile debate.

The standard RFC7230 ( says

3.2. Header Fields

Each header field consists of a case-insensitive field name followed by a colon (":"), optional leading whitespace, the field value, and optional trailing whitespace.

So would it be possible to make the tests case insensitive in the code?


It seems that in the code, they convert it first to lower-case before comparing the strings:

Perhaps some issue with the white spaces? If you still have problems, please create a bug report on github.

Agree that the code compares header VALUE as lower case.

However the code searches without case conversion for a header NAME as
is (e.g. X-XSS-Protection) and does not find it - as it has been
converted to x-xss-protection.

I’ll create a bug report.





Ah, it is doubling the entries, I thought you just wrote to each header into what it was converted. The case sensitivity would then probably be a new issue. But you should make sure to have the problem with case sensitivity without doubling the headers.

Then open a new issue and refer to the RFC violation.

Thank you for clarifying the underlying issue.

It is the case-sensitive lookup (in core/js/setupchecks.js) that is giving rise to the admin message.

I would be grateful if you could raise a bug with just that.

[When I changed the definition of SecurityHeaders to lower case, the admin error messages went away. Of course, this is an incorrect fix.]

The duplication of headers is occurring for a more subtle reason and I need to get past the various caching, i.e. let it time out, and other elements within the ISP to determine the root cause.

Of course, the ISP is NOT randomly adding headers - Nextcloud is.

.htaccess has (lines snipped)

<IfModule mod_headers.c>
  <IfModule mod_env.c>
    # Add security and privacy related headers
    Header set X-XSS-Protection "1; mode=block"
    Header set X-Robots-Tag "none"
    Header set X-Frame-Options "SAMEORIGIN"
    Header set X-Download-Options "noopen"
    Header set X-Permitted-Cross-Domain-Policies "none"
    SetEnv modHeadersAvailable true

So I expect that if the header is set, then so is the environment variable.

/lib/private/legacy/response.php has

		if(getenv('modHeadersAvailable') !== 'true') {
			header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters
			header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE
			header('X-Frame-Options: Sameorigin'); // Disallow iFraming from other domains

The headers being sent include (in order received)

x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-frame-options: Sameorigin

and later

x-xss-protection: 1; mode=block
x-robots-tag: none
x-frame-options: SAMEORIGIN

I am trying to understand what is occurring, and although I understand that the overall ordering of headers can be changed, they cannot be for a given header name, such as x-frame-options.

So it would at first sight that the legacy code is being invoked before the .htaccess process has been set.

But there are more tests needed before I could state definitively what is occuring.

Merging the headers could make this problem go away.