أمان Lovable وقواعد RLS
الأمان في مشاريع Lovable ليس زرّاً تفعّله، بل قرارات صغيرة تكرّرها في كل جدول ودالّة سيرفر. هذه الصفحة تشرح المفاهيم وتقدّم قائمة تحقّق عملية قبل النشر. المحتوى تصفه المنصّة (Lovable بالعربي) وليس مصدر تحقّق رسمي؛ راجع دوماً الوثائق الرسميّة عند وجود شكّ.
ما معنى RLS؟
Row-Level Security ميزة داخل Postgres تسمح لك بكتابة «شرط قراءة أو تعديل» على مستوى كل صف. عندما يُفعَّل RLS على جدول، لا يعود أي طلب من العميل قادراً على قراءة صف ما لم تسمح به سياسة صريحة. وبذلك تكون منطقة الحماية داخل قاعدة البيانات نفسها — لا في الواجهة ولا في زرّ يمكن إخفاؤه.
خطر الجداول المفتوحة
خطأ شائع: إنشاء جدول ثم منح GRANT للجميع بدون تفعيل RLS، أو تفعيل RLS بلا سياسات مطابقة لنيّة المشروع. النتيجة: تسريب بيانات مستخدمين، أو السماح لأي شخص بتعديل صفوف الآخرين. القاعدة الآمنة: ابدأ بالإغلاق ثم افتح ما تحتاجه فقط.
سياسات SELECT/INSERT/UPDATE/DELETE
من له الحق أن يقرأ صفاً؟ عادةً auth.uid() = user_id، أو ‹مقروء للجميع› فقط لجداول محتوى عام صريح.
من يستطيع إنشاء صف؟ اربط WITH CHECK بـ auth.uid() = user_id حتى لا يُنشِئ المستخدم صفاً باسم شخص آخر.
من يعدّل ماذا؟ USING تضبط الصفوف المرئية للتعديل، وWITH CHECK تضبط الشكل النهائي بعد التعديل.
من يحذف؟ غالباً صاحب الصف فقط. تجنّب سياسات حذف مفتوحة على جداول تحتوي بيانات مستخدمين.
فصل الأدوار
لا تخزّن الدور في نفس جدول المستخدم (profiles أو users) — أي تصعيد صلاحية يصبح مكلفاً. استخدم جدولاً منفصلاً user_roles مع نوع تعداد (enum) للأدوار، ودالّة has_role مع SECURITY DEFINER يستدعيها RLS للتحقّق من الدور. هذا يمنع الدور من أن يُتلاعب به من العميل ويجنّبك حلقات recursive RLS.
حماية الأسرار
- أضف كل مفتاح خارجي (Stripe، مزوّد بريد، إلخ) كسِرّ في Lovable Cloud، لا في الكود.
- اقرأه فقط داخل
handlerدالّة السيرفر عبرprocess.env.NAME. - لا تضعه في متغيّر يبدأ بـ
VITE_— تلك المتغيّرات تصل للمتصفّح. - لا تُعِد قيمة السرّ في استجابة الـ API حتى لأغراض التصحيح.
حماية Server Functions
- الدوالّ التي تلمس بيانات مستخدم مسجّل: أضف
.middleware([requireSupabaseAuth]). - لا تثق بحقل
userIdالقادم من الطلب — استخدمcontext.userIdمن الجلسة. - تحقّق من الدور داخل الدالّة إذا كانت عمليّة إداريّة (has_role)، لا في العميل فقط.
- تحقّق من توقيع أي Webhook قبل معالجته، ولا تكتب في قاعدة البيانات قبل التحقّق.
سياسات Storage
Storage يُعامَل كجدول storage.objects — يحتاج RLS كذلك. اجعل الباكِت خاصّاً، وأصدر روابط موقّعة (signed URLs) بمدة انتهاء قصيرة للوصول المؤقّت. اربط اسم الملف بمعرّف المستخدمauth.uid() واستخدم ذلك في السياسة، بدلاً من الاعتماد على «اسم مسار يصعب تخمينه».
Basic Scan وDeep Scan
داخل Lovable Cloud فحوصات جاهزة: Basic Scan يكتشف الجداول بلا RLS، السياسات الخطرة، والأسرار المسرَّبة في الكود العميل. Deep Scan يمضي أبعد فيراجع علاقات الجداول ودوالّ السيرفر ومسارات Storage. شغّلهما قبل كل نشر مهم، وعالج كل «High» قبل الإطلاق.
اختبار الصلاحيات بحسابين مختلفين
أنشئ حسابَي مستخدم عاديَّين، وأنشئ بيانات لكل واحد. جرّب:
- هل يرى الحساب A بيانات الحساب B عرَضاً في أي قائمة؟
- هل يقدر A أن يعدّل صفّاً يحمل
user_idيخصّ B عبر تعديل الطلب يدوياً؟ - هل يقدر A أن يقرأ ملفاً في Storage بمسار يعرفه من B؟
- هل يظهر دور «admin» بأي شكل لحساب عادي في الاستجابات؟
قائمة تحقّق قبل النشر
- كل جدول في schema public عليه ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
- لكل جدول سياسات SELECT/INSERT/UPDATE/DELETE واضحة — لا تعتمد على «لا توجد سياسة» لحجب الجدول.
- الأدوار (roles) في جدول user_roles منفصل، وليست عموداً على profiles أو users.
- أي فحص لدور المستخدم يمرّ عبر دالّة SECURITY DEFINER (مثل has_role)، لا استعلام متكرّر داخل RLS.
- لا يوجد مفتاح API أو Service Role Key في كود العميل ولا في متغيّرات تبدأ بـ VITE_.
- دوالّ السيرفر التي تُعدّل بيانات المستخدم تستخدم requireSupabaseAuth، وتقرأ userId من الجلسة لا من الطلب.
- روابط Storage خاصّة: الباكِت private، والوصول عبر signed URLs، وسياسات RLS على storage.objects محدّدة.
- اختبرت السيناريوهات بحسابين مختلفين: كل واحد لا يرى ولا يعدّل بيانات الآخر.
- شغّلت Basic Scan وDeep Scan في Lovable، وعالجت أو وثّقت كل تنبيه.
- راجعت logs أوّل 24 ساعة بعد النشر بحثاً عن أخطاء 401/403 أو رفض RLS غير متوقّع.
حدود المسؤولية
- البنية التحتيّة والتشفير أثناء النقل والتخزين.
- إتاحة أدوات RLS وSecrets وServer Functions وSocial Auth.
- تحديثات الأمان الأساسيّة للمنصّة.
- كتابة سياسات RLS تناسب نموذج البيانات.
- فصل الأدوار وحماية دوالّ السيرفر.
- سياسة خصوصيّة وشروط استخدام واضحة لمستخدميه.
- مراجعة logs وتشغيل Scans دورياً.
الأسئلة الشائعة
Row-Level Security طبقة أمان داخل Postgres نفسها. لكل جدول سياسات تُصفّي الصفوف حسب هويّة الطالب، بحيث لا يرى المستخدم إلا صفوفه — حتى لو أخطأ كود العميل.
لا. الواجهة قابلة للتجاوز من أي طرف. الحماية الحقيقية تكون على مستوى قاعدة البيانات عبر RLS، ومستوى دوالّ السيرفر عبر التحقق من الجلسة والدور.
في «الأسرار» (Secrets) داخل Lovable Cloud، ثم اقرأها فقط داخل دوالّ السيرفر عبر process.env. لا تضعها في كود العميل ولا في متغيّرات VITE_.
لا. جدول «عام» يعني أنه في schema public، وهذا لا يعطي صلاحية قراءة. بدون سياسات RLS مناسبة الجدول محجوب فعلياً حتى لو كان مرئياً.
Lovable مسؤولة عن البنية التحتيّة والتشفير الأساسي وأدوات الأمان. مالك المشروع مسؤول عن كتابة السياسات، فصل الأدوار، اختيار ما يُنشر، وحماية بيانات مستخدميه.
