Package: release.debian.org Severity: normal Tags: bullseye User: release.debian....@packages.debian.org Usertags: pu
[ Reason ] Regex Denial of Service (CVE-2021-3803) [ Impact ] Medium vulnerability [ Tests ] Test passed [ Risks ] Low risk, patch isn't so complicated and test passed [ Checklist ] [X] *all* changes are documented in the d/changelog [X] I reviewed all changes and I approve them [X] attach debdiff against the package in (old)stable [X] the issue is verified as fixed in unstable [ Changes ] Replace regex with hand-rolled parser Cheers, Yadd
diff --git a/debian/changelog b/debian/changelog index b80a144..e2e201b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +node-nth-check (2.0.0-1+deb11u1) bullseye; urgency=medium + + * Team upload + * Replace regex with hand-rolled parser (Closes: CVE-2021-3803) + + -- Yadd <y...@debian.org> Sat, 05 Feb 2022 12:42:20 +0100 + node-nth-check (2.0.0-1) unstable; urgency=medium * Team upload diff --git a/debian/patches/CVE-2021-3803.patch b/debian/patches/CVE-2021-3803.patch new file mode 100644 index 0000000..da4870c --- /dev/null +++ b/debian/patches/CVE-2021-3803.patch @@ -0,0 +1,107 @@ +Description: Replace regex with hand-rolled parser +Author: Felix Böhm <188768+f...@users.noreply.github.com> +Origin: upstream, https://patch-diff.githubusercontent.com/raw/fb55/nth-check/pull/9.patch +Bug: https://github.com/advisories/GHSA-rp65-9cf3-cjxr +Forwarded: not-needed +Reviewed-By: Yadd <y...@debian.org> +Last-Update: 2022-02-05 + +--- a/src/parse.ts ++++ b/src/parse.ts +@@ -1,7 +1,9 @@ + // Following http://www.w3.org/TR/css3-selectors/#nth-child-pseudo + +-// [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? +-const RE_NTH_ELEMENT = /^([+-]?\d*n)?\s*(?:([+-]?)\s*(\d+))?$/; ++// Whitespace as per https://www.w3.org/TR/selectors-3/#lex is " \t\r\n\f" ++const whitespace = new Set([9, 10, 12, 13, 32]); ++const ZERO = "0".charCodeAt(0); ++const NINE = "9".charCodeAt(0); + + /** + * Parses an expression. +@@ -19,24 +21,72 @@ + return [2, 1]; + } + +- const parsed = formula.match(RE_NTH_ELEMENT); ++ // Parse [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? + +- if (!parsed) { ++ let idx = 0; ++ ++ let a = 0; ++ let sign = readSign(); ++ let number = readNumber(); ++ ++ if (idx < formula.length && formula.charAt(idx) === "n") { ++ idx++; ++ a = sign * (number ?? 1); ++ ++ skipWhitespace(); ++ ++ if (idx < formula.length) { ++ sign = readSign(); ++ skipWhitespace(); ++ number = readNumber(); ++ } else { ++ sign = number = 0; ++ } ++ } ++ ++ // Throw if there is anything else ++ if (number === null || idx < formula.length) { + throw new Error(`n-th rule couldn't be parsed ('${formula}')`); + } + +- let a; ++ return [a, sign * number]; + +- if (parsed[1]) { +- a = parseInt(parsed[1], 10); +- if (isNaN(a)) { +- a = parsed[1].startsWith("-") ? -1 : 1; ++ function readSign() { ++ if (formula.charAt(idx) === "-") { ++ idx++; ++ return -1; + } +- } else a = 0; + +- const b = +- (parsed[2] === "-" ? -1 : 1) * +- (parsed[3] ? parseInt(parsed[3], 10) : 0); ++ if (formula.charAt(idx) === "+") { ++ idx++; ++ } ++ ++ return 1; ++ } + +- return [a, b]; ++ function readNumber() { ++ const start = idx; ++ let value = 0; ++ ++ while ( ++ idx < formula.length && ++ formula.charCodeAt(idx) >= ZERO && ++ formula.charCodeAt(idx) <= NINE ++ ) { ++ value = value * 10 + (formula.charCodeAt(idx) - ZERO); ++ idx++; ++ } ++ ++ // Return `null` if we didn't read anything. ++ return idx === start ? null : value; ++ } ++ ++ function skipWhitespace() { ++ while ( ++ idx < formula.length && ++ whitespace.has(formula.charCodeAt(idx)) ++ ) { ++ idx++; ++ } ++ } + } diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..4ac3e54 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1 @@ +CVE-2021-3803.patch