fix: replace deprecated url.parse() with WHATWG URL API#2081
fix: replace deprecated url.parse() with WHATWG URL API#2081roli-lpci wants to merge 3 commits intoredis:mainfrom
Conversation
Replace the deprecated Node.js `url.parse()` with the standard WHATWG
`new URL()` API in the `parseURL` function, resolving the DEP0169
deprecation warning about security implications.
Key changes:
- Remove `import { parse as urllibParse } from "url"`
- Use `new URL()` with a dummy `redis://` protocol prefix for URLs
without a scheme (e.g. "127.0.0.1:6379")
- Handle Unix socket paths (starting with "/") as an early return since
they are not valid URLs for the WHATWG parser
- Replace `.slashes` check (not available on WHATWG URL) with explicit
protocol detection via `startsWith("redis://")` / `startsWith("rediss://")`
- Replace `.auth` with `.username` / `.password`, adding
`decodeURIComponent()` since WHATWG URL percent-encodes special
characters (e.g. colons in passwords)
- Replace `.query` object with `searchParams` iterated into a plain object
- Use `.hostname` directly instead of `.host` (avoids port-in-host issues)
Fixes redis#1747
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ackets Address three edge cases in the url.parse() → new URL() migration: 1. Password-only auth (redis://:password@host) - WHATWG URL returns empty username (falsy), so check both username and password before extracting credentials. This is the default auth pattern for Redis 5 and below, AWS ElastiCache, and most managed Redis services. 2. Unix socket paths with query params (/tmp/redis.sock?db=2) - preserve query parameters instead of stripping them on early return. 3. IPv6 hostname brackets - WHATWG URL keeps brackets around IPv6 addresses ([::1]), strip them to match url.parse() behavior. Also removes dead urlStr alias variable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…wing The isInt() function's type guard (value is string) incorrectly narrows the url parameter to 'never' in the false branch since url is already typed as string. Use rawUrl alias to work around the narrowing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Hi, I’m Jit, a friendly security platform designed to help developers build secure applications from day zero with an MVS (Minimal viable security) mindset. In case there are security findings, they will be communicated to you as a comment inside the PR. Hope you’ll enjoy using Jit. Questions? Comments? Want to learn more? Get in touch with us. |
|
@roli-lpci , thanks for the PR, I’ll take a look when I get a chance. |
|
Quick note on the Node 24.x CI status — all 521 unit tests and 17 cluster tests pass on every Node version including 24.x. The only failing step is the Coveralls coverage upload, which hit a transient service outage (HTTP 530, DNS error 1016). Not related to the URL changes in this PR. |
|
@copilot fix this make no mistakes |
|
@PavelPashov @roli-lpci I also worked on this and opened PR #2091, but I’ve closed it since this PR covers the same change. Happy to help if needed. |

Summary
Replaces the deprecated Node.js
url.parse()with the WHATWGURLAPI in theparseURLfunction, addressing #1747.url.parse()withnew URL()throughoutparseURL()redis://:password@host) correctly —decodeURIComponent()on both username and password/tmp/redis.sock?db=2)url.parse()behaviorhost:portstrings by prependingredis://protocol.slashescheck with explicitstartsWith("redis://")/startsWith("rediss://")Changes
lib/utils/index.ts: RewroteparseURLfunction (+35/-13 lines)import { parse as urllibParse } from "url"(URL is a global)Property mapping
url.parse()new URL().auth.username+.passworddecodeURIComponent()— WHATWG URL percent-encodes.hostname.hostname[]brackets for IPv6.port.port''instead ofnull(both falsy).pathname.pathnameredis://scheme.query.searchParamsforEach.slashesstartsWith()protocol checkTest plan
parseURLunit tests passRedisconstructor tests pass (including password-only auth)tsc --noEmit)