[nginx] Upstream: unexpected connection upgrades now rejected.

Maxim Dounin mdounin at mdounin.ru
Mon Aug 18 00:30:24 UTC 2025


details:   http://freenginx.org/hg/nginx/rev/f6bcc86eb3bb
branches:  
changeset: 9407:f6bcc86eb3bb
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Mon Aug 18 03:19:11 2025 +0300
description:
Upstream: unexpected connection upgrades now rejected.

Unless the client explicitly requested to change the application protocol,
the "101 Switching Protocols" response is now considered to be an upstream
server error and not forwarded to the client.

Similarly, other 1xx responses are also rejected for now.  This will be
changed in subsequent patches.

This ensures that such responses won't affect the connection with the client.

diffstat:

 src/http/modules/ngx_http_fastcgi_module.c |  13 +++++++++++++
 src/http/modules/ngx_http_proxy_module.c   |  19 ++++++++++++++-----
 src/http/modules/ngx_http_scgi_module.c    |  12 ++++++++++++
 src/http/modules/ngx_http_uwsgi_module.c   |  12 ++++++++++++
 4 files changed, 51 insertions(+), 5 deletions(-)

diffs (97 lines):

diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -2063,6 +2063,19 @@ ngx_http_fastcgi_process_header(ngx_http
                     ngx_str_set(&u->headers_in.status_line, "200 OK");
                 }
 
+                if (u->headers_in.status_n < NGX_HTTP_OK) {
+
+                    /* reject 1xx responses */
+
+                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                                  "upstream sent unexpected status \"%V\"",
+                                  u->headers_in.status_line.len
+                                  ? &u->headers_in.status_line
+                                  : &u->headers_in.status->value);
+
+                    return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+                }
+
                 break;
             }
 
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
@@ -2009,12 +2009,21 @@ ngx_http_proxy_process_header(ngx_http_r
                 u->keepalive = !u->headers_in.connection_close;
             }
 
-            if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS) {
+            if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS
+                && r->headers_in.upgrade)
+            {
                 u->keepalive = 0;
-
-                if (r->headers_in.upgrade) {
-                    u->upgrade = 1;
-                }
+                u->upgrade = 1;
+
+            } else if (u->headers_in.status_n < NGX_HTTP_OK) {
+
+                /* reject unexpected 1xx responses */
+
+                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                              "upstream sent unexpected status \"%V\"",
+                              &u->headers_in.status_line);
+
+                return NGX_HTTP_UPSTREAM_INVALID_HEADER;
             }
 
             return NGX_OK;
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -1157,6 +1157,18 @@ ngx_http_scgi_process_header(ngx_http_re
                 && r->headers_in.upgrade)
             {
                 u->upgrade = 1;
+
+            } else if (u->headers_in.status_n < NGX_HTTP_OK) {
+
+                /* reject unexpected 1xx responses */
+
+                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                              "upstream sent unexpected status \"%V\"",
+                              u->headers_in.status_line.len
+                              ? &u->headers_in.status_line
+                              : &u->headers_in.status->value);
+
+                return NGX_HTTP_UPSTREAM_INVALID_HEADER;
             }
 
             return NGX_OK;
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -1386,6 +1386,18 @@ ngx_http_uwsgi_process_header(ngx_http_r
                 && r->headers_in.upgrade)
             {
                 u->upgrade = 1;
+
+            } else if (u->headers_in.status_n < NGX_HTTP_OK) {
+
+                /* reject unexpected 1xx responses */
+
+                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                              "upstream sent unexpected status \"%V\"",
+                              u->headers_in.status_line.len
+                              ? &u->headers_in.status_line
+                              : &u->headers_in.status->value);
+
+                return NGX_HTTP_UPSTREAM_INVALID_HEADER;
             }
 
             return NGX_OK;


More information about the nginx-devel mailing list