00:00:00صدر تقرير هذا الشهر فحص حوالي 20,000 تطبيق مستقل ووجد أن تطبيقاً من بين كل تسعة
00:00:04كانت تعرض بيانات اعتماد “Supa-based” في الكود البرمجي للواجهة الأمامية.
00:00:08هذا ليس في سجل الخادم أو في مستودع خاص.
00:00:11بل هو موجود ببساطة في ملفات الجافا سكريبت التي يحملها كل زائر.
00:00:14والأمر هو أن هذه التطبيقات لم تتعرض للاختراق، بل شحنوا المفاتيح السرية عن طريق الخطأ.
00:00:18للتوضيح، بعض المفاتيح مخصصة لتكون عامة.
00:00:21المشكلة تكمن في آلية العمل، لأن نفس الخطأ قد يتسبب في شحن مفتاح لا ينبغي أن يتواجد
00:00:25في المتصفح أصلاً.
00:00:27لدينا فيديوهات جديدة تصدر باستمرار.
00:00:28تأكد من الاشتراك.
00:00:35إليك الحقيقة البسيطة التي يقع فيها الكثيرون.
00:00:38جميعنا ندركها، لكن من السهل إغفالها عندما تعمل بسرعة.
00:00:41عندما تحدد متغيراً بيئياً على أنه عام، فإن أداة البناء تعامله كأنه ينتمي
00:00:46إلى المتصفح ويتم إضافته إلى حزمة العميل.
00:00:50يقوم Next.js بذلك عبر Next.public، وVite عبر Vite، وSvelteKit يستخدم
00:00:56اللاحقة public.
00:00:57كلمة Next ليست ملصق أمان بأي حال، بل هي فعلياً ملصق الشحن للجمهور.
00:01:01الآن عرفنا ذلك، ولكن إليكم الجزء المتعلق بـ Supa-based.
00:01:04بعض المفاتيح مخصصة لتكون عامة، مثل مفاتيح anon أو المفاتيح القابلة للنشر، وبعضها خاص، مثل
00:01:10مفاتيح أدوار الخدمة أو المفاتيح السرية.
00:01:12إذا انتهى المطاف بمفتاح خاص في المتصفح، حسناً، أظنكم تتخيلون ما سيحدث.
00:01:17أمن مستوى الصف (RLS) لن ينقذك في هذه الحالة.
00:01:20توثيقات Supa-based واضحة في أن مفاتيح الخدمة يمكنها تجاوز RLS.
00:01:24لذا إذا كان هذا المفتاح في واجهتك الأمامية، فكل عملك على السياسات لم يعد له قيمة.
00:01:29دعوني أريكم بالضبط كيف حدث هذا باستخدام بيئة التجربة الخاصة بي.
00:01:33أولاً، قمت ببناء تطبيق CRUD بسيط باستخدام Next.js وربطت قاعدة بياناتي فيه.
00:01:38هذا هو ملف البيئة الخاص بي، وهنا يكمن الخطأ.
00:01:41وضعت مفتاحاً خلف متغير يبدأ ببادئة عامة (public).
00:01:45هذا المفتاح قابل للنشر، لذا فمن المتوقع أن يكون مرئياً.
00:01:48المشكلة الحقيقية هي أن نفس مسار Next.public يمكنه شحن مفتاح خاص بالخطأ أيضاً.
00:01:53عندما قمت بتشغيل npm run build لبناء التطبيق، ثم قمت بتشغيله.
00:01:59أنا الآن في متصفح كروم.
00:02:00سأضيف بعض المعلومات السريعة إلى قاعدة البيانات في تطبيقنا.
00:02:05حسناً، الآن يمكنني فتح حزمة الجافا سكريبت المجمعة وسأبحث عن المفتاح.
00:02:10ها هو ذا.
00:02:12الرابط والمفتاح موجودان حرفياً داخل الملف الذي سحبه المستخدمون للتو
00:02:18إلى متصفحاتهم.
00:02:19ولاحظوا ما لم يحدث.
00:02:21لم يقم أحد باقتحام النظام.
00:02:22لقد وجدته ببساطة، صحيح؟
00:02:24لم يستغل أحد أي ثغرة.
00:02:25هذا مجرد قراءة لما قام التطبيق بالفعل بشحنه إلى الإنترنت العام.
00:02:29إذا كان بإمكانك رؤيته، فبإمكان أي شخص رؤيته.
00:02:32افتح أدوات المطور، وانظر في ملفات الجافا سكريبت وابحث عنه.
00:02:35هذا كل ما عليك فعله.
00:02:36لذا إذا كانت خطتك هي أن أحداً لن يبحث، فاعلم أن الإنترنت مليء بالأشخاص والروبوتات
00:02:41التي تتمثل وظيفتها حرفياً في البحث عن مثل هذه الأشياء.
00:02:44إليك الحل الذي يعمل فعلياً.
00:02:47يجب على المتصفح استدعاء واجهة البرمجة (API) الخاصة بك فقط.
00:02:50واجهة البرمجة تعمل من جهة الخادم.
00:02:52هناك حيث تعيش المفاتيح الخاصة.
00:02:54انقل العمليات الخاصة إلى مسار API أو وظيفة خادم (server function).
00:02:58يستدعي العميل نقطة النهاية الخاصة بك، وهي بدورها تستدعي قاعدة البيانات، ثم أعد البناء وافحص الحزمة.
00:03:03إذا اختفى المفتاح من الحزمة، فقد أصلحت المشكلة حقاً، ولكن لا تتوقف هنا.
00:03:04لأن هناك أشياء أخرى يمكنك القيام بها.
00:03:09تأكد من تفعيل أمن مستوى الصف (RLS) للجداول التي يواجهها المستخدم.
00:03:11وتأكد من أن سياساتك تفعل ما تظن أنها تفعله.
00:03:16اقضِ بعض الوقت في الاختبار أيضاً.
00:03:18أعتقد أن هذا الأمر يتم التغاضي عنه أحياناً.
00:03:19الآن، الجزء الذي يمنع عودة هذه المشكلة؛ معظم الناس يصلحونها مرة واحدة، ثم يعيدونها
00:03:21لاحقاً أثناء العمل تحت الضغط.
00:03:26لذا أضف بعض الضوابط؛ ابدأ بفحص الأسرار في CI الخاص بك حتى يفشل البناء
00:03:28إذا ظهر مفتاح في مكان لا ينبغي أن يظهر فيه.
00:03:34ثم ضع قاعدة لمراجعة الأكواد تعتبر أي شيء يحتوي على Next public أو Vite عاماً بشكل افتراضي
00:03:36لأنه كذلك بالفعل.
00:03:41أخيراً، اعتمد تدوير المفاتيح.
00:03:42إذا كان لديك أدنى تلميح بأن المفاتيح قد انكشفت، فقم بتدويرها فوراً.
00:03:43هذا أفضل من الانتظار لترى كيف ستتطور الأمور خلال بضعة أيام.
00:03:47إليك ما يمكنك تجربته الآن.
00:03:50قم ببناء تطبيقك بنفس الطريقة التي تشحنه بها.
00:03:52ابحث في المخرجات عن روابط الـ JWT وسر الخدمة وأي شيء يشبه الرمز التعريفي (token).
00:03:55إذا وجدت أي شيء خاص، فافترض أنه مخترق لأنك استطعت العثور عليه.
00:04:01قم بتدويره ثم غير منطق البرمجة الخاص بك ليكون من جهة الخادم.
00:04:05إذا تذكرت سطراً واحداً من هذا الفيديو، فليكن هذا:
00:04:08إذا كان الشيء في حزمة البيانات، فهو عام للجميع.
00:04:11نراكم في فيديو آخر.
00:04:13We'll see you in another video.