URL parsing / input validation

MEDIUM
nodejs/node
Commit: 81e05e124f71
Affected: Versions prior to 25.9.0 (e.g., 25.x before 25.9.0)
2026-04-05 10:57 UTC

Description

The commit replaces uses of the public/user-mutable URL.parse with the internal URLParse in core code paths that parse URLs from untrusted input (e.g., socketaddress.js and test runner mocks). It also adds an ESLint rule to enforce using URLParse instead of URL.parse. This hardens URL handling by avoiding reliance on the potentially mutable URL.parse API, reducing risk from input misparsing, normalization issues, or downstream logic vulnerabilities related to URL handling.

Commit Details

Author: Antoine du Hamel

Date: 2025-12-12 12:34 UTC

Message:

lib: enforce use of `URLParse` There's no reason to use the user-mutable `URL.parse` in core. PR-URL: https://github.com/nodejs/node/pull/61016 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Jacob Smith <jacob@frende.me> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: René <contact.9a5d6388@renegade334.me.uk> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Erick Wendel <erick.workspace@gmail.com> Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

Triage Assessment

Vulnerability Type: URL parsing / input validation

Confidence: MEDIUM

Reasoning:

The commit replaces uses of the potentially user-modifiable URL.parse with the internal URLParse to standardize URL handling and reduce risk from using a mutable global API. This reduces surface area for incorrect URL parsing of untrusted input, which can lead to security issues in downstream logic (e.g., input validation, path handling, or URL normalization). The changes include code paths where user input is parsed as URLs and an ESLint rule to enforce the safer API usage. Vulnerability type: URL parsing/input validation related (not a specific CVE, but an internal hardening of URL handling).

Verification Assessment

Vulnerability Type: URL parsing / input validation

Confidence: MEDIUM

Affected Versions: Versions prior to 25.9.0 (e.g., 25.x before 25.9.0)

Code Diff

diff --git a/lib/eslint.config_partial.mjs b/lib/eslint.config_partial.mjs index fc899bff694524..bb5b4d8cc7c980 100644 --- a/lib/eslint.config_partial.mjs +++ b/lib/eslint.config_partial.mjs @@ -30,6 +30,10 @@ const noRestrictedSyntax = [ selector: "CallExpression[callee.object.name='Error'][callee.property.name='captureStackTrace']", message: "Use 'hideStackFrames' from 'internal/errors' instead.", }, + { + selector: "CallExpression[callee.object.name='URL'][callee.property.name='parse']", + message: "Use 'URLParse' from 'internal/url' instead.", + }, { selector: "AssignmentExpression:matches([left.object.name='Error']):matches([left.name='prepareStackTrace'], [left.property.name='prepareStackTrace'])", message: "Use 'overrideStackTrace' from 'internal/errors' instead.", diff --git a/lib/internal/socketaddress.js b/lib/internal/socketaddress.js index 7fbe63980a0226..724ffd90cf77f1 100644 --- a/lib/internal/socketaddress.js +++ b/lib/internal/socketaddress.js @@ -37,7 +37,7 @@ const { kDeserialize, } = require('internal/worker/js_transferable'); -const { URL } = require('internal/url'); +const { URLParse } = require('internal/url'); const kHandle = Symbol('kHandle'); const kDetail = Symbol('kDetail'); @@ -156,7 +156,7 @@ class SocketAddress { const { hostname: address, port, - } = URL.parse(`http://${input}`); + } = URLParse(`http://${input}`); if (address.startsWith('[') && address.endsWith(']')) { return new SocketAddress({ address: address.slice(1, -1), diff --git a/lib/internal/test_runner/mock/mock.js b/lib/internal/test_runner/mock/mock.js index c018d1690fc9fb..1af24c77a10731 100644 --- a/lib/internal/test_runner/mock/mock.js +++ b/lib/internal/test_runner/mock/mock.js @@ -30,7 +30,7 @@ const { fileURLToPath, isURL, pathToFileURL, - URL, + URLParse, } = require('internal/url'); const { emitExperimentalWarning, @@ -652,7 +652,7 @@ class MockTracker { if (format) { // Format is not yet known for ambiguous files when detection is enabled. validateOneOf(format, 'format', kSupportedFormats); } - const baseURL = URL.parse(url); + const baseURL = URLParse(url); if (!baseURL) { throw new ERR_INVALID_ARG_VALUE(
← Back to Alerts View on GitHub →