Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AUTO-CHERRYPICK] Patch Reaper for multiple CVEs - branch main #10735

Merged
merged 3 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions SPECS/reaper/CVE-2024-43799.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
From 6309d1f68103ef27c565cf58ab03f9ed32ff631c Mon Sep 17 00:00:00 2001
From: Rohit Rawat <[email protected]>
Date: Thu, 10 Oct 2024 13:44:09 +0000
Subject: [PATCH] CVE-2024-43799

from: https://github.com/pillarjs/send/commit/ae4f2989491b392ae2ef3b0015a019770ae65d35
---
send/index.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/ui/node_modules/send/index.js b/src/ui/node_modules/send/index.js
index 89afd7e5..768f8ca6 100644
--- a/src/ui/node_modules/send/index.js
+++ b/src/ui/node_modules/send/index.js
@@ -482,8 +482,7 @@ SendStream.prototype.redirect = function redirect (path) {
}

var loc = encodeUrl(collapseLeadingSlashes(this.path + '/'))
- var doc = createHtmlDocument('Redirecting', 'Redirecting to <a href="' + escapeHtml(loc) + '">' +
- escapeHtml(loc) + '</a>')
+ var doc = createHtmlDocument('Redirecting', 'Redirecting to ' + escapeHtml(loc))

// redirect
res.statusCode = 301
--
2.39.4

26 changes: 26 additions & 0 deletions SPECS/reaper/CVE-2024-43800.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
From cb67c9a152a1e2d8ffb3a74c504d4c9a845bf4dc Mon Sep 17 00:00:00 2001
From: Rohit Rawat <[email protected]>
Date: Mon, 14 Oct 2024 07:18:16 +0000
Subject: [PATCH] serve-static don't pass untrusted user input

---
serve-static/index.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/ui/node_modules/serve-static/index.js b/src/ui/node_modules/serve-static/index.js
index b7d3984c..3f3e64e9 100644
--- a/src/ui/node_modules/serve-static/index.js
+++ b/src/ui/node_modules/serve-static/index.js
@@ -195,8 +195,7 @@ function createRedirectDirectoryListener () {

// reformat the URL
var loc = encodeUrl(url.format(originalUrl))
- var doc = createHtmlDocument('Redirecting', 'Redirecting to <a href="' + escapeHtml(loc) + '">' +
- escapeHtml(loc) + '</a>')
+ var doc = createHtmlDocument('Redirecting', 'Redirecting to ' + escapeHtml(loc))

// send redirect response
res.statusCode = 301
--
2.39.4

190 changes: 190 additions & 0 deletions SPECS/reaper/CVE-2024-45296.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
From 6f1351c1c631d01ced7d2461c5eeee4552865306 Mon Sep 17 00:00:00 2001
From: Rohit Rawat <[email protected]>
Date: Thu, 10 Oct 2024 12:14:51 +0000
Subject: [PATCH] Upgrade path-to-regexp from 0.1.7 to 0.1.11

CVE-2024-45296 was fixed in https://github.com/pillarjs/path-to-regexp/pull/320
which was released in version 0.1.11
---
path-to-regexp/index.js | 103 ++++++++++++++++++++++++----------------
1 file changed, 62 insertions(+), 41 deletions(-)

diff --git a/src/ui/node_modules/path-to-regexp/index.js b/src/ui/node_modules/path-to-regexp/index.js
index 500d1dad..39b7caac 100644
--- a/src/ui/node_modules/path-to-regexp/index.js
+++ b/src/ui/node_modules/path-to-regexp/index.js
@@ -1,13 +1,13 @@
/**
- * Expose `pathtoRegexp`.
+ * Expose `pathToRegexp`.
*/

-module.exports = pathtoRegexp;
+module.exports = pathToRegexp;

/**
* Match matching groups in a regular expression.
*/
-var MATCHING_GROUP_REGEXP = /\((?!\?)/g;
+var MATCHING_GROUP_REGEXP = /\\.|\((?:\?<(.*?)>)?(?!\?)/g;

/**
* Normalize the given path string,
@@ -25,22 +25,27 @@ var MATCHING_GROUP_REGEXP = /\((?!\?)/g;
* @api private
*/

-function pathtoRegexp(path, keys, options) {
+function pathToRegexp(path, keys, options) {
options = options || {};
keys = keys || [];
var strict = options.strict;
var end = options.end !== false;
var flags = options.sensitive ? '' : 'i';
+ var lookahead = options.lookahead !== false;
var extraOffset = 0;
var keysOffset = keys.length;
var i = 0;
var name = 0;
+ var pos = 0;
+ var backtrack = '';
var m;

if (path instanceof RegExp) {
while (m = MATCHING_GROUP_REGEXP.exec(path.source)) {
+ if (m[0][0] === '\\') continue;
+
keys.push({
- name: name++,
+ name: m[1] || name++,
optional: false,
offset: m.index
});
@@ -54,20 +59,51 @@ function pathtoRegexp(path, keys, options) {
// the same keys and options instance into every generation to get
// consistent matching groups before we join the sources together.
path = path.map(function (value) {
- return pathtoRegexp(value, keys, options).source;
+ return pathToRegexp(value, keys, options).source;
});

- return new RegExp('(?:' + path.join('|') + ')', flags);
+ return new RegExp(path.join('|'), flags);
+ }
+
+ if (typeof path !== 'string') {
+ throw new TypeError('path must be a string, array of strings, or regular expression');
}

- path = ('^' + path + (strict ? '' : path[path.length - 1] === '/' ? '?' : '/?'))
- .replace(/\/\(/g, '/(?:')
- .replace(/([\/\.])/g, '\\$1')
- .replace(/(\\\/)?(\\\.)?:(\w+)(\(.*?\))?(\*)?(\?)?/g, function (match, slash, format, key, capture, star, optional, offset) {
+ path = path.replace(
+ /\\.|(\/)?(\.)?:(\w+)(\(.*?\))?(\*)?(\?)?|[.*]|\/\(/g,
+ function (match, slash, format, key, capture, star, optional, offset) {
+ pos = offset + match.length;
+
+ if (match[0] === '\\') {
+ backtrack += match;
+ return match;
+ }
+
+ if (match === '.') {
+ backtrack += '\\.';
+ extraOffset += 1;
+ return '\\.';
+ }
+
+ backtrack = slash || format ? '' : path.slice(pos, offset);
+
+ if (match === '*') {
+ extraOffset += 3;
+ return '(.*)';
+ }
+
+ if (match === '/(') {
+ backtrack += '/';
+ extraOffset += 2;
+ return '/(?:';
+ }
+
slash = slash || '';
- format = format || '';
- capture = capture || '([^\\/' + format + ']+?)';
+ format = format ? '\\.' : '';
optional = optional || '';
+ capture = capture ?
+ capture.replace(/\\.|\*/, function (m) { return m === '*' ? '(.*)' : m; }) :
+ (backtrack ? '((?:(?!/|' + backtrack + ').)+?)' : '([^/' + format + ']+?)');

keys.push({
name: key,
@@ -75,41 +111,20 @@ function pathtoRegexp(path, keys, options) {
offset: offset + extraOffset
});

- var result = ''
- + (optional ? '' : slash)
- + '(?:'
- + format + (optional ? slash : '') + capture
- + (star ? '((?:[\\/' + format + '].+?)?)' : '')
+ var result = '(?:'
+ + format + slash + capture
+ + (star ? '((?:[/' + format + '].+?)?)' : '')
+ ')'
+ optional;

extraOffset += result.length - match.length;

return result;
- })
- .replace(/\*/g, function (star, index) {
- var len = keys.length
-
- while (len-- > keysOffset && keys[len].offset > index) {
- keys[len].offset += 3; // Replacement length minus asterisk length.
- }
-
- return '(.*)';
});

// This is a workaround for handling unnamed matching groups.
while (m = MATCHING_GROUP_REGEXP.exec(path)) {
- var escapeCount = 0;
- var index = m.index;
-
- while (path.charAt(--index) === '\\') {
- escapeCount++;
- }
-
- // It's possible to escape the bracket.
- if (escapeCount % 2 === 1) {
- continue;
- }
+ if (m[0][0] === '\\') continue;

if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) {
keys.splice(keysOffset + i, 0, {
@@ -122,8 +137,14 @@ function pathtoRegexp(path, keys, options) {
i++;
}

+ path += strict ? '' : path[path.length - 1] === '/' ? '?' : '/?';
+
// If the path is non-ending, match until the end or a slash.
- path += (end ? '$' : (path[path.length - 1] === '/' ? '' : '(?=\\/|$)'));
+ if (end) {
+ path += '$';
+ } else if (path[path.length - 1] !== '/') {
+ path += lookahead ? '(?=/|$)' : '(?:/|$)';
+ }

- return new RegExp(path, flags);
-};
+ return new RegExp('^' + path, flags);
+};
\ No newline at end of file
--
2.39.4

116 changes: 116 additions & 0 deletions SPECS/reaper/CVE-2024-47764.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
From 9ca5ddf291fcd82a34925e1584bb7356a554fbe3 Mon Sep 17 00:00:00 2001
From: Rohit Rawat <[email protected]>
Date: Mon, 14 Oct 2024 09:44:29 +0000
Subject: [PATCH] narrow the validation cookies to match RFC6265

---
cookie/index.js | 64 ++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 55 insertions(+), 9 deletions(-)

diff --git a/src/ui/node_modules/cookie/index.js b/src/ui/node_modules/cookie/index.js
index 03d4c386..5e8c805d 100644
--- a/src/ui/node_modules/cookie/index.js
+++ b/src/ui/node_modules/cookie/index.js
@@ -23,14 +23,60 @@ exports.serialize = serialize;
var __toString = Object.prototype.toString

/**
- * RegExp to match field-content in RFC 7230 sec 3.2
+ * RegExp to match cookie-name in RFC 6265 sec 4.1.1
+ * This refers out to the obsoleted definition of token in RFC 2616 sec 2.2
+ * which has been replaced by the token definition in RFC 7230 appendix B.
*
- * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
- * field-vchar = VCHAR / obs-text
- * obs-text = %x80-FF
+ * cookie-name = token
+ * token = 1*tchar
+ * tchar = "!" / "#" / "$" / "%" / "&" / "'" /
+ * "*" / "+" / "-" / "." / "^" / "_" /
+ * "`" / "|" / "~" / DIGIT / ALPHA
*/

-var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
+var cookieNameRegExp = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
+
+/**
+ * RegExp to match cookie-value in RFC 6265 sec 4.1.1
+ *
+ * cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
+ * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
+ * ; US-ASCII characters excluding CTLs,
+ * ; whitespace DQUOTE, comma, semicolon,
+ * ; and backslash
+ */
+
+var cookieValueRegExp = /^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/;
+
+/**
+ * RegExp to match domain-value in RFC 6265 sec 4.1.1
+ *
+ * domain-value = <subdomain>
+ * ; defined in [RFC1034], Section 3.5, as
+ * ; enhanced by [RFC1123], Section 2.1
+ * <subdomain> = <label> | <subdomain> "." <label>
+ * <label> = <let-dig> [ [ <ldh-str> ] <let-dig> ]
+ * Labels must be 63 characters or less.
+ * 'let-dig' not 'letter' in the first char, per RFC1123
+ * <ldh-str> = <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+ * <let-dig-hyp> = <let-dig> | "-"
+ * <let-dig> = <letter> | <digit>
+ * <letter> = any one of the 52 alphabetic characters A through Z in
+ * upper case and a through z in lower case
+ * <digit> = any one of the ten digits 0 through 9
+ */
+
+var domainValueRegExp = /^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;
+
+/**
+ * RegExp to match path-value in RFC 6265 sec 4.1.1
+ *
+ * path-value = <any CHAR except CTLs or ";">
+ * CHAR = %x01-7F
+ * ; defined in RFC 5234 appendix B.1
+ */
+
+var pathValueRegExp = /^[\u0020-\u003A\u003D-\u007E]*$/;

/**
* Parse a cookie header.
@@ -116,13 +162,13 @@ function serialize(name, val, options) {
throw new TypeError('option encode is invalid');
}

- if (!fieldContentRegExp.test(name)) {
+ if (!cookieNameRegExp.test(name)) {
throw new TypeError('argument name is invalid');
}

var value = enc(val);

- if (value && !fieldContentRegExp.test(value)) {
+ if (value && !cookieValueRegExp.test(value)) {
throw new TypeError('argument val is invalid');
}

@@ -139,7 +185,7 @@ function serialize(name, val, options) {
}

if (opt.domain) {
- if (!fieldContentRegExp.test(opt.domain)) {
+ if (!domainValueRegExp.test(opt.domain)) {
throw new TypeError('option domain is invalid');
}

@@ -147,7 +193,7 @@ function serialize(name, val, options) {
}

if (opt.path) {
- if (!fieldContentRegExp.test(opt.path)) {
+ if (!pathValueRegExp.test(opt.path)) {
throw new TypeError('option path is invalid');
}

--
2.39.4

23 changes: 23 additions & 0 deletions SPECS/reaper/CVE-2024-48949.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
From 7ac5360118f74eb02da73bdf9f24fd0c72ff5281 Mon Sep 17 00:00:00 2001
From: Markus-MS <[email protected]>
Date: Tue, 16 Jul 2024 22:22:53 -0400
Subject: [PATCH] Merge commit from fork

---
lib/elliptic/eddsa/index.js | 3 +++
1 file changed, 3 insertions(+)

diff --git a/src/ui/node_modules/elliptic/lib/elliptic/eddsa/index.js b/src/ui/node_modules/elliptic/lib/elliptic/eddsa/index.js
index d777983..cb703a7 100644
--- a/src/ui/node_modules/elliptic/lib/elliptic/eddsa/index.js
+++ b/src/ui/node_modules/elliptic/lib/elliptic/eddsa/index.js
@@ -52,6 +52,9 @@ EDDSA.prototype.sign = function sign(message, secret) {
EDDSA.prototype.verify = function verify(message, sig, pub) {
message = parseBytes(message);
sig = this.makeSignature(sig);
+ if (sig.S().gte(sig.eddsa.curve.n) || sig.S().isNeg()) {
+ return false;
+ }
var key = this.keyFromPublic(pub);
var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
var SG = this.g.mul(sig.S());
Loading
Loading