[PATCH 11 of 12] Proxy: connection upgrades now rejected if not configured

Maxim Dounin mdounin at mdounin.ru
Fri Aug 8 20:09:06 UTC 2025


# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1754683269 -10800
#      Fri Aug 08 23:01:09 2025 +0300
# Node ID 9b2abd883ed2b44c0b48db7506f24d0a326bfb7f
# Parent  07b82a889a0e69eef4d90c3457b390dbdb38e2c9
Proxy: connection upgrades now rejected if not configured.

Previously, connection upgrades from upstream servers were accepted
as long as they were requested by the client.  With this change, we
additionally check that the "Upgrade" header was actually sent to the
upstream server, as per "proxy_set_header Upgrade ..." in the configuration.

This shouldn't change anything for well-behaving upstream servers, though
makes things safer to use with misbehaving ones (and assuming the client
uses the "Upgrade" header for unrelated reasons, such as when trying to
start HTTP/2 over cleartext TCP with "Upgrade: h2c", currently deprecated).

diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -141,6 +141,7 @@ typedef struct {
     ngx_chain_t                   *busy;
 
     unsigned                       head:1;
+    unsigned                       upgrade:1;
     unsigned                       internal_chunked:1;
     unsigned                       header_sent:1;
 } ngx_http_proxy_ctx_t;
@@ -1244,6 +1245,7 @@ ngx_http_proxy_create_key(ngx_http_reque
 static ngx_int_t
 ngx_http_proxy_create_request(ngx_http_request_t *r)
 {
+    u_char                       *key;
     size_t                        len, uri_len, loc_len, body_len,
                                   key_len, val_len;
     uintptr_t                     escape;
@@ -1498,9 +1500,17 @@ ngx_http_proxy_create_request(ngx_http_r
             continue;
         }
 
+        key = e.pos;
+
         code = *(ngx_http_script_code_pt *) e.ip;
         code((ngx_http_script_engine_t *) &e);
 
+        if (e.pos - key == 7
+            && ngx_strncasecmp(key, (u_char *) "Upgrade", 7) == 0)
+        {
+            ctx->upgrade = 1;
+        }
+
         *e.pos++ = ':'; *e.pos++ = ' ';
 
         while (*(uintptr_t *) e.ip) {
@@ -2010,7 +2020,8 @@ ngx_http_proxy_process_header(ngx_http_r
             }
 
             if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS
-                && r->headers_in.upgrade)
+                && r->headers_in.upgrade
+                && ctx->upgrade)
             {
                 u->keepalive = 0;
                 u->upgrade = 1;



More information about the nginx-devel mailing list