الأمان
نموذج أماننا في جملة واحدة: لا يوجد شيء على الخادم يمكن مهاجمته. كل ما يلي قابل للتحقق من DevTools لديك.
البنية التقنية
Abundera QR تطبيق صفحة واحدة ثابت يُقدَّم من Cloudflare Pages. لا يوجد خادم تطبيقات، ولا قاعدة بيانات، ولا حسابات مستخدمين، ولا مصادقة، ولا نقاط نهاية API، ولا أي مسار كود خلفي يعالج بيانات المستخدم. كل عملية توليد وتشفير وفحص وعرض لرمز QR تعمل بالكامل داخل متصفحك.
نموذج التهديد
بما أننا لا نجمع ولا نخزن ولا ننقل أي بيانات مستخدم، فإن أكثر تهديدات تطبيقات الويب شيوعًا, سرقة بيانات الاعتماد، واختراق قواعد البيانات، واختطاف الجلسات، والحقن من جانب الخادم, لا تنطبق علينا. المساحة المتبقية للهجوم هي حزمة الأصول الثابتة (HTML وCSS وJavaScript) المقدَّمة من مصدرنا. نصمم بافتراض:
- اختراق المصدر: يستبدل المهاجم أحد أصولنا المجمَّعة بأصل ضار. يحدّ CSP أدناه من نطاق الضرر؛ وتجعل رموز cache-buster التراجع إلى نسخة معروفة الصحة أمرًا سهلًا.
- المدخلات المقدَّمة من المستخدم: حمولات QR، وأسماء vCard، وكلمات مرور Wi-Fi، وصفوف CSV دُفعية، ومحتويات الصور الممسوحة. كل مسار إدخال يُعامَل كمحتوى غير موثوق عند عرضه مجددًا في DOM.
- الصور المقدَّمة من المستخدم: روابط صور vCard وتحميلات الشعارات. تُعرض الصور في canvas ولا تُضمَّن أبدًا في DOM كترميز خام.
- إضافات المتصفح التابعة لجهات خارجية: خارج النطاق. إن كانت إضافة في متصفحك تملك صلاحية تعديل كل صفحة، فبإمكانها تعديل صفحاتنا. ضماناتنا سارية عند تحميل الصفحة دون تعديل.
سياسة أمان المحتوى, بحسب كل توجيه
السياسة الحالية (يمكن التحقق منها في رؤوس الاستجابة لأي طلب):
Content-Security-Policy:
default-src 'self';
script-src 'self' 'wasm-unsafe-eval';
worker-src 'self' blob:;
style-src 'self' 'unsafe-inline';
font-src 'self';
img-src 'self' data: blob: https:;
connect-src 'self' https:;
frame-ancestors 'none';
base-uri 'self';
form-action 'self'ما يتيحه كل توجيه وأين يُقدِّم تنازلًا:
default-src 'self', الحد الأدنى الصارم. كل ما لا نُخفِّفه صراحةً يبقى محصورًا في نفس المصدر.script-src 'self' 'wasm-unsafe-eval', لا<script>مضمَّن، ولاeval(). يستلزم'wasm-unsafe-eval'مسار تجميع WebAssembly الخاص بمكتبة تشفير QR لدينا؛ وهو لا يُتيحeval()التقليدي. يفحص فحص ما قبل النشر لدينا كل صفحة HTML بحثًا عن سكريبتات مضمَّنة ويُخفق البناء عند اكتشافها.style-src 'self' 'unsafe-inline', تنازل حقيقي. يحسب معاينة QR لدينا الألوان على مستوى البكسل بشكل مضمَّن (سمات style على الوحدات الفردية). ستنجح قائمة السماح المعتمدة على التجزئة لكنها ستفشل عند أي تحديث للأنماط دون نشر. المقايضة: نقبل سياسة أنماط أضعف قليلًا؛ لا يستطيع التصميم تسريب البيانات على أي حال (لا يملك CSS نطاق وصولconnect-src).img-src 'self' data: blob: https:,data:لعروض QR المضمَّنة، وblob:لروابط تنزيل التصدير، وhttps:لروابط صور vCard المقدَّمة من المستخدم. الروابط المقدَّمة من المستخدم لا تُنفَّذ أبدًا، بل تُعرض فقط.connect-src 'self' https:, يقتصر fetch() على مصدرنا وعمليات جلب HTTPS التي يبدؤها المستخدم (مثل مسح رابط صورة). يمنع التسريب عبر DNS / WebSocket / beacon إلى مضيفين عشوائيين.frame-ancestors 'none', لا يمكن لأي موقع آخر تضمينا. يمنع clickjacking.base-uri 'self', لا يستطيع وسم<base>مُحقَن بشكل ضار إعادة توجيه الروابط النسبية إلى مصدر المهاجم.form-action 'self', أي نموذج مُحقَن لا يمكنه الإرسال إلا إلى مصدرنا. ليس لدينا نماذج ترسل البيانات من جانب الخادم؛ هذا تدبير احترازي مضاعف.
تسري سياسات CSP مختلفة على /bio/* (تخفيف img-src للصور الرمزية المقدَّمة من المستخدم) و/embed/* (تخفيف frame-ancestors للتضمين المقصود). كلاهما موثَّق في site/_headers.
رؤوس النقل والإطارات
- HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload, سنة كاملة، جميع النطاقات الفرعية، مؤهَّل لقائمة HSTS preload. ترفض المتصفحات المتوافقة الرجوع إلى HTTP. - X-Frame-Options: DENY, يتكرر مع
frame-ancestorsفي CSP، لكنه محتفظ به لتغطية المتصفحات القديمة. - X-Content-Type-Options: nosniff, يمنع هجمات ارتباك MIME.
- Referrer-Policy: strict-origin-when-cross-origin, نقرات الروابط الخارجية تُسرِّب المصدر دون المسار.
- Permissions-Policy:
camera=(self), microphone=(), geolocation=(), الكاميرا مسموح بها فقط لماسحنا الخاص؛ الميكروفون والموقع مرفوضان صراحةً حتى عند التضمين.
Service Worker
يخزن Service Worker لدينا (site/sw.js) مؤقتًا الأصول من المصدر ذاته فقط. يرفض معالج الجلب صراحةً الطلبات عبر المصادر والأساليب غير GET, يمكنك قراءة المنطق على GitHub. تُغلَّف عمليات الكتابة في الذاكرة المؤقتة بـevent.waitUntil() لئلا تُحذف في منتصف التنقل.
تعقيم المدخلات
كل مسار عرض يقبل مدخلات المستخدم يعاملها كنص غير موثوق:
- معاينات حمولة QR تستخدم
textContentلاinnerHTML. - أهداف المشاركة (الحافظة،
navigator.share()) تمرر نص المستخدم كسلسلة نصية لا كترميز. - تصدير SVG يُوَلَّد من مكتبة التشفير لدينا؛ محتوى المستخدم يُشفَّر بـbase64 في
xlink:hrefالخاص بـ<image>، ولا يُحقَن كعناصر SVG. - معاينات الطباعة تستخدم رابط blob لا
document.write(). - تحليل localStorage مُغلَّف بـ
try/catch, تُنتج إدخالات تالفة قيمة افتراضية فارغة جديدة، لا استثناءً قد يتكشَّف في مسار كود حيّ. - الروابط المقدَّمة من المستخدم والمعروضة كأزرار "فتح رابط" مقيَّدة بـ
http(s)://, تُرفض مخططاتjavascript:وdata:.
جلب الصور عبر المصادر
عندما يلصق المستخدم رابط https: كصورة vCard أو شعار، يجلبه المتصفح وفق CORS وقائمة سماح img-src في CSP. تُعرض الصورة في canvas. لا تصبح DOM حيًّا، ولا تُنفَّذ كود، ولا تصل إلى مصدرنا, الجلب يتم من المتصفح إلى الصورة البعيدة مباشرةً، والنتيجة تُرسم من جانب العميل. مهاجم يتحكم في رابط صورة بعيدة يمكنه تتبع تحميل الرابط (سطر سجل في خادمه) لكن لا يستطيع تسريب أي شيء من صفحتنا.
تكامل الموارد الفرعية (SRI)
جميع JavaScript وCSS التي نشحنها من المصدر ذاته. لا نحمِّل سكريبتات أو أوراق أنماط تابعة لجهات خارجية، لذا لا تنطبق تجزئات SRI. إن حمَّلنا أصلًا تابعًا لجهة خارجية مستقبلًا، سنضيف سمة integrity عليه ونوثِّق عملية تحديث التجزئة في هذه الصفحة.
الإبلاغ عن ثغرة أمنية
إن اكتشفت مشكلة أمنية تؤثر على Abundera QR, سواء في كودنا أو في عملية النشر أو في إحدى التبعيات التي نشحنها, يرجى الإبلاغ عنها بشكل خاص إلى security@abundera.ai. نهدف إلى الفرز خلال 72 ساعة. يمكنك أيضًا التواصل معنا عبر تفاصيل الاتصال في ملف /.well-known/security.txt.
لا برنامج مكافآت (حتى الآن)
لا نقدم مكافآت مدفوعة حاليًا، لكن كل تقرير صحيح مؤكَّد يحصل على ذكر في سجل التغييرات وشكرنا العلني.
التحقق من كل ما سبق
كل ادعاء في هذه الصفحة قابل للتحقق من DevTools المتصفح دون الحاجة إلى الوثوق بنا:
- CSP: DevTools ← Network ←
/← Headers. اقرأ رأس الاستجابةContent-Security-Policy. - HSTS ورؤوس الأمان: في المكان ذاته, كل
Strict-Transport-SecurityوX-Frame-Optionsوغيرها مرئية. - لا اتصالات خارجية: DevTools ← Network ← Fetch/XHR. ولِّد رمز QR. راقب العداد يبقى على صفر.
- نطاق Service Worker: DevTools ← Application ← Service Workers. تحقق من مصدر السكريبت وقائمة الأصول المخزَّنة مؤقتًا.
- لا كوكيز: DevTools ← Application ← Cookies. فارغ.
- جولة كاملة: قسم التحقق في البيان.
التواصل
الإفصاحات الأمنية: security@abundera.ai