Version in base suite: 1.0.7-1 Base version: node-eventsource_1.0.7-1 Target version: node-eventsource_1.0.7-1+deb11u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/n/node-eventsource/node-eventsource_1.0.7-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/n/node-eventsource/node-eventsource_1.0.7-1+deb11u1.dsc changelog | 8 ++ patches/CVE-2022-1650.patch | 159 ++++++++++++++++++++++++++++++++++++++++++++ patches/series | 1 3 files changed, 168 insertions(+) diff -Nru node-eventsource-1.0.7/debian/changelog node-eventsource-1.0.7/debian/changelog --- node-eventsource-1.0.7/debian/changelog 2020-10-06 14:48:12.000000000 +0000 +++ node-eventsource-1.0.7/debian/changelog 2022-05-13 09:13:54.000000000 +0000 @@ -1,3 +1,11 @@ +node-eventsource (1.0.7-1+deb11u1) bullseye; urgency=medium + + * Team upload + * Strip sensitive headers on redirect to different origin + (Closes: CVE-2022-1650) + + -- Yadd Fri, 13 May 2022 11:13:54 +0200 + node-eventsource (1.0.7-1) unstable; urgency=medium * Team upload diff -Nru node-eventsource-1.0.7/debian/patches/CVE-2022-1650.patch node-eventsource-1.0.7/debian/patches/CVE-2022-1650.patch --- node-eventsource-1.0.7/debian/patches/CVE-2022-1650.patch 1970-01-01 00:00:00.000000000 +0000 +++ node-eventsource-1.0.7/debian/patches/CVE-2022-1650.patch 2022-05-13 09:13:54.000000000 +0000 @@ -0,0 +1,159 @@ +Description: Strip sensitive headers on redirect to different origin +Author: Espen Hovlandsdal +Origin: upstream, https://github.com/EventSource/eventsource/commit/f9f64165 +Bug: https://huntr.dev/bounties/dc9e467f-be5d-4945-867d-1044d27e9b8e/ +Forwarded: not-needed +Reviewed-By: +Last-Update: 2022-05-13 + +--- a/lib/eventsource.js ++++ b/lib/eventsource.js +@@ -31,6 +31,8 @@ + **/ + function EventSource (url, eventSourceInitDict) { + var readyState = EventSource.CONNECTING ++ var headers = eventSourceInitDict && eventSourceInitDict.headers ++ var hasNewOrigin = false + Object.defineProperty(this, 'readyState', { + get: function () { + return readyState +@@ -51,11 +53,12 @@ + readyState = EventSource.CONNECTING + _emit('error', new Event('error', {message: message})) + +- // The url may have been changed by a temporary +- // redirect. If that's the case, revert it now. ++ // The url may have been changed by a temporary redirect. If that's the case, ++ // revert it now, and flag that we are no longer pointing to a new origin + if (reconnectUrl) { + url = reconnectUrl + reconnectUrl = null ++ hasNewOrigin = false + } + setTimeout(function () { + if (readyState !== EventSource.CONNECTING) { +@@ -67,9 +70,9 @@ + + var req + var lastEventId = '' +- if (eventSourceInitDict && eventSourceInitDict.headers && eventSourceInitDict.headers['Last-Event-ID']) { +- lastEventId = eventSourceInitDict.headers['Last-Event-ID'] +- delete eventSourceInitDict.headers['Last-Event-ID'] ++ if (headers && headers['Last-Event-ID']) { ++ lastEventId = headers['Last-Event-ID'] ++ delete headers['Last-Event-ID'] + } + + var discardTrailingNewline = false +@@ -83,9 +86,10 @@ + var isSecure = options.protocol === 'https:' + options.headers = { 'Cache-Control': 'no-cache', 'Accept': 'text/event-stream' } + if (lastEventId) options.headers['Last-Event-ID'] = lastEventId +- if (eventSourceInitDict && eventSourceInitDict.headers) { +- for (var i in eventSourceInitDict.headers) { +- var header = eventSourceInitDict.headers[i] ++ if (headers) { ++ var reqHeaders = hasNewOrigin ? removeUnsafeHeaders(headers) : headers ++ for (var i in reqHeaders) { ++ var header = reqHeaders[i] + if (header) { + options.headers[i] = header + } +@@ -139,14 +143,18 @@ + } + + // Handle HTTP redirects +- if (res.statusCode === 301 || res.statusCode === 307) { +- if (!res.headers.location) { ++ if (res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 307) { ++ var location = res.headers.location ++ if (!location) { + // Server sent redirect response without Location header. + _emit('error', new Event('error', {status: res.statusCode, message: res.statusMessage})) + return + } ++ var prevOrigin = original(url) ++ var nextOrigin = original(location) ++ hasNewOrigin = prevOrigin !== nextOrigin + if (res.statusCode === 307) reconnectUrl = url +- url = res.headers.location ++ url = location + process.nextTick(connect) + return + } +@@ -428,3 +436,23 @@ + } + } + } ++ ++/** ++ * Returns a new object of headers that does not include any authorization and cookie headers ++ * ++ * @param {Object} headers An object of headers ({[headerName]: headerValue}) ++ * @return {Object} a new object of headers ++ * @api private ++ */ ++function removeUnsafeHeaders (headers) { ++ var safe = {} ++ for (var key in headers) { ++ if (/^(cookie|authorization)$/i.test(key)) { ++ continue ++ } ++ ++ safe[key] = headers[key] ++ } ++ ++ return safe ++} +--- a/test/eventsource_test.js ++++ b/test/eventsource_test.js +@@ -559,6 +559,49 @@ + }) + }) + ++ it('follows http ' + status + ' redirects, drops sensitive headers on origin change', function (done) { ++ var redirectSuffix = '/foobar' ++ var clientRequestedRedirectUrl = false ++ var receivedHeaders = {} ++ createServer(function (err, server) { ++ if (err) return done(err) ++ ++ var newServerUrl = server.url.replace('http://localhost', 'http://127.0.0.1') ++ ++ server.on('request', function (req, res) { ++ if (req.url === '/') { ++ res.writeHead(status, { ++ 'Connection': 'Close', ++ 'Location': newServerUrl + redirectSuffix ++ }) ++ res.end() ++ } else if (req.url === redirectSuffix) { ++ clientRequestedRedirectUrl = true ++ receivedHeaders = req.headers ++ res.writeHead(200, {'Content-Type': 'text/event-stream'}) ++ res.end() ++ } ++ }) ++ ++ var es = new EventSource(server.url, { ++ headers: { ++ keep: 'me', ++ authorization: 'Bearer someToken', ++ cookie: 'some-cookie=yep' ++ } ++ }) ++ ++ es.onopen = function () { ++ assert.ok(clientRequestedRedirectUrl) ++ assert.equal(newServerUrl + redirectSuffix, es.url) ++ assert.equal(receivedHeaders.keep, 'me', 'safe header no longer present') ++ assert.equal(typeof receivedHeaders.authorization, 'undefined', 'authorization header still present') ++ assert.equal(typeof receivedHeaders.cookie, 'undefined', 'cookie header still present') ++ server.close(done) ++ } ++ }) ++ }) ++ + it('causes error event when response is ' + status + ' with missing location', function (done) { + createServer(function (err, server) { + if (err) return done(err) diff -Nru node-eventsource-1.0.7/debian/patches/series node-eventsource-1.0.7/debian/patches/series --- node-eventsource-1.0.7/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ node-eventsource-1.0.7/debian/patches/series 2022-05-13 09:13:54.000000000 +0000 @@ -0,0 +1 @@ +CVE-2022-1650.patch