يتناول منشور المدوّنة هذا تنفيذ دعم "أدوات مطوري البرامج" لتصحيح أخطاء "سياسة أمان المحتوى" (CSP) بمساعدة علامة التبويب المشاكل التي تم طرحها مؤخرًا.
تم تنفيذ العمل خلال فترتَي تدريب: 1. خلال المرحلة الأولى، أنشأنا إطار العمل العام لإعداد التقارير وصمّمنا رسائل المشاكل لـ 3 مشاكل متعلّقة بمخالفة سياسة أمان المحتوى. 2. وخلال المرحلة الثانية، أضفنا مشاكل "الأنواع الموثوق بها" إلى جانب بعض ميزات "أدوات مطوري البرامج في Chrome" المتخصّصة لتصحيح أخطاء "الأنواع الموثوق بها".
ما هي "سياسة أمان المحتوى"؟
تتيح سياسة أمان المحتوى (CSP) حظر سلوكيات معيّنة في موقع إلكتروني لتعزيز الأمان. على سبيل المثال، يمكن استخدام سياسة أمان المحتوى (CSP) لمنع النصوص البرمجية المضمّنة أو لمنع eval، وكلاهما يقلّل من فرص الهجوم من خلال البرمجة عبر المواقع (XSS). للحصول على مقدّمة مفصّلة حول CSP، يُرجى الاطّلاع على هذه الصفحة.
ومن سياسات أمان المحتوى الجديدة بشكل خاص سياسة الأنواع الموثوق بها(TT) التي تتيح إجراء تحليل ديناميكي يمكنه منع فئة كبيرة من هجمات حقن النصوص البرمجية على المواقع الإلكترونية بشكل منهجي. لتحقيق ذلك، تتيح واجهة TT لموقع إلكتروني مراقبة رمز JavaScript الخاص به للسماح فقط بتعيين أنواع معيّنة من العناصر إلى مخازن DOM، مثل innerHTML.
يمكن لموقع إلكتروني تفعيل سياسة أمان المحتوى من خلال تضمين عنوان HTTP معيّن. على سبيل المثال، يؤدي العنوان
content-security-policy: require-trusted-types-for 'script'; trusted-types default
إلى تفعيل سياسة "الأنواع الموثوق بها" لصفحة معيّنة.
يمكن أن تعمل كل سياسة في أحد الأوضاع التالية:
- وضع التنفيذ: حيث يُعدّ كل انتهاك للسياسة خطأً
- وضع إعداد التقارير فقط: يعرض رسالة الخطأ كتحذير، ولكنّه لا يؤدي إلى حدوث عطل في صفحة الويب.
مشاكل تنفيذ "سياسة أمان المحتوى" في علامة التبويب المشاكل
كان الهدف من هذا العمل هو تحسين تجربة تصحيح الأخطاء في مشاكل CSP. عند النظر في المشاكل الجديدة، يتّبع فريق "أدوات مطوّري البرامج" هذه العملية تقريبًا:
- تحديد قصص المستخدمين تحديد مجموعة من قصص المستخدمين في واجهة أدوات مطوري البرامج الأمامية التي تغطي كيفية احتياج مطوِّر تطبيقات ويب إلى التحقيق في المشكلة.
- تنفيذ الواجهة الأمامية: استنادًا إلى قصص المستخدمين، حدِّد المعلومات المطلوبة للتحقيق في المشكلة في الواجهة الأمامية (مثل طلب ذي صلة أو اسم ملف تعريف ارتباط أو سطر في نص برمجي أو ملف HTML وما إلى ذلك).
- رصد المشاكل: حدِّد الأماكن في المتصفّح التي يمكن رصد المشكلة فيها في Chrome، وجهِّز المكان للإبلاغ عن مشكلة تتضمّن المعلومات ذات الصلة من الخطوة (2).
- احفظ المشاكل واعرِضها. تخزين المشاكل في مكان مناسب وإتاحتها لـ "أدوات مطوّري البرامج" بعد فتحها
- تصميم نص المشاكل اكتب نصًا توضيحيًا يساعد مطوِّر تطبيقات الويب في فهم المشكلة، والأهم من ذلك، حلّها
الخطوة 1: تحديد قصص المستخدمين لمشاكل CSP
قبل أن نبدأ عملنا على التنفيذ، أنشأنا مستند تصميم يتضمّن قصص مستخدمين لفهم ما نحتاج إلى فعله بشكل أفضل. على سبيل المثال، كتبنا قصة المستخدم التالية:
بصفتي مطوّرًا أدرك للتو أنّ بعض أجزاء موقعي الإلكتروني محظورة، أريد:- ...معرفة ما إذا كانت "سياسة أمان المحتوى" هي سبب حظر إطارات iframe أو الصور على موقعي الإلكتروني - ...معرفة توجيه "سياسة أمان المحتوى" الذي يتسبب في حظر مورد معيّن - ...معرفة كيفية تغيير "سياسة أمان المحتوى" لموقعي الإلكتروني للسماح بعرض الموارد المحظورة حاليًا أو تنفيذ ملفات JavaScript المحظورة حاليًا.
لاستكشاف قصة المستخدم هذه، أنشأنا بعض نماذج صفحات الويب البسيطة التي عرضت انتهاكات سياسة أمان المحتوى التي كنا مهتمين بها، واستكشفنا نماذج الصفحات للتعرّف على العملية بأنفسنا. في ما يلي بعض الأمثلة على صفحات الويب (افتح العرض التوضيحي مع فتح علامة التبويب المشاكل):
باستخدام هذه العملية، تبيّن لنا أنّ الموقع الجغرافي المصدر هو أهم معلومة لتصحيح أخطاء CSP. وجدنا أيضًا أنّه من المفيد العثور بسرعة على إطار iframe والطلب المرتبطَين في حال تم حظر أحد الموارد، وأنّ الرابط المباشر إلى عنصر HTML في لوحة العناصر ضمن "أدوات مطوري البرامج في Chrome" يمكن أن يكون مفيدًا أيضًا.
الخطوة 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 إلى واجهة DevTools الأمامية. باستخدام هذه المكتبة، يمكن إنشاء عنصر 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 عن المشاكل إلى نقطة نهاية (اختيارية) لإعداد التقارير يمكن ضبطها في عنوان CSP HTTP. كانت معظم المعلومات التي أردنا الإبلاغ عنها متاحة من قبل، لذلك لم تكن هناك حاجة إلى إجراء تغييرات كبيرة في الخلفية لكي تعمل أدواتنا.
الخطوة 4: حفظ المشاكل وعرضها
هناك مشكلة بسيطة، وهي أنّنا أردنا أيضًا الإبلاغ عن المشاكل التي حدثت قبل فتح "أدوات مطوري البرامج في Chrome"، على غرار طريقة معالجة رسائل وحدة التحكّم. يعني ذلك أنّنا لا نبلّغ عن المشاكل مباشرةً إلى الواجهة الأمامية، بل نستخدم مساحة تخزين يتم ملؤها بالمشاكل بشكل مستقل عمّا إذا كانت "أدوات مطوّري البرامج" مفتوحة أم لا. بعد فتح "أدوات مطوّري البرامج" (أو ربط أي برنامج آخر لبروتوكول 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/
بعد التكرار، وصلنا إلى:

كما ترى، فإنّ إشراك فريق الميزات وفريق علاقات المطوّرين يجعل الوصف أكثر وضوحًا ودقة.
يمكن أيضًا اكتشاف مشاكل CSP على صفحتك في علامة التبويب المخصّصة تحديدًا لانتهاكات CSP.
تصحيح أخطاء Trusted Types
قد يكون العمل مع TT على نطاق واسع أمرًا صعبًا بدون أدوات المطوّرين المناسبة.
تحسين الطباعة من وحدة التحكّم
عند العمل مع "العناصر الموثوقة"، نريد عرض كمية المعلومات نفسها على الأقل التي نعرضها للعناصر غير الموثوقة. للأسف، لا يتم حاليًا عرض أي معلومات عن العنصر المغلَّف عند عرض "عنصر موثوق به".
ويعود السبب في ذلك إلى أنّ القيمة المعروضة في وحدة التحكّم مأخوذة من استدعاء .valueOf() على العنصر تلقائيًا. ومع ذلك، في حالة النوع الموثوق به، لا تكون القيمة المعروضة مفيدة جدًا. بدلاً من ذلك، نريد الحصول على شيء مشابه لما تحصل عليه عند الاتصال بـ .toString(). لتحقيق ذلك، نحتاج إلى تعديل V8 وBlink لتقديم معالجة خاصة لكائنات الأنواع الموثوق بها.
على الرغم من أنّ هذه المعالجة المخصّصة تم تنفيذها في V8 لأسباب تاريخية، فإنّ هذا النهج له عيوب كبيرة. هناك العديد من العناصر التي تتطلّب عرضًا مخصّصًا ولكن نوعها هو نفسه على مستوى JS. بما أنّ محرّك V8 هو لغة JS خالصة، لا يمكنه التمييز بين المفاهيم التي تتوافق مع واجهة برمجة تطبيقات ويب، مثل النوع الموثوق به. لهذا السبب، على محرّك V8 طلب المساعدة من أداة التضمين (Blink) للتمييز بينهما.
وبالتالي، يبدو أنّ نقل هذا الجزء من الرمز إلى Blink أو أي أداة تضمين هو خيار منطقي. بالإضافة إلى المشكلة التي تم الكشف عنها، هناك العديد من المزايا الأخرى:
- يمكن أن يكون لكل أداة تضمين وصف خاص بها
- من الأسهل بكثير إنشاء الوصف من خلال Blink API
- يمكن لـ Blink الوصول إلى التعريف الأصلي للعنصر. وبالتالي، إذا استخدمنا
.toString()لإنشاء الوصف، لن يكون هناك خطر من إعادة تعريف.toString().
الإيقاف عند الانتهاك (في وضع إعداد التقارير فقط)
في الوقت الحالي، الطريقة الوحيدة لتصحيح أخطاء انتهاكات TT هي من خلال ضبط نقاط توقّف على استثناءات JS. بما أنّ انتهاكات TT المفروضة ستؤدي إلى حدوث استثناء، يمكن أن تكون هذه الميزة مفيدة إلى حدّ ما. ومع ذلك، في سيناريوهات العالم الحقيقي، تحتاج إلى تحكم أكثر دقة في انتهاكات TT. على وجه الخصوص، نود أن نكسر فقط انتهاكات TT (وليس الاستثناءات الأخرى)، ونكسر أيضًا في وضع التقرير فقط ونميز بين الأنواع المختلفة لانتهاكات TT.
تتيح "أدوات مطوري البرامج في Chrome" استخدام مجموعة كبيرة من نقاط الإيقاف، لذا فإنّ البنية قابلة للتوسيع بشكل كبير. تتطلّب إضافة نوع جديد من نقاط الإيقاف إجراء تغييرات في الخلفية (Blink) وCDP والواجهة الأمامية.
يجب أن نقدّم أمرًا جديدًا في بروتوكول "أدوات مطوّري البرامج في Chrome"، لنُطلق عليه اسم setBreakOnTTViolation. سيتم استخدام هذا الأمر من قِبل الواجهة الأمامية لإعلام الواجهة الخلفية بنوع انتهاكات TT التي يجب أن تتوقف عندها. ستوفّر الخلفية، وتحديدًا InspectorDOMDebuggerAgent، "مسبارًا"، وهو onTTViolation()، سيتم استدعاؤه في كل مرة تحدث فيها مخالفة لـ TT. بعد ذلك، ستتحقّق InspectorDOMDebuggerAgent مما إذا كان يجب أن تؤدي هذه المخالفة إلى تفعيل نقطة توقّف، وإذا كان الأمر كذلك، سترسل رسالة إلى الواجهة الأمامية لإيقاف التنفيذ مؤقتًا.
ما تم إنجازه وما سيتم إنجازه؟
منذ ظهور المشاكل الموضّحة هنا، خضعت علامة التبويب المشاكل لبعض التغييرات:
- وتم تحسين ترابطها مع اللوحات الأخرى في "أدوات مطوّري البرامج في Chrome".
- تم نقل الإبلاغ عن عدد من المشاكل الأخرى إلى علامة التبويب المشاكل: التباين المنخفض والنشاط الموثوق به على الويب ووضع Quirks وواجهة برمجة التطبيقات لإعداد تقارير تحديد المصدر والمشاكل المتعلّقة بمشاركة الموارد المتعددة المصادر (CORS) وغيرها.
- تمت إضافة فرصة لإخفاء المشاكل
في المستقبل، نخطّط لاستخدام علامة التبويب المشاكل لعرض المزيد من المشاكل، ما سيجعل من الممكن على المدى الطويل إزالة تدفق رسائل الخطأ غير المقروءة من وحدة التحكّم.
تنزيل قنوات النسخة الحصرية
ننصحك باستخدام إصدار Chrome Canary أو Dev أو Beta كمتصفّح التطوير التلقائي. تتيح لك قنوات المعاينة هذه الوصول إلى أحدث ميزات "أدوات مطوّري البرامج"، واختبار واجهات برمجة التطبيقات المتطوّرة لمنصات الويب، والعثور على المشاكل في موقعك الإلكتروني قبل أن يكتشفها المستخدمون.
التواصل مع فريق أدوات مطوري البرامج في Chrome
استخدِم الخيارات التالية لمناقشة الميزات الجديدة أو التحديثات أو أي موضوع آخر يتعلّق بـ "أدوات مطوّري البرامج".
- يمكنك إرسال الملاحظات وطلبات الميزات إلينا على crbug.com.
- يمكنك الإبلاغ عن مشكلة في "أدوات مطوّري البرامج" من خلال النقر على خيارات إضافية > مساعدة > الإبلاغ عن مشكلة في "أدوات مطوّري البرامج" في "أدوات مطوّري البرامج".
- يمكنك نشر تغريدة على @ChromeDevTools.
- يمكنك إضافة تعليقات على فيديوهات على YouTube حول الميزات الجديدة في "أدوات مطوّري البرامج" أو فيديوهات على YouTube حول نصائح "أدوات مطوّري البرامج".