Version in base suite: 1.7.4+~1.7.1-1+deb13u1 Base version: node-shell-quote_1.7.4+~1.7.1-1+deb13u1 Target version: node-shell-quote_1.7.4+~1.7.1-1+deb13u2 Base file: /srv/ftp-master.debian.org/ftp/pool/main/n/node-shell-quote/node-shell-quote_1.7.4+~1.7.1-1+deb13u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/n/node-shell-quote/node-shell-quote_1.7.4+~1.7.1-1+deb13u2.dsc changelog | 9 ++++ patches/CVE-2026-102422.patch | 83 ++++++++++++++++++++++++++++++++++++++++++ patches/CVE-2026-13311.patch | 80 ++++++++++++++++++++++++++++++++++++++++ patches/series | 2 + 4 files changed, 174 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpvcgrgluk/node-shell-quote_1.7.4+~1.7.1-1+deb13u1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpvcgrgluk/node-shell-quote_1.7.4+~1.7.1-1+deb13u2.dsc: no acceptable signature found diff -Nru node-shell-quote-1.7.4+~1.7.1/debian/changelog node-shell-quote-1.7.4+~1.7.1/debian/changelog --- node-shell-quote-1.7.4+~1.7.1/debian/changelog 2026-05-23 09:56:08.000000000 +0000 +++ node-shell-quote-1.7.4+~1.7.1/debian/changelog 2026-10-06 09:29:23.000000000 +0000 @@ -1,3 +1,12 @@ +node-shell-quote (1.7.4+~1.7.1-1+deb13u2) trixie-security; urgency=medium + + * Team upload + * Reject line terminators in tokens after a comment + (Closes: #1149713, CVE-2026-102422) + * Finalize parse tokens in linear time (Closes: #1140921, CVE-2026-13311) + + -- Xavier Guimard Tue, 06 Oct 2026 11:29:23 +0200 + node-shell-quote (1.7.4+~1.7.1-1+deb13u1) trixie-security; urgency=medium * Team upload diff -Nru node-shell-quote-1.7.4+~1.7.1/debian/patches/CVE-2026-102422.patch node-shell-quote-1.7.4+~1.7.1/debian/patches/CVE-2026-102422.patch --- node-shell-quote-1.7.4+~1.7.1/debian/patches/CVE-2026-102422.patch 1970-01-01 00:00:00.000000000 +0000 +++ node-shell-quote-1.7.4+~1.7.1/debian/patches/CVE-2026-102422.patch 2026-10-05 12:56:52.000000000 +0000 @@ -0,0 +1,83 @@ +Description: reject line terminators in tokens after a comment +Author: Jordan Harband +Origin: upstream, https://github.com/ljharb/shell-quote/commit/6002b2ed +Bug: https://www.cve.org/CVERecord?id=CVE-2026-102422 +Bug-Debian: https://bugs.debian.org/1149713 +Forwarded: not-needed +Applied-Upstream: 1.12.0, commit:6002b2ed +Reviewed-By: Xavier Guimard + +--- a/README.md ++++ b/README.md +@@ -111,8 +111,9 @@ + `parse` emits: `{ op }` (where `op` is one of the control operators + `||`, `&&`, `;;`, `|&`, `<(`, `<<<`, `>>`, `>&`, `<&`, `&`, `;`, `(`, + `)`, `|`, `<`, `>`), `{ op: 'glob', pattern }`, or `{ comment }`. Any +-other object shape, an unrecognized `op`, or a `pattern`/`comment` +-containing line terminators throws a `TypeError`. ++other object shape, an unrecognized `op`, a `pattern`/`comment` ++containing line terminators, or a string containing line terminators ++anywhere after a `{ comment }` throws a `TypeError`. + + ## parse(cmd, env={}) + +--- a/index.js ++++ b/index.js +@@ -22,7 +22,11 @@ + var GLOB_SHELL_SPECIAL = /[\s#!"$&'():;<=>@\\^`|]/g; + + exports.quote = function (xs) { ++ var sawComment = false; + return xs.map(function (s) { ++ if (sawComment && typeof s === 'string' && LINE_TERMINATORS.test(s)) { ++ throw new TypeError('a token after a `comment` must not contain line terminators'); ++ } + if (s && typeof s === 'object') { + if (s.op === 'glob') { + if (typeof s.pattern !== 'string') { +@@ -43,6 +47,7 @@ + if (LINE_TERMINATORS.test(s.comment)) { + throw new TypeError('`comment` must not contain line terminators'); + } ++ sawComment = true; + return '#' + s.comment; + } + throw new TypeError('unrecognized object token shape'); +--- a/test/quote.js ++++ b/test/quote.js +@@ -2,6 +2,7 @@ + + var test = require('tape'); + var quote = require('../').quote; ++var parse = require('../').parse; + + test('quote', function (t) { + t.equal(quote(['a', 'b', 'c d']), 'a b \'c d\''); +@@ -98,6 +99,27 @@ + t.end(); + }); + ++test('quote comment: rejects line terminators in later tokens', function (t) { ++ t['throws'](function () { quote(['echo', { comment: 'x' }, 'a\nid;#']); }, TypeError, 'newline after a comment'); ++ t['throws'](function () { quote(['echo', { comment: 'x' }, 'a\rb']); }, TypeError, 'CR after a comment'); ++ t['throws'](function () { quote(['echo', { comment: 'x' }, 'a\u2028b']); }, TypeError, 'U+2028 after a comment'); ++ t['throws'](function () { quote(['echo', { comment: 'x' }, 'a\u2029b']); }, TypeError, 'U+2029 after a comment'); ++ t['throws']( ++ function () { quote(['echo', { comment: 'x' }, 'ok', 'it\'s\nid;#']); }, ++ TypeError, ++ 'newline in any later token, not just the next one' ++ ); ++ t['throws']( ++ function () { quote(parse('curl http://x/#frag').concat('a\nid;#')); }, ++ TypeError, ++ 'a mid-word `#` from parse, followed by an appended token' ++ ); ++ ++ t.equal(quote(['echo', 'a\nb', { comment: 'x' }]), 'echo \'a\nb\' #x', 'a line terminator before a comment is fine'); ++ t.equal(quote(['echo', { comment: 'x' }, 'y']), 'echo #x y', 'later tokens without line terminators are unchanged'); ++ t.end(); ++}); ++ + test('quote rejects unrecognized object shapes', function (t) { + t['throws'](function () { quote([{}]); }, TypeError, 'empty object'); + t['throws'](function () { quote([{ foo: 'bar' }]); }, TypeError, 'unknown key'); diff -Nru node-shell-quote-1.7.4+~1.7.1/debian/patches/CVE-2026-13311.patch node-shell-quote-1.7.4+~1.7.1/debian/patches/CVE-2026-13311.patch --- node-shell-quote-1.7.4+~1.7.1/debian/patches/CVE-2026-13311.patch 1970-01-01 00:00:00.000000000 +0000 +++ node-shell-quote-1.7.4+~1.7.1/debian/patches/CVE-2026-13311.patch 2026-10-05 12:56:56.000000000 +0000 @@ -0,0 +1,80 @@ +Description: `parse`: finalize tokens in linear time + The two finalizing reduces used `prev.concat(arg)` as the accumulator, + reallocating and copying the whole array each iteration, so `parse()` ran + in O(n²) in the token count: a small (~128 KB) input could block the event + loop for tens of seconds (CWE-407 DoS). + Push into the accumulator instead. +Author: Jordan Harband +Origin: upstream, https://github.com/ljharb/shell-quote/commit/7ff54885 +Bug: https://github.com/ljharb/shell-quote/security/advisories/GHSA-395f-4hp3-45gv +Bug-Debian: https://bugs.debian.org/1140921 +Forwarded: not-needed +Applied-Upstream: 1.9.0, commit:7ff54885 +Reviewed-By: Xavier Guimard +Last-Update: 2026-10-05 + +--- a/index.js ++++ b/index.js +@@ -223,7 +223,10 @@ + if (arg === undefined) { + return prev; + } +- return prev.concat(arg); ++ [].concat(arg).forEach(function (entry) { ++ prev[prev.length] = entry; ++ }); ++ return prev; + }, []); + } + +@@ -234,17 +237,19 @@ + } + return mapped.reduce(function (acc, s) { + if (typeof s === 'object') { +- return acc.concat(s); ++ acc[acc.length] = s; ++ return acc; + } + var xs = s.split(RegExp('(' + TOKEN + '.*?' + TOKEN + ')', 'g')); + if (xs.length === 1) { +- return acc.concat(xs[0]); ++ acc[acc.length] = xs[0]; ++ return acc; + } +- return acc.concat(xs.filter(Boolean).map(function (x) { +- if (RegExp('^' + TOKEN).test(x)) { +- return JSON.parse(x.split(TOKEN)[1]); +- } +- return x; +- })); ++ xs.filter(Boolean).forEach(function (x) { ++ acc[acc.length] = RegExp('^' + TOKEN).test(x) ++ ? JSON.parse(x.split(TOKEN)[1]) ++ : x; ++ }); ++ return acc; + }, []); + }; +--- a/test/parse.js ++++ b/test/parse.js +@@ -23,3 +23,20 @@ + + t.end(); + }); ++ ++test('parse stays linear in token count (GHSA-395f-4hp3-45gv)', function (t) { ++ // the old concat-in-reduce finalizer was O(n^2): this many tokens took ++ // ~minutes, so under the unfixed code this test hangs rather than passes ++ var n = 2e5; ++ var input = new Array(n + 1).join('x '); // avoid String#repeat for old engines ++ ++ var words = parse(input); ++ t.equal(words.length, n, 'every token is returned'); ++ t.equal(words[0], 'x', 'first token is correct'); ++ t.equal(words[n - 1], 'x', 'last token is correct'); ++ ++ var withEnv = parse(input, function () { return 'v'; }); ++ t.equal(withEnv.length, n, 'env-function path returns every token'); ++ ++ t.end(); ++}); diff -Nru node-shell-quote-1.7.4+~1.7.1/debian/patches/series node-shell-quote-1.7.4+~1.7.1/debian/patches/series --- node-shell-quote-1.7.4+~1.7.1/debian/patches/series 2026-05-23 09:49:31.000000000 +0000 +++ node-shell-quote-1.7.4+~1.7.1/debian/patches/series 2026-10-05 12:56:56.000000000 +0000 @@ -1 +1,3 @@ CVE-2026-9277.patch +CVE-2026-102422.patch +CVE-2026-13311.patch