How to Configure NGINX for Precise CORS Control and Secure Cross‑Origin Requests

This tutorial explains the fundamentals of same‑origin policy, demonstrates how to allow all origins or restrict methods in NGINX, shows how to handle pre‑flight OPTIONS requests, and provides complete configuration examples for secure CORS header management.

Cognitive Technology Team
Cognitive Technology Team
Cognitive Technology Team
How to Configure NGINX for Precise CORS Control and Secure Cross‑Origin Requests

1. Introduction

NGINX is a versatile server that can act as a forward proxy, reverse proxy, mail proxy, or load balancer, and it supports all modern HTTP(S) features expected from a web server.

In this tutorial we explore how to control origin restrictions in NGINX. We first review the concept of origins and related issues, then present a quick example that allows requests from any origin, followed by a configuration that limits permissions to simple requests, and finally we show how to narrow the scope further and query the current configuration.

The code tested in this article runs on Debian 12 (Bookworm) with GNU Bash 5.2.15 and should work in most POSIX‑compatible environments unless otherwise noted.

2. Web Origin Issues

The Same‑Origin Policy (SOP) was introduced to control how one origin interacts with another, i.e., the cross‑origin policy.

For example, a script from http://gerganov.com needs special permission to request data from https://gerganov.com . Without proper settings the request fails and browsers show an error in the console.

Typical JavaScript error:

Cross Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://gerganov.com/.

Similarly, an XMLHttpRequest may produce:

Access to XMLHttpRequest at 'https://gerganov.com' from origin 'http://gerganov.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

To enable or disable cross‑origin data access, the Cross‑Origin Resource Sharing (CORS) policy sends the necessary HTTP headers. In NGINX these headers are added with the add_header directive, which requires the headers module.

Note that different request types may require different headers.

3. NGINX Allow All Origins

Although it goes against best practices, many servers are configured to grant a blanket permission for all cross‑origin requests.

In NGINX this can be done with a simple location block. Crucially, NGINX uses only one location directive, so configurations with multiple location blocks can be ambiguous.

$ cat /etc/nginx/conf.d/default.conf
location / {
  add_header 'Access-Control-Allow-Origin' '*';
}

Opening NGINX to all origins exposes content to abuse and the server to attacks, which is why adhering to SOP is important.

It is essential to decide on specific origins or use server‑side scripts to dynamically set the Origin header value and take appropriate actions.

If the Access-Control-Allow-Origin header is missing, the server does not permit CORS.

Simple HTTP requests (GET, POST) are a direct way to test cross‑origin policies, but they may be rejected if not explicitly allowed:

GET

POST

Our responsibility is to check the response for CORS‑specific issues.

To allow only GET and POST cross‑origin requests, we again use location but restrict the methods:

$ cat /etc/nginx/conf.d/default.conf
location / {
  add_header 'Access-Control-Allow-Origin' '*';
  add_header 'Access-Control-Allow-Methods' 'GET, POST';
}

Thus we ensure two important headers exist with correct values:

Access-Control-Allow-Origin expected to be * (any origin)

Access-Control-Allow-Methods allowed only GET and POST

We can also limit CORS headers by pattern‑matching locations:

location ~* \.(x|ox|0x)$ {
  add_header 'Access-Control-Allow-Origin' '*';
  add_header 'Access-Control-Allow-Methods' 'GET, POST';
}

However, this approach may be limited for newer request methods.

Before communication begins, browsers may send a pre‑flight request using the OPTIONS method to query the server’s supported features and cross‑origin policy.

We can retrieve this information so the server can share it before the actual resource request:

OPTIONS / HTTP/1.1
Host: gerganov.com:443
...
Origin: http://gerganov.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-requested-with

When the server receives such an OPTIONS request, it can respond with the appropriate CORS headers without returning any content:

$ cat /etc/nginx/conf.d/default.conf
location / {
  add_header 'Access-Control-Allow-Origin' '*';
  add_header 'Access-Control-Allow-Methods' 'GET, POST, HEAD, OPTIONS';
  if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
    add_header 'Access-Control-Max-Age' 57542400;
    add_header 'Content-Type' 'text/plain charset=UTF-8';
    add_header 'Content-Length' 0;
    return 204;
  }
}

This if statement inside the location block checks for the OPTIONS method and adds additional headers:

Access-Control-Allow-Methods now permits OPTIONS requests (crucial)

Access-Control-Allow-Credentials allows credentials as part of cross‑origin requests

Access-Control-Allow-Headers permits a standard set of headers

Finally, the response returns a 204 No Content status to indicate success.

6. Summary

In this article we discussed NGINX header configurations related to the Same‑Origin Policy (SOP).

Because CORS headers are an important security measure and permission mechanism, understanding how to configure them for a widely used web server like NGINX is essential.

securityCORSNginx
Cognitive Technology Team
Written by

Cognitive Technology Team

Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.