Nginx X-Accel-Redirect trusts the upstream response
X-Accel-Redirect is an internal redirect mechanism used with nginx upstreams. An application can finish its authorization checks and return a response header that tells nginx to serve a protected URI. The browser never receives the internal path. This design is convenient, but it makes the upstream response part of the file-serving trust boundary.
Nginx documents X-Accel-Redirect among the request-redirection mechanisms that produce an internal redirect. A matching internal location can then serve a file that is not directly addressable from the internet. The security property depends on two things happening together: the application must authorize the request, and nginx must restrict the URI space that the response can reach.
How the redirect works
A common mistake is treating the header as a harmless optimization while letting a user-controlled value reach it. If a download endpoint accepts a user-supplied filename and places that value in X-Accel-Redirect, the user may influence the internal path. Path normalization, prefix checks, and a fixed identifier-to-path map are safer than concatenating user input into a URI. Where nginx does not provide the required normalization, the application should select a server-side object ID rather than rebuild a path.
Upstream and path control
The reverse configuration problem also matters. A proxy that trusts every upstream header may accept X-Accel-Redirect from an application that was never meant to serve files. When the upstream is a general web application or a third-party service, review whether the directive should be ignored for that route. Nginx provides upstream header controls such as proxy_ignore_headers and equivalent FastCGI settings, but the exact directive depends on the handler.
Audit checklist
An audit should answer these questions:
- Which upstream responses can set
X-Accel-Redirect? - Which
internallocations exist, and what filesystem path does each expose? - Can a request parameter become part of the redirect URI?
- Does authorization happen before the header is emitted?
- Are range requests, cache behavior, and error handling covered by the same policy?
- Is the application reachable without nginx, bypassing the internal location?
Testing and design
The last question is often decisive. If clients can connect directly to the application server, they may receive a response that assumes nginx will handle it, or they may reach a file endpoint the proxy was supposed to hide. Network policy should make nginx the only reachable path for those routes.
The safest design uses a small set of internal locations, maps identifiers to fixed paths on the server, and keeps the file-serving policy in one reviewable place. Test denied requests, malformed identifiers, missing files, and unexpected upstream headers. Log the selected object and authorization result, not the secret path. X-Accel-Redirect is useful when the upstream is trusted and the mapping is narrow; it becomes an exposure when a request can steer the redirect or bypass the proxy.
References
- nginx core module,
internaland X-Accel-Redirect redirect sources: https://nginx.org/en/docs/http/ngx_http_core_module.html - nginx FastCGI module, X-Accel-Redirect behavior: https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html
Top comments (0)