سياسة أمان المحتوى (CSP): الجهاز المناعي للويب
منع هجمات XSS وMagecart. دليل نهائي لتنفيذ CSP الصارم مع Nonces، ووضع التقرير فقط، و"الديناميكية الصارمة" في Remix/Hydrogen.
في عام 2018، تعرضت الخطوط الجوية البريطانية لاختراق كارثي للبيانات. سرق المتسللون تفاصيل بطاقة الائتمان الخاصة بـ 380 ألف عميل. ولم يقتحموا قاعدة البيانات. لم يخمنوا كلمة مرور المسؤول. لقد أدخلوا 22 سطرًا من JavaScript في صفحة الدفع عبر مكتبة خارجية مخترقة. يقرأ هذا البرنامج النصي مدخلات النموذج بصمت ويرسلها إلى “baways.com” (نطاق مزيف).
هذا هجوم على سلسلة التوريد (على وجه التحديد Formjacking أو Magecart). الجزء المخيف؟ لا يمكن لجدار الحماية (WAF) الخاص بك إيقافه. يأتي الطلب من متصفح المستخدم، وليس من الخادم الخاص بك.
الدفاع الوحيد ضد ذلك هو سياسة أمان المحتوى (CSP). CSP هو رأس HTTP يخبر المتصفح: “هذه هي المجالات الموثوقة. احظر كل شيء آخر.”
في Maison Code Paris، نعتبر CSP إلزاميًا لأي موقع ينفذ المعاملات. إن التشغيل بدونه يشبه ترك باب القبو مفتوحًا لأن “القفل يصعب استخدامه”.
لماذا تتحدث Maison Code عن هذا
في Maison Code Paris، نعمل كضمير معمari لعملائنا. غالبًا ما نرث حزمًا “حديثة” تم بناؤها دون فهم أساسي للحجم.
نناقش هذا الموضوع لأنه يمثل نقطة تحول حاسمة في النضج الهندسي. التنفيذ الصحيح يميز MVP الهش عن منصة مؤسسية مرنة يمكنها التعامل مع حركة مرور الجمعة السوداء.
لماذا يفرض قانون Maison قواعد صارمة على CSP
الأمان ليس وظيفة إضافية؛ هذا هو خط الأساس لدينا. بالنسبة لتجارة التجزئة المتخصصة ذات القيمة العالية، فإن خطر Magecart (القشط الرقمي) يعد خطرًا وجوديًا. لقد قمنا مؤخرًا بتدقيق عميل محتمل ووجدنا مكونًا إضافيًا ضارًا لـ jQuery يجمع مدخلات بطاقة الائتمان. لقد كان هناك لمدة 6 أشهر. كان من الممكن أن يقوم CSP الصارم بحظر هذا على الفور. نحن ننفذ CSP غير المعتمد على كل واجهة متجر بدون رأس نشحنها، مما يضمن أن التعليمات البرمجية التي نثق بها صراحة هي الوحيدة التي يمكن تنفيذها في متصفح عميلك.
الآلية: القائمة البيضاء
بشكل افتراضي، تكون متصفحات الويب الحالية غير شرعية. إذا كان HTML يقول <script src="https://evil.com/hack.js">، فسيقوم المتصفح بتحميله.
يقوم CSP بتغيير هذا الإعداد الافتراضي إلى “رفض الكل”.
سياسة أمان المحتوى: default-src 'self'; script-src 'self' https://analytics.google.com;
باستخدام هذا الرأس، إذا قام أحد المهاجمين بإدخال <script src="https://evil.com/hack.js">، فستصرخ وحدة تحكم المتصفح باللون الأحمر: تم رفض تحميل البرنامج النصي لأنه ينتهك توجيه سياسة أمان المحتوى التالي. لا يتم تنفيذ البرنامج النصي أبدًا.
الاستراتيجية: الطاقة الشمسية المركزة غير القائمة على التركيز (Strict CSP)
نطاقات القائمة البيضاء (https://google.com) هشة. تستضيف Google ملايين النصوص البرمجية (Drive والخرائط ومحتوى المستخدم). إذا تمكن أحد المهاجمين من تحميل ملف إلى Google Drive، فيمكنه تجاوز القائمة البيضاء الخاصة بك.
المعيار الذهبي هو مزود خدمات الطاقة الشمسية المعتمد على غير أساس. Nonce (الرقم المستخدم مرة واحدة) هو رمز تشفير عشوائي يتم إنشاؤه بواسطة الخادم لكل طلب.
- إنشاء الخادم:
const nonce = crypto.randomBytes(16).toString('base64'); // "r4nd0m" - الرأس: `script-src ‘nonce-r4nd0m”
- حقن HTML:
<script nonce="r4nd0m" src="/app.js"></script>
إذا قام المهاجم بإدخال <script>alert(1)</script>، فلن يعرف الرقم. المتصفح يمنعه
التنفيذ في الهيدروجين (ريمكس)
في تطبيق يتم عرضه من جانب الخادم (SSR) مثل Hydrogen، نقوم بإنشاء الرقم nonce في “entry.server.tsx”.
// التطبيق/entry.server.tsx
استيراد { createContentSecurityPolicy } من '@shopify/hydrogen'؛
تصدير وظيفة المزامنة الافتراضية HandleRequest(request, ResponseStatusCode, ResponseHeaders, remixContext) {
// مساعد الهيدروجين يولد الرقم والرأس
const { nonce, header, NonceProvider } = createContentSecurityPolicy({
// التوجيهات القياسية
defaultSrc: ["'ذاتي'"]،
imgSrc: ["'self'"، 'cdn.shopify.com'، 'data:'، 'https://www.google-analytics.com']،
styleSrc: ["'self'"، "'unsafe-inline'"]، // صالح للمكونات المصممة
ConnectSrc: ["'self'"، 'https://monorail-edge.shopifysvc.com'، 'https://vitals.vercel-insights.com']،
// الجزء الحاسم
البرنامج النصي: [
""النفس""،
// "ديناميكية صارمة" تخبر المتصفحات الحديثة: "الوثوق بأي برنامج نصي تم تحميله بواسطة برنامج نصي موثوق به"
// يسمح هذا لـ GTM بتحميل Facebook Pixel دون إدراج Facebook في القائمة البيضاء بشكل صريح.
""ديناميكية صارمة""،
// احتياطي للمتصفحات القديمة
"https://cdn.shopify.com"،
"https://www.googletagmanager.com"
]،
});
ResponseHeaders.set('سياسة أمان المحتوى', header);
العودة (
يقوم // NonceProvider بتمرير الرقم nonce إلى مكون <Scripts />
<NonceProvider>
<RemixServer context={remixContext} url={request.url} />
</NonceProvider>
);
}
التوجيه “الديناميكي الصارم”.
تستخدم المواقع الحديثة Google Tag Manager (GTM). يقوم GTM بتحميل Facebook Pixel. يقوم Facebook Pixel بتحميل نصوص التتبع الأخرى. لا يمكنك التنبؤ بالشجرة الكاملة للتبعيات. وقد أدى ذلك إلى قيام المطورين بتمكين “التقييم غير الآمن” و”غير الآمن المضمّن”، وهو ما يتعارض مع غرض CSP.
ديناميكية صارمة تحل هذه المشكلة.
تقول: “إذا كان البرنامج النصي موثوقًا به (يحتوي على رقم صالح)، فاسمح له بتحميل البرامج النصية الأخرى ديناميكيًا.”
وبما أننا نثق في GTM (من خلال عدم نشرها)، فإننا نثق في ما تقوم GTM بتحميله.
تحذير: هذا يضع الكثير من الثقة في GTM. تأكد من أن حاوية GTM الخاصة بك تتمتع بضوابط وصول صارمة.
تحديد التوجيهات
تغطي السياسة القوية ما هو أكثر من النصوص البرمجية.
base-uri 'none': يمنع سرقة العلامات<base>(إعادة توجيه الروابط النسبية إلى المواقع الشريرة).object-src 'none': يحظر تطبيقات Flash وJava و<embed>.frame-ancestors 'none': يمنع Clickjacking. لا يمكن وضع موقعك في Iframe.form-action 'self': يضمن إمكانية إرسال النماذج إلى واجهة برمجة التطبيقات (API) الخاصة بك فقط. يمنع المهاجمين من تغيير إجراء النموذج إلى الخادم الخاص بهم.connect-src: يقيدfetch()/XHR. حتى إذا قام المهاجم بتنفيذ JS، فلن يتمكن من إرسال البيانات إلى “evil.com”.
النشر بأمان: وضع التقرير فقط
لا يمكنك “تشغيل” CSP بعد ظهر يوم الجمعة. سوف تكسر الموقع. سوف تقوم بحظر أداة الدردشة. سوف تقوم بحظر تطبيق المراجعات. عليك أن تبدأ في وضع التقرير فقط.
تقرير سياسة أمان المحتوى فقط: default-src 'self'؛ ... تقرير-uri /api/csp-report;
سيقوم المتصفح بتنفيذ كل شيء، ولكنه سيرسل تقرير انتهاك JSON إلى الواجهة الخلفية لديك عندما يمنع شيئًا ما.
نقطة نهاية المجمع
أنت بحاجة إلى خدمة لاستيعاب هذه التقارير. من الأفضل استخدام Sentry أو Datadog؛ يصورون الانتهاكات.
{
"تقرير CSP": {
"document-uri": "https://maisoncode.paris/checkout",
"المرجع": ""،
"التوجيه المنتهك": "script-src"،
"التوجيه الفعال": "script-src"،
"original-policy": "default-src 'self'؛ script-src 'nonce-xyz'"،
"blocked-uri": "https://malicious-analytics.com/tracker.js",
"رمز الحالة": 200
}
}
سير العمل:
- قم بنشر “التقرير فقط”.
- انتظر أسبوعًا واحدًا.
- تحليل السجلات. “آه، لقد نسينا إضافة علامة Pinterest إلى القائمة البيضاء.”
- تحديث السياسة.
- عندما تكون السجلات هادئة (الهجمات الفعلية فقط)، قم بالتبديل إلى “سياسة أمان المحتوى” (فرض).
كود إعادة البناء لـ CSP
يجبرك CSP على كتابة تعليمات برمجية أفضل. إنه يحظر معالجات الأحداث المضمنة.
سيء (محظور):
<button onclick="trackClick()">شراء</button>
جيد (مسموح):
<button id="buyBtn">شراء</button>
<script nonce="...">document.getElementById('buyBtn').addEventListener('click',trackClick);</script>
إنه يفصل السلوك عن العلامات.
10. الأنواع الموثوقة (مستقبل منع XSS)
يقوم CSP بحظر مصدر البرنامج النصي.
الأنواع الموثوقة تحظر الحوض (HTML الداخلي).
إنه يجبر المطورين على تعقيم السلاسل قبل حقنها.
div.innerHTML = string -> محظور.
div.innerHTML = TrustedHTML.create(string) -> مسموح.
يؤدي هذا إلى التخلص من ثغرات DOM XSS على مستوى محرك المتصفح.
إنه صارم (“الوضع الصعب”)، ولكن بالنسبة للأمان على مستوى البنوك، فهو نهاية اللعبة.
11. Edge CSP (عمال Cloudflare)
يعد إنشاء CSP في الأصل (Node.js) أمرًا جيدًا. حقنه على الحافة أفضل. نحن نستخدم Cloudflare Workers لإدخال رؤوس الأمان. يؤدي هذا إلى حماية الأصول الثابتة (الصور وملفات HTML العارية) التي قد لا تمر عبر منطق تطبيق Node.js. كما يسمح أيضًا بـ “الحظر في حالات الطوارئ”. إذا تم اختراق إحدى المكتبات، فيمكننا تحديث CSP على Edge خلال 300 مللي ثانية على مستوى العالم.
13. الطاقة الشمسية المركزة في عالم الواجهة الصغيرة
ماذا لو قمت بتحميل عنصر واجهة مستخدم من الفريق ب؟ لا يمكنك مشاركة Nonce (يتم إنشاؤه على الخادم). CSP القائم على التجزئة. بدلاً من عدم الحذف، يمكنك حساب تجزئة SHA-256 لمحتوى البرنامج النصي. `script-src ‘sha256-K7g…”. يقوم المتصفح بتجزئة البرنامج النصي المضمن. إذا تطابق، فإنه يعمل.
- برو: ثابت. يمكن تخزينها مؤقتا.
- السلبيات: إذا قمت بتغيير حرف واحد (ولو مسافة)، فسوف ينقطع التجزئة. نحن نستخدم هذا للبرامج النصية المستقرة لموردي الطرف الثالث والتي نادرًا ما تغير الإصدار.
14. الكلمة الرئيسية “التجزئة غير الآمنة”.
في بعض الأحيان يجب عليك استخدام معالجات الأحداث المضمنة (المكتبات القديمة).
التنقل ('foo') داخل onclick.
يمنع CSP القياسي هذا.
تتيح لك “التجزئة غير الآمنة” إضافة سلاسل محددة لمعالج الأحداث إلى القائمة البيضاء.
`script-src ‘unsafe-hashs’ ‘sha256-…” (حيث يكون التجزئة من “التنقل (‘foo’)”).
يتيح لك هذا تأمين التعليمات البرمجية القديمة دون إعادة كتابة نموذج حدث DOM بالكامل.
15. الاستنتاج
سياسة أمان المحتوى هي حزام الأمان للويب. إنه لا يمنع الاصطدام (الحقن)، لكنه يمنعك من الطيران عبر الزجاج الأمامي (استخراج البيانات). إنه أمر شاق للتكوين. يتطلب صيانة مستمرة عند إضافة أدوات تسويقية جديدة. ولكن بالنسبة لعلامة تجارية فاخرة تتعامل مع أفراد من ذوي الثروات العالية، فهذا هو خط الأساس للثقة.
هل موقعك مفتوح على مصراعيه؟
إذا لم تقم بإرسال رأس CSP، فأنت عرضة لـ Magecart.