Two High severity CVEs, eight Medium, two Low — the June 18 security releases patch 12 vulnerabilities across all three active Node.js release lines. Here's what each one means for your applications.
On June 18, 2026, the Node.js team shipped coordinated security releases across all three active release lines — v22.23.0 (LTS), v24.17.0 (LTS), and v26.3.1 (Current) — patching a total of 12 CVEs.
The release addresses two High severity vulnerabilities: a WebCrypto AES integer overflow that can remotely crash the process (CVE-2026-48933), and a TLS wildcard-depth authentication bypass exploiting Unicode dot separator hostname normalization mismatches (CVE-2026-48618). Eight Medium severity issues round out the core fixes, covering HTTP/2 memory exhaustion, proxy credential leaks, mTLS bypass vectors, and hostname rebinding attacks.
Additionally, four dependency updates bring important security patches: llhttp 9.4.2, nghttp2 1.69.0, openssl 3.5.7, and line-specific undici updates.
These are coordinated releases — Node.js follows a predictable security release cadence, typically every 3 months, with out-of-band releases for critical vulnerabilities. The high severity rating means you should prioritise this update within days, not weeks.
The patched versions for each release line are:
| Release Line | Status | Patched Version | undici |
|---|---|---|---|
| Node.js 22.x | Active LTS | v22.23.0 | 6.27.0 |
| Node.js 24.x | Active LTS | v24.17.0 | 7.28.0 |
| Node.js 26.x | Current | v26.3.1 | 8.5.0 |
Impact: A flaw in Node.js WebCrypto implementation can crash the process if
the input of subtle.encrypt() is a multiple of 2 GiB. The integer overflow occurs
in the internal AES encryption path when handling oversized buffers.
Attack vector: Any application that accepts user-controlled data and passes it
to crypto.subtle.encrypt() without a size check. A malicious request sending an
input of exactly 2,147,483,648 bytes (2 GiB) or more triggers an internal integer wrap,
resulting in a segmentation fault and process termination.
Affected: All supported release lines (22.x, 24.x, 26.x).
Reported by: erichen · Fixed by: Filip Skokan
Impact: The DNS resolver and the TLS certificate verifier in Node.js normalise hostnames differently when processing Unicode dot separators (U+3002 "." ideographic full stop, U+FF0E "." fullwidth full stop, and similar characters that normalize to "." in Unicode NFKC).
Attack vector: An attacker who controls a DNS zone can register a TLS certificate
for a hostname containing Unicode dot separators. The resolver interprets the separator as a
regular dot (changing the apparent domain hierarchy), while the certificate verifier sees the
raw character, bypassing wildcard-depth restrictions. For example, a certificate for
*.subdomain。example.com (with a U+3002 separator) might be accepted as valid
for subdomain.example.com traffic when it should not be.
Affected: All supported release lines (22.x, 24.x, 26.x).
Reported by: tmeletlidis · Fixed by: Matteo Collina
When proxy credentials are embedded in the proxy URL (e.g., http://user:pass@proxy:8080),
the ERR_PROXY_TUNNEL error message may include the full proxy URL in its text.
This exposes credentials to logs, error reporting systems, and any consumer of the error object.
In production, these errors are frequently logged to files, forwarded to error-tracking services (Sentry, Datadog), or displayed in debug panels. Sensitive credentials embedded in proxy URLs should never appear in error output.
Fix: Node.js now redacts credentials from the proxy URL in error messages. Fixed by: Matteo Collina
A malicious HTTP/2 server can send an unlimited number of ORIGIN frames to a client connection. Each ORIGIN frame contains an origin tuple that the HTTP/2 client stores in memory. Without a limit, an attacker can cause unbounded memory growth on the client, eventually leading to an Out of Memory (OOM) condition.
This is a client-side vulnerability — it affects Node.js applications that make HTTP/2 requests to untrusted servers. The fix caps the number of ORIGIN frames the client will accept. Fixed by: Matteo Collina
When an HTTP/2 server sends a GOAWAY frame in response to protocol errors, the connection should stop accepting new streams. However, the cleanup logic was incomplete — the server could continue processing data even after signalling shutdown, allowing a client to exhaust server resources through continued requests.
Note: This vulnerability affects Node.js 22.x and 24.x only. The fix was already in place in 26.x. Fixed by: Tim Perry
In multi-context mTLS setups, TLS servers use the Server Name Indication (SNI) value to select the correct security context (certificate, CA list). Node.js performed case-insensitive SNI matching on the wire but case-sensitive matching when selecting the security context, creating an inconsistency.
An attacker could register a certificate for Example.com (uppercase E) and have
it applied to traffic for example.com (lowercase e), bypassing per-hostname
trust policies in multi-tenant deployments.
Fixed by: Matteo Collina
C-string convention treats NUL (0x00) as a string terminator, but JavaScript strings can
contain embedded NUL characters. The DNS resolver in Node.js truncates hostnames at the
first NUL byte, while the TLS verifier checks the full original string. This mismatch lets
an attacker register a certificate for example.com\0.attacker.com and have it
accepted as valid for example.com.
This is a classic NUL-injection pattern in systems that bridge C and JavaScript string handling. Fixed by: Matteo Collina
TLS session resumption is a performance optimisation — after an initial handshake, subsequent connections can reuse the session ticket without a full handshake. However, Node.js did not verify that the ServerName in the resumed session matched the target hostname. An attacker in a position to observe or intercept TLS session tickets could reuse a ticket for one hostname to authenticate to a different hostname, bypassing certificate validation entirely.
Fixed by: Matteo Collina
The process.report.writeReport() API writes diagnostic reports to disk. Under
the Permission Model (--experimental-permission), this should respect read-only
file system restrictions. However, the path validation for reports was incomplete, allowing
a process to write a report to a path that was set as read-only.
Fixed by: RafaelGSS
The Promises API's FileHandle.utimes() method modifies file timestamps. When the
Permission Model was active, a read-only file path (set via --allow-fs-read)
should prevent timestamp modifications. The utimes() path was not properly gated, allowing
file metadata modification on otherwise read-only paths.
Fixed by: RafaelGSS
The Permission Model in Node.js 26.x introduced --allow-net to restrict network
access. However, Unix domain socket servers were not covered by these restrictions — a process
could start a local server via a Unix socket even without explicit network permission. This is
an incomplete fix for the earlier CVE-2026-21636.
Note: This only affects Node.js 26.x. Fixed by: RafaelGSS
A Time-of-Check Time-of-Use (TOCTOU) race condition in the http.Agent connection pool could cause a client to accept a response that was sent before the client had sent its request. In shared connection pools, a slow or delayed request could receive a response intended for another request in the same pool.
This is a subtle race condition that primarily affects scenarios with connection reuse and unexpected request queuing. Fixed by: Matteo Collina
Beyond the Node.js CVEs, this release includes important dependency security updates applied across all release lines:
| Dependency | Updated Version | Scope |
|---|---|---|
| llhttp | 9.4.2 | All release lines |
| nghttp2 | 1.69.0 | All release lines |
| openssl | 3.5.7 | All release lines |
| undici | 8.5.0 / 7.28.0 / 6.27.0 | Per release line |
llhttp 9.4.2 addresses HTTP parsing issues, nghttp2 1.69.0 fixes HTTP/2 protocol handling, openssl 3.5.7 patches CVE-2026-... in the underlying TLS library, and undici gets version- specific updates for the HTTP client library used internally by Node.js.
nvm install 26.3.1 # or 24.17.0 or 22.23.0
nvm alias default 26.3.1
# Arch Linux (community/nodejs)
sudo pacman -Syu
# Ubuntu/Debian (NodeSource)
curl -fsSL https://deb.nodesource.com/setup_26.x | sudo -E bash -
sudo apt-get install -y nodejs
# Update your Dockerfile base image
FROM node:26.3.1-alpine # or node:24.17.0-alpine, node:22.23.0-alpine
# Or pull the latest
docker pull node:26.3.1
Download the installer or binaries directly from nodejs.org.
If you run Node.js in CI/CD pipelines, here's how to roll out the security update efficiently:
# Update your test matrix
jobs:
test:
strategy:
matrix:
node-version: ['22.23.0', '24.17.0', '26.3.1']
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
# For production deployments, update only your target version
- name: Build and deploy
uses: actions/setup-node@v4
with:
node-version: '26.3.1'
services:
app:
image: node:26.3.1-alpine
# ... rest of your compose file
After updating, verify the installed version:
node -v
# Should output: v26.3.1 (or your target version)
# Check process.abort() path if you're concerned about CVE-2026-48933
node -e "require('crypto').subtle.encrypt({name:'AES-GCM'}, 'invalid', Buffer.alloc(2*1024*1024*1024+1))"
# Should throw an error, not crash
Beyond just updating Node.js, here's a checklist of security practices that would have mitigated or prevented most of these CVEs in production:
subtle.encrypt() calls. Any input over 1 GiB should be rejected at the application level--experimental-permission) in production if you run untrusted code. Even at Experimental status, it catches file system and network bypass vectors like CVE-2026-48617 and CVE-2026-48935maxSessionMemory and enforce connection-level resource quotas for outward HTTP/2 connectionsnpm audit and npm outdated as part of your CI pipelineNode.js follows a predictable release schedule with three active lines at any time: two LTS (Long-Term Support) lines and one Current (active development) line. If your application is on an End-of-Life (EOL) version, this security release — like all future ones — does not provide patches for it. You must upgrade to a supported line.
The Node.js 26.x release line introduced native TypeScript execution, a built-in SQLite module, an enhanced Permission Model, and experimental SEA (Single Executable Applications) support. For a complete overview of what Node.js 26 offers, see my Node.js 26 deep-dive guide. For details on the Permission Model specifically, read the Node.js Permission Model guide. And to stay on top of the release cadence itself, see the Node.js release schedule overview.
subtle.encrypt() causes an integer overflow that crashes the process (DoS). The fix adds proper bounds checking on the input size before passing it to OpenSSL's AES encryption path.nvm install 26.3.1), your package manager (apt, pacman, brew), download from nodejs.org, or update Docker images. For CI/CD, update your GitHub Actions setup-node version and Docker base images. Pin by digest for production to guarantee the exact patched image.--experimental-permission flag. However, if you are considering using the Permission Model in production, these fixes close important bypass paths — making it a more viable security control.crypto and tls modules, so upstream OpenSSL fixes require a Node.js release to take effect. This is standard practice for security releases.Security updates are critical — but doing them right means testing your application against the new version, verifying that dependencies are compatible, and ensuring your CI/CD pipeline deploys the update without downtime. If you're managing a Node.js production deployment and need assistance with the upgrade, get in touch. I provide free initial consultations — no pressure, no sales pitch.
I'm a full-stack web developer with deep experience in Node.js security, from audit and remediation to hardening production deployments. Based in Minsk and working worldwide, let's discuss your project.
Tell me about your project — I'll help you review your Node.js security posture and plan the update. Free of charge.