File CVE-2020-8287.patch of Package nodejs8.18412

commit fc70ce08f5818a286fb5899a1bc3aff5965a745e
Author: Fedor Indutny <fedor@indutny.com>
Date:   Wed Nov 18 20:50:21 2020 -0800

    http: unset `F_CHUNKED` on new `Transfer-Encoding`
    
    Duplicate `Transfer-Encoding` header should be a treated as a single,
    but with original header values concatenated with a comma separator. In
    the light of this, even if the past `Transfer-Encoding` ended with
    `chunked`, we should be not let the `F_CHUNKED` to leak into the next
    header, because mere presence of another header indicates that `chunked`
    is not the last transfer-encoding token.
    
    CVE-ID: CVE-2020-8287
    PR-URL: https://github.com/nodejs-private/node-private/pull/235
    Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>

commit aa6b97fb99d7528649fadb4c6a894e078fe4323c
Author: Richard Lau <rlau@redhat.com>
Date:   Thu Nov 26 15:50:56 2020 +0000

    http: add test for http transfer encoding smuggling
    
    Refs: https://github.com/nodejs-private/node-private/pull/228
    Refs: https://hackerone.com/bugs?report_id=1002188&subject=nodejs
    
    PR-URL: https://github.com/nodejs-private/node-private/pull/235
    Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>


Index: node-v8.17.0/test/parallel/test-http-transfer-encoding-smuggling.js
===================================================================
--- /dev/null
+++ node-v8.17.0/test/parallel/test-http-transfer-encoding-smuggling.js
@@ -0,0 +1,46 @@
+'use strict';
+
+const common = require('../common');
+
+const assert = require('assert');
+const http = require('http');
+const net = require('net');
+
+const msg = [
+  'POST / HTTP/1.1',
+  'Host: 127.0.0.1',
+  'Transfer-Encoding: chunked',
+  'Transfer-Encoding: chunked-false',
+  'Connection: upgrade',
+  '',
+  '1',
+  'A',
+  '0',
+  '',
+  'GET /flag HTTP/1.1',
+  'Host: 127.0.0.1',
+  '',
+  '',
+].join('\r\n');
+
+// Verify that the server is called only once even with a smuggled request.
+
+const server = http.createServer(common.mustCall((req, res) => {
+  res.end();
+}, 1));
+
+function send(next) {
+  const client = net.connect(server.address().port, 'localhost');
+  client.setEncoding('utf8');
+  client.on('error', common.mustNotCall());
+  client.on('end', next);
+  client.write(msg);
+  client.resume();
+}
+
+server.listen(0, common.mustCall((err) => {
+  assert.ifError(err);
+  send(common.mustCall(() => {
+    server.close();
+  }));
+}));
Index: node-v8.17.0/deps/http_parser/http_parser.c
===================================================================
--- node-v8.17.0.orig/deps/http_parser/http_parser.c
+++ node-v8.17.0/deps/http_parser/http_parser.c
@@ -1339,6 +1339,13 @@ reexecute:
               } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
                 parser->header_state = h_transfer_encoding;
                 parser->flags |= F_TRANSFER_ENCODING;
+
+                /* Multiple `Transfer-Encoding` headers should be treated as
+                 * one, but with values separate by a comma.
+                 *
+                 * See: https://tools.ietf.org/html/rfc7230#section-3.2.2
+                 */
+                parser->flags &= ~F_CHUNKED;
               }
               break;
 
Index: node-v8.17.0/deps/http_parser/test.c
===================================================================
--- node-v8.17.0.orig/deps/http_parser/test.c
+++ node-v8.17.0/deps/http_parser/test.c
@@ -2045,6 +2045,58 @@ const struct message responses[] =
   ,.body= "2\r\nOK\r\n0\r\n\r\n"
   ,.num_chunks_complete= 0
   }
+#define HTTP_200_DUPLICATE_TE_NOT_LAST_CHUNKED 30
+, {.name= "HTTP 200 response with `chunked` and duplicate Transfer-Encoding"
+  ,.type= HTTP_RESPONSE
+  ,.raw= "HTTP/1.1 200 OK\r\n"
+         "Transfer-Encoding: chunked\r\n"
+         "Transfer-Encoding: identity\r\n"
+         "\r\n"
+         "2\r\n"
+         "OK\r\n"
+         "0\r\n"
+         "\r\n"
+  ,.should_keep_alive= FALSE
+  ,.message_complete_on_eof= TRUE
+  ,.http_major= 1
+  ,.http_minor= 1
+  ,.status_code= 200
+  ,.response_status= "OK"
+  ,.content_length= -1
+  ,.num_headers= 2
+  ,.headers=
+    { { "Transfer-Encoding", "chunked" }
+    , { "Transfer-Encoding", "identity" }
+    }
+  ,.body= "2\r\nOK\r\n0\r\n\r\n"
+  ,.num_chunks_complete= 0
+  }
+#define HTTP_200_DUPLICATE_TE_NOT_LAST_CHUNKED 30
+, {.name= "HTTP 200 response with `chunked` and duplicate Transfer-Encoding"
+  ,.type= HTTP_RESPONSE
+  ,.raw= "HTTP/1.1 200 OK\r\n"
+         "Transfer-Encoding: chunked\r\n"
+         "Transfer-Encoding: identity\r\n"
+         "\r\n"
+         "2\r\n"
+         "OK\r\n"
+         "0\r\n"
+         "\r\n"
+  ,.should_keep_alive= FALSE
+  ,.message_complete_on_eof= TRUE
+  ,.http_major= 1
+  ,.http_minor= 1
+  ,.status_code= 200
+  ,.response_status= "OK"
+  ,.content_length= -1
+  ,.num_headers= 2
+  ,.headers=
+    { { "Transfer-Encoding", "chunked" }
+    , { "Transfer-Encoding", "identity" }
+    }
+  ,.body= "2\r\nOK\r\n0\r\n\r\n"
+  ,.num_chunks_complete= 0
+  }
 };
 
 /* strnlen() is a POSIX.2008 addition. Can't rely on it being available so
openSUSE Build Service is sponsored by