CORS Anywhere on Pure NGINX Config

Cross-Origin Resource Sharing (CORS) often becomes a stumbling block for developers attempting to interact with APIs hosted on different domains. The challenge intensifies when direct server configuration isn't an option, pushing developers towards alternative solutions like the widely-used cors-anywhere. However, less known is the capability of NGINX's proxy_pass directive to handle not only local domains and upstreams but also external sources, for example:

proxy_pass directive example


This is how the idea was born to write a universal (with some reservations) NIGNX config that supports any given domain.

Understanding the Basics and Setup

CORS is a security feature that restricts web applications from making requests to a different domain than the one that served the web application itself. This is a crucial security measure to prevent malicious websites from accessing sensitive data. However, when legitimate cross-domain requests are necessary, properly configuring CORS is essential.

The NGINX proxy server offers a powerful solution to this dilemma. By utilizing NGINX's flexible configuration system, developers can create a proxy that handles CORS preflight requests and manipulates headers to ensure compliance with CORS policies. Here's how:

Variable Declaration and Manipulation

With the map directive, NGINX allows the declaration of new variables based on existing global ones, incorporating regular expression support for dynamic processing. For instance, extracting a specific path from a URL can be achieved, allowing for precise control over request handling.

map directive example


Thus, when requesting http://example.com/api, the $my_request_path variable will contain api.

Header Management

NGINX facilitates the addition of custom headers to responses via add_header and to proxied requests through proxy_set_header. Simultaneously, proxy_hide_header can be used to conceal headers received from the proxied server, ensuring only the necessary information is passed back to the client.

add_header example


We now have an X-Request-Path header with api.

Conditional Processing

Utilizing the if directive, NGINX can perform actions based on specific conditions, such as returning a predetermined response code for OPTIONS method requests, streamlining the handling of CORS preflight checks.

if directive example


Putting It All Together

First, let’s declare $proxy_uri that we will extract from $request_uri:

Declare $proxy_uri to extract from $request_ur


In short, it works like this: when requesting http://example.com/example.com, the $proxy_uri variable will contain https://example.com

From the resulting $proxy_uri, extract the part that will match the Origin header:

From the resulting $proxy_uri, extract the part that will match the Origin header


For the Forwarded header, we need to process 2 variables at once:

For the Forwarded header, we need to process 2 variables at once


The processed X-Forwarded-For header is already built into NGINX.

Now we can move on to declaring our proxy server:

Declaring proxy server


We get a minimally working proxy server, which can process the CORS Preflight Request and add the appropriate headers.

Enhancing Security and Performance

Beyond basic setup, further refinements can improve security and performance: 

Hiding CORS Headers

When NGINX handles CORS internally, it's beneficial to hide these headers from client responses to prevent exposure of server internals.

Hide these headers from client responses to prevent exposure of server internals


Rate Limit Bypassing

It would also be nice to pass the client’s IP to somehow bypass the rate limit, which can occur if several users access the same resource.

Pass the client’s IP to bypass the rate limit


Disabling Caching

And finally, for dynamic content or sensitive information, disabling caching is a best practice, ensuring data freshness and privacy.

Disabling caching


Conclusion

This guide not only demystifies the process of configuring NGINX to handle CORS requests but also equips developers with the knowledge to create a robust, flexible proxy server capable of supporting diverse application needs. Through careful configuration and understanding of both CORS policies and NGINX's capabilities, developers can overcome cross-origin restrictions, enhance application performance, and ensure data security. This advanced understanding and application of NGINX not only solves a common web development hurdle but also showcases the depth of skill and innovation possible when navigating web security and resource-sharing challenges.

 

 

 

 

Top