دليل CSP: إغلاق Shopify الهيدروجين
البرمجة النصية عبر المواقع (XSS) هي التهديد رقم 1 للتجارة بلا رأس. دليل فني لتنفيذ نظام الطاقة الشمسية المركزة الصارم مع Nonces في الريمكس والهيدروجين.
في التجارة الإلكترونية، الثقة هي العملة الوحيدة. إذا قام أحد العملاء بكتابة رقم بطاقة الائتمان الخاصة به في موقعك، فهو يثق بك لتأمينه. ولكن إذا كانت لديك ثغرة أمنية Cross-Site Scripting (XSS)، فيمكن للمهاجم إدخال برنامج نصي يقرأ ضغطات المفاتيح. المهاجم يحصل على بطاقة الائتمان. تحصل على الدعوى.
الدفاع ضد XSS هو سياسة أمان المحتوى (CSP). إنها القائمة البيضاء. يخبر المتصفح: “قم فقط بتحميل البرامج النصية من هذه المجالات. احظر كل شيء آخر.”
يعد تنفيذ CSP في تطبيق صفحة واحدة (SPA) مثل Shopify Hydrogen (Remix) أمرًا صعبًا للغاية بسبب الترطيب وعلامات الطرف الثالث. هذا هو الدليل النهائي للقيام بذلك بشكل صحيح.
لماذا تتحدث Maison Code عن هذا
في Maison Code Paris، نعمل كضمير معمari لعملائنا. غالبًا ما نرث حزمًا “حديثة” تم بناؤها دون فهم أساسي للحجم.
نناقش هذا الموضوع لأنه يمثل نقطة تحول حاسمة في النضج الهندسي. التنفيذ الصحيح يميز MVP الهش عن منصة مؤسسية مرنة يمكنها التعامل مع حركة مرور الجمعة السوداء.
1. الإستراتيجية: CSP صارم مع عدم وجود أرقام
في الماضي، كنا نستخدم “القائمة البيضاء للنطاق”.
script-src 'self' https://google-analytics.com https://facebook.com
هذا غير آمن. إذا كان لدى Google Analytics ثغرة أمنية في Open Redirect، فيمكن للمهاجم تجاوز موفر الخدمة الخاص بك.
المعيار الحديث هو Nonces (الرقم المستخدم مرة واحدة).
- يقوم الخادم بإنشاء رمز تشفير عشوائي (
abc123yz) لكل كل طلب. - يضيف الخادم رأسًا: `سياسة أمان المحتوى: script-src ‘nonce-abc123yz”.
- يتضمن HTML الرمز المميز:
<script nonce="abc123yz">.
إذا قام المهاجم بإدخال <script>alert(1)</script>، فلن يكون له حرف nonce. المتصفح يمنعه
2. التنفيذ في الريمكس (الهيدروجين)
في Remix، نحتاج إلى إنشاء الرقم nonce في أداة تحميل الجذر وتمريره.
الخطوة 1: إنشاء Nonce في entry.server.tsx
// التطبيق/entry.server.tsx
استيراد { generatorNonce } من './utils'؛ // crypto.randomBytes(16).toString('base64')
تصدير الوظيفة الافتراضية HandleRequest(request, ResponseStatusCode, ResponseHeaders, remixContext) {
const nonce = generatorNonce();
// تحديد التوجيهات
ثابت CSP = [
"افتراضي-src 'ذاتي'"،
`script-src 'self' 'nonce-${nonce}' https://cdn.shopify.com https://challenges.cloudflare.com`,
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com"، // غير آمن مضمن مطلوب لـ CSS-in-JS عادةً
"بيانات img-src "الذاتية": https://cdn.shopify.com"،
"connect-src 'self' https://monorail-edge.shopifysvc.com https://www.google-analytics.com"،
"frame-ancestors 'none'"، // مكافحة Clickjacking
].join(';');
ResponseHeaders.set('سياسة أمان المحتوى', csp);
// قم بتمرير nonce إلى السياق حتى يتمكن <Scripts /> من استخدامه
return <RemixServer context={remixContext} url={request.url} nonce={nonce} />;
}
الخطوة 2: قم بإرفاق Nonce بالبرامج النصية في root.tsx
// التطبيق/root.tsx
استيراد { useNonce } من '@shopify/hydrogen'؛
تصدير الوظيفة الافتراضية التطبيق () {
const nonce = useNonce();
العودة (
<html لانج="ar">
<الرأس>
<ميتا />
<الروابط />
</الرأس>
<الجسم>
<مخرج />
<ScrollRestoration nonce={nonce} />
<مخطوطات nonce={nonce} />
</الجسم>
</html>
);
}
الآن، كل علامة نصية تم إنشاؤها بواسطة Remix سيكون لها قانونيًا الرقم nonce.
3. نظام “التقرير فقط” الآمن من الفشل
إن نشر CSP أمر مخيف. إذا نسيت أحد النطاقات (على سبيل المثال، fonts.gstatic.com)، فسيتعطل موقعك.
الحل: وضع التقرير فقط.
- قم بتعيين الرأس “تقرير سياسة أمان المحتوى فقط”.
- سيقوم المتصفح بتحميل الموارد ولكن تسجيل الانتهاك إلى وحدة التحكم (ونقطة النهاية).
- قم بتشغيل هذا لمدة أسبوعين. مراقبة السجلات.
- بمجرد تنظيف السجلات، قم بالتبديل إلى وضع الفرض.
4. إعداد التقارير: استخدام الحراسة
قراءة انتهاكات CSP في وحدة التحكم غير مجدية لمستخدمي الإنتاج.
أنت بحاجة إلى نقطة نهاية المجموعة.
يدعم Sentry (و Datadog) القيم الأساسية لإعداد تقارير CSP.
تقرير-uri https://o450.ingest.sentry.io/api/.../security/?sentry_key=...;
عندما يقوم مستخدم في البرازيل بانتهاك CSP (ربما امتدادًا للبرامج الضارة)، ينبهك Sentry.
تصفية الضوضاء: سترى الكثير من الضوضاء الصادرة عن ملحقات المتصفح (يتسبب LastPass في حدوث انتهاكات). تجاهل مخططات “امتداد moz” و”امتداد الكروم”. التركيز على الحقن http.
5. سلامة الموارد الفرعية (SRI)
ماذا لو تم اختراق CDN؟
إذا قمت بتحميل https://code.jquery.com/jquery.min.js، وقام أحد المتسللين بتعديل هذا الملف على CDN، فسيتجاوز CSP الخاص بك (لأن النطاق مدرج في القائمة البيضاء).
الإصلاح: استخدم SRI.
<script src="..." Integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..." crossorigin="anonymous"></script>
يقوم المتصفح بتجزئة الملف الذي تم تنزيله. إذا لم يتطابق مع السمة النزاهة، فإنه يرفض التنفيذ.
وهذا يضمن عدم إمكانية تغيير الكود دون نشر ملف HTML جديد.
6. جحيم الطرف الثالث (Google Tag Manager)
التسويق يحب GTM. الأمن يكره GTM. تقوم GTM بإدخال البرامج النصية بشكل ديناميكي. هل تقوم GTM بنشر nonce؟ نعم، إذا تم تكوينها بشكل صحيح.
في مقتطف GTM الخاص بك، يجب عليك فحص “nonce” النص الأصلي وتمريره للأمام.
ومع ذلك، فإن معظم وحدات البكسل التابعة لجهات خارجية (Facebook) ليست على علم بذلك.
الحل الوسط: غالبًا ما يتعين عليك إدراج نطاقاتهم في القائمة البيضاء في script-src بالإضافة إلى nonce.
script-src 'self' 'nonce-...' https://connect.facebook.net ...
5. منع Clickjacking (أسلاف الإطار)
تحدث عملية Clickjacking عندما يقوم أحد المهاجمين بتضمين موقعك في "). لقد وضعوا زرًا غير مرئي “Win iPhone” أعلى زر “Buy Now” الخاص بك. يعتقد المستخدم أنه ينقر على “فوز”، لكنه ينقر على “شراء”.
الإصلاح: “لا شيء” لأسلاف الإطار.
وهذا يمنع أي شخص من استخدام إطار iframe لموقعك.
إذا كنت بحاجة إلى استخدام إطار iframe (على سبيل المثال، بواسطة شريك)، فقم بإدراجهم في القائمة البيضاء: frame-ancestors 'self' https://partner.com.
6. هل تم انتهاك خدمة CSP؟ ماذا يحدث؟
عند انتهاك CSP، يقوم المتصفح بإلقاء خطأ مبسط في وحدة التحكم.
تم رفض تحميل البرنامج النصي من 'http://evil.com/hack.js' لأنه ينتهك توجيه سياسة أمان المحتوى التالي: "script-src 'self'...".
بالنسبة للمستخدم، يفشل تنفيذ البرنامج النصي الضار ببساطة. بقية الموقع يعمل بشكل جيد. يتم تحييد الهجوم بصمت.
7. الأنواع الموثوقة (مستقبل دفاع XSS)
يقوم CSP بحظر تحميل البرامج النصية الضارة.
الأنواع الموثوقة تمنع كتابة التعليمات البرمجية الضارة.
إنه يفرض عليك تعقيم السلاسل قبل أن تلمس DOM.
element.innerHTML = dirtyString; -> خطأ في المتصفح المحظور.
يجب عليك تغليفه:
element.innerHTML = DOMPurify.sanitize(dirtyString);
يؤدي هذا إلى إنشاء كائن “السياسة”. يضمن المتصفح أن السلاسل التي تم إنشاؤها بواسطة السياسة هي فقط التي يمكنها لمس DOM.
إنه يدمر فئة كاملة من ثغرات XSS المستندة إلى DOM.
8. أمن عمال الويب
العمال (عمال الخدمة، عمال الويب) معزولون. لكن لا يزال من الممكن أن يشكلوا خطورة (تعدين العملات المشفرة). يجب عليك تقييدها عبر توجيهات محددة:
worker-src 'self' blob:;: السماح للعمال من المجال الخاص بك فقط.- “child-src ‘self”: يقيد إطارات iframe والعاملين. يحب المهاجمون تدوير العامل في الخلفية لمواقع DDOS الأخرى أو استخراج البيتكوين. CSP الخاص بك يوقف هذا.
10. CSP لـ WebAssembly (WASM)
إذا كنت تستخدم WASM (على سبيل المثال، لتغيير حجم الصور من جانب العميل)، فستحتاج إلى توجيهات خاصة.
يعد script-src 'unsafe-eval' (لتجميع WASM) أمرًا خطيرًا. تدعم المتصفحات الحديثة: script-src ‘wasm-unsafe-eval’.
يسمح هذا لـ WASM بالتجميع دون فتح الباب أمام JavaScript eval().
إنه يبقي الأجزاء “السيئة الجيدة” منفصلة عن الأجزاء “السيئة السيئة”.
11. دورة حياة Nonce (نطاق الطلب)
Nonce عديمة الفائدة إذا كانت ثابتة.
إذا قمت بترميز nonce="123" في ملف HTML الخاص بك، فسيقوم المهاجم فقط بإدخال <script nonce="123">.
يجب إنشاء Nonce لكل طلب.
** نمط الريمكس **:
entry.server.tsx: إنشاءnonce = crypto.randomUUID().- قم بالتمرير إلى
<RemixServer nonce={nonce}>. - قم بترطيب العميل باستخدام
<Scripts nonce={nonce}>. وهذا يضمن أنه إذا قمت بتحديث الصفحة، فسوف أحصل على رقم جديد. لا يستطيع المهاجم تخمين ذلك.
12. الأنماط مقابل البرامج النصية (“غير آمنة مضمّنة”)
غالبًا ما نسمح بـ style-src 'unsafe-inline'. لماذا؟ لأن مكتبات CSS-in-JS (Emotion، Styled Components) تقوم بإدخال علامات .css` ثابتة.
ثم يمكنك إزالة “unsafe-inline” وتحقيق CSP Nirvana.
13. لماذا ميزون كود؟
في Maison Code، نؤمن بأن الأمان هو السمعة. الاختراق لا يكلف المال فقط؛ يكلف الثقة. نحن لا نستقر على “إنه يعمل”. نحن نطالب “أنها آمنة”. نحن نطبق Strict Crypto-Nonce CSPs لكل عميل. نقوم برصد مخالفات (السنتري) وترقيع الثغرات قبل استغلالها. نحن ننام جيدًا في الليل لأننا نعرف أن المتصفح يفرض قواعدنا.
12. الاستنتاج
إن CSP الصارم هو السمة المميزة لفريق هندسي ناضج. يُظهر أنك تفهم البيئة المعادية للويب. إنه يحمي عملائك من Magecart و keyloggers وتسلل البيانات. من الصعب إعداده، ولكنه إلزامي لأي علامة تجارية تلتقط بيانات الدفع. لا تنتظر الاختراق. قفل الباب الآن.
هل متجرك معرض للخطر؟
نقوم بإجراء اختبار الاختراق وتنفيذ CSP للعلامات التجارية Shopify Plus.