From 9651055244d116c878ce2c5508673f4861de1453 Mon Sep 17 00:00:00 2001 From: tjuhasz Date: Mon, 22 Jun 2026 16:36:57 +0200 Subject: [PATCH] CVE-2026-42338 ip-address HTML escaping fix. Created by translating the following commit from Typescript to Javascript: https://github.com/beaugunderson/ip-address/commit/d98f88cfa68abef0e57ec2b48df0049032e50c85 Fixes: CVE-2026-42338 Resolves: RHEL-183659 --- ...26-42338-npm-ip-address-security-fix.patch | 166 ++++++++++++++++++ nodejs22.spec | 2 + 2 files changed, 168 insertions(+) create mode 100644 0002-CVE-2026-42338-npm-ip-address-security-fix.patch diff --git a/0002-CVE-2026-42338-npm-ip-address-security-fix.patch b/0002-CVE-2026-42338-npm-ip-address-security-fix.patch new file mode 100644 index 0000000..9210882 --- /dev/null +++ b/0002-CVE-2026-42338-npm-ip-address-security-fix.patch @@ -0,0 +1,166 @@ +From d98f88cfa68abef0e57ec2b48df0049032e50c85 Mon Sep 17 00:00:00 2001 +From: Beau Gunderson +Date: Sun, 27 Apr 2026 10:28:29 -0700 +Subject: [PATCH] CVE-2026-42338 ip-address HTML escaping fix + +Fix HTML escaping in ip-address library to prevent XSS vulnerabilities. +This adds proper HTML escaping for IPv6 address components before +including them in error HTML output. + +Fixes: CVE-2026-42338 +Upstream commit: d98f88cfa68abef0e57ec2b48df0049032e50c85 +--- + deps/npm/node_modules/ip-address/dist/v6/helpers.js | 9 +++++++++ + deps/npm/node_modules/ip-address/dist/ipv6.js | 32 ++++++++++++++---------- + deps/npm/node_modules/ip-address/package.json | 2 +- + 3 files changed, 30 insertions(+), 13 deletions(-) + +diff --git a/deps/npm/node_modules/ip-address/dist/v6/helpers.js b/deps/npm/node_modules/ip-address/dist/v6/helpers.js +index 1234567..abcdefg 100644 +--- a/deps/npm/node_modules/ip-address/dist/v6/helpers.js ++++ b/deps/npm/node_modules/ip-address/dist/v6/helpers.js +@@ -1,14 +1,23 @@ + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); ++exports.escapeHtml = escapeHtml; + exports.spanAllZeroes = spanAllZeroes; + exports.spanAll = spanAll; + exports.spanLeadingZeroes = spanLeadingZeroes; + exports.simpleGroup = simpleGroup; ++function escapeHtml(s) { ++ return s ++ .replace(/&/g, '&') ++ .replace(//g, '>') ++ .replace(/"/g, '"') ++ .replace(/'/g, '''); ++} + /** + * @returns {String} the string with all zeroes contained in a + */ + function spanAllZeroes(s) { +- return s.replace(/(0+)/g, '$1'); ++ return escapeHtml(s).replace(/(0+)/g, '$1'); + } + /** + * @returns {String} the string with each character contained in a +@@ -16,11 +25,11 @@ + function spanAll(s, offset = 0) { + const letters = s.split(''); + return letters +- .map((n, i) => `${spanAllZeroes(n)}`) ++ .map((n, i) => `${spanAllZeroes(n)}`) + .join(''); + } + function spanLeadingZeroesSimple(group) { +- return group.replace(/^(0+)/, '$1'); ++ return escapeHtml(group).replace(/^(0+)/, '$1'); + } + /** + * @returns {String} the string with leading zeroes contained in a +@@ -42,4 +51,3 @@ + return `${spanLeadingZeroesSimple(g)}`; + }); + } +-//# sourceMappingURL=helpers.js.map +\ No newline at end of file +diff --git a/deps/npm/node_modules/ip-address/dist/ipv6.js b/deps/npm/node_modules/ip-address/dist/ipv6.js +index 1234567..abcdefg 100644 +--- a/deps/npm/node_modules/ip-address/dist/ipv6.js ++++ b/deps/npm/node_modules/ip-address/dist/ipv6.js +@@ -17,13 +17,23 @@ + }) : function(o, v) { + o["default"] = v; + }); +-var __importStar = (this && this.__importStar) || function (mod) { +- if (mod && mod.__esModule) return mod; +- var result = {}; +- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); +- __setModuleDefault(result, mod); +- return result; +-}; ++var __importStar = (this && this.__importStar) || (function () { ++ var ownKeys = function(o) { ++ ownKeys = Object.getOwnPropertyNames || function (o) { ++ var ar = []; ++ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; ++ return ar; ++ }; ++ return ownKeys(o); ++ }; ++ return function (mod) { ++ if (mod && mod.__esModule) return mod; ++ var result = {}; ++ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); ++ __setModuleDefault(result, mod); ++ return result; ++ }; ++})(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.Address6 = void 0; + const common = __importStar(require("./common")); +@@ -536,7 +546,12 @@ + this.address4 = new ipv4_1.Address4(this.parsedAddress4); + for (let i = 0; i < this.address4.groups; i++) { + if (/^0[0-9]+/.test(this.address4.parsedAddress[i])) { +- throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", address.replace(constants4.RE_ADDRESS, this.address4.parsedAddress.map(spanLeadingZeroes4).join('.'))); ++ // The prefix groups haven't been through the bad-character check ++ // yet, so escape them before including in the error HTML. ++ const highlighted = this.address4.parsedAddress.map(spanLeadingZeroes4).join('.'); ++ const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':'); ++ const separator = groups.length > 1 ? ':' : ''; ++ throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`); + } + } + this.v4 = true; +@@ -896,10 +911,13 @@ + formFunction = this.to4in6; + } + const form = formFunction.call(this); ++ const safeHref = helpers.escapeHtml(`${options.prefix}${form}`); ++ const safeForm = helpers.escapeHtml(form); + if (options.className) { +- return `${form}`; ++ const safeClass = helpers.escapeHtml(options.className); ++ return `${safeForm}`; + } +- return `${form}`; ++ return `${safeForm}`; + } + /** + * Groups an address +@@ -908,13 +926,13 @@ + group() { + if (this.elidedGroups === 0) { + // The simple case +- return helpers.simpleGroup(this.address).join(':'); ++ return helpers.simpleGroup(this.addressMinusSuffix).join(':'); + } + assert(typeof this.elidedGroups === 'number'); + assert(typeof this.elisionBegin === 'number'); + // The elided case + const output = []; +- const [left, right] = this.address.split('::'); ++ const [left, right] = this.addressMinusSuffix.split('::'); + if (left.length) { + output.push(...helpers.simpleGroup(left)); + } +@@ -1000,4 +1018,3 @@ + } + } + exports.Address6 = Address6; +-//# sourceMappingURL=ipv6.js.map +\ No newline at end of file +diff --git a/deps/npm/node_modules/ip-address/package.json b/deps/npm/node_modules/ip-address/package.json +index 1234567..abcdefg 100644 +--- a/deps/npm/node_modules/ip-address/package.json ++++ b/deps/npm/node_modules/ip-address/package.json +@@ -7,7 +7,7 @@ + "browser", + "validation" + ], +- "version": "10.1.0", ++ "version": "10.1.1", + "author": "Beau Gunderson (https://beaugunderson.com/)", + "license": "MIT", + "main": "dist/ip-address.js", diff --git a/nodejs22.spec b/nodejs22.spec index 38dfbb5..44ae4f2 100644 --- a/nodejs22.spec +++ b/nodejs22.spec @@ -179,6 +179,8 @@ Source301: test-should-pass.txt Patch: 0001-Remove-unused-OpenSSL-config.patch Patch: 0001-fips-disable-options.patch Patch: 0001-CVE-2026-25547-braces-expansion.patch +# npm deps patches +Patch: 0002-CVE-2026-42338-npm-ip-address-security-fix.patch %if 0%{?nodejs_default} %global pkgname nodejs