تنفيذ تصحيح أخطاء سياسة أمان المحتوى (CSP) والأنواع الموثوق بها في "أدوات مطوري البرامج في Chrome"

Kateryna Prokopenko
Kateryna Prokopenko
Alfonso Castaño
Alfonso Castaño

تتناول مشاركة المدونة هذه إتاحة "أدوات مطوري البرامج" لتصحيح أخطاء "سياسة أمان المحتوى" (CSP) بمساعدة علامة التبويب المشاكل التي تم طرحها مؤخرًا.

وتم التنفيذ على مدار تدريبين داخليين: 1- في المرحلة الأولى، صمّمنا إطار العمل العام للإبلاغ وصمّمنا رسائل حلّ المشاكل المتعلّقة بانتهاك 3 سياسة CSP. 2. وخلال المرحلة الثانية، أضفنا مشاكل "النوع الموثوق به" إلى جانب بعض ميزات "أدوات مطوري البرامج" المتخصصة لتصحيح أخطاء "الأنواع الموثوق بها".

ما المقصود بسياسة أمان المحتوى؟

تسمح سياسة أمان المحتوى (CSP) بحظر سلوكيات معيّنة في موقع إلكتروني لزيادة مستوى الأمان. على سبيل المثال، يمكن استخدام سياسة CSP لمنع النصوص البرمجية المضمّنة أو منع استخدام eval، وكلاهما يقلل من احتمال هجمات البرمجة النصية على المواقع الإلكترونية (XSS). للاطّلاع على مقدمة مفصّلة عن سياسة CSP، يُرجى قراءة المعلومات هنا.

إنّ سياسة CSP الجديدة بشكل خاص هي سياسة الأنواع الموثوق بها(TT) التي تتيح تحليلاً ديناميكيًا يمكنه أن يمنع بشكل منهجي فئة كبيرة من هجمات الحقن على المواقع الإلكترونية. لتحقيق ذلك، تدعم TT وظيفة الموقع الإلكتروني في فرض رمز JavaScript الخاص به للسماح فقط بتعيين أنواع معينة من الأشياء إلى أحواض DOM مثل innerHTML.

يمكن لموقع الويب تفعيل سياسة أمان المحتوى عن طريق تضمين عنوان HTTP معيّن. على سبيل المثال، العنوان content-security-policy: require-trusted-types-for 'script'; trusted-types default تفعيل سياسة TT لأحد الصفحات.

يمكن أن تعمل كل سياسة بأحد الأوضاع التالية:

  • وضع الفرض - حيث يمثل كل انتهاك للسياسة خطأً،
  • وضع الإبلاغ فقط - يبلغ عن رسالة الخطأ كتحذير، ولكن لا يتسبب في إخفاق صفحة الويب.

تنفيذ "مشاكل أمان المحتوى" في علامة التبويب المشاكل

كان الهدف من هذا العمل تحسين تجربة تصحيح الأخطاء لمشاكل CSP. عند التفكير في مشاكل جديدة، يتّبع فريق "أدوات مطوري البرامج" هذه العملية تقريبًا:

  1. تعريف قصص المستخدم. حدد مجموعة من قصص المستخدمين في الواجهة الأمامية لـ "أدوات مطوري البرامج" والتي تتناول كيف سيحتاج مطوّر الويب إلى التحقيق في المشكلة.
  2. تنفيذ الواجهة الأمامية: استنادًا إلى قصص المستخدمين، حدد المعلومات المطلوبة للتحقيق في المشكلة في الواجهة الأمامية (على سبيل المثال، طلب ذي صلة، أو اسم ملف تعريف ارتباط، أو سطر في نص برمجي أو ملف html، إلخ).
  3. اكتشاف المشاكل: حدد الأماكن في المتصفح التي يمكن فيها اكتشاف المشكلة في Chrome واستخدم الأداة للإبلاغ عن المشكلة بما في ذلك المعلومات ذات الصلة من الخطوة (2).
  4. حفظ المشاكل وعرضها: تخزين المشاكل في مكان مناسب وإتاحتها على "أدوات مطوري البرامج" بعد فتحها
  5. تصميم نص المشاكل: التوصل إلى نص توضيحي يساعد مطوّر برامج الويب في فهم المشكلة والأهم من ذلك

الخطوة 1: تحديد قصص المستخدمين حول مشاكل سياسة أمان المحتوى (CSP)

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


بصفتي مطوِّرًا، أدركت للتو أنّ جزءًا من موقعي الإلكتروني محظور، وأريد ما يلي: - ...معرفة ما إذا كانت سياسة CSP سببًا في حظر إطارات iframe أو الصور على موقعي الإلكتروني - ...التعرّف على توجيه CSP الذي يتسبب في حظر مورد معيّن - ...معرفة كيفية تغيير سياسة أمان المحتوى (CSP) على موقعي الإلكتروني للسماح بعرض الموارد المحظورة حاليًا / تنفيذ رموز js المحظورة حاليًا.


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

باستخدام هذه العملية، توصّلنا إلى أنّ الموقع الجغرافي المصدر كان أهم معلومات لتصحيح مشاكل سياسة أمان المحتوى (CSP). واكتشفنا أيضًا أنه من المفيد العثور سريعًا على إطار iframe المرتبط والطلب في حال حظر مورد، ومن الاستفادة أيضًا من رابط مباشر إلى عنصر HTML في لوحة Elements ضِمن أدوات مطوّري البرامج.

الخطوة 2: تنفيذ الواجهة الأمامية

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

في ما يلي مقتطف من third_party/blink/public/devtools_protocol/browser_protocol.pdl

 type ContentSecurityPolicyIssueDetails extends object
   properties
     # The url not included in allowed sources.
     optional string blockedURL
     # Specific directive that is violated, causing the CSP issue.
     string violatedDirective
     boolean isReportOnly
     ContentSecurityPolicyViolationType contentSecurityPolicyViolationType
     optional AffectedFrame frameAncestor
     optional SourceCodeLocation sourceCodeLocation
     optional DOM.BackendNodeId violatingNodeId

يعمل التعريف أعلاه بشكل أساسي على ترميز بنية بيانات JSON. فهي مكتوبة بلغة بسيطة تسمى PDL (لغة بيانات البروتوكول). يتم استخدام PDL لغرضين. أولاً، نستخدم PDL لإنشاء تعريفات TypeScript التي تعتمد عليها واجهة DevTools الأمامية. على سبيل المثال، يُنشئ تعريف PDL أعلاه واجهة TypeScript التالية:

export interface ContentSecurityPolicyIssueDetails {
  /**
  * The url not included in allowed sources.
  */
  blockedURL?: string;
  /**
  * Specific directive that is violated, causing the CSP issue.
  */
  violatedDirective: string;
  isReportOnly: boolean;
  contentSecurityPolicyViolationType: ContentSecurityPolicyViolationType;
  frameAncestor?: AffectedFrame;
  sourceCodeLocation?: SourceCodeLocation;
  violatingNodeId?: DOM.BackendNodeId;
}

ثانيًا، ربما الأهم من ذلك، ننشئ مكتبة C++ من التعريف الذي يعالج إنشاء بُنى البيانات هذه وإرسالها من الواجهة الخلفية لـ C++ Chromium إلى الواجهة الأمامية في أدوات مطوّري البرامج. باستخدام هذه المكتبة، يمكن إنشاء كائن ContentSecurityPolicyIssueDetails باستخدام الجزء التالي من رمز C++:

protocol::Audits::ContentSecurityPolicyIssueDetails::create()
  .setViolatedDirective(d->violated_directive)
  .setIsReportOnly(d->is_report_only)
  .setContentSecurityPolicyViolationType(BuildViolationType(
      d->content_security_policy_violation_type)))
  .build();

بعد أن قرّرنا نوع المعلومات التي أردنا توفيرها، أردنا معرفة أين يمكن الحصول على هذه المعلومات من Chromium.

الخطوة 3: اكتشاف المشكلة

لتوفير المعلومات لبروتوكول أدوات مطوري البرامج في Chrome (CDP) بالتنسيق الموضح في القسم الأخير، احتجنا إلى العثور على المكان الذي كانت فيه المعلومات متوفرة فعليًا في الواجهة الخلفية. لحسن الحظ، كان لرمز سياسة أمان المحتوى (CSP) سابق مشكلة مُستخدَمة في وضع إعداد التقارير فقط، والذي يمكننا من خلاله التركيز على: ContentSecurityPolicy::ReportViolation تبلّغ عن المشاكل في نقطة نهاية (اختيارية) لإعداد التقارير يمكن ضبطها في عنوان HTTP CSP. كانت معظم المعلومات التي أردنا الإبلاغ عنها متوفرة بالفعل، لذلك لم تكن هناك تغييرات كبيرة في الخلفية لكي تعمل أدواتنا.

الخطوة 4: حفظ المشاكل وعرضها

وهناك تعقيد بسيط يتمثل في أنّنا أردنا أيضًا الإبلاغ عن المشاكل التي حدثت قبل فتح "أدوات مطوري البرامج"، وهي تشبه طريقة معالجة رسائل وحدة التحكّم. وهذا يعني أنّنا لا نبلّغ عن المشاكل مباشرةً في الواجهة الأمامية، ولكنّنا نستخدم مساحة تخزين مليئة بالمشاكل بصرف النظر عمّا إذا كانت "أدوات مطوري البرامج" مفتوحة أم لا. بعد فتح أدوات مطوّري البرامج (أو إرفاق أي برنامج CDP آخر)، يمكن إعادة تشغيل كل المشاكل التي تم تسجيلها سابقًا من مساحة التخزين.

وقد انتهى ذلك من عمل الواجهة الخلفية، ونحتاج الآن إلى التركيز على كيفية إظهار المشكلة في الواجهة الأمامية.

الخطوة 5: تصميم نص المشكلات

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

عادةً ما يبدأ فريق DevTools بمسودة تقريبية لما يتخيلونه:


## Header
Content Security Policy: include all sources of your resources in content security policy header to improve the functioning of your site

## General information
Even though some sources are included in the content security policy header, some resources accessed by your site like images, stylesheets or scripts originate from sources not included in content security policy directives.

Usage of content from not included sources is restricted to strengthen the security of your entire site.

## Specific information

### VIOLATED DIRECTIVES
`img-src 'self'`

### BLOCKED URLs
https://imgur.com/JuXCo1p.jpg

## Specific information
https://web.dev/strict-csp/

بعد التكرار، وصلنا إلى:

ALT_TEXT_HERE

كما ترى، يؤدي إشراك فريق الميزة وDevRel إلى جعل الوصف أكثر وضوحًا ودقة!

يمكن أيضًا اكتشاف مشاكل سياسة أمان المحتوى (CSP) على صفحتك في علامة التبويب المخصّصة تحديدًا لسياسة CSP.

تصحيح أخطاء "الأنواع الموثوق بها"

قد يُعَدّ استخدام "الترجمة النصية" على نطاق واسع تحديًا كبيرًا بدون استخدام أدوات المطوّرين المناسبة.

الطباعة المُحسَّنة لوحدة التحكّم

عند التعامل مع العناصر الموثوق بها، نود عرض كمية المعلومات نفسها على الأقل بالنسبة إلى نظيرها غير الموثوق. للأسف، عند عرض كائن موثوق به، لا يتم حاليًا عرض أي معلومات عن الكائن الملفوف.

ويعود السبب في ذلك إلى أنّ القيمة المعروضة في وحدة التحكّم مأخوذة من استدعاء .valueOf() على العنصر تلقائيًا. ومع ذلك، في حالة النوع الموثوق به، لا تكون القيمة المعروضة مفيدة جدًا. بدلاً من ذلك، نريد الحصول على مزايا مشابهة لما تحصل عليه عند الاتصال بـ .toString(). لتحقيق ذلك، نحتاج إلى تعديل V8 وBlink لتوفير معالجة خاصة لكائنات النوع الموثوق به.

ونظرًا لأسباب سابقة، تمت معالجة المعالجة المخصّصة في V8، إلا أنّ هذه الطريقة لها عيوب مهمة. هناك العديد من العناصر التي تتطلب عرضًا مخصّصًا ولكن نوعها هو نفسه على مستوى JavaScript. نظرًا لأن V8 هو مجرد JavaScript، لا يمكنه التمييز بين المفاهيم التي تتوافق مع واجهة برمجة تطبيقات الويب مثل النوع الموثوق به. لهذا السبب، يجب أن يطلب V8 من أداة التضمين (Blink) المساعدة في التفريق بينها.

وبالتالي، فإن نقل هذا الجزء من الرمز إلى Blink أو أي برنامج تضمين يبدو اختيارًا منطقيًا. وبصرف النظر عن المشكلة المعروضة، هناك العديد من المزايا الأخرى:

  • يمكن أن تنشئ كل أداة تضمين وصفها الخاص
  • من الأسهل إنشاء الوصف من خلال Blink API.
  • بإمكان Blink الوصول إلى التعريف الأصلي للكائن. وبالتالي، إذا استخدمنا .toString() لإنشاء الوصف، ليس هناك خطر في أن يتم إعادة تعريف السمة .toString().

إجراء فواصل إعلانية (في وضع التقرير فقط)

في الوقت الحالي، الطريقة الوحيدة لتصحيح أخطاء أخطاء TT هي تحديد نقاط توقف على استثناءات JavaScript. ونظرًا لأن انتهاكات TT المفروضة ستؤدي إلى استثناء، فقد تكون هذه الميزة مفيدة بطريقة ما. ومع ذلك، في سيناريوهات العالم الواقعي، تحتاج إلى تحكّم أكثر دقة في انتهاكات TT. وعلى وجه الخصوص، نرغب في التقسيم فقط على انتهاكات TT (وليس استثناءات أخرى)، كما نرغب في الفصل أيضًا في وضع إعداد التقارير فقط والتمييز بين الأنواع المختلفة من انتهاكات TT.

تتوافق "أدوات مطوري البرامج" حاليًا مع مجموعة متنوعة من نقاط الإيقاف، لذا تكون البنية قابلة للتوسّع. لإضافة نوع جديد من نقاط الإيقاف، يجب إجراء تغييرات في الواجهة الخلفية (Blink) وCDP والواجهة الأمامية. يجب أن نقدم أمر CDP جديدًا، يسمى setBreakOnTTViolation. ستستخدم الواجهة الأمامية هذا الأمر لإخبار الخلفية بنوعية انتهاكات TT التي يجب أن تنتهك. ستقدم الخلفية، ولا سيما InspectorDOMDebuggerAgent، "تحقيقًا"، onTTViolation() سيتم استدعاؤه في كل مرة يحدث فيها انتهاك لـ TT. وبعد ذلك، سيتحقّق InspectorDOMDebuggerAgent مما إذا كان يجب أن يؤدي انتهاك السياسة إلى نقطة توقّف، وفي حال حدوث ذلك، سيتم إرسال رسالة إلى الواجهة الأمامية لإيقاف عملية التنفيذ مؤقتًا.

ما هي الخطوات التي تم اتّخاذها وما هي الخطوات التالية؟

بما أنّنا طرحنا المشاكل الموضّحة هنا، خضعت علامة التبويب المشاكل إلى بعض التغييرات:

من الآن فصاعدًا، نخطّط لاستخدام علامة التبويب المشاكل لعرض المزيد من المشاكل، ما سيتيح إلغاء تحميل وحدة التحكّم الخاصة بمسار رسائل الخطأ غير القابلة للقراءة على المدى الطويل.

تنزيل قنوات المعاينة

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

التواصل مع فريق "أدوات مطوري البرامج في Chrome"

استخدِم الخيارات التالية لمناقشة الميزات والتغييرات الجديدة في المشاركة أو مناقشة أي معلومات أخرى متعلّقة بأدوات مطوري البرامج.

  • يمكنك إرسال اقتراح أو ملاحظات إلينا عبر crbug.com.
  • الإبلاغ عن مشكلة في "أدوات مطوري البرامج" باستخدام خيارات إضافية   المزيد > مساعدة > الإبلاغ عن مشاكل في "أدوات مطوري البرامج" في "أدوات مطوري البرامج"
  • يمكنك نشر تغريدة على @ChromeDevTools.
  • شارِك في التعليقات على الميزات الجديدة في فيديوهات YouTube أو نصائح حول أدوات مطوّري البرامج فيديوهات YouTube.