
Next.js में CVE-2025-29927, CVE-2026-27978 और CVE-2026-29057 के लिए कुछ Proof-of-Concept (POCs)।
यह रिपॉजिटरी तीन Next.js कमजोरियों के लिए पुनरुत्पादन योग्य प्रूफ-ऑफ-कॉन्सेप्ट वातावरण समाहित करती है। प्रत्येक PoC में एक असुरक्षित टारगेट, एक सुधारित टारगेट, और एक स्क्रिप्ट शामिल है जो दोनों के बीच व्यवहारिक अंतर प्रदर्शित करती है।
इस प्रोजेक्ट का लक्ष्य प्रत्येक समस्या के मूल कारण और व्यावहारिक प्रभाव को न्यूनतम वातावरण में आसानी से देखने योग्य बनाना है।
| CVE | सुरक्षा सलाह | प्रभाव | असुरक्षित संस्करण | सुधारित संस्करण |
|---|---|---|---|---|
CVE-2025-29927 | GHSA-f82v-jwr5-mffw | प्राधिकरण बाईपास जब एक्सेस नियंत्रण केवल middleware पर निर्भर करता है | 15.2.2 | 15.2.3 |
CVE-2026-27978 | GHSA-mq59-m269-xvcx | Server Actions CSRF जाँच का Origin: null बाईपास | 16.1.6 | 16.1.7 |
CVE-2026-29057 | GHSA-ggv3-7p47-pfv8 | बाहरी बैकएंड पर रीराइट्स के माध्यम से HTTP रिक्वेस्ट स्मगलिंग | 15.5.12 | 15.5.13 |
NEXT-16.2.4-IMAGE-REDIRECT | स्थानीय स्रोत ऑडिट निष्कर्ष | रीडायरेक्ट्स के माध्यम से इमेज ऑप्टिमाइज़र रिमोट allowlist बाईपास | 16.2.4 | सत्यापित नहीं |
NEXT-16.2.4-IMAGE-LOCAL-REWRITE | स्थानीय स्रोत ऑडिट निष्कर्ष | इमेज ऑप्टिमाइज़र लोकल URL बाहरी रीराइट्स के माध्यम से प्राइवेट अपस्ट्रीम तक पहुँच सकता है | 16.2.4 | सत्यापित नहीं |
नीचे दिए गए हैश अपस्ट्रीम vercel/next.js से लिए गए हैं।
| CVE | असुरक्षित रिलीज़ कमिट | सुधारित रिलीज़ कमिट | प्रासंगिक पैच कमिट |
|---|---|---|---|
CVE-2025-29927 | v15.2.2 -> f4552826e1ed15fbeb951be552d67c5a08ad0672 | v15.2.3 -> 535e26d3c69de49df8bd17618a424cbe65ec897b | 52a078da3884efe6501613c7834a3d02a91676d2 |
CVE-2026-27978 | v16.1.6 -> adf8c612adddd103647c90ff0f511ea35c57076e | v16.1.7 -> bdf3e3577a6d55ea186a48238d61fbd8da07a626 | a27a11d78e748a8c7ccfd14b7759ad2b9bf097d8 |
CVE-2026-29057 | v15.5.12 -> d23f41c42506005fe6978e076a1ccbf8979e4925 | v15.5.13 -> cfd5f533b08df3038476dcd54f1d6d660d85f069 | dc98c04f376c6a1df76ec3e0a2d07edf4abdabd6 |
.
|- docker-compose.yml
|- pocs/
| |- cve-2025-29927/
| |- cve-2026-27978/
| |- cve-2026-29057/
| |- next-16.2.4-image-redirect-allowlist-bypass/
| `- next-16.2.4-image-local-rewrite-ssrf/
`- scripts/
|- run-cve-2025-29927.mjs
|- run-cve-2026-27978.mjs
|- run-cve-2026-29057.mjs
|- run-next-16.2.4-image-redirect-allowlist-bypass.mjs
`- run-next-16.2.4-image-local-rewrite-ssrf.mjs
docker compose उपलब्ध है।docker compose up --build
एक्सपोज़्ड पोर्ट:
3001 -> CVE-2025-29927 असुरक्षित3002 -> CVE-2025-29927 सुधारित3003 -> CVE-2026-27978 असुरक्षित3004 -> CVE-2026-27978 सुधारित3005 -> CVE-2026-29057 असुरक्षित3006 -> CVE-2026-29057 सुधारित3007 -> NEXT-16.2.4-IMAGE-REDIRECT3008 -> NEXT-16.2.4-IMAGE-LOCAL-REWRITEइस PoC में, /dashboard केवल middleware द्वारा सुरक्षित है:
export function middleware(request) {
const session = request.cookies.get('session')?.value
if (session !== 'admin') {
return NextResponse.redirect(new URL('/login', request.url))
}
return NextResponse.next()
}
प्राधिकरण जाँच स्वयं गलत नहीं है। समस्या यह है कि रूट पूरी तरह से इस धारणा पर निर्भर है कि middleware निष्पादन को स्किप नहीं किया जा सकता।
प्रभावित Next.js संस्करणों में, बाहरी अनुरोध आंतरिक हेडर x-middleware-subrequest की आपूर्ति कर सकते थे, और रनटाइम उस मान को विश्वसनीय middleware मेटाडेटा के रूप में मानता था। प्रासंगिक असुरक्षित लॉजिक यह था:
const INTERNAL_HEADERS = [
'x-middleware-rewrite',
'x-middleware-redirect',
'x-middleware-set-cookie',
'x-middleware-skip',
'x-middleware-override-headers',
'x-middleware-next',
'x-now-route-matches',
'x-matched-path',
]
export const filterInternalHeaders = (headers) => {
for (const header in headers) {
if (INTERNAL_HEADERS.includes(header)) {
delete headers[header]
}
}
}
x-middleware-subrequest को वहाँ फ़िल्टर नहीं किया गया था, इसलिए हमलावर-नियंत्रित इनपुट middleware रनटाइम तक पहुँच सकता था। उस मान का उपयोग फिर रिकर्सन गहराई निकालने के लिए किया गया:
const subreq = params.request.headers['x-middleware-subrequest']
const subrequests = typeof subreq === 'string' ? subreq.split(':') : []
const depth = subrequests.reduce(
(acc, curr) => (curr === params.name ? acc + 1 : acc),
0
)
if (depth >= MAX_RECURSION_DEPTH) {
return {
response: new Response(null, {
headers: {
'x-middleware-next': '1',
},
}),
}
}
यदि कोई हमलावर middleware:middleware:middleware:middleware:middleware भेजता है, तो रनटाइम यह निष्कर्ष निकाल सकता है कि रिकर्सन गहराई पहले ही पहुँच चुकी है और अनुरोध को एप्लिकेशन middleware निष्पादित किए बिना आगे भेज देता है।
docker compose up --build cve-2025-29927-vuln cve-2025-29927-fixed
node scripts/run-cve-2025-29927.mjs http://localhost:3001
node scripts/run-cve-2025-29927.mjs http://localhost:3002
अपेक्षित व्यवहार:
3001 बिना एक्सप्लॉइट हेडर के एक रीडायरेक्ट लौटाता है, लेकिन x-middleware-subrequest के साथ 200 OK लौटाता है।3002 /login पर रीडायरेक्ट करता रहता है, क्योंकि आंतरिक हेडर अब बाहरी इनपुट से विश्वसनीय नहीं माना जाता।यह PoC एक सामान्य Server Action को एक्सपोज़ करता है जो सर्वर-साइड स्थिति को बदलता है:
'use server'
import { cookies } from 'next/headers'
import { revalidatePath } from 'next/cache'
import { recordTransfer } from '../lib/state'
export async function transferFunds(formData) {
const cookieStore = await cookies()
const session = cookieStore.get('session')?.value
if (!session) {
throw new Error('Victim session cookie is missing.')
}
const amount = Number(formData.get('amount') || '0')
recordTransfer(session, amount)
revalidatePath('/')
}
समस्या स्वयं transferFunds() में नहीं है। असुरक्षित व्यवहार Server Actions के लिए Next.js CSRF सत्यापन में था। प्रभावित संस्करणों में, Origin: null को स्पष्ट अपारदर्शी ऑरिजिन के बजाय अनुपस्थित ऑरिजिन की तरह माना जाता था:
const originHeader = req.headers['origin']
const originDomain =
typeof originHeader === 'string' && originHeader !== 'null'
? new URL(originHeader).host
: undefined
const host = parseHostHeader(req.headers)
if (!originDomain) {
warning = 'Missing `origin` header from a forwarded Server Actions request.'
} else if (!host || originDomain !== host.value) {
if (isCsrfOriginAllowed(originDomain, serverActions?.allowedOrigins)) {
// Ignore it
} else {
const error = new Error('Invalid Server Actions request.')
// ...
}
}
चूँकि 'null' undefined बन जाता था, सैंडबॉक्स किए गए iframe जैसे अपारदर्शी ऑरिजिन से आने वाले अनुरोध होस्ट/ऑरिजिन तुलना पथ से बच सकते थे और फिर भी पीड़ित के कुकीज़ के साथ संसाधित हो सकते थे।
docker compose up --build cve-2026-27978-vuln cve-2026-27978-fixed
node scripts/run-cve-2026-27978.mjs http://localhost:3003
node scripts/run-cve-2026-27978.mjs http://localhost:3004
अपेक्षित व्यवहार:
Origin: null के साथ सबमिट करती हैयह PoC /rewrites/:path* को बाहरी बैकएंड पर रीराइट करता है: