با نقض کد میزبان از راه دور مقابله کنید

کد میزبانی‌شده از راه دور یا RHC، چیزی است که فروشگاه وب کروم به هر چیزی که توسط مرورگر اجرا می‌شود و از جایی غیر از فایل‌های خود افزونه بارگذاری می‌شود، می‌گوید. چیزهایی مانند جاوا اسکریپت و WASM. این شامل داده‌ها یا چیزهایی مانند JSON یا CSS نمی‌شود .

چرا RHC دیگر مجاز نیست؟

با Manifest V3 افزونه‌ها اکنون باید تمام کدهایی را که استفاده می‌کنند درون خود افزونه قرار دهند. در گذشته، می‌توانستید تگ‌های اسکریپت را به صورت پویا از هر URL در وب تزریق کنید.

به من گفته شد که پسوند من RHC دارد. چه اتفاقی دارد می‌افتد؟

اگر افزونه‌ی شما در طول بررسی با خطای Blue Argon رد شد، بررسی‌کنندگان ما معتقدند که افزونه‌ی شما از کد میزبانی‌شده از راه دور استفاده می‌کند. این معمولاً نتیجه‌ی تلاش افزونه برای اضافه کردن یک تگ اسکریپت با یک منبع از راه دور (یعنی از وب باز، به جای فایل‌های موجود در افزونه) یا دریافت یک منبع برای اجرا مستقیم است.

چگونه RHC را تشخیص دهیم؟

تشخیص RHC وقتی بدانید که به دنبال چه چیزی باشید، کار چندان سختی نیست. ابتدا، رشته‌های "http://" یا "https://" را در پروژه خود بررسی کنید. اگر نقض RHC دارید، احتمالاً می‌توانید با پیدا کردن آنها، آنها را پیدا کنید. اگر یک سیستم ساخت کامل دارید یا از وابستگی‌های npm یا سایر منابع شخص ثالث استفاده می‌کنید، مطمئن شوید که نسخه کامپایل شده کد را جستجو می‌کنید، زیرا این همان چیزی است که توسط فروشگاه ارزیابی می‌شود. اگر هنوز قادر به یافتن مشکل نیستید، مرحله بعدی تماس با پشتیبانی One Stop است. آنها می‌توانند موارد نقض خاص و آنچه را که برای انتشار هرچه سریعتر افزونه لازم است، شرح دهند.

اگر یک کتابخانه درخواست کد کند، چه باید کرد؟

صرف نظر از اینکه کد از کجا آمده است، مجاز به داشتن RHC نیست. این شامل کدی می‌شود که شما آن را ننوشته‌اید، اما اتفاقاً به عنوان یک وابستگی در پروژه خود استفاده می‌کنید. برخی از توسعه‌دهندگانی که از Firebase استفاده می‌کنند، هنگام استفاده از کد از راه دور برای استفاده در Firebase Auth با این مشکل مواجه شدند. اگرچه این یک کتابخانه شخص ثالث (یعنی متعلق به گوگل) بود، اما هیچ استثنایی برای RHC قائل نشده است. شما باید کد را طوری پیکربندی کنید که یا RHC را حذف کند یا پروژه خود را به‌روزرسانی کنید تا از ابتدا کد را شامل نشود. اگر با مشکلی مواجه شدید که در آن کد شما RHC را بارگیری نمی‌کند، بلکه کتابخانه‌ای است که از آن استفاده می‌کنید، بهترین اقدام این است که با نویسنده کتابخانه تماس بگیرید. به آنها اطلاع دهید که این اتفاق می‌افتد و از آنها بخواهید که راه حلی ارائه دهند یا کد را به‌روزرسانی کنند تا آن را حذف کنند.

اگر نمی‌توانید منتظر به‌روزرسانی کتابخانه باشید، چه؟

برخی از کتابخانه‌ها تقریباً بلافاصله پس از اطلاع، به‌روزرسانی را ارسال می‌کنند، اما برخی دیگر ممکن است رها شوند یا مدتی طول بکشد تا مشکل را برطرف کنند. بسته به آنچه در تخلف خاص اتفاق می‌افتد، ممکن است نیازی نباشد منتظر بمانید تا آنها از حالت مسدود خارج شوند و بررسی موفقیت‌آمیزی را انجام دهند. گزینه‌های مختلفی برای راه‌اندازی سریع و دوباره وجود دارد.

کد را حسابرسی کنید

آیا مطمئن هستید که کدی که باعث درخواست می‌شود مورد نیاز است؟ اگر می‌توان آن را حذف کرد، یا کتابخانه‌ای که باعث آن شده است قابل حذف است، آن کد را حذف کنید و کار تمام است.

از طرف دیگر، آیا کتابخانه دیگری وجود دارد که همین ویژگی‌ها را ارائه دهد؟ برای گزینه‌های دیگری که موارد استفاده مشابهی را برآورده می‌کنند ، npmjs.com ، GitHub یا سایت‌های دیگر را بررسی کنید.

تکان دادن درخت

اگر کدی که باعث نقض RHC می‌شود واقعاً مورد استفاده قرار نمی‌گیرد، ممکن است بتوان آن را به طور خودکار با ابزار حذف کرد. ابزارهای ساخت مدرن مانند webpack ، Rollup و Vite (فقط برای نام بردن چند مورد) دارای ویژگی‌ای به نام tree-shaking هستند. پس از فعال شدن در سیستم ساخت شما، tree-shaking باید هرگونه مسیر کد استفاده نشده را حذف کند. این می‌تواند به این معنی باشد که شما نه تنها نسخه‌ای سازگارتر از کد خود دارید، بلکه نسخه‌ای سبک‌تر و سریع‌تر نیز خواهید داشت! توجه به این نکته مهم است که همه کتابخانه‌ها قادر به tree-shaking نیستند، اما بسیاری از آنها این قابلیت را دارند. برخی از ابزارها، مانند Rollup و Vite، به طور پیش‌فرض tree-shaking را فعال دارند. webpack برای فعال شدن آن باید پیکربندی شود . اگر از یک سیستم build به عنوان بخشی از افزونه خود استفاده نمی‌کنید، اما از کتابخانه‌های کد استفاده می‌کنید ، واقعاً توصیه می‌شود که اضافه کردن یک ابزار build به گردش کار خود را بررسی کنید. ابزارهای build به شما کمک می‌کنند پروژه‌های ایمن‌تر، قابل اعتمادتر و قابل نگهداری‌تری بنویسید.

جزئیات نحوه پیاده‌سازی treeshaking به پروژه خاص شما بستگی دارد. اما برای یک مثال ساده با Rollup، می‌توانید treeshaking را فقط با کامپایل کردن کد پروژه خود اضافه کنید. به عنوان مثال، اگر فایلی دارید که فقط به Firebase Auth وارد می‌شود، به نام main.js:

import { GoogleAuthProvider, initializeAuth } from "firebase/auth";

chrome.identity.getAuthToken({ 'interactive': true }, async (token) => {
  const credential = GoogleAuthProvider.credential(null, token);
  try {
    const app = initializeApp({ ... });
    const auth = initializeAuth(app, { popupRedirectResolver: undefined, persistence: indexDBLocalPersistence });
    const { user } = await auth.signInWithCredential(credential)
    console.log(user)
  } catch (e) {
    console.error(error);
  }
});

سپس تنها کاری که باید انجام دهید این است که به Rollup فایل ورودی، افزونه مورد نیاز برای بارگذاری فایل‌های گره @rollup/plugin-node-resolve و نام فایل خروجی که تولید می‌کند را بگویید.

npx rollup --input main.js --plugin '@rollup/plugin-node-resolve' --file compiled.js

با اجرای آن دستور در یک پنجره ترمینال، یک نسخه تولید شده از فایل main.js ما را دریافت خواهید کرد که همه در یک فایل واحد به نام compiled.js کامپایل شده است.

Rollup می‌تواند ساده باشد، اما در عین حال بسیار قابل تنظیم است. می‌توانید انواع منطق و پیکربندی پیچیده را اضافه کنید، فقط مستندات آنها را بررسی کنید. اضافه کردن ابزارهای ساخت مانند این منجر به کد کوچکتر و کارآمدتر می‌شود و در این مورد، مشکل کد میزبانی شده از راه دور ما را برطرف می‌کند.

ویرایش خودکار فایل‌ها

یک روش رایج که کد میزبانی شده از راه دور می‌تواند وارد پایگاه کد شما شود، به عنوان یک زیر-وابسته از کتابخانه‌ای است که شما در حال اضافه کردن آن هستید. اگر کتابخانه X بخواهد کتابخانه Y را از یک CDN import ، شما همچنان باید آن را به‌روزرسانی کنید تا از یک منبع محلی بارگیری شود. با سیستم‌های ساخت مدرن، می‌توانید به راحتی افزونه‌هایی برای استخراج یک مرجع از راه دور ایجاد کنید و آن را مستقیماً در کد خود قرار دهید.

این به معنی کد داده شده‌ای است که به این شکل است:

import moment from "https://unpkg.com/moment@2.29.4/moment.js"
console.log(moment())

شما می‌توانید یک افزونه‌ی کوچک برای جمع کردن فایل‌ها بسازید.

import { existsSync } from 'fs';
import fetch from 'node-fetch';

export default {
  plugins: [{
    load: async function transform(id, options, outputOptions) {
      // this code runs over all of out javascript, so we check every import
      // to see if it resolves as a local file, if that fails, we grab it from
      // the network using fetch, and return the contents of that file directly inline
      if (!existsSync(id)) {
        const response = await fetch(id);
        const code = await response.text();

        return code
      }
      return null
    }
  }]
};

به محض اینکه نسخهٔ نهایی را با افزونهٔ جدید اجرا کنید، هر URL import از راه دور، صرف نظر از اینکه کد ما، یک زیروابستگی، زیروابستگی یا هر جای دیگری بوده باشد یا نه، کشف می‌شود.

npx rollup --input main.js --config ./rollup.config.mjs --file compiled.js

ویرایش دستی فایل‌ها

ساده‌ترین گزینه، حذف کدی است که باعث RHC می‌شود. آن را در ویرایشگر متن مورد نظر خود باز کنید و خطوط ناقض را حذف کنید. این کار معمولاً توصیه نمی‌شود ، زیرا شکننده است و ممکن است فراموش شود. وقتی فایلی به نام "library.min.js" در واقع library.min.js نباشد، نگهداری پروژه شما دشوارتر می‌شود. به جای ویرایش فایل‌های خام، گزینه‌ای که کمی قابل نگهداری‌تر است، استفاده از ابزاری مانند patch-package است. این یک گزینه فوق‌العاده قدرتمند است که به شما امکان می‌دهد تغییرات را در یک فایل ذخیره کنید، نه خود فایل. این ابزار بر اساس فایل‌های patch ساخته شده است، همان چیزی که سیستم‌های کنترل نسخه مانند Git یا Subversion را پشتیبانی می‌کند. شما فقط باید کد ناقض را به صورت دستی تغییر دهید، فایل diff را ذخیره کنید و patch-package را با تغییراتی که می‌خواهید اعمال کنید، پیکربندی کنید. می‌توانید یک آموزش کامل را در readme پروژه بخوانید. اگر در حال پچ کردن یک پروژه هستید، واقعاً شما را تشویق می‌کنیم که با پروژه تماس بگیرید تا درخواست ایجاد تغییرات در بالادست را داشته باشید. در حالی که patch-package مدیریت پچ‌ها را بسیار آسان‌تر می‌کند، نداشتن چیزی برای پچ کردن حتی بهتر است.

اگر کد استفاده نمی‌شود، چه باید کرد؟

با رشد پایگاه‌های کد، وابستگی‌ها (یا وابستگی یک وابستگی، یا وابستگی…) می‌توانند مسیرهای کدی را که دیگر استفاده نمی‌شوند، نگه دارند. اگر یکی از آن بخش‌ها شامل کدی برای بارگذاری یا اجرای RHC باشد، باید حذف شود. فرقی نمی‌کند که از کار افتاده باشد یا بلااستفاده باشد. اگر استفاده نمی‌شود، باید حذف شود، یا با treeshaking یا وصله کردن کتابخانه برای حذف آن.

آیا راه حلی وجود دارد؟

به طور کلی، خیر. RHC مجاز نیست. با این حال، تعداد کمی از موارد وجود دارد که مجاز است . اینها تقریباً همیشه مواردی هستند که هیچ گزینه دیگری غیرممکن است.

API اسکریپت‌های کاربر

اسکریپت‌های کاربر، قطعه کدهای کوچکی هستند که معمولاً توسط کاربر ارائه می‌شوند و برای مدیران اسکریپت کاربر مانند TamperMonkey و Violentmonkey در نظر گرفته شده‌اند. این مدیران نمی‌توانند کدی را که توسط کاربران نوشته شده است، بسته‌بندی کنند، بنابراین API اسکریپت کاربر راهی برای اجرای کد ارائه شده توسط کاربر ارائه می‌دهد. این جایگزینی برای chrome.scripting.executeScript یا سایر محیط‌های اجرای کد نیست . کاربران باید حالت توسعه‌دهنده را برای اجرای هر چیزی فعال کنند. اگر تیم بررسی فروشگاه وب کروم فکر کند که این کد به روشی غیر از آنچه برای آن در نظر گرفته شده است (یعنی کد ارائه شده توسط کاربر) استفاده می‌شود، ممکن است رد شود یا فهرست آن از فروشگاه حذف شود.

اشکال‌زدای کروم

رابط برنامه‌نویسی کاربردی chrome.debugger به افزونه‌ها این امکان را می‌دهد که با پروتکل Devtools کروم تعامل داشته باشند. این همان پروتکلی است که برای Devtools کروم و تعداد شگفت‌انگیزی از ابزارهای دیگر استفاده می‌شود. با استفاده از آن، یک افزونه می‌تواند کد از راه دور را درخواست و اجرا کند. درست مانند اسکریپت‌های کاربر، جایگزینی برای chrome.scripting نیست و تجربه کاربری بسیار قابل توجه‌تری دارد. در حین استفاده، کاربر یک نوار هشدار در بالای پنجره مشاهده می‌کند. اگر بنر بسته یا رد شود، جلسه اشکال‌زدایی خاتمه می‌یابد.

تصویری از نوار آدرس در کروم که پیام «افزونه اشکال‌زدا شروع به اشکال‌زدایی این مرورگر کرد» را نشان می‌دهد
تصویری از نوار آدرس در کروم که پیام «افزونه اشکال‌زدا شروع به اشکال‌زدایی این مرورگر کرد» را نشان می‌دهد

آیفریم‌های سندباکس شده

اگر نیاز دارید که یک رشته را به عنوان کد ارزیابی کنید و در یک محیط DOM هستید (مثلاً یک اسکریپت محتوا، برخلاف یک سرویس‌دهنده افزونه)، گزینه دیگر استفاده از یک iframe سندباکس شده است. افزونه‌ها به طور پیش‌فرض از مواردی مانند eval() به عنوان یک اقدام احتیاطی ایمنی پشتیبانی نمی‌کنند. کد مخرب می‌تواند ایمنی و امنیت کاربر را در معرض خطر قرار دهد. اما وقتی کد فقط در یک محیط امن شناخته شده، مانند یک iframe که از بقیه وب سندباکس شده است، اجرا شود، این خطرات تا حد زیادی کاهش می‌یابد. در این زمینه، می‌توان سیاست امنیتی محتوا را که استفاده از eval را مسدود می‌کند، لغو کرد و به شما امکان داد هر کد جاوا اسکریپت معتبری را اجرا کنید.

اگر موردی دارید که پوشش داده نشده است، می‌توانید با استفاده از فهرست پستی افزونه‌های کروم با تیم تماس بگیرید تا بازخورد دریافت کنید، یا یک تیکت جدید باز کنید و از پشتیبانی یکپارچه درخواست راهنمایی کنید.

اگر با حکمی مخالف هستید چه باید بکنید

اجرای سیاست‌ها می‌تواند ظریف باشد و بررسی شامل ورودی دستی باشد، به این معنی که تیم فروشگاه وب Chrome ممکن است گاهی اوقات با تغییر تصمیم بررسی موافقت کند. اگر معتقدید که در بررسی اشتباهی رخ داده است، می‌توانید با استفاده از One Stop Support به رد درخواست تجدیدنظر دهید.