استخدام eval في إضافات Chrome

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

ومع ذلك، فإننا ندرك أن مجموعة متنوعة من المكتبات تستخدم التركيبات eval() والتركيبات المشابهة لـ eval مثل. new Function() لتحسين الأداء وسهولة التعبير. تعتبر مكتبات النماذج عرضة بشكل خاص لأسلوب التنفيذ هذا. في حين أنّ بعض المواقع (مثل Angular.js) تتوافق مع سياسة CSP. فإن العديد من أطر العمل الشائعة لم يتم تحديثها بعد إلى آلية تتوافق مع الإضافات عالم بدون eval بالتالي، أثبتت إزالة إمكانية استخدام هذه الوظيفة المزيد من المعلومات. أكثر من المتوقع لمطوّري البرامج.

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

لماذا وضع الحماية؟

يُعد eval خطيرًا داخل إضافة لأن الرمز البرمجي الذي ينفّذه لديه إمكانية الوصول إلى كل شيء في ذات الأذونات العالية للإضافة. يتوفر عدد كبير من واجهات برمجة تطبيقات chrome.* الفعّالة التي يمكن تؤثر بشدة في أمان المستخدم وخصوصيته؛ والاستخراج البسيط للبيانات هو أقل ما يقلقنا. الحل المعروض هو وضع حماية يمكن من خلاله لـ eval تنفيذ الرمز بدون الوصول إلى أي من بيانات الإضافة أو واجهات برمجة التطبيقات العالية القيمة للإضافة. ما مِن بيانات أو واجهات برمجة تطبيقات.

ونحقق ذلك من خلال إدراج ملفات HTML محددة داخل حزمة الإضافات باعتبارها في وضع الحماية. عند تحميل صفحة في وضع الحماية، سيتم نقلها إلى مصدر فريد، وسيتم رفضها. الوصول إلى واجهات برمجة تطبيقات chrome.*. إذا قمنا بتحميل الصفحة التي تم وضع الحماية لها في الإضافة عبر iframe، فيمكننا وتمريرها، والسماح لها بالتصرف بشأن هذه الرسائل بطريقة ما، ثم الانتظار حتى ترسل إلينا الرسالة نتيجته. تمنحنا آلية المراسلة البسيطة هذه كل ما نحتاج إليه لتضمين المحتوى الذي يعتمد على eval بأمان. في سير عمل الإضافة.

إنشاء وضع حماية واستخدامه

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

إدراج الملفات في البيان

يجب إدراج كل ملف يجب تشغيله داخل وضع الحماية في بيان الإضافة عن طريق إضافة الموقع: sandbox. هذه خطوة مهمة، ويسهل نسيانها، لذا يرجى التحقق مرة أخرى من أن أن يتم إدراج الملف الذي تم وضع الحماية له في البيان. في هذا النموذج، نضع الملف في وضع الحماية بشكل ذكي باسم "sandbox.html". يبدو إدخال البيان كما يلي:

{
  ...,
  "sandbox": {
     "pages": ["sandbox.html"]
  },
  ...
}

تحميل الملف في وضع الحماية

ولتنفيذ أمر مثير للاهتمام باستخدام الملف المحمي في وضع الحماية، نحتاج إلى تحميله في سياق حيث فيمكن معالجتها من خلال رمز الإضافة. هنا، تم تحميل sandbox.html في صفحة الحدث للإضافة (eventpage.html) عبر iframe. يحتوي eventpage.js على رمز ترسل رسالة إلى وضع الحماية كلما تم النقر على إجراء المتصفح من خلال العثور على iframe في الصفحة، مع تنفيذ الطريقة postMessage على contentWindow. الرسالة عبارة عن كائن تحتوي على خاصيتين: context وcommand. سنتعمق في كليهما بعد قليل.

chrome.browserAction.onClicked.addListener(function() {
 var iframe = document.getElementById('theFrame');
 var message = {
   command: 'render',
   context: {thing: 'world'}
 };
 iframe.contentWindow.postMessage(message, '*');
});
للحصول على معلومات عامة عن postMessage API، يمكنك الاطّلاع على مستندات postMessage حول MDN . إنه كامل تمامًا وتستحق القراءة. على وجه الخصوص، لاحظ أنه لا يمكن تمرير البيانات ذهابًا وإيابًا إلا إذا كانت قابلة للتسلسل. الدوال، على سبيل المثال، ليست كذلك.

تنفيذ إجراءات خطيرة

عند تحميل sandbox.html، يتم تحميل مكتبة "المقاود" وإنشاء محتوى مضمّن وتجميعه. قالب دقيق بالطريقة التي تقترح بها المقاود:

<script src="handlebars-1.0.0.beta.6.js"></script>
<script id="hello-world-template" type="text/x-handlebars-template">
  <div class="entry">
    <h1>Hello, !</h1>
  </div>
</script>
<script>
  var templates = [];
  var source = document.getElementById('hello-world-template').innerHTML;
  templates['hello'] = Handlebars.compile(source);
</script>

وهذا لا يفشل! على الرغم من أنّ "Handlebars.compile" ينتهي باستخدام new Function، تعمل بعض الميزات. تمامًا كما هو متوقع، وسننتهي في النهاية على نموذج مجمّع في templates['hello'].

تمرير النتيجة مرة أخرى

سنجعل هذا النموذج متاحًا للاستخدام من خلال إعداد أداة معالجة رسائل تقبل الأوامر. من صفحة الحدث. سنستخدم command الذي تم تمريره لتحديد ما يجب فعله (يمكنك تخيّل تنفيذ ما هو أكثر من مجرد العرض، وربما إنشاء قوالب؟ ربما تقوم بإدارتها في بعض ؟)، وسيتم تمرير context إلى النموذج مباشرةً للعرض. رمز HTML المعروض سيتم تمريرها مرة أخرى إلى صفحة الحدث بحيث يمكن للإضافة الاستفادة منها لاحقًا في ما يلي:

<script>
  window.addEventListener('message', function(event) {
    var command = event.data.command;
    var name = event.data.name || 'hello';
    switch(command) {
      case 'render':
        event.source.postMessage({
          name: name,
          html: templates[name](event.data.context)
        }, event.origin);
        break;

      // case 'somethingElse':
      //   ...
    }
  });
</script>

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

تجعل هذه الطريقة صياغة النماذج أمرًا بسيطًا، لكنها بالطبع لا تقتصر على إنشاء النماذج. أي تقييم إذا كان الرمز البرمجي الذي لا يعمل بشكل فوري في إطار سياسة أمان المحتوى الصارمة، يمكن وضعه في وضع الحماية، بوصة في الواقع، من المفيد في كثير من الأحيان وضع وضع الحماية لمكونات الإضافات التي ستعمل بشكل صحيح من أجل بقصر كل جزء من برنامجك على أصغر مجموعة من الامتيازات اللازمة له وتنفيذه بشكل صحيح. عرض تقديمي من Google حول كتابة تطبيقات الويب الآمنة وإضافات Chrome ويقدم مؤتمر I/O 2012 بعض الأمثلة الجيدة لهذه الأساليب في التطبيق، وتستحق 56 دقيقة من الوقت.