Skip to content
Open
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
12 changes: 12 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
node-webpack (5.76.1+dfsg1+~cs17.16.16-2) unstable; urgency=medium

* Fix CVE-2025-68157: HTTP(S) resolver enforces allowedUris only for the
initial URL, but does not re-validate allowedUris after following HTTP
30x redirects. This allows an import that appears restricted to a trusted
allow-list to be redirected to URLs outside the allow-list.
* Fix CVE-2025-68458: HTTP(S) resolver can be bypassed to fetch resources
from hosts outside allowedUris by using crafted URLs that include userinfo
(username:password@host).

-- deepin-ci-robot <packages@deepin.org> Fri, 09 May 2026 09:50:00 +0800

node-webpack (5.76.1+dfsg1+~cs17.16.16-1) unstable; urgency=medium

* Team upload
Expand Down
113 changes: 113 additions & 0 deletions debian/patches/CVE-2025-68157-68458.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
Index: node-webpack-cve-2025-68157-68458/lib/schemes/HttpUriPlugin.js
===================================================================
--- node-webpack-cve-2025-68157-68458.orig/lib/schemes/HttpUriPlugin.js
+++ node-webpack-cve-2025-68157-68458/lib/schemes/HttpUriPlugin.js
@@ -20,6 +20,8 @@ const memoize = require("../util/memoize

const getHttp = memoize(() => require("http"));
const getHttps = memoize(() => require("https"));
+
+const MAX_REDIRECTS = 5;
const proxyFetch = (request, proxy) => (url, options, callback) => {
const eventEmitter = new EventEmitter();
const doRequest = socket =>
@@ -147,6 +149,20 @@ const areLockfileEntriesEqual = (a, b) =
);
};

+
+/**
+ * Sanitize URL for inclusion in error messages
+ * @param {string} href URL string to sanitize
+ * @returns {string} sanitized URL text for logs/errors
+ */
+const sanitizeUrlForError = href => {
+ try {
+ const u = new URL(href);
+ return `${u.protocol}//${u.host}`;
+ } catch (_err) {
+ return String(href).slice(0, 200).replace(/[\r\n]/g, "");
+ }
+};
const entryToString = entry => {
return `resolved: ${entry.resolved}, integrity: ${entry.integrity}, contentType: ${entry.contentType}`;
};
@@ -511,9 +527,28 @@ class HttpUriPlugin {
const resolveContent = (url, integrity, callback) => {
const handleResult = (err, result) => {
if (err) return callback(err);
- if ("location" in result) {
+ if ("location" in result) {
+ // CVE-2025-68157: Validate redirect URL against allowedUris
+ let nextUrl;
+ try {
+ nextUrl = new URL(result.location, url);
+ } catch (_err) {
+ return callback(new Error(
+ `Invalid redirect URL: ${sanitizeUrlForError(result.location)}`
+ ));
+ }
+ if (nextUrl.protocol !== "http:" && nextUrl.protocol !== "https:") {
+ return callback(new Error(
+ `Redirected URL uses disallowed protocol: ${sanitizeUrlForError(nextUrl.href)}`
+ ));
+ }
+ if (!isAllowed(nextUrl.href)) {
+ return callback(new Error(
+ `${nextUrl.href} doesn't match the allowedUris policy after redirect. These URIs are allowed:\n${allowedUris.map(uri => ` - ${uri}`).join("\n")}`
+ ));
+ }
return resolveContent(
- result.location,
+ nextUrl.href,
integrity,
(err, innerResult) => {
if (err) return callback(err);
@@ -525,7 +560,6 @@ class HttpUriPlugin {
}
);
} else {
- if (
!result.fresh &&
integrity &&
result.entry.integrity !== integrity &&
@@ -739,19 +773,34 @@ class HttpUriPlugin {
(url, callback) => fetchContentRaw(url, undefined, callback)
);

- const isAllowed = uri => {
+ const isAllowed = uri => {
+ let parsedUri;
+ try {
+ // Parse the URI to prevent userinfo bypass attacks
+ // (e.g., http://allowed@malicious/path where @malicious is the actual host)
+ parsedUri = new URL(uri);
+ } catch (_err) {
+ return false;
+ }
for (const allowed of allowedUris) {
if (typeof allowed === "string") {
- if (uri.startsWith(allowed)) return true;
+ let parsedAllowed;
+ try {
+ parsedAllowed = new URL(allowed);
+ } catch (_err) {
+ continue;
+ }
+ if (parsedUri.href.startsWith(parsedAllowed.href)) {
+ return true;
+ }
} else if (typeof allowed === "function") {
- if (allowed(uri)) return true;
+ if (allowed(parsedUri.href)) return true;
} else {
- if (allowed.test(uri)) return true;
+ if (allowed.test(parsedUri.href)) return true;
}
}
return false;
};
-
const getInfo = cachedWithKey(
/**
* @param {string} url the url
1 change: 1 addition & 0 deletions debian/patches/series
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
CVE-2025-68157-68458.patch
update-importing-eslint-scope.patch
dont-require-wast-loader.patch
webpack-cli-path.patch
Expand Down
Loading