الحدّ من النصوص البرمجية على المواقع الإلكترونية (XSS) من خلال تطبيق سياسة أمان المحتوى الصارمة (CSP)

التوافق مع المتصفح

  • 52
  • 79
  • 52
  • 15.4

المصدر

البرمجة النصية على المواقع الإلكترونية (XSS) هي القدرة على إدخال نصوص برمجية ضارة في تطبيق الويب، وهي واحدة من أكبر الثغرات الأمنية على الويب لأكثر من عشر سنوات.

سياسة أمان المحتوى (CSP) هي طبقة إضافية من الأمان تساعد في الحدّ من استخدام بروتوكول XSS. لضبط سياسة CSP، أضِف عنوان HTTP يتضمّن العنصر Content-Security-Policy إلى صفحة ويب واضبط القيم التي تتحكّم في الموارد التي يمكن لوكيل المستخدم تحميلها لتلك الصفحة.

توضّح هذه الصفحة كيفية استخدام سياسة CSP استنادًا إلى nonces أو علامات التجزئة للتخفيف من تأثير XSS، بدلاً من سياسة CSP المستنِدة إلى القائمة المسموح بها والتي يشيع استخدامها والتي غالبًا ما تترك الصفحة معرَّضة لـ XSS، لأنّه يمكن تجاوزها في معظم الإعدادات.

مصطلح رئيسي: nonce هو رقم عشوائي لا يُستخدم إلا مرة واحدة ويمكنك استخدامه لوضع علامة <script> على أنّها موثوق بها.

المصطلح الرئيسي: دالة التجزئة هي دالة رياضية تحوِّل قيمة الإدخال إلى قيمة رقمية مضغوطة تُسمى تجزئة. يمكنك استخدام تجزئة (على سبيل المثال، SHA-256) لوضع علامة <script> مضمّنة على أنّها موثوق بها.

غالبًا ما تُسمّى سياسة أمان المحتوى المستندة إلى nonces أو علامات التجزئة سياسة أمان المحتوى (CSP) صارمة. عند استخدام تطبيق سياسة CSP صارمًا، لا يمكن للمهاجمين الذين يجدون عيوبًا بإدخال HTML بشكل عام استخدامها لإجبار المتصفح على تنفيذ نصوص برمجية ضارة في مستند معرَّض للاختراق. ويرجع ذلك إلى أنّ سياسة CSP الصارمة لا تسمح بالنصوص البرمجية المجزّأة أو النصوص البرمجية التي تتضمّن القيمة الصحيحة التي يتم إنشاؤها على الخادم، وبالتالي لا يمكن للمهاجمين تنفيذ النص البرمجي بدون معرفة الاسم الصحيح لاستجابة معيّنة.

لماذا يجب استخدام سياسة CSP صارمة؟

إذا كان موقعك الإلكتروني يتضمّن سياسة CSP تشبه script-src www.googleapis.com، قد لا يكون فعالاً على منصات أخرى. يُعرَف هذا النوع من سياسة أمان المحتوى (CSP) باسم قائمة سياسة أمان المحتوى (CSP). وتتطلّب قدرًا كبيرًا من التخصيص ويمكن أن تجتازها المهاجمون.

يتجنّب مقدِّمو خدمة CSP الصارمون استنادًا إلى عناصر تشفير أو علامات تجزئة، هذه المخاطر.

بنية سياسة أمان المحتوى (CSP) صارمة

تستخدم "سياسة أمان المحتوى الصارمة" الأساسية أحد رؤوس استجابة HTTP التالية:

سياسة سياسة المحتوى الصارمة المستندة إلى سياسة CSP

Content-Security-Policy:
  script-src 'nonce-{RANDOM}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';
آلية عمل سياسة CSP الصارمة غير المستندة إلى معايير محددة

سياسة CSP صارمة مستندة إلى التجزئة

Content-Security-Policy:
  script-src 'sha256-{HASHED_INLINE_SCRIPT}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';

تجعل السمات التالية سياسة CSP مثل هذه "صارمة" وبالتالي آمنة:

  • تستخدم هذه السمة 'nonce-{RANDOM}' الخاصة بك أو علامات التجزئة 'sha256-{HASHED_INLINE_SCRIPT}' للإشارة إلى علامات <script> التي يثق مطوّر الموقع الإلكتروني في تنفيذها في متصفّح المستخدم.
  • تضبط هذه السياسة 'strict-dynamic' لتقليل الجهد المبذول لنشر سياسة CSP مستندة إلى علامات التجزئة أو مستندة إلى التجزئة، وذلك من خلال السماح تلقائيًا بتنفيذ النصوص البرمجية التي ينشئها نص برمجي موثوق به. يؤدي ذلك أيضًا إلى إزالة حظر استخدام معظم مكتبات وأدوات JavaScript التابعة لجهات خارجية.
  • ولا يستند إلى القوائم المسموح بها لعناوين URL، لذا لا يتأثر بحالات تجاوز سياسة CSP الشائعة.
  • يحظر هذه الميزة النصوص البرمجية المضمّنة غير الموثوق بها، مثل معالِجات الأحداث المضمَّنة أو معرّفات الموارد المنتظمة (URI) javascript:.
  • تفرض هذه السياسة قيودًا على object-src لإيقاف المكوّنات الإضافية الخطيرة، مثل Flash.
  • تفرض هذه السياسة قيودًا على base-uri لحظر إدخال علامات <base>. يمنع ذلك المهاجمين من تغيير مواقع النصوص البرمجية التي تم تحميلها من عناوين URL النسبية.

استخدام سياسة CSP صارمة

لاستخدام سياسة أمان محتوى (CSP)، يجب استيفاء الشروط التالية:

  1. حدِّد ما إذا كان التطبيق يجب أن يضبط سياسة CSP مستندة إلى التجزئة أو مستندة إلى التجزئة.
  2. انسخ سياسة CSP من قسم بنية CSP الصارمة وعيِّنه كعنوان استجابة في تطبيقك.
  3. إعادة تحليل نماذج HTML والرموز البرمجية من جهة العميل لإزالة الأنماط غير المتوافقة مع CSP.
  4. فعِّل سياسة أمان المحتوى (CSP).

يمكنك استخدام Lighthouse (الإصدار 7.3.0 والإصدارات الأحدث مع إصدار العلامة --preset=experimental) لأفضل الممارسات طوال هذه العملية للتحقق مما إذا كان موقعك الإلكتروني يتضمّن CSP، وما إذا كان صارمًا بدرجة كافية ليكون صارمًا بدرجة كافية ضد XSS.

يحذر تقرير Lighthouse من أنّه لم يتم العثور على سياسة CSP في وضع التنفيذ.
إذا لم يكن موقعك الإلكتروني يتضمّن سياسة CSP، ستعرِض أداة Lighthouse هذا التحذير.

الخطوة 1: تحديد ما إذا كنت بحاجة إلى سياسة CSP مستندة إلى التجزئة أو مستندة إلى التجزئة

في ما يلي كيفية عمل نوعَي سياسة CSP الصارمة:

سياسة أمان محتوى (CSP) مستندة إلى Nonce

باستخدام سياسة CSP غير مستندة إلى سياسة CSP، يمكنك إنشاء رقم عشوائي في وقت التشغيل وتضمينه في سياسة CSP وربطه بكل علامة نص برمجي في صفحتك. ولا يمكن للمهاجم تضمين نص برمجي ضار أو تشغيله في صفحتك، لأنه قد يحتاج إلى تخمين الرقم العشوائي الصحيح لهذا النص البرمجي. لا يعمل هذا إلا إذا كان الرقم غير قابل للتخمين، ويتم إنشاؤه حديثًا في وقت التشغيل لكل استجابة.

استخدِم سياسة CSP غير مستندة إلى معايير CSP لصفحات HTML المعروضة على الخادم. بالنسبة لهذه الصفحات، يمكنك إنشاء رقم عشوائي جديد لكل استجابة.

سياسة أمان المحتوى (CSP) المستندة إلى التجزئة

بالنسبة إلى سياسة CSP المستندة إلى التجزئة، تتم إضافة تجزئة كل علامة نص برمجي مضمّنة إلى سياسة CSP. لكل نص برمجي تجزئة مختلفة. لا يمكن للمهاجم تضمين نص برمجي ضار أو تشغيله في صفحتك، لأن تجزئة هذا النص البرمجي يجب أن تكون في CSP حتى يتم تشغيله.

استخدِم سياسة CSP مستندة إلى التجزئة لصفحات HTML التي يتم عرضها بشكل ثابت أو للصفحات التي تحتاج إلى تخزين مؤقت. على سبيل المثال، يمكنك استخدام سياسة CSP مستندة إلى التجزئة لتطبيقات الويب المكوّنة من صفحة واحدة والتي تم إنشاؤها باستخدام أُطر عمل، مثل Angular أو React أو غيرها، والتي يتم عرضها بشكل ثابت بدون العرض من جهة الخادم.

الخطوة 2: ضبط سياسة CSP صارمة وإعداد النصوص البرمجية

عند إعداد سياسة أمان محتوى (CSP)، تتوفّر لك بعض الخيارات:

  • في وضع إعداد التقارير فقط (Content-Security-Policy-Report-Only) أو وضع التنفيذ (Content-Security-Policy). في وضع إعداد التقارير فقط، لن تحظر سياسة أمان المحتوى (CSP) الموارد بعد، لذا لا يتوقّف أي شيء على موقعك الإلكتروني، ولكن يمكنك الاطّلاع على الأخطاء والحصول على تقارير عن أي عنصر كان من الممكن حظره. محليًا، عند ضبط سياسة أمان المحتوى (CSP)، لا يهم ذلك، لأنّ كلا الوضعين يعرضان الأخطاء في وحدة تحكم المتصفح. وإذا توفّرت، يمكن أن يساعدك وضع التنفيذ في العثور على الموارد التي تحظرها مسودّات سياسة أمان المحتوى (CSP)، لأنّ حظر أحد الموارد قد يجعل صفحتك تبدو معطّلة. يصبح وضع "إعداد التقارير فقط" مفيدًا للغاية لاحقًا في العملية (راجِع الخطوة 5).
  • علامة HTML أو عنوان <meta> بالنسبة إلى التطوير المحلي، يمكن أن تكون علامة <meta> أكثر ملاءمة لتعديل سياسة CSP ومعرفة مدى تأثيرها في موقعك الإلكتروني بسرعة. في المقابل:
    • في وقت لاحق، عند نشر سياسة CSP في مرحلة الإنتاج، ننصحك بضبطها كعنوان HTTP.
    • إذا أردت ضبط سياسة CSP في وضع إعداد التقارير فقط، عليك ضبطه كعنوان، لأنّ العلامات الوصفية لـ CSP لا تتيح استخدام وضع "إعداد التقارير فقط".

الخيار "أ": سياسة CSP المستندة إلى رقم الهاتف

اضبط عنوان استجابة HTTP Content-Security-Policy التالي في تطبيقك:

Content-Security-Policy:
  script-src 'nonce-{RANDOM}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';

إنشاء نموذج خاص بـ CSP

الرقم nonce هو رقم عشوائي يُستخدم مرة واحدة فقط لكل تحميل للصفحة. لا يمكن لـ CSP المستند إلى غير صالح أن يخفف من XSS فقط إذا لم يتمكن المهاجمون من تخمين القيمة nonce. يجب أن يكون رقم CSP الخاص بـ CSP:

  • قيمة عشوائية قوية من الناحية المشفَّرة (من الناحية المثالية يبلغ طولها أكثر من 128 بت)
  • تم إنشاؤها حديثًا لكل ردّ
  • Base64 مرمّز

في ما يلي بعض الأمثلة على كيفية إضافة إشعار CSP في أُطر العمل من جهة الخادم:

const app = express();

app.get('/', function(request, response) {
  // Generate a new random nonce value for every response.
  const nonce = crypto.randomBytes(16).toString("base64");

  // Set the strict nonce-based CSP response header
  const csp = `script-src 'nonce-${nonce}' 'strict-dynamic'; object-src 'none'; base-uri 'none';`;
  response.set("Content-Security-Policy", csp);

  // Every <script> tag in your application should set the `nonce` attribute to this value.
  response.render(template, { nonce: nonce });
});

إضافة السمة nonce إلى عناصر <script>

مع سياسة CSP غير مستندة إلى سياسة CSP، يجب أن يتضمّن كل عنصر <script> السمة nonce التي تطابق القيمة العشوائية غير المحدَّدة في عنوان سياسة CSP. ويمكن أن تحتوي جميع النصوص البرمجية على الأرقام نفسها. تتمثّل الخطوة الأولى في إضافة هذه السمات إلى جميع النصوص البرمجية لكي تسمح بها سياسة CSP.

الخيار ب: عنوان استجابة CSP المستند إلى التجزئة

اضبط عنوان استجابة HTTP Content-Security-Policy التالي في تطبيقك:

Content-Security-Policy:
  script-src 'sha256-{HASHED_INLINE_SCRIPT}' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';

في ما يتعلّق بالنصوص البرمجية المضمّنة المتعددة، تكون البنية على النحو التالي: 'sha256-{HASHED_INLINE_SCRIPT_1}' 'sha256-{HASHED_INLINE_SCRIPT_2}'.

تحميل النصوص البرمجية من المصادر بشكل ديناميكي

بما أنّ تجزئات سياسة أمان المحتوى (CSP) تكون متاحة في المتصفحات للنصوص البرمجية المضمّنة فقط، عليك تحميل جميع النصوص البرمجية التابعة لجهات خارجية بشكل ديناميكي باستخدام نص برمجي مضمّن. لا تتوافق علامات التجزئة للنصوص البرمجية المصدر بشكل جيد على جميع المتصفحات.

مثال على كيفية تضمين النصوص البرمجية
مسموح به من قِبل سياسة أمان المحتوى (CSP)
<script>
  var scripts = [ 'https://example.org/foo.js', 'https://example.org/bar.js'];

  scripts.forEach(function(scriptUrl) {
    var s = document.createElement('script');
    s.src = scriptUrl;
    s.async = false; // to preserve execution order
    document.head.appendChild(s);
  });
</script>
للسماح بتشغيل هذا النص البرمجي، يجب حساب تجزئة النص البرمجي المضمّن وإضافتها إلى عنوان استجابة CSP، مع استبدال العنصر النائب {HASHED_INLINE_SCRIPT}. لتقليل عدد علامات التجزئة، يمكنك دمج جميع النصوص البرمجية المضمّنة في نص برمجي واحد. لتنفيذ هذا الإجراء، يمكنك الاطّلاع على هذا المثال والرمز الخاص به.
تم الحظر بواسطة سياسة أمان المحتوى (CSP)
<script src="https://example.org/foo.js"></script>
<script src="https://example.org/bar.js"></script>
تحظر سياسة أمان المحتوى (CSP) هذه النصوص البرمجية لأنّه يمكن تجزئة النصوص البرمجية المضمّنة فقط.

اعتبارات تحميل النص البرمجي

يضيف مثال النص البرمجي المضمّن s.async = false لضمان تنفيذ foo قبل bar، حتى إذا تم تحميل bar أولاً. في هذا المقتطف، لا يحظر s.async = false المحلّل أثناء تحميل النصوص البرمجية، لأنّ النصوص البرمجية تتم إضافتها بشكل ديناميكي. لا يتوقف المحلل اللغوي إلا أثناء تنفيذ النصوص البرمجية، كما هو الحال مع async نصوص برمجية. مع ذلك، يُرجى أخذ ما يلي في الاعتبار باستخدام هذا المقتطف:

  • قد يتم تنفيذ نص برمجي واحد أو كلا النصَّين قبل الانتهاء من تنزيل المستند. إذا كنت تريد أن يكون المستند جاهزًا بحلول الوقت الذي يتم فيه تنفيذ النصوص البرمجية، يُرجى الانتظار إلى أن يظهر الحدث DOMContentLoaded قبل إلحاق النصوص البرمجية. إذا تسبّب ذلك في حدوث مشكلة في الأداء بسبب عدم بدء تنزيل النصوص البرمجية مبكرًا بما يكفي، استخدِم علامات التحميل المُسبق في بداية الصفحة.
  • لا ينفّذ defer = true أي إجراء. إذا كنت بحاجة إلى هذا السلوك، يمكنك تشغيل النص البرمجي يدويًا عند الحاجة.

الخطوة 3: إعادة ضبط نماذج HTML والرموز البرمجية من جهة العميل

يمكن استخدام معالِجات الأحداث المضمّنة (مثل onclick="…" وonerror="…") ومعرّفات الموارد المنتظمة (URI) في JavaScript (<a href="javascript:…">) لتشغيل النصوص البرمجية. أي أنّ المهاجم الذي يعثر على خطأ XSS يمكنه إدخال هذا النوع من ترميز HTML وتنفيذ رمز JavaScript ضارّ. يحظر سياسة CSP المستندة إلى التجزئة استخدام هذا النوع من الترميز. إذا كان موقعك الإلكتروني يستخدم أيًا من هذه الأنماط، ستحتاج إلى إعادة تحليلها لتصبح بدائل أكثر أمانًا.

إذا فعّلت سياسة CSP في الخطوة السابقة، ستتمكّن من الاطّلاع على انتهاكات سياسة CSP في وحدة التحكّم في كل مرة تحظر فيها سياسة CSP نمطًا غير متوافق.

تقارير انتهاكات سياسة أمان المحتوى (CSP) في Chrome Developers Console
أخطاء في وحدة التحكّم مرتبطة بالرمز المحظور:

في معظم الحالات، يكون الإصلاح واضحًا:

معالِجات الأحداث المضمّنة في إعادة هيكلة

مسموح به من قِبل سياسة أمان المحتوى (CSP)
<span id="things">A thing.</span>
<script nonce="${nonce}">
  document.getElementById('things').addEventListener('click', doThings);
</script>
يسمح سياسة أمان المحتوى (CSP) بمعالجات الأحداث التي يتم تسجيلها باستخدام JavaScript.
تم الحظر بواسطة سياسة أمان المحتوى (CSP)
<span onclick="doThings();">A thing.</span>
يحظر سياسة أمان المحتوى (CSP) معالِجات الأحداث المضمّنة.

إعادة ضبط معرِّفات الموارد المنتظمة (URI) لـ javascript:

مسموح به من قِبل سياسة أمان المحتوى (CSP)
<a id="foo">foo</a>
<script nonce="${nonce}">
  document.getElementById('foo').addEventListener('click', linkClicked);
</script>
يسمح سياسة أمان المحتوى (CSP) بمعالجات الأحداث التي يتم تسجيلها باستخدام JavaScript.
تم الحظر بواسطة سياسة أمان المحتوى (CSP)
<a href="javascript:linkClicked()">foo</a>
يحظر سياسة أمان المحتوى (CSP) JavaScript: معرّفات الموارد المنتظمة (URI).

إزالة "eval()" من JavaScript

إذا كان تطبيقك يستخدم eval() لتحويل تسلسلات سلاسل JSON إلى كائنات JavaScript، عليك إعادة بناء هذه الحالات إلى JSON.parse()، وسيكون ذلك أسرع أيضًا.

إذا لم تتمكّن من إزالة جميع استخدامات eval()، يمكنك ضبط سياسة CSP صارمة غير مستندة إلى معايير CSP، ولكن عليك استخدام الكلمة الرئيسية 'unsafe-eval' CSP، ما يجعل سياستك أقل أمانًا إلى حد ما.

يمكنك العثور على هذه الأمثلة وغيرها عن إعادة البناء في هذا الدرس التطبيقي الصارم حول ترميز CSP:

الخطوة 4 (اختيارية): إضافة عناصر احتياطية لإتاحة إصدارات المتصفّح القديمة

التوافق مع المتصفح

  • 52
  • 79
  • 52
  • 15.4

المصدر

إذا كنت تريد دعم إصدارات المتصفح القديمة:

  • يتطلب استخدام strict-dynamic إضافة https: كإجراء احتياطي للإصدارات السابقة من Safari. عند إجراء ذلك:
    • تتجاهل جميع المتصفّحات المتوافقة مع strict-dynamic الإجراء الاحتياطي https:، لذا لن يؤدي ذلك إلى تقليل قوة السياسة.
    • في المتصفّحات القديمة، لا يمكن تحميل النصوص البرمجية ذات المصادر الخارجية إلا إذا كانت مصدرها HTTPS. يُعدّ هذا الإجراء أقل أمانًا من سياسة CSP الصارمة، ولكنّه لا يزال يمنع بعض أسباب XSS الشائعة، مثل إدخال معرّفات الموارد المنتظمة (URI) javascript:.
  • لضمان التوافق مع إصدارات المتصفّح القديمة جدًا (التي يبلغ عمرها 4 سنوات أو أكثر)، يمكنك إضافة unsafe-inline كإجراء احتياطي. تتجاهل جميع المتصفّحات الحديثة العلامة unsafe-inline في حال توفّر nonce أو التجزئة في سياسة CSP.
Content-Security-Policy:
  script-src 'nonce-{random}' 'strict-dynamic' https: 'unsafe-inline';
  object-src 'none';
  base-uri 'none';

الخطوة 5: نشر سياسة أمان المحتوى (CSP)

بعد التأكّد من أنّ سياسة CSP لا تحظر أي نصوص برمجية مشروعة في بيئة التطوير المحلية، يمكنك نشر هذه السياسة في مرحلة التطوير ثم على بيئة الإنتاج:

  1. (اختياري) يمكنك تفعيل سياسة أمان المحتوى (CSP) في وضع "إعداد التقارير فقط" باستخدام عنوان Content-Security-Policy-Report-Only. يساعدك وضع "إعداد التقارير فقط" في اختبار تغيير قد يؤدي إلى عطل، مثل سياسة CSP جديدة في مرحلة الإنتاج، قبل البدء في فرض قيود سياسة CSP. في وضع "إعداد التقارير فقط"، لا يؤثر سياسة أمان المحتوى (CSP) في سلوك تطبيقك، ولكن يظل بإمكان المتصفِّح إنشاء أخطاء في وحدة التحكّم وتقارير الانتهاكات عندما يواجه أنماطًا غير متوافقة مع سياسة أمان المحتوى (CSP)، وبذلك يمكنك معرفة المشاكل التي قد تتسبّب في تعطّل المستخدمين النهائيين. لمزيد من المعلومات، يُرجى الاطّلاع على Reporting API.
  2. إذا كنت متأكّدًا من أنّ سياسة CSP لن تعطّل موقعك الإلكتروني للمستخدمين النهائيين، يمكنك نشر CSP باستخدام عنوان الاستجابة Content-Security-Policy. ننصحك بضبط سياسة أمان المحتوى (CSP) من جهة خادم عنوان HTTP لأنّها أكثر أمانًا من علامة <meta>. بعد إكمال هذه الخطوة، يبدأ CSP في حماية تطبيقك من XSS.

القيود

يوفر CSP الصارم بشكل عام طبقة إضافية قوية من الأمان تساعد في الحد من XSS. في معظم الحالات، تقلل سياسة CSP من الأجزاء المعرضة للهجوم بشكل كبير من خلال رفض الأنماط الخطيرة، مثل معرّفات الموارد المنتظمة (URI) javascript:. ومع ذلك، استنادًا إلى نوع سياسة أمان المحتوى (CSP) الذي تستخدمه (بدون علامات تجزئة، أو تجزئات أو مع 'strict-dynamic')، هناك حالات لا تحمي فيها سياسة أمان المحتوى (CSP) تطبيقك أيضًا:

  • إذا لم تضع نصًا برمجيًا ولكن تم حقنة في النص مباشرةً أو في معلَمة src للعنصر <script>
  • إذا كانت هناك عمليات إدخال في أماكن النصوص البرمجية التي تم إنشاؤها ديناميكيًا (document.createElement('script'))، بما في ذلك أي من وظائف المكتبة التي تنشئ عُقد script DOM استنادًا إلى قيم وسيطاتها ويتضمّن ذلك بعض واجهات برمجة التطبيقات الشائعة، مثل .html() في jQuery، بالإضافة إلى .get() و.post() في jQuery < 3.0.
  • إذا كانت هناك عمليات حقن نماذج في تطبيقات AngularJS القديمة. ويمكن للمهاجم الذي يمكنه إدخال البيانات في نموذج AngularJS استخدامه لتنفيذ JavaScript عشوائي.
  • إذا كانت السياسة تحتوي على 'unsafe-eval'، وإدخالات في eval() وsetTimeout() وبعض واجهات برمجة التطبيقات الأخرى التي نادرًا ما يتم استخدامها.

ويجب على المطوّرين ومهندسي الأمان الانتباه بشكل خاص إلى هذه الأنماط أثناء مراجعات الرموز والتدقيقات الأمنية. يمكنك الاطّلاع على مزيد من التفاصيل حول هذه الحالات في سياسة أمان المحتوى: تأثير ناجح بين زيادة القيود والتخفيف.

محتوى إضافي للقراءة