How to Force Secure Flag on Cookies in Nginx Reverse Proxy for HTTPS Backends


2 views

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:

  1. Reload Nginx: sudo nginx -s reload
  2. Use browser dev tools to inspect response headers
  3. Verify cookies show the Secure flag
  4. 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