When using Nginx as a reverse proxy for HTTPS sites with HTTP backends, cookies returned from the backend won't automatically get the Secure flag. This creates a security gap where sensitive cookies could potentially be transmitted over unencrypted connections.
Nginx provides powerful header manipulation through the proxy_cookie_path
and more_set_headers
directives. For cookie security, we need to modify the Set-Cookie header in responses from the backend.
The most reliable approach is using Nginx's built-in headers module:
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
# Add Secure and SameSite flags to all cookies
proxy_cookie_path / "/; Secure; SameSite=Lax";
}
For more complex scenarios where you need to preserve some cookie attributes while adding Secure:
location / {
proxy_pass http://backend;
# Preserve existing attributes while adding Secure
proxy_cookie_flags ~ Secure;
}
When you need to apply Secure flag selectively to certain cookies:
location / {
proxy_pass http://backend;
# Apply to specific cookies
proxy_cookie_flags sessionid Secure;
proxy_cookie_flags csrftoken Secure;
# Alternative regex approach
proxy_cookie_flags ~^(.*session.*)$ Secure;
}
After implementing these changes, verify using:
curl -I https://yoursite.com
Check the Set-Cookie header in response to confirm Secure flag is present.
Cookie manipulation adds minimal overhead. For high-traffic sites, test with:
ab -n 1000 -c 100 https://yoursite.com/login
Monitor response times to ensure acceptable performance impact.
When using Nginx as a reverse proxy for an HTTPS-only site, you might encounter a situation where your backend server (running on HTTP) doesn't set the Secure
flag for cookies. This creates a security vulnerability as cookies could potentially be transmitted over unencrypted connections.
The Secure
attribute ensures cookies are only sent over HTTPS connections. Without it:
- Session cookies could be intercepted
- Authentication tokens become vulnerable
- Your site fails security compliance checks
Nginx's proxy_cookie_path
and sub_filter
directives can solve this. Here's a complete configuration example:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Add Secure and SameSite flags to all cookies
proxy_cookie_path / "/; Secure; SameSite=Lax";
# For cases where cookies have Path attribute
proxy_cookie_flags ~ Secure;
}
}
For more complex cases where cookies have specific attributes, use sub_filter
:
location / {
proxy_pass http://backend_server;
sub_filter_types *;
sub_filter 'Set-Cookie: ' 'Set-Cookie: $1; Secure; SameSite=Lax';
sub_filter_once off;
}
After implementing these changes:
- Reload Nginx:
sudo nginx -s reload
- Use browser dev tools to inspect response headers
- Verify cookies show the Secure flag
- Test with
curl -I https://yoursite.com
- Forgetting to reload Nginx after config changes
- Mixing HTTP and HTTPS content causing cookie rejection
- Overwriting important cookie attributes