FixVibe

// docs / baas security / supabase storage

قائمة التحقق لأمان دلاء Supabase Storage: 22 بندًا

Supabase Storage عبارة عن غلاف رفيع حول دلو متوافق مع S3 بالإضافة إلى نفس نموذج Row-Level Security مثل قاعدة البيانات. هذا يعني أن نفس مشاكل RLS التي تؤثر على الجداول تؤثر على الوصول إلى الملفات — وبضع مشاكل خاصة بالتخزين تظهر عندما تربط أدوات البرمجة بالذكاء الاصطناعي عمليات الرفع. هذه القائمة من 22 بندًا عبر خمسة أقسام: تكوين الدلو، وسياسات RLS، والتحقق من الرفع، وعناوين URL الموقَّعة، والنظافة التشغيلية. كل واحد قابل للتحقق في أقل من 15 دقيقة.

كل بند أدناه أساسي. للأساسيات التقنية لـ RLS، راجع ماسح Supabase RLS. لفئة كشف المفاتيح المجاورة للتخزين، راجع مفتاح Supabase service role المكشوف في JavaScript.

تكوين الدلو

ابدأ بالافتراضيات الصحيحة. يُسرِّب الدلو المُهيأ بشكل خاطئ الملفات سواء كان RLS الخاص بك صحيحًا أم لا.

  1. اجعل كل دلو افتراضيًا خاصًا. في لوحة Supabase → Storage → Buckets، اضبط مفتاح Public bucket على إيقاف ما لم يكن لديك سبب صريح (أصول تسويقية، صور رمزية عامة دون معلومات شخصية). تتجاوز الدلاء العامة RLS لعمليات القراءة — يمكن لأي شخص يعرف اسم الدلو سرد الملفات وتنزيلها.
  2. اضبط حدًا صلبًا لحجم الملف على كل دلو. لوحة → إعدادات الدلو → حد حجم الملف. 50 ميغابايت افتراضيًا منطقي لعمليات رفع المستخدمين؛ ارفعه عمدًا لحالات الاستخدام الخاصة بالفيديو / الملفات الكبيرة. بدون حد، يمكن لرفع خبيث واحد استنفاد حصة التخزين أو عرض النطاق الترددي الشهري.
  3. قيِّد أنواع MIME المسموح بها لكل دلو. قائمة أنواع MIME المسموح بها — قائمة سماح صريحة، لا قائمة حظر. image/jpeg وimage/png وimage/webp لدلاء الصور فقط. لا تسمح أبدًا بـ text/html أو application/javascript أو image/svg+xml في دلو محتوى مستخدم — تنفِّذ في المتصفح عند تقديمها عبر URL موقَّع.
  4. استخدم دلوًا واحدًا لكل نوع محتوى، لا دلوًا واحدًا مشتركًا. إعدادات كل دلو (الحجم وأنواع MIME وسياسات RLS) هي مستوى التفصيل الذي تملكه. دلو user-avatars ودلو document-uploads ودلو public-assets أسهل في التقييد من دلو واحد مختلط.
  5. تحقق من تكوين CORS إذا كانت عمليات الرفع من الواجهة الأمامية. إذا قام المستخدمون بالرفع مباشرة من المتصفح إلى URL موقَّع، يجب أن يسرد CORS الخاص بالدلو أصل الإنتاج الخاص بك. * مقبول للدلاء العامة فقط — أبدًا للدلاء التي تحتوي على معلومات شخصية للمستخدم.

سياسات RLS على storage.objects

يُخزِّن Supabase Storage بيانات وصف الملف في جدول storage.objects. يتحكم RLS على ذلك الجدول في من يستطيع القراءة أو الرفع أو التحديث أو الحذف. بدون RLS، يكون علم الدلو عام/خاص حمايتك الوحيدة.

  1. تأكد من تفعيل RLS على storage.objects. يجب أن يُرجع SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects'; القيمة true. يُفعّل Supabase ذلك افتراضيًا في المشاريع الجديدة؛ تحقق من عدم تعطيله.
  2. اكتب سياسة SELECT محصورة بـ auth.uid() للدلاء الخاصة. CREATE POLICY "users_read_own_files" ON storage.objects FOR SELECT USING (auth.uid()::text = (storage.foldername(name))[1]);. الاصطلاح هو تخزين الملفات تحت [user-id]/[filename] واستخدام storage.foldername() لاستخراج المالك من المسار.
  3. اكتب سياسة INSERT تُفرض نفس اصطلاح المسار. CREATE POLICY "users_upload_own" ON storage.objects FOR INSERT WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);. بدون WITH CHECK، يمكن لمستخدم مصادق الرفع إلى مجلد مستخدم آخر.
  4. أضف سياسات UPDATE وDELETE إذا كان تطبيقك يدعم تعديل أو حذف الملفات. يحتاج كل أمر إلى سياسته الخاصة. تخطي DELETE يعني أن المستخدمين المُصادقين لا يستطيعون إزالة ملفاتهم الخاصة؛ تخطي UPDATE يعني أن إعادة كتابة الملفات تفشل بصمت.
  5. اختبر الوصول عبر المستخدمين في جلستي متصفح. سجِّل الدخول كالمستخدم A، ارفع ملفًا، انسخ المسار. سجِّل الدخول كالمستخدم B في متصفح آخر، حاول جلب الملف عبر REST API. يجب أن تكون الاستجابة 403 أو 404، وليس 200 أبدًا.
sql
-- Confirm RLS on storage.objects
SELECT rowsecurity
FROM   pg_tables
WHERE  schemaname = 'storage' AND tablename = 'objects';

-- SELECT policy: scope reads to the owning user's folder.
CREATE POLICY "users_read_own_files"
  ON storage.objects
  FOR SELECT
  USING (auth.uid()::text = (storage.foldername(name))[1]);

-- INSERT policy: enforce the [user-id]/[filename] path convention.
CREATE POLICY "users_upload_own"
  ON storage.objects
  FOR INSERT
  WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);

التحقق من الرفع

تحقق من كل عملية رفع على الخادم، حتى عندما يكون للدلو قيود MIME والحجم. تُولِّد أدوات البرمجة بالذكاء الاصطناعي التحقق من جانب العميل فقط افتراضيًا؛ هذا لا يحمي شيئًا.

  1. أعد فحص نوع MIME على الخادم من بايتات الملف الفعلية، لا من ترويسة Content-Type. استخدم مكتبة مثل file-type (Node) أو شم البايتات السحرية. يمكن لمهاجم ادعاء Content-Type: image/jpeg على ملف هو في الواقع حمولة polyglot HTML / JavaScript.
  2. جرِّد بيانات EXIF من الصور المرفوعة. يمكن أن يحتوي EXIF على إحداثيات GPS، وأرقام تسلسلية للأجهزة، وطوابع زمنية. استخدم sharp مع .withMetadata(false) أو exif-parser للتجريد قبل التخزين.
  3. ارفض ملفات SVG التي تحتوي على وسوم script أو معالجات onload. SVG هو XML — والعديد من التطبيقات المُولَّدة بالذكاء الاصطناعي تسمح برفع SVG كـ "مجرد صورة". استخدم DOMPurify على الخادم أو ارفض رفع SVG تمامًا.
  4. استخدم أسماء ملفات حتمية لا يمكن تخمينها. لا تحتفظ بالاسم الأصلي. استخدم UUID أو هاش لمحتويات الملف. الأسماء الأصلية تُسرِّب ("passport_scan_2024_01_15.jpg") والأسماء التي يمكن التنبؤ بها تُمكِّن التعداد.

عناوين URL الموقَّعة

عناوين URL الموقَّعة هي كيف يصل العملاء إلى الدلاء الخاصة. تاريخ انتهاء الصلاحية، ونطاق الدلو، وما يُسجَّل، كلها مهمة.

  1. اجعل افتراضي انتهاء صلاحية URL الموقَّع ساعة واحدة أو أقل. دالة createSignedUrl(path, expiresIn) في Supabase JS SDK تأخذ ثوانٍ. لا تستخدم أبدًا قيمًا مثل 31536000 (سنة واحدة) — يصبح URL رابطًا دائمًا شبه عام.
  2. لا تخزِّن أبدًا عناوين URL الموقَّعة في قاعدة بياناتك. ولِّد عناوين جديدة على الخادم مع كل طلب. URL موقَّع مخزَّن بانتهاء صلاحية سنة واحدة يتسرب عبر تفريغ قاعدة بيانات يمنح وصولًا طويل الأمد.
  3. سجِّل توليد URL الموقَّع، لا فقط رفع الملفات. إذا اشتبهت في اختراق لاحقًا، فأنت بحاجة لمعرفة من ولَّد أي URL ومتى. سجِّل auth.uid() + الدلو + مسار الكائن + الطابع الزمني.
  4. استخدم خيار downloadAs عند تقديم الملفات المرفوعة من المستخدم. createSignedUrl(path, expiresIn, { download: '.jpg' }) يُجبر ترويسة Content-Disposition: attachment لتنزيل الملف بدلًا من عرضه — يهزم فئة تنفيذ HTML / SVG / HTML في PDF.

النظافة التشغيلية

تكوين التخزين ينحرف بمرور الوقت. هذه العناصر التشغيلية الأربعة تحافظ على السطح ضيقًا.

  1. راجع الدلاء فصليًا. لوحة → Storage → Buckets. تأكد من أن الحالة عام/خاص وقوائم أنواع MIME تتطابق مع ما يتوقعه التطبيق. الدلاء التي تُنشأ "مؤقتًا" تصبح دائمة إذا لم يُزلها أحد.
  2. راقب عمليات السرد المجهولة. سجلات التخزين (لوحة → Logs → Storage) تُسجِّل طلبات LIST. ارتفاع طلبات السرد المجهولة على دلو خاص يعني أن شخصًا ما يستكشفه من الخارج.
  3. اضبط سياسة احتفاظ للعمليات المؤقتة. الدلاء المؤقتة (معاينة الصور، المسودات المرفوعة) يجب أن تُحذف تلقائيًا بعد 24-72 ساعة عبر دالة مجدولة. الاحتفاظ غير المحدود مسؤولية بموجب التزامات تقليل البيانات في GDPR / CCPA.
  4. شغِّل مسح FixVibe شهريًا. فحص baas.supabase-storage-public يستكشف الدلاء التي تستجيب لـ GET + LIST المجهولين. تُضاف الدلاء الجديدة؛ تتغير الدلاء القديمة في الرؤية — فقط المسح المستمر يلتقط الانحراف.

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

شغِّل مسح FixVibe على عنوان URL الإنتاج — تظهر القوائم المجهولة للتخزين تحت baas.supabase-storage-public. اقرن هذه القائمة بـ ماسح Supabase RLS لطبقة الجدول ومفتاح Supabase service role المكشوف في JavaScript لمجاورة كشف المفاتيح. للتهيئات الخاطئة للتخزين عبر موفِّري BaaS الآخرين، راجع ماسح التهيئة الخاطئة لـ BaaS.

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

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

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

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

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

قائمة التحقق لأمان دلاء Supabase Storage: 22 بندًا — Docs · FixVibe