[Pkg-nginx-maintainers] Bug#964950: nginx: CVE-2020-11724

Sylvain Beucler beuc at beuc.net
Mon Jul 13 16:00:23 BST 2020


In case this helps, here's some documentation to test the issue with the
new upstream test cases:
https://wiki.debian.org/LTS/TestSuites/nginx

and my planned stretch package:
https://www.beuc.net/tmp/debian-lts/nginx/

Cheers!
Sylvain Beucler
Debian LTS Team

-------------- next part --------------
diff -Nru nginx-1.10.3/debian/changelog nginx-1.10.3/debian/changelog
--- nginx-1.10.3/debian/changelog	2020-01-11 08:28:05.000000000 +0100
+++ nginx-1.10.3/debian/changelog	2020-07-13 11:40:49.000000000 +0200
@@ -1,3 +1,11 @@
+nginx (1.10.3-1+deb9u5) stretch-security; urgency=high
+
+  * Non-maintainer upload by the LTS Security Team.
+  * CVE-2020-11724: ngx_http_lua_subrequest.c allows HTTP request
+    smuggling, as demonstrated by the ngx.location.capture API.
+
+ -- Sylvain Beucler <beuc at debian.org>  Mon, 13 Jul 2020 11:40:49 +0200
+
 nginx (1.10.3-1+deb9u4) stretch; urgency=medium
 
   * Handle CVE-2019-20372, error page request smuggling
diff -Nru nginx-1.10.3/debian/modules/patches/nginx-lua/CVE-2020-11724.patch nginx-1.10.3/debian/modules/patches/nginx-lua/CVE-2020-11724.patch
--- nginx-1.10.3/debian/modules/patches/nginx-lua/CVE-2020-11724.patch	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.10.3/debian/modules/patches/nginx-lua/CVE-2020-11724.patch	2020-07-13 11:40:49.000000000 +0200
@@ -0,0 +1,863 @@
+Origin: https://github.com/openresty/openresty/commit/4e8b4c395f842a078e429c80dd063b2323999957
+Origin: https://github.com/openresty/lua-nginx-module/commit/9ab38e8ee35fc08a57636b1b6190dca70b0076fa
+Last-Update: 2020-07-13
+Reviewed-by: Sylvain Beucler <beuc at debian.org>
+
+commit 96c330c3cb2a5abc95d293854801c7ba2896d1da
+Author: Thibault Charbonnier <thibaultcha at me.com>
+Date:   Mon Mar 23 19:40:47 2020 -0700
+
+    bugfix: prevented request smuggling in the ngx.location.capture API.
+
+From 9ab38e8ee35fc08a57636b1b6190dca70b0076fa Mon Sep 17 00:00:00 2001
+From: Thibault Charbonnier <thibaultcha at me.com>
+Date: Mon, 23 Mar 2020 19:40:47 -0700
+Subject: [PATCH] bugfix: prevented request smuggling in the
+ ngx.location.capture API.
+
+Signed-off-by: Yichun Zhang (agentzh) <yichun at openresty.com>
+(tests)
+
+Index: nginx-lua/src/ngx_http_lua_subrequest.c
+===================================================================
+--- nginx-lua.orig/src/ngx_http_lua_subrequest.c
++++ nginx-lua/src/ngx_http_lua_subrequest.c
+@@ -56,8 +56,6 @@ static ngx_str_t  ngx_http_lua_content_l
+     ngx_string("Content-Length");
+ 
+ 
+-static ngx_int_t ngx_http_lua_set_content_length_header(ngx_http_request_t *r,
+-    off_t len);
+ static ngx_int_t ngx_http_lua_adjust_subrequest(ngx_http_request_t *sr,
+     ngx_uint_t method, int forward_body,
+     ngx_http_request_body_t *body, unsigned vars_action,
+@@ -78,7 +76,7 @@ static void ngx_http_lua_cancel_subreq(n
+ static ngx_int_t ngx_http_post_request_to_head(ngx_http_request_t *r);
+ static ngx_int_t ngx_http_lua_copy_in_file_request_body(ngx_http_request_t *r);
+ static ngx_int_t ngx_http_lua_copy_request_headers(ngx_http_request_t *sr,
+-    ngx_http_request_t *r);
++    ngx_http_request_t *pr, ngx_uint_t prcl);
+ 
+ 
+ /* ngx.location.capture is just a thin wrapper around
+@@ -622,8 +620,8 @@ ngx_http_lua_adjust_subrequest(ngx_http_
+     unsigned vars_action, ngx_array_t *extra_vars)
+ {
+     ngx_http_request_t          *r;
+-    ngx_int_t                    rc;
+     ngx_http_core_main_conf_t   *cmcf;
++    ngx_uint_t                   prcl = 0;
+     size_t                       size;
+ 
+     r = sr->parent;
+@@ -633,46 +631,32 @@ ngx_http_lua_adjust_subrequest(ngx_http_
+     if (body) {
+         sr->request_body = body;
+ 
+-        rc = ngx_http_lua_set_content_length_header(sr,
+-                                                    body->buf
+-                                                    ? ngx_buf_size(body->buf)
+-                                                    : 0);
+-
+-        if (rc != NGX_OK) {
+-            return NGX_ERROR;
+-        }
+-
+     } else if (!always_forward_body
+                && method != NGX_HTTP_PUT
+                && method != NGX_HTTP_POST
+                && r->headers_in.content_length_n > 0)
+     {
+-        rc = ngx_http_lua_set_content_length_header(sr, 0);
+-        if (rc != NGX_OK) {
+-            return NGX_ERROR;
+-        }
+-
+-#if 1
+         sr->request_body = NULL;
+-#endif
+ 
+     } else {
+-        if (ngx_http_lua_copy_request_headers(sr, r) != NGX_OK) {
+-            return NGX_ERROR;
++        if (!r->headers_in.chunked) {
++            prcl = 1;
+         }
+ 
+-        if (sr->request_body) {
++        if (sr->request_body && sr->request_body->temp_file) {
+ 
+             /* deep-copy the request body */
+ 
+-            if (sr->request_body->temp_file) {
+-                if (ngx_http_lua_copy_in_file_request_body(sr) != NGX_OK) {
+-                    return NGX_ERROR;
+-                }
++            if (ngx_http_lua_copy_in_file_request_body(sr) != NGX_OK) {
++                return NGX_ERROR;
+             }
+         }
+     }
+ 
++    if (ngx_http_lua_copy_request_headers(sr, r, prcl) != NGX_OK) {
++        return NGX_ERROR;
++    }
++
+     sr->method = method;
+ 
+     switch (method) {
+@@ -1118,100 +1102,6 @@ ngx_http_lua_post_subrequest(ngx_http_re
+ }
+ 
+ 
+-static ngx_int_t
+-ngx_http_lua_set_content_length_header(ngx_http_request_t *r, off_t len)
+-{
+-    ngx_table_elt_t                 *h, *header;
+-    u_char                          *p;
+-    ngx_list_part_t                 *part;
+-    ngx_http_request_t              *pr;
+-    ngx_uint_t                       i;
+-
+-    r->headers_in.content_length_n = len;
+-
+-    if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
+-                      sizeof(ngx_table_elt_t)) != NGX_OK)
+-    {
+-        return NGX_ERROR;
+-    }
+-
+-    h = ngx_list_push(&r->headers_in.headers);
+-    if (h == NULL) {
+-        return NGX_ERROR;
+-    }
+-
+-    h->key = ngx_http_lua_content_length_header_key;
+-    h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
+-    if (h->lowcase_key == NULL) {
+-        return NGX_ERROR;
+-    }
+-
+-    ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
+-
+-    r->headers_in.content_length = h;
+-
+-    p = ngx_palloc(r->pool, NGX_OFF_T_LEN);
+-    if (p == NULL) {
+-        return NGX_ERROR;
+-    }
+-
+-    h->value.data = p;
+-
+-    h->value.len = ngx_sprintf(h->value.data, "%O", len) - h->value.data;
+-
+-    h->hash = ngx_http_lua_content_length_hash;
+-
+-#if 0
+-    dd("content length hash: %lu == %lu", (unsigned long) h->hash,
+-       ngx_hash_key_lc((u_char *) "Content-Length",
+-                       sizeof("Content-Length") - 1));
+-#endif
+-
+-    dd("r content length: %.*s",
+-       (int) r->headers_in.content_length->value.len,
+-       r->headers_in.content_length->value.data);
+-
+-    pr = r->parent;
+-
+-    if (pr == NULL) {
+-        return NGX_OK;
+-    }
+-
+-    /* forward the parent request's all other request headers */
+-
+-    part = &pr->headers_in.headers.part;
+-    header = part->elts;
+-
+-    for (i = 0; /* void */; i++) {
+-
+-        if (i >= part->nelts) {
+-            if (part->next == NULL) {
+-                break;
+-            }
+-
+-            part = part->next;
+-            header = part->elts;
+-            i = 0;
+-        }
+-
+-        if (header[i].key.len == sizeof("Content-Length") - 1
+-            && ngx_strncasecmp(header[i].key.data, (u_char *) "Content-Length",
+-                               sizeof("Content-Length") - 1) == 0)
+-        {
+-            continue;
+-        }
+-
+-        if (ngx_http_lua_set_input_header(r, header[i].key,
+-                                          header[i].value, 0) == NGX_ERROR)
+-        {
+-            return NGX_ERROR;
+-        }
+-    }
+-
+-    return NGX_OK;
+-}
+-
+-
+ static void
+ ngx_http_lua_handle_subreq_responses(ngx_http_request_t *r,
+     ngx_http_lua_ctx_t *ctx)
+@@ -1724,11 +1614,17 @@ ngx_http_lua_copy_in_file_request_body(n
+ 
+ 
+ static ngx_int_t
+-ngx_http_lua_copy_request_headers(ngx_http_request_t *sr, ngx_http_request_t *r)
++ngx_http_lua_copy_request_headers(ngx_http_request_t *sr,
++    ngx_http_request_t *pr, ngx_uint_t prcl)
+ {
+-    ngx_table_elt_t                 *header;
++    ngx_table_elt_t                 *clh, *header;
+     ngx_list_part_t                 *part;
+     ngx_uint_t                       i;
++    u_char                          *p;
++    off_t                            len;
++
++    dd("before: parent req headers count: %d",
++       (int) pr->headers_in.headers.part.nelts);
+ 
+     if (ngx_list_init(&sr->headers_in.headers, sr->pool, 20,
+                       sizeof(ngx_table_elt_t)) != NGX_OK)
+@@ -1736,10 +1632,46 @@ ngx_http_lua_copy_request_headers(ngx_ht
+         return NGX_ERROR;
+     }
+ 
+-    dd("before: parent req headers count: %d",
+-       (int) r->headers_in.headers.part.nelts);
++    if (sr->request_body && !prcl) {
++
++        /* craft our own Content-Length */
++
++        len = sr->request_body->buf ? ngx_buf_size(sr->request_body->buf) : 0;
++
++        clh = ngx_list_push(&sr->headers_in.headers);
++        if (clh == NULL) {
++            return NGX_ERROR;
++        }
+ 
+-    part = &r->headers_in.headers.part;
++        clh->hash = ngx_http_lua_content_length_hash;
++        clh->key = ngx_http_lua_content_length_header_key;
++        clh->lowcase_key = ngx_pnalloc(sr->pool, clh->key.len);
++        if (clh->lowcase_key == NULL) {
++            return NGX_ERROR;
++        }
++
++        ngx_strlow(clh->lowcase_key, clh->key.data, clh->key.len);
++
++        p = ngx_palloc(sr->pool, NGX_OFF_T_LEN);
++        if (p == NULL) {
++            return NGX_ERROR;
++        }
++
++        clh->value.data = p;
++        clh->value.len = ngx_sprintf(clh->value.data, "%O", len)
++                         - clh->value.data;
++
++        sr->headers_in.content_length = clh;
++        sr->headers_in.content_length_n = len;
++
++        dd("sr crafted content-length: %.*s",
++           (int) sr->headers_in.content_length->value.len,
++           sr->headers_in.content_length->value.data);
++    }
++
++    /* copy the parent request's headers */
++
++    part = &pr->headers_in.headers.part;
+     header = part->elts;
+ 
+     for (i = 0; /* void */; i++) {
+@@ -1754,7 +1686,14 @@ ngx_http_lua_copy_request_headers(ngx_ht
+             i = 0;
+         }
+ 
+-        dd("setting request header %.*s: %.*s", (int) header[i].key.len,
++        if (!prcl && header[i].key.len == sizeof("Content-Length") - 1
++            && ngx_strncasecmp(header[i].key.data, (u_char *) "Content-Length",
++                               sizeof("Content-Length") - 1) == 0)
++        {
++            continue;
++        }
++
++        dd("sr copied req header %.*s: %.*s", (int) header[i].key.len,
+            header[i].key.data, (int) header[i].value.len,
+            header[i].value.data);
+ 
+@@ -1766,9 +1705,10 @@ ngx_http_lua_copy_request_headers(ngx_ht
+     }
+ 
+     dd("after: parent req headers count: %d",
+-       (int) r->headers_in.headers.part.nelts);
++       (int) pr->headers_in.headers.part.nelts);
+ 
+     return NGX_OK;
+ }
+ 
++
+ /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
+Index: nginx-lua/t/020-subrequest.t
+===================================================================
+--- nginx-lua.orig/t/020-subrequest.t
++++ nginx-lua/t/020-subrequest.t
+@@ -14,6 +14,7 @@ repeat_each(2);
+ plan tests => repeat_each() * (blocks() * 3 + 23);
+ 
+ $ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
++$ENV{TEST_NGINX_HTML_DIR} ||= html_dir();
+ 
+ #no_diff();
+ no_long_string();
+@@ -210,7 +211,7 @@ GET
+ 
+ 
+ 
+-=== TEST 8: PUT (nobody, proxy method)
++=== TEST 8: PUT (with body, proxy method)
+ --- config
+     location /other {
+         default_type 'foo/bar';
+@@ -242,7 +243,7 @@ hello
+ 
+ 
+ 
+-=== TEST 9: PUT (nobody, no proxy method)
++=== TEST 9: PUT (with body, no proxy method)
+ --- config
+     location /other {
+         default_type 'foo/bar';
+@@ -271,7 +272,7 @@ hello
+ 
+ 
+ 
+-=== TEST 10: PUT (nobody, no proxy method)
++=== TEST 10: PUT (no body, no proxy method)
+ --- config
+     location /other {
+         default_type 'foo/bar';
+@@ -2873,3 +2874,516 @@ DELETE /file.txt, response status: 204
+ --- no_error_log
+ [error]
+ --- error_code: 200
++
++
++
++=== TEST 77: avoid request smuggling 1/4 (default capture + smuggle in header)
++--- http_config
++    upstream backend {
++        server unix:$TEST_NGINX_HTML_DIR/nginx.sock;
++        keepalive 32;
++    }
++
++    server {
++        listen unix:$TEST_NGINX_HTML_DIR/nginx.sock;
++
++        location / {
++            content_by_lua_block {
++                ngx.say("method: ", ngx.var.request_method,
++                        ", uri: ", ngx.var.uri,
++                        ", X: ", ngx.var.http_x)
++            }
++        }
++    }
++--- config
++    location /proxy {
++        proxy_http_version 1.1;
++        proxy_set_header   Connection "";
++        proxy_pass         http://backend/foo;
++    }
++
++    location /capture {
++        server_tokens off;
++        more_clear_headers Date;
++
++        content_by_lua_block {
++            local res = ngx.location.capture("/proxy")
++            ngx.print(res.body)
++        }
++    }
++
++    location /t {
++        content_by_lua_block {
++            local req = [[
++GET /capture HTTP/1.1
++Host: test.com
++Content-Length: 37
++Transfer-Encoding: chunked
++
++0
++
++GET /capture HTTP/1.1
++Host: test.com
++X: GET /bar HTTP/1.0
++
++]]
++
++            local sock = ngx.socket.tcp()
++            sock:settimeout(1000)
++
++            local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT)
++            if not ok then
++                ngx.say("failed to connect: ", err)
++                return
++            end
++
++            local bytes, err = sock:send(req)
++            if not bytes then
++                ngx.say("failed to send req: ", err)
++                return
++            end
++
++            ngx.say("req bytes: ", bytes)
++
++            local n_resp = 0
++
++            local reader = sock:receiveuntil("\r\n")
++            while true do
++                local line, err = reader()
++                if line then
++                    ngx.say(line)
++                    if line == "0" then
++                        n_resp = n_resp + 1
++                    end
++
++                    if n_resp >= 2 then
++                        break
++                    end
++
++                else
++                    ngx.say("err: ", err)
++                    break
++                end
++            end
++
++            sock:close()
++        }
++    }
++--- request
++GET /t
++--- response_body
++req bytes: 146
++HTTP/1.1 200 OK
++Server: nginx
++Content-Type: text/plain
++Transfer-Encoding: chunked
++Connection: keep-alive
++
++1f
++method: GET, uri: /foo, X: nil
++
++0
++
++HTTP/1.1 200 OK
++Server: nginx
++Content-Type: text/plain
++Transfer-Encoding: chunked
++Connection: keep-alive
++
++2d
++method: GET, uri: /foo, X: GET /bar HTTP/1.0
++
++0
++--- no_error_log
++[error]
++
++
++
++=== TEST 78: avoid request smuggling 2/4 (POST capture + smuggle in body)
++--- http_config
++    upstream backend {
++        server unix:$TEST_NGINX_HTML_DIR/nginx.sock;
++        keepalive 32;
++    }
++
++    server {
++        listen unix:$TEST_NGINX_HTML_DIR/nginx.sock;
++
++        location / {
++            content_by_lua_block {
++                ngx.say("method: ", ngx.var.request_method,
++                        ", uri: ", ngx.var.uri)
++            }
++        }
++    }
++--- config
++    location /proxy {
++        proxy_http_version 1.1;
++        proxy_set_header   Connection "";
++        proxy_pass         http://backend/foo;
++    }
++
++    location /capture {
++        server_tokens off;
++        more_clear_headers Date;
++
++        content_by_lua_block {
++            ngx.req.read_body()
++            local res = ngx.location.capture("/proxy", { method = ngx.HTTP_POST })
++            ngx.print(res.body)
++        }
++    }
++
++    location /t {
++        content_by_lua_block {
++            local req = [[
++GET /capture HTTP/1.1
++Host: test.com
++Content-Length: 57
++Transfer-Encoding: chunked
++
++0
++
++POST /capture HTTP/1.1
++Host: test.com
++Content-Length: 60
++
++POST /bar HTTP/1.1
++Host: test.com
++Content-Length: 5
++
++hello
++
++]]
++
++            local sock = ngx.socket.tcp()
++            sock:settimeout(1000)
++
++            local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT)
++            if not ok then
++                ngx.say("failed to connect: ", err)
++                return
++            end
++
++            local bytes, err = sock:send(req)
++            if not bytes then
++                ngx.say("failed to send req: ", err)
++                return
++            end
++
++            ngx.say("req bytes: ", bytes)
++
++            local n_resp = 0
++
++            local reader = sock:receiveuntil("\r\n")
++            while true do
++                local line, err = reader()
++                if line then
++                    ngx.say(line)
++                    if line == "0" then
++                        n_resp = n_resp + 1
++                    end
++
++                    if n_resp >= 2 then
++                        break
++                    end
++
++                else
++                    ngx.say("err: ", err)
++                    break
++                end
++            end
++
++            sock:close()
++        }
++    }
++--- request
++GET /t
++--- response_body
++req bytes: 205
++HTTP/1.1 200 OK
++Server: nginx
++Content-Type: text/plain
++Transfer-Encoding: chunked
++Connection: keep-alive
++
++18
++method: POST, uri: /foo
++
++0
++
++HTTP/1.1 200 OK
++Server: nginx
++Content-Type: text/plain
++Transfer-Encoding: chunked
++Connection: keep-alive
++
++18
++method: POST, uri: /foo
++
++0
++--- no_error_log
++[error]
++
++
++
++=== TEST 79: avoid request smuggling 3/4 (POST capture w/ always_forward_body + smuggle in body)
++--- http_config
++    upstream backend {
++        server unix:$TEST_NGINX_HTML_DIR/nginx.sock;
++        keepalive 32;
++    }
++
++    server {
++        listen unix:$TEST_NGINX_HTML_DIR/nginx.sock;
++
++        location / {
++            content_by_lua_block {
++                ngx.say("method: ", ngx.var.request_method,
++                        ", uri: ", ngx.var.uri)
++            }
++        }
++    }
++--- config
++    location /proxy {
++        proxy_http_version 1.1;
++        proxy_set_header   Connection "";
++        proxy_pass         http://backend/foo;
++    }
++
++    location /capture {
++        server_tokens off;
++        more_clear_headers Date;
++
++        content_by_lua_block {
++            ngx.req.read_body()
++            local res = ngx.location.capture("/proxy", {
++                method = ngx.HTTP_POST,
++                always_forward_body = true
++            })
++            ngx.print(res.body)
++        }
++    }
++
++    location /t {
++        content_by_lua_block {
++            local req = [[
++GET /capture HTTP/1.1
++Host: test.com
++Content-Length: 57
++Transfer-Encoding: chunked
++
++0
++
++POST /capture HTTP/1.1
++Host: test.com
++Content-Length: 60
++
++POST /bar HTTP/1.1
++Host: test.com
++Content-Length: 5
++
++hello
++
++]]
++
++            local sock = ngx.socket.tcp()
++            sock:settimeout(1000)
++
++            local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT)
++            if not ok then
++                ngx.say("failed to connect: ", err)
++                return
++            end
++
++            local bytes, err = sock:send(req)
++            if not bytes then
++                ngx.say("failed to send req: ", err)
++                return
++            end
++
++            ngx.say("req bytes: ", bytes)
++
++            local n_resp = 0
++
++            local reader = sock:receiveuntil("\r\n")
++            while true do
++                local line, err = reader()
++                if line then
++                    ngx.say(line)
++                    if line == "0" then
++                        n_resp = n_resp + 1
++                    end
++
++                    if n_resp >= 2 then
++                        break
++                    end
++
++                else
++                    ngx.say("err: ", err)
++                    break
++                end
++            end
++
++            sock:close()
++        }
++    }
++--- request
++GET /t
++--- response_body
++req bytes: 205
++HTTP/1.1 200 OK
++Server: nginx
++Content-Type: text/plain
++Transfer-Encoding: chunked
++Connection: keep-alive
++
++18
++method: POST, uri: /foo
++
++0
++
++HTTP/1.1 200 OK
++Server: nginx
++Content-Type: text/plain
++Transfer-Encoding: chunked
++Connection: keep-alive
++
++18
++method: POST, uri: /foo
++
++0
++--- no_error_log
++[error]
++
++
++
++=== TEST 80: avoid request smuggling 4/4 (POST capture w/ body + smuggle in body)
++--- http_config
++    upstream backend {
++        server unix:$TEST_NGINX_HTML_DIR/nginx.sock;
++        keepalive 32;
++    }
++
++    server {
++        listen unix:$TEST_NGINX_HTML_DIR/nginx.sock;
++
++        location / {
++            content_by_lua_block {
++                ngx.say("method: ", ngx.var.request_method,
++                        ", uri: ", ngx.var.uri)
++            }
++        }
++    }
++--- config
++    location /proxy {
++        proxy_http_version 1.1;
++        proxy_set_header   Connection "";
++        proxy_pass         http://backend/foo;
++    }
++
++    location /capture {
++        server_tokens off;
++        more_clear_headers Date;
++
++        content_by_lua_block {
++            ngx.req.read_body()
++            local res = ngx.location.capture("/proxy", {
++                method = ngx.HTTP_POST,
++                always_forward_body = true,
++                body = ngx.req.get_body_data()
++            })
++            ngx.print(res.body)
++        }
++    }
++
++    location /t {
++        content_by_lua_block {
++            local req = [[
++GET /capture HTTP/1.1
++Host: test.com
++Content-Length: 57
++Transfer-Encoding: chunked
++
++0
++
++POST /capture HTTP/1.1
++Host: test.com
++Content-Length: 60
++
++POST /bar HTTP/1.1
++Host: test.com
++Content-Length: 5
++
++hello
++
++]]
++
++            local sock = ngx.socket.tcp()
++            sock:settimeout(1000)
++
++            local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT)
++            if not ok then
++                ngx.say("failed to connect: ", err)
++                return
++            end
++
++            local bytes, err = sock:send(req)
++            if not bytes then
++                ngx.say("failed to send req: ", err)
++                return
++            end
++
++            ngx.say("req bytes: ", bytes)
++
++            local n_resp = 0
++
++            local reader = sock:receiveuntil("\r\n")
++            while true do
++                local line, err = reader()
++                if line then
++                    ngx.say(line)
++                    if line == "0" then
++                        n_resp = n_resp + 1
++                    end
++
++                    if n_resp >= 2 then
++                        break
++                    end
++
++                else
++                    ngx.say("err: ", err)
++                    break
++                end
++            end
++
++            sock:close()
++        }
++    }
++--- request
++GET /t
++--- response_body
++req bytes: 205
++HTTP/1.1 200 OK
++Server: nginx
++Content-Type: text/plain
++Transfer-Encoding: chunked
++Connection: keep-alive
++
++18
++method: POST, uri: /foo
++
++0
++
++HTTP/1.1 200 OK
++Server: nginx
++Content-Type: text/plain
++Transfer-Encoding: chunked
++Connection: keep-alive
++
++18
++method: POST, uri: /foo
++
++0
++--- no_error_log
++[error]
diff -Nru nginx-1.10.3/debian/modules/patches/nginx-lua/series nginx-1.10.3/debian/modules/patches/nginx-lua/series
--- nginx-1.10.3/debian/modules/patches/nginx-lua/series	2019-08-19 11:31:19.000000000 +0200
+++ nginx-1.10.3/debian/modules/patches/nginx-lua/series	2020-07-13 11:40:49.000000000 +0200
@@ -1 +1,2 @@
 openssl-1.1.0.patch
+CVE-2020-11724.patch


More information about the Pkg-nginx-maintainers mailing list