FixVibe

// docs / baas security / supabase service role exposure

مفتاح Supabase service role المكشوف في JavaScript: ما يعنيه وكيفية العثور عليه

مفتاح Supabase service role هو المفتاح الرئيسي لقاعدة بياناتك. أي شخص يحمله يتجاوز Row-Level Security، ويمكنه قراءة كل عمود من كل جدول، والكتابة أو الحذف بأي شيء يختاره. مُصمَّم ليعيش حصريًا في الكود من جانب الخادم — أبدًا في المتصفح. عندما تشحنه أداة برمجة بالذكاء الاصطناعي إلى حزمة JavaScript، تصبح قاعدة بياناتك، في الواقع، عامة. يشرح هذا المقال شكل JWT الذي يُعرِّف مفتاحًا مُسرَّبًا، وأنماط أدوات الذكاء الاصطناعي الثلاثة التي تُنتج التسرب، وما يجب فعله في الساعة الأولى بعد الاكتشاف، وكيفية المسح عنه تلقائيًا قبل أن يفعل المستخدمون.

ما هو مفتاح service role

يُصدر Supabase مفتاحين مختلفين لكل مشروع: مفتاح anon (يُسمى أيضًا المفتاح القابل للنشر في المشاريع الأحدث) ومفتاح service_role. كلاهما رموز JSON Web موقَّعة بسر JWT الخاص بمشروعك. الفرق هو ادعاء role المضمَّن في حمولة JWT — anon للمفتاح العام، service_role للمفتاح الرئيسي. يتحول PostgREST وSupabase Storage وSupabase Auth جميعًا إلى وضع تجاوز كل شيء عندما يرون ادعاء service_role.

فُكَّ ترميز أي مفتاح Supabase على jwt.io وانظر إلى الحمولة. شكل JWT الخاص بـ service-role لا يُخطئ:

حمولة مفكوكة لـ JWT خاص بـ service-role (تُعرض ككتلة مُلوَّنة بالأدنى).

json
{
  "iss": "supabase",
  "ref": "[project-ref]",
  "role": "service_role",
  "iat": 1700000000,
  "exp": 2000000000
}

تُصدر مشاريع Supabase الأحدث مفاتيح على نمط الأسرار بالبادئة sb_secret_ بدلًا من JWT. السلوك متطابق — أي شيء يحمل sb_secret_ في حزمة عامة هو كارثي بنفس القدر.

كيف تُسرِّب أدوات البرمجة بالذكاء الاصطناعي مفتاح service role

رأينا الأنماط الثلاثة نفسها عبر آلاف التطبيقات المبرمجة بأسلوب vibe-coding. يبدأ كل واحد منها بمطوّر يطلب المساعدة من أداة ذكاء اصطناعي وينتهي بمفتاح الخدمة مُدمج داخل الحزمة.

النمط 1: ملف .env واحد بالبادئة NEXT_PUBLIC_

يطلب المطور من أداة الذكاء الاصطناعي "إعداد Supabase" ويقبل ملف .env واحدًا يحتوي على كلا المفتاحين. أداة الذكاء الاصطناعي — المدرَّبة على مجموعة بيانات حيث معظم متغيرات البيئة مكشوفة عبر NEXT_PUBLIC_* — تضع البادئة NEXT_PUBLIC_ على كليهما. يُدمج Next.js أي شيء يطابق تلك البادئة في حزمة العميل عند البناء. أطلق إلى Vercel، وسيكون مفتاح الخدمة في main.[hash].js.

النمط 2: مفتاح خاطئ في استدعاء createClient

يلصق المطور كلا المفتاحين في ملف config.ts الذي ولّدته أداة الذكاء الاصطناعي، ثم تضع الأداة في استدعاء createClient() من جانب المتصفح القيمة process.env.SUPABASE_SERVICE_ROLE_KEY بالخطأ. يجلب البناء المتغير، ويهبط JWT في الحزمة.

النمط 3: مفتاح service-role مُضمَّن في سكربتات البذر

يطلب المطور من أداة الذكاء الاصطناعي كتابة سكربت يبذر قاعدة البيانات. تُضمِّن الأداة مفتاح service-role مباشرة في الملف (بدلًا من القراءة من البيئة)، وتُودِع الملف في المستودع، ويصبح مستودع GitHub العام أو مسار /scripts/seed.js الخاص بالتطبيق المنشور يخدم المفتاح الآن.

كيف يكتشف مسح حزمة FixVibe التسرب

يُنزِّل فحص الأسرار في الحزمة من FixVibe كل ملف JavaScript يُشير إليه التطبيق المنشور — كتل الدخول، والكتل المُحمَّلة بشكل كسول، وعمال الويب، وعمال الخدمة — ويُمرِّرها عبر كاشف يفك ترميز أي شيء يطابق شكل JWT (eyJ[base64-header].eyJ[base64-payload].[signature]). إذا احتوت الحمولة المفكوكة على "role": "service_role"، يُبلِّغ المسح عنها كنتيجة حرجة مع مسار الملف والسطر الدقيق الذي يظهر فيه المفتاح. يطابق الفحص نفسه أيضًا نمط sb_secret_* الأحدث عبر البادئة.

لا يُصادق المسح أبدًا بالمفتاح المُكتشَف. يُحدِّد الشكل ويُبلِّغ عن التسرب — استخدام المفتاح لإثبات الاستغلال سيكون وصولًا غير مصرَّح به إلى قاعدة بياناتك. الدليل في حمولة JWT نفسها.

تم الاكتشاف — ماذا تفعل في الساعة الأولى

مفتاح service role مُسرَّب طارئ في وقت التشغيل. افترض أن المفتاح قد جُمع — يراقب المهاجمون الحزم العامة في الوقت الفعلي. عامل قاعدة البيانات على أنها مُختَرَقة حتى تُدوِّر المفتاح وتراجع النشاط الأخير.

  1. دوِّر المفتاح فورًا. في لوحة تحكم Supabase، انتقل إلى Project Settings → API → Service role key → Reset. يُبطَل المفتاح القديم خلال ثوانٍ. يجب تحديث أي كود من جانب الخادم يستخدم المفتاح وإعادة نشره قبل أن يهبط التدوير.
  2. راجع نشاط قاعدة البيانات الأخير. افتح Database → Logs في لوحة التحكم. صفِّ على آخر 7 أيام. ابحث عن استعلامات SELECT * غير عادية على جداول تحتوي على معلومات شخصية، وعبارات UPDATE أو DELETE الكبيرة، وطلبات من IPs خارج بنيتك التحتية المعروفة. يُسجِّل Supabase ترويسة x-real-ip في كل طلب.
  3. تحقق من كائنات التخزين. قم بزيارة Storage → Logs وراجع تنزيلات الملفات الأخيرة. مفتاح service-role مُسرَّب يمنح وصول تجاوز كل شيء أيضًا إلى الدلاء الخاصة.
  4. أزل المفتاح من التحكم بالمصدر. حتى بعد التدوير، فإن ترك JWT في تاريخ git الخاص بك يعني أنه قابل للاكتشاف في المستودع العام. استخدم git filter-repo أو BFG Repo-Cleaner لمحوه من التاريخ، ثم ادفع بالقوة (حذِّر المتعاونين أولًا).
  5. أعد المسح بعد الإصلاح. شغِّل مسح FixVibe جديد على التطبيق المُعاد نشره. يجب أن تختفي نتيجة الأسرار في الحزمة. تأكد من عدم بقاء أي JWT بـ service_role أو سلسلة sb_secret_* في أي كتلة.

منع التسرب من الأساس

الإصلاح البنيوي هو الانضباط في التسمية بالإضافة إلى ضمانات على مستوى الأداة:

  • لا تضع أبدًا البادئة NEXT_PUBLIC_* أو VITE_* أو أي بادئة دمج في الحزمة على مفتاح الخدمة. اصطلاح التسمية هو الحدود — كل إطار عمل يحترمه.
  • أبقِ مفتاح الخدمة خارج .env تمامًا على جهاز المطور. اقرأه من مدير أسرار (Doppler وInfisical ومتغيرات بيئة Vercel المُشفَّرة) عند النشر، ولا تُودِعه محليًا أبدًا.
  • <strong>Mark every Supabase client construction with explicit context.</strong> Files named <code>supabase/browser.ts</code> use the anon key; files named <code>supabase/server.ts</code> use the service-role key with <code>import 'server-only'</code> at the top. The <code>server-only</code> import causes a build error if a client component tries to consume the module.
  • <strong>Add a pre-commit hook that greps for JWT-shaped strings.</strong> <code>git diff --staged | grep -E 'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+'</code> catches both anon and service tokens before they leave your machine.
  • أضف بوابة CI تمسح مخرجات البناء. بعد next build، ابحث في مخرجات .next/static/chunks/ عن سلسلة service_role. أفشل البناء إذا تطابق أي شيء.
bash
# Pre-commit hook: refuse any staged JWT-shaped string.
git diff --staged \
  | grep -E 'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+' \
  && echo "JWT detected in staged changes — refusing commit" \
  && exit 1

# CI gate: fail the build if "service_role" shipped to the static bundle.
grep -RE 'service_role|sb_secret_' .next/static/chunks/ \
  && echo "Service-role credential leaked into bundle" \
  && exit 1

الأسئلة الشائعة

كم بسرعة يجد المهاجمون فعلًا مفاتيح Supabase service-role المُسرَّبة؟

ماسحات الحزم العامة تجوب النشرات الجديدة خلال دقائق. وثَّق الباحثون استغلالات عاملة ضد مشاريع Supabase جديدة في أقل من ساعة من أول نشر. عامل أي كشف لـ service-role كنافذة 60 دقيقة، لا 60 يومًا.

هل تدوير المفتاح كافٍ، أم يجب أن أفترض تسريب البيانات؟

يُبطل التدوير المفتاح المُسرَّب ولكنه لا يُلغي البيانات التي سُحبت بالفعل. إذا احتوت جداولك على معلومات شخصية أو بيانات دفع أو أي بيانات منظَّمة، فقد يكون لديك التزام إخطار بموجب GDPR (72 ساعة) أو CCPA أو HIPAA. راجع السجلات واستشر مستشارًا قانونيًا إذا أظهر التدقيق وصولًا مشبوهًا.

هل يمكن لـ RLS حمايتي إذا تسرَّب مفتاح service-role؟

لا. يتم تجاوز Row-Level Security بالكامل بواسطة ادعاء service_role. هذا بحسب التصميم — يوجد المفتاح تحديدًا للسماح لكود الخلفية بتخطي RLS للعمليات الإدارية. التخفيف هو ضمان عدم وصول المفتاح أبدًا إلى سياق يمكن للمهاجم قراءته فيه.

هل ينطبق هذا على نموذج المفاتيح القابل للنشر / السري الجديد في Supabase (<code>sb_publishable_</code> / <code>sb_secret_</code>)؟

نعم — فئة مخاطر متطابقة. مفتاح sb_secret_* هو تنسيق المفتاح السري الجديد الذي يحل محل JWT الخاص بـ service-role في المشاريع الأحدث. أي شيء يحمل sb_secret_* في حزمة هو كارثي بنفس قدر JWT خاص بـ service-role مُسرَّب. يطابق كاشف الأسرار في حزمة FixVibe كلا الشكلين.

ماذا عن مفتاح anon / القابل للنشر — هل هو آمن في الحزمة؟

نعم، حسب التصميم. مفتاح anon مُصمَّم ليعيش في المتصفح وهو ما يستخدمه كل عميل ويب Supabase. تعتمد سلامته بالكامل على تهيئة RLS بشكل صحيح على كل جدول عام. راجع مقال ماسح Supabase RLS لمعرفة ما يجب التحقق منه.

الخطوات التالية

شغِّل مسح FixVibe على عنوان URL الإنتاج — فحص الأسرار في الحزمة مجاني، بدون تسجيل، ويُبلِّغ عن كشف service_role في أقل من دقيقة. أقرنه بمقال ماسح Supabase RLS للتحقق من أن طبقة RLS تُؤدي عملها، وقائمة التحقق لأمان دلاء Supabase Storage لإحكام الوصول إلى الملفات. للخلفية حول لماذا تُولِّد أدوات الذكاء الاصطناعي فئة التسرب هذه بشكل موثوق، اقرأ لماذا تترك أدوات البرمجة بالذكاء الاصطناعي ثغرات أمنية.

// افحص سطح baas الخاص بك

اعثر على الجدول المفتوح قبل أن يفعل ذلك شخص آخر.

أدخل عنوان URL للإنتاج. سيُعدِّد FixVibe موفّري BaaS الذين يتحدث تطبيقك معهم، ويُحدِّد بصمة نقاط النهاية العامة لديهم، ويُبلغ عما يستطيع عميل غير مصادق عليه قراءته أو الكتابة فيه. مجاني، بدون تثبيت، بدون بطاقة.

  • الباقة المجانية — 3 عمليات مسح شهريًا، بدون بطاقة عند التسجيل.
  • بصمة BaaS سلبية — لا حاجة للتحقق من النطاق.
  • Supabase وFirebase وClerk وAuth0 وAppwrite والمزيد.
  • مطالبات إصلاح بالذكاء الاصطناعي مع كل نتيجة — الصقها مرة أخرى في Cursor / Claude Code.
ابدأ مسح BaaS مجاني

لا حاجة للتسجيل

مفتاح Supabase service role المكشوف في JavaScript: ما يعنيه وكيفية العثور عليه — Docs · FixVibe