حول MV3
إذا كنت تعرف أي شيء عن المتصفحات ، فمن المحتمل أن تكون قد سمعت أن Google Chrome تتلاشى MV2 لصالح MV3. ربما تكون قد سمعت أيضًا أن هذا يؤلم adblockers.
شرح سريع: “MV” يقف ل “manifest version.” يقدم MV3 نوعًا جديدًا من وقت التشغيل لتمديدات الكروم التي تتخلص منها من بين أمور أخرى webRequestBlocking، الإذن الذي يسمح للملحقات بحظر الطلبات بشكل ديناميكي بناءً على محتوىها (الذي”https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest”> بديل لا يدعم). يعتمد Adblockers اعتمادًا كبيرًا webRequestBlocking للعمل بشكل صحيح. مريحة للغاية (سعال السعال) للشركة التي تجعل معظم إيراداتها من الإعلانات لإزالة ذلك.
على أي حال ، مع الانتهاء من الانتهاء من MV2 إلى حد كبير ، يبدو الآن أنه وقت مناسب للحديث عن خطأ في Chrome وجدته وأبلغت Google في عام 2023.”https://issues.chromium.org/issues/40926777″> الخطأ يترك webRequestBlocking (ونعم ، Adblockers) العمل في MV3.
ما زلت أعتبر ذلك ربما أطرف خطأ وجدته على الإطلاق.
توقف عن كتابة المتصفحات في جافا سكريبت
نعم ، Chrome مكتوب في C ++. ومع ذلك ، تتم كتابة الامتدادات في JavaScript ، ووظائف API التي يسمونها تبدو مثل وظائف JavaScript ، على الأقل من وجهة نظر الامتداد. لكنها ليست وظائف عادية: إنها خاصة وتفعل المستعرض C ++ من خلال الارتباطات. من الناحية النظرية ، يجب أن يكون هذا آمنًا.
ولكن في الأيام الخوالي ، قررت Google أنه سيكون من الجيد حقن مجموعة من ملفات JS في الصفحات التي تستخدم واجهات برمجة تطبيقات Chrome. هؤلاء “extension binding modules” من شأنه تهيئة وظائف API والتحقق من صحة الحجج قبل نقلها إلى المتصفح.
(ملحوظة:”https://source.chromium.org/chromium/chromium/src/+/dc42ae208c2744f7fb144b2e396358a1fc34db87:extensions/renderer/resources/”> ها هي قاعدة كود من تلك الملفات في عام 2016.)
لم يكن تشغيل JavaScript المتميز في مواقع الويب التي يسيطر عليها المستخدمون فكرة جيدة ، لأنه يمكن معالجة JS غالبًا عن طريق تجاوز الوظائف والنماذج الأولية. منذ واجهات برمجة التطبيقات معينة مثل chrome.runtime موجود على مواقع الويب العادية أيضًا ، أدى نظام روابط الامتداد إلى عودة عدادات XSS عالمية متعددة في عامي 2015 و 2016.”https://issues.chromium.org/issues/40083765″> هذا واحد هذا يسمح لأي موقع ويب بحقن الرمز في أي موقع ويب آخر. أشياء مجنونة حقا. إذا لم أكن فقط 8 سنوات في ذلك الوقت … ربما كان بإمكاني صرفها.
على أي حال ، تعلمت Google من خطأها ونقلت معظم روابط API إلى Pure C ++. ومع ذلك ، لا تزال هناك اثنين من ملفات ربط JS موجودة ويتم استخدامها اليوم. على سبيل المثال ، إذا كان امتداد الكروم يعمل على تشغيل الكود التالي ، فسوف يضغط”https://source.chromium.org/chromium/chromium/src/+/60039d4d4bd70512e21a2dfe586602aca1d9d35e:extensions/renderer/resources/permissions_custom_bindings.js;l=46;bpv=0;bpt=0″> JS Loop وشنق بلا حدود: (اعتبارا من يوليو 2025)
chrome.permissions.contains({ permissions: { length: Infinity }})
ربما تتساءل ما علاقة هذا بـ Adblockers.
تذكر كيف قلت فقط عدد قليل من واجهات برمجة التطبيقات لا تزال تستخدم روابط JavaScript؟ chrome.webRequest هو واحد منهم.
الخطأ
هذه هي الطريقة التي يمكن أن تمنع امتداد MV2 طلبات إلى example.com:
chrome.webRequest.onBeforeRequest.addListener(()=> { return { cancel: true } }, { urls: ['*://*.example.com/*'] }, ['blocking'])
انها 'blocking' جزء في النهاية يتطلب webRequestBlocking إذن ، وبالتالي غير مسموح به في MV3. بدونها ، cancel: true لا شيء.
لذلك من الواضح إضافة مستمع حظر إلى chrome.webRequest.onBeforeRequest الحدث لا يعمل بعد الآن. لكن يمكننا أن نفعل شيئًا مجنونًا. يمكننا أن نجعل حدثنا الخاص. الآن ، لا ينبغي أن يكون هذا ممكنًا ؛ إنه ليس مفهومًا منطقيًا. ولكن بسبب كيفية عمل روابط JS ، يمكنك القيام بذلك. لسبب ما ، هناك أ”https://source.chromium.org/chromium/chromium/src/+/main:extensions/renderer/resources/web_request_event.js;l=52;drc=f52b068efda528bf42d0b7d245674deb99ee58ba”> فئة الغلاف ل webRequest الأحداث التي تحتوي على بعض الحالة الإضافية.
(أ”http://0x44.xyz/./wrei-note.txt”> ملاحظة حول الأمن من الكود أعلاه.)
بدلاً من القيام بالارتباطات الخالصة بين JS و C ++ ، يقوم المتصفح بإنشاء واحدة من هذه الفئات لكل شيء chrome.webRequest حدث: onBeforeRequestو onCompleted، إلخ. من المدهش ، .constructor من هذه الأحداث لا تزال عامة. إنه يشير إلى فئة غلاف أخرى ، والتي تتصل بها داخليًا WebRequestEventImpl (من الكود أعلاه). يمكنك استخدام هذا لإنشاء حدث جديد مع خصائصك الخاصة:
دع WebRequestevent=chrome.webrequest.onbeforerequest.constructor دع fooevent=جديد webrequestevent ("foo")
لا يزال هناك الكثير من التحقق من الصحة يحدث في الخلفية عندما تحاول فعل الأشياء بالفعل مع هذه الأحداث المزيفة. على سبيل المثال ، محاولة إضافة مستمع إلى fooEvent يقتل عملية التمديد ، لأن اسم الحدث غير صالح. فكيف تتلاعب بخصائص WebRequestEventImpl لفعل أي شيء مثير للاهتمام؟
بعد الكثير من الوقت النظر في رمز C ++ ، وجدت بالضبط شيء واحد ضعيف: opt_webViewInstanceId المعلمة. تم تعيين هذا لتطبيقات منصة Chrome ، من أجل السماح لهم بإدارة مواقع الويب المضمنة (WebViews). من بين أشياء أخرى ، يتيح لهم استخدام طلب الويب الذي يحجبه للتحكم في التنقل. في الأساس ، إذا كان هناك حدث معرف WebView ، فإن التحقق من الإذن webRequestBlocking سيتم تخطيها. كانت المشكلة أن المتصفح لم يتحقق أبدًا من أن حدثًا يحتوي على معرف WebView ينتمي فعليًا إلى تطبيق منصة. لذلك يمكن للامتداد أن يكون محاكاة ساخرة ، وتخطي الشيك ، واستخدام ميزة الحظر.
دع WebRequestEvent=chrome.webrequest.onbeforerequest.constructor // opt_webviewinstanceid هي الوسيطة الخامسة Let FakeEvent=new WebRequestevent ("webRequest.onBeforeRequest"، 0 ، 0. ['*://*.example.com/*'] } ، ['blocking'])
ربما يجب أن ألاحظ أن تطبيقات النظام الأساسي كانت تم إهماله في عام 2020. لقد وجدت هذا الخطأ في عام 2023 ، والرمز للتعامل معه opt_webViewInstanceId لا يزال موجودًا في عام 2025. يذهب لإظهار كيف يؤدي الكود القديم إلى الأخطاء.
ما الذي يمكن أن يحدث ، وما حدث
من الناحية الفنية ، كان من الممكن أن يستخدم شخص ما هذا الخطأ لصنع AdBlocker يعمل بشكل مثالي في MV3 ببساطة عن طريق استبدال جميع مثيلات chrome.webRequest.onBeforeRequest مع fakeEvent. كان هذا مضحكا للغاية ، بعد كل هذه الضجيج حول كيفية مقتل adblockers.
لكني لا أعرف كيف أصنع adblocker ، لذلك قررت ذلك”https://issues.chromium.org/issues/40926777″> الإبلاغ عن المشكلة إلى Google في أغسطس 2023. تم تصحيحه في Chrome 118 بواسطة”https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/api/web_request/web_request_api.cc;l=722;bpv=1;bpt=0;drc=40cc134ade29c59e86399520db9d252e79058a3c;dlc=ccbf0af81b332209d276725c17e381a76acb9b1c”> التحقق من ما إذا كان الامتدادات باستخدام opt_webViewInstanceId في الواقع كان WebView أذونات. للتقرير ، قمت بتسجيل مكافأة ضخمة قدرها 0 دولار. قرروا أنها لم تكن مشكلة أمنية ، وبصراحة ، أوافق ، لأنها لم تمنح الامتدادات الوصول إلى البيانات التي لم يكن لديهم بالفعل.
(كما هو موضح أعلاه: أرباحي من هذا الخطأ.)
على أي حال ، لقد كان ممتعًا ، ويوضح حقًا كيف يمكن لبعض خطوط التعليمات البرمجية في بعض الأحيان تجاوز تحديث كبير من قبل شركة كبيرة. أتمنى أن تكون قد وجدت أنها مثيرة للاهتمام! إذا كنت ترغب في قراءة منشور آخر حول خطأ في ملحقات الكروم ، فحاول”http://0x44.xyz/blog/cve-2023-4369/”> هذا واحد وجدته في نفس العام، الذي حصل على رقم CVE ومكافأة بقيمة 10،000 دولار.