NGINX underscores_in_headers: Explained with examples

Updated: February 20, 2024 By: Guest Contributor 2 comments

Introduction

When working with NGINX, a popular HTTP and reverse proxy server, understanding and properly-configuring header field names is critical. By default, NGINX does not recognize headers with underscores in them. This setting can affect applications that rely on custom header names. This tutorial explores the underscores_in_headers directive in NGINX, explains its functionality, and provides examples of how to use it effectively.

Understanding Headers in HTTP

HTTP headers are the name/value pairs that are sent in HTTP requests and responses. Header names are case-insensitive and conventionally use hyphens rather than underscores. However, some applications may incorrectly generate header names with underscores, an issue that NGINX addresses with the underscores_in_headers directive.

The Default Behavior of NGINX

By default, NGINX ignores headers that contain underscores. This behavior is designed to prevent ambiguities and security issues. For instance, the header X_User_Auth will be ignored by NGINX, while X-User-Auth will be read correctly.

Enabling Underscore in Headers

To allow NGINX to read headers with underscores, you need to set the underscores_in_headers directive to ‘on’ in your NGINX configuration:

http {
    ...
    underscores_in_headers on;
}

This will instruct NGINX to recognize and accept headers with underscores.

Examples

Basic Configuration

Let’s start with a basic example. Consider an upstream application that requires a custom header API_KEY. We would include the directive in our NGINX server block configuration:

server {
    ...
    location / {
        ...
        underscores_in_headers on;
    }
}

With this setting, NGINX will accept the API_KEY header from incoming requests.

Using map with underscores in headers

You can map headers with underscores to variables within the NGINX configuration. Below is an example of mapping the X_User_Type header to a variable and applying logic based on its value:

http {
    ...
    map $http_x_user_type $user_type {
        default 'guest';
        admin 'administrator';
        user 'registered_user';
    }

    server {
        ...
        underscores_in_headers on;
        location /adminpanel {
            if ($user_type != 'administrator') {
                return 403;
            }
        }
    }
}

In this example, we’ve securely restricted access to the /adminpanel location, based on the user’s type obtained from the headers.

Conditional Logging

If your application sends specific headers with underscores for debugging purposes such as X_Debug_Info, you can conditionally log those headers. To achieve this, use the following configuration:

http {
    ...
    underscores_in_headers on;
    map $http_x_debug_info $loggable_debug_info {
        ~^.{5,} 1;
        default 0;
    }

    access_log /path/to/access.log combined if=$loggable_debug_info;
}

Here, we only log requests that include a X_Debug_Info header with a value that is at least 5 characters long.

Securing Proxy Headers

When setting headers in an NGINX reverse proxy scenario, it’s essential to sanitize incoming headers to avoid conflicts with the ones set by your server configuration. See the following example:

server {
    ...
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://backend;
        underscores_in_headers off;
    }
}

In the proxy scenario above, we’ve turned off underscores_in_headers to ensure only sanitized headers, like X-Real-IP, pass through to the proxy.

Best Practices

When dealing with headers in NGINX, keep the following best practices in mind:

  • Use a consistent convention for header names, preferably hyphenated names to avoid needing underscores_in_headers.
  • Only enable underscores_in_headers if absolutely necessary, as underscores in header names are non-standard and may be deprecated in the future.
  • When working with upstream services that require headers with underscores, ensure that these services are trusted and the headers are not used for important transactions, avoiding potential security risks.

Conclusion

In conclusion, the underscores_in_headers directive in NGINX is a powerful but often overlooked feature. By carefully evaluating the use cases and following best practices, administrators can ensure the reliability and security of their web applications’ communication.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments