انتقل إلى المحتوى

الأمان

تقوم جميع منصّات المنظومة على أساس أمني واحد. وتحدّد هذه الصفحة ذلك الأساس؛ وعند إضافة منصّة جديدة عُدّ ما يلي متطلّبات لا خيارات.

الدفاع في العمق

تتراصّ الطبقات على مبدأ أنّ أي طبقة وحدها لا تكفي:

الطبقة الحماية
الحافّة (nginx) ‏TLS، وHSTS، وتحديد المعدّل، وحدّ لحجم جسم الطلب
التطبيق (HTTP) ترويسات أمنية، وقائمة سماح لـ CORS، وحماية CSRF، ومُدد انتهاء
التطبيق (المنطق) ‏RBAC، وفحص الصلاحيات، والتحقّق من المدخلات
قاعدة البيانات RLS، واستعلامات مُمَعلَمة
التدقيق سجل تدقيق مترابط بسلسلة تجزئة

الرمز لا يصل إلى جافاسكربت العميل

نمط BFF (Backend-for-Frontend) هو أساس أمن الواجهة الأمامية.

فالمتصفّح لا يخاطب الواجهة الخلفية مباشرةً إطلاقًا؛ بل يخاطب مسارات Next.js على النطاق نفسه، وهي تُمرّر الطلب إلى الخلفية من جهة الخادم. ويعيش الرمز في كوكي httpOnly.

والنتيجة: يكفّ XSS عن أن يكون طريقًا لسرقة الرموز. فحتى لو نجح المهاجم في تشغيل جافاسكربت، فلن يبلغ الرمز.

ويُضاف إلى ذلك حماية مزدوجة من CSRF: ترويسة مخصّصة وفحص الأصل (origin).

الترويسات الأمنية

في كل استجابة:

الترويسة الغرض
Content-Security-Policy يسدّ طريق تنفيذ هجمات XSS
Strict-Transport-Security يفرض HTTPS (‏HSTS)
Cross-Origin-Opener-Policy يعزل عن الهجمات بين النوافذ
Cross-Origin-Embedder-Policy يضبط الموارد الخارجية
Cross-Origin-Resource-Policy يقيّد استعمال الموارد من الخارج

ويعمل CORS بقائمة سماح — ولا يُستخدم * أبدًا.

أمن مستوى الصف في Postgres

يُفرَض عزل بيانات الجهات والمستخدمين على مستوى قاعدة البيانات، لا بشرط WHERE في شيفرة التطبيق.

والسبب: يكفي نسيان WHERE user_id = ? واحدة في الشيفرة حتى تتسرّب البيانات. أمّا RLS فيطبّق ذلك الفحص على كل استعلام، بمعزل عن أخطاء البرمجة.

حارس التحقّق عند الإقلاع

يتحقّق التطبيق عند إقلاعه من أنّ RLS مفعَّل فعلًا. فإن غابت السياسة، أو كان لمستخدم الاتّصال حقُّ تجاوز RLS، رفض التطبيق الإقلاع.

والسبب أنّ تعطُّل RLS بصمت هو أخطر الحالات جميعًا: إذ يبدو كل شيء وكأنّه يعمل على ما يرام.

SQL

  • استعلامات مُمَعلَمة — بلا وصل للسلاسل النصّية.
  • بلا ORM — ‏SQL يدوي فوق pgx. وكل استعلام ظاهر للعيان.

تحديد المعدّل ومُدد الانتهاء

الحماية الموضع
تحديد معدّل المصادقة (صارم) مسارات /login و/oauth و/auth و/api/auth
تحديد المعدّل العام للتطبيق (مرن) بقية المسارات
تحديد معدّل الواجهات البرمجية الواجهات العامة من نوع /v1/*
مُدد انتهاء خادم HTTP ‏read · write · idle · header — كلّها مضبوطة
حدّ حجم جسم الطلب عند الحافّة

الحدود الصارمة للمصادقة وحدها

وضعُ الحدّ الصارم للمصادقة على كل المسارات يجعل طلبات prefetch الخاصة بـ RSC في Next.js تتجاوز الحدّ فتتلقّى 503. ولذلك يوضع الحدّ الصارم على مسارات المصادقة فقط، وحدٌّ مرن على ما عداها.

إدارة الأسرار

  • تعمية الرموز — تُخزَّن رموز OAuth الخاصة بأطراف ثالثة (Google Drive وDropbox وغيرها) مشفَّرةً بـ AES-256-GCM.
  • مفاتيح التشفير — في وحدات HSM؛ ويتحوّل الجهاز الداخلي والسحابي أحدهما إلى الآخر عند العطل.
  • أسرار التطبيق — عبر متغيّرات البيئة، ولا تدخل git أبدًا.

لا تضع الأسرار في المستودع

بيانات اعتماد الخوادم، ومفاتيح API، وأسرار العملاء، وأرقام PIN لوحدات HSM — لا يُكتب أيٌّ منها إطلاقًا في مستودع أو نصّ برمجي أو وثيقة. ولا تتلقّى نصوصُ النشر الأسرارَ إلّا عبر متغيّرات البيئة.

وإن انكشف سرٌّ عرضًا: (1) بادر إلى تدويره فورًا، (2) راجع سجلّات الوصول، (3) انقله إلى نظام لإدارة الأسرار.

نقاط نهاية مغلقة في الإنتاج

يكشف /metrics و/swagger البنيةَ الداخلية وقائمةَ نقاط النهاية. وهما في الإنتاج محميّان برمز bearer.

سجل التدقيق

سجلّ مترابط بسلسلة تجزئة، للإضافة فقط. ويحوي كل قيدٍ فيه تجزئةَ القيد الذي سبقه.

ومعنى ذلك: لا يمكن حذف أو تعديل أي قيد في الوسط — إذ تنقطع السلسلة ويسقط فحصُ السلامة. ولا يقرؤه إلّا المشرف، وثمّة عملية مستقلّة للتحقّق من سلامته.

التوقيع وعدم الإنكار

تستلزم الأفعال ذات الأثر القانوني توقيعًا بـPIN2؛ فالمصادقة (PIN1) لا تكفي. راجع التفصيل في المصادقة والصلاحيات.

والمفتاح الخاص للتوقيع مقسومٌ بـECDSA عتَبيّة 2-of-2 — فلا يستطيع أيّ طرف التوقيعَ بمفرده.

الاختبار

  • اختبارات وحدة — لمنطق الأعمال وفحوص الصلاحيات.
  • اختبارات تكامل بـ testcontainers — مقابل PostgreSQL/Redis حقيقيَّين، تختبر RLS اختبارًا فعليًا.
  • اختبارات المتجهات الذهبية — للتوافق التشفيري على مستوى البروتوكول.

قائمة التحقّق الأمنية

قبل خروج أي منصّة جديدة إلى الإنتاج:

  • [ ] تفعيل TLS وHSTS، وتجديد الشهادات تلقائيًا
  • [ ] ضبط جميع الترويسات الأمنية (CSP · HSTS · COOP · COEP · CORP)
  • [ ] قائمة سماح لـ CORS — من دون *
  • [ ] تحديد المعدّل: صارم للمصادقة، مرن لما عداها
  • [ ] ضبط جميع مُدد انتهاء خادم HTTP
  • [ ] تفعيل RLS وعمل حارس الإقلاع
  • [ ] جميع الاستعلامات مُمَعلَمة
  • [ ] الرموز في كوكيز httpOnly ولا تصل إلى جافاسكربت العميل
  • [ ] حماية مزدوجة من CSRF
  • [ ] إغلاق /metrics و/swagger
  • [ ] كتابة سجل التدقيق وإمكان التحقّق من سلامته
  • [ ] الأسرار عبر متغيّرات البيئة وغيابها عن المستودع
  • [ ] اختبارات التكامل تختبر RLS اختبارًا فعليًا