טיפול בהפרות של קוד באירוח מרוחק

קוד באירוח מרוחק, או RHC, הוא השם שנקרא בחנות האינטרנט של Chrome לכל מה שהדפדפן מפעיל ונטען ממקום אחר שאינו הקבצים של התוסף עצמו. דברים כמו JavaScript ו-WASM. הוא לא כולל נתונים או דברים כמו JSON או CSS.

למה כבר אין הרשאה ל-RHC?

באמצעות תוספי Manifest V3 צריך לקבץ את כל הקודים שבהם הם משתמשים בתוך התוסף עצמו. בעבר, ניתן היה להחדיר תגי סקריפטים באופן דינמי מכל כתובת URL באינטרנט.

נאמר לי שלתוסף שלי יש RHC. מה הבעיה?

אם התוסף נדחה במהלך בדיקה עקב שגיאת ארגון כחול, הבודקים שלנו חושבים שהתוסף משתמש בקוד באירוח מרוחק. לרוב הסיבה לכך היא שתוסף מנסה להוסיף תג סקריפט באמצעות משאב מרוחק (כלומר מהאינטרנט הפתוח, ולא מהקבצים הכלולים בתוסף), או מאחזר משאב להפעלה ישירה.

איך מזהים RHC

איתור RHC לא קשה במיוחד ברגע שיודעים מה לחפש. קודם כל, מחפשים את המחרוזות 'http://' או 'https://' בפרויקט. אם נתקלתם בהפרה של ה-RHC, סביר להניח שתוכלו לאתר אותה אם תגלו אותה. אם יש לכם מערכת build מלאה או שאתם משתמשים בתלות מ-npm או ממקורות אחרים של צד שלישי, חשוב לוודא שאתם מחפשים את הגרסה הקומפלת של הקוד, כי זו הכתובת שנבדקת על ידי החנות. אם אתם עדיין לא מוצאים את הבעיה, השלב הבא הוא לפנות לתמיכה One Stop. הצוות יוכל לפרט את ההפרות הספציפיות ואת מה שנדרש כדי לפרסם את התוסף בהקדם האפשרי.

מה לעשות אם ספרייה מבקשת את הקוד

לא ניתן להשתמש ב-RHC, ללא קשר למקור הקוד. כולל קוד שלא אתם כתבתם, אבל אפשר להשתמש כתלות בפרויקט. חלק מהמפתחים שהשתמשו ב-Firebase נתקלו בבעיה הזו כשנוסף קוד מרחוק לשימוש ב-Firebase Auth. למרות שזו הייתה ספריית צד ראשון (כלומר בבעלות Google), לא ניתן חריג ל-RHC. צריך להגדיר את הקוד כך שיסיר את ה-RHC או לעדכן את האובייקט כך שלא יכלול את הקוד מלכתחילה. אם נתקלתם בבעיה שבה לא בקוד שלכם נטען RHC, אלא ספרייה שבה אתם משתמשים, הפעולה הטובה ביותר היא לפנות למחבר הספרייה. עדכנו אותם לגבי הבעיה ותבקשו עזרה בפתרון עקיף או עדכוני קוד כדי להסיר את הבעיה.

מה קורה אם אתם לא יכולים לחכות לעדכון הספרייה

ספריות מסוימות שולחות עדכון כמעט מיד לאחר קבלת ההודעה, אבל ייתכן שספריות אחרות יינטשו או שייקח זמן לטפל בבעיה. בהתאם למה שקורה בהפרה הספציפית, יכול להיות שלא תצטרכו לחכות עד שהחסימה שלהן תבוטל והם יעברו בדיקה מוצלחת. יש מספר אפשרויות זמינות לחזור ולהפעיל במהירות.

בדיקת הקוד

האם בטוח שצריך את הקוד שגורם לבקשה? אם אפשר פשוט למחוק אותו או להסיר ספרייה שגורמת לו, מחקו את הקוד והפעולה בוצעה.

לחלופין, האם יש ספרייה אחרת שמציעה את אותן תכונות? נסו לבדוק ב-npmjs.com, ב-GitHub או באתרים אחרים אפשרויות אחרות שמתאימות לאותם תרחישים לדוגמה.

עץ רועד

אם לא נעשה שימוש בפועל בקוד שגורם להפרה של ה-RHC, ייתכן שהוא יימחק באופן אוטומטי באמצעות כלים. לכלי פיתוח מודרניים כמו Webpack , Rollup ו-Vite (רק כמה דוגמאות) יש תכונה בשם רעידת עצים. אחרי שמפעילים את התכונה במערכת ה-build, רעידת העצים אמורה להסיר את נתיבי הקוד שלא נמצאים בשימוש. כלומר, לא רק שיש לכם גרסה תואמת יותר של הקוד, אלא גם גרסה קלה ומהירה יותר! חשוב לציין שלא בכל הספריות אפשר לנער את העצים, אבל רבות מהן כן. לכלים מסוימים, כמו Rollup ו-Vite, רעידת העצים מופעלת כברירת מחדל. כדי שהיא תפעל, צריך להגדיר אותה. אם אתם לא משתמשים במערכת build כחלק מהתוסף, אלא משתמשים בספריות קודים, מומלץ מאוד לבדוק איך מוסיפים כלי build לזרימת העבודה שלכם. פיתוח כלים עוזרים לכתוב פרויקטים בטוחים, אמינים יותר ונוחים יותר לתחזוקה.

אופן היישום של רעידת עצים תלוי בפרויקט הספציפי שלכם. לדוגמה, כדי לראות דוגמה פשוטה עם רשימה, תוכלו להוסיף רעידת עץ פשוט על ידי הידור קוד הפרויקט. לדוגמה, אם יש לך קובץ שמתחבר ל-Firebase Auth בלבד, שנקרא primary.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/plugin-node-resolve, ולציין את שם קובץ הפלט שהוא יוצר.

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

אם תריצו את הפקודה הזו בחלון טרמינל, תתקבל גרסה שנוצרה של הקובץ main.js, שבה כל הגרסאות מקובצות לקובץ אחד בשם compiled.js.

איסוף יכול להיות פשוט, אבל מאוד אפשר להגדיר אותו. אפשר להוסיף כל מיני סוגים של לוגיקה והגדרות מורכבות, פשוט עיינו במסמכי התיעוד שלהם. הוספה של כלי build כאלה תוביל ליצירת קוד קטן ויעיל יותר, ובמקרה הזה הבעיה תפתור את הבעיה בקוד באירוח מרוחק.

עריכה אוטומטית של קבצים

דרך נפוצה יותר ויותר שבאמצעותה קוד באירוח מרוחק יכול להיכנס ל-codebase שלכם היא תת-תחום של הספרייה שאתם כוללים. אם הספרייה X רוצה import לספרייה את Y מ-CDN, עדיין צריך לעדכן אותה על מנת שנטען ממקור מקומי. במערכות build מודרניות, אפשר ליצור יישומי פלאגין כדי לחלץ קובץ עזר מרוחק ולהטביע אותו ישירות בקוד.

כלומר, הקוד הנתון נראה כך:

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
    }
  }]
};

אחרי שמריצים את ה-build עם הפלאגין החדש, מתגלה כל כתובת URL מרוחקת של import – לא משנה אם זה הקוד שלנו, תת-תלות, תת-תלות או כל מקום אחר.

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

עריכת קבצים באופן ידני

האפשרות הפשוטה ביותר היא פשוט למחוק את הקוד שגורם ל-RHC. פותחים את הקובץ בעורך הטקסט הרצוי ומוחקים את השורות שמפרות את המדיניות. בדרך כלל זה לא מומלץ, כי הוא שבור ואפשר לשכוח אותו. היא מקשה על תחזוקת הפרויקט כשקובץ בשם "library.min.js" אינו למעשה library.min.js. במקום לערוך את הקבצים הגולמיים, אפשרות שקצת תחזוקה היא להשתמש בכלי כמו patch-package. זו אפשרות עוצמתית מאוד שמאפשרת לשמור את השינויים בקובץ במקום בקובץ עצמו. הוא מבוסס על קובצי תיקון, שהם אותם דברים שמאפשרים מערכות לניהול גרסאות כמו Git או Subversion. פשוט צריך לשנות באופן ידני את הקוד שמפר את המדיניות, לשמור את קובץ ה-diff ולהגדיר חבילת תיקונים עם השינויים שרוצים להחיל. תוכלו לקרוא מדריך מלא בקובץ ה-readme של הפרויקט. אם אתם מתקנים פרויקט, אנחנו ממליצים באמת לפנות לצוות הפרויקט כדי לבקש שהשינויים ייכנסו לתוקף. חבילת התיקון מקלה על ניהול התיקונים, אבל עדיף שלא לתקן כלום.

מה לעשות אם לא משתמשים בקוד

ככל שבסיסי הקוד גדלים, יחסי התלות (או התלות ב...) עלולים לשמר את נתיבי הקוד שלא נמצאים יותר בשימוש. אם אחד מהקטעים האלה כולל קוד לטעינה או להפעלה של RHC, יהיה צורך להסיר אותו. לא משנה אם הוא מת או אינו בשימוש. אם הוא לא בשימוש, צריך להסיר אותו על ידי רעידת עץ או לתקן את הספרייה כדי להסיר אותה.

האם יש פתרון עקיף?

באופן כללי, לא. RHC אינו מותר. עם זאת, יש מספר קטן של מקרים שבהם היא מותרת. כמעט תמיד מדובר במקרים שבהם לא ניתן להשתמש בשום אפשרות אחרת.

ממשק API של סקריפטים של משתמשים

סקריפטים של משתמש הם קטעי קוד קטנים שבדרך כלל מסופקים על ידי המשתמש ומיועדים למנהלי סקריפטים של משתמשים כמו TamperMonkey ו-Spammonkey. המנהלים האלה לא יכולים לאגד קוד שנכתב על ידי משתמשים, ולכן ה-User Script API חושף את הדרך להפעיל קוד שסופק על ידי המשתמש. הוא לא תחליף ל-chrome.scripting.executeScript או לסביבות אחרות של הפעלת קוד. המשתמשים חייבים להפעיל מצב פיתוח כדי לבצע כל פעולה. אם צוות הבדיקה של חנות האינטרנט של Chrome סבור שנעשה שימוש באפליקציה באופן שונה מזה שמיועד לה (כלומר, קוד שהמשתמש סיפק), ייתכן שהיא תידחה או שהכרטיס יוסר מהחנות.

chrome.debugger

ה-API של chrome.debugger מאפשר לתוספים לקיים אינטראקציה עם פרוטוקול Chrome Devtools. זה אותו פרוטוקול שבו משתמשים ב-Devtools של Chrome, ועוד מספר מדהים של כלים אחרים. באמצעותו, תוסף יכול לבקש ולהפעיל קוד מרחוק. בדיוק כמו בסקריפטים של משתמשים, התכונה הזו לא תחליף ל-chrome.scripting, והיא מספקת חוויית משתמש הרבה יותר בולטת. בזמן השימוש, המשתמש יראה סרגל אזהרה בחלק העליון של החלון. אם הבאנר נסגר או נסגר, סשן ניפוי הבאגים יסתיים.

צילום מסך של סרגל הכתובות ב-Chrome שבו מופיעה ההודעה 'התוסף לניפוי באגים התחיל לנפות באגים בדפדפן זה'
צילום מסך של סרגל הכתובות ב-Chrome שבו מופיעה ההודעה 'התוסף לניפוי באגים התחיל לנפות באגים בדפדפן הזה'

iframes בארגז חול

אם אתם צריכים להעריך מחרוזת כקוד ואתם נמצאים בסביבת DOM (למשל סקריפט תוכן ולא ב-Service Worker של תוסף), אפשרות נוספת היא להשתמש ב-iframe שבארגז חול (sandbox). כברירת מחדל, תוספים לא תומכים בדברים כמו eval() כאמצעי זהירות. קוד זדוני עלול לסכן את הבטיחות והאבטחה של המשתמשים. אבל כשהקוד מופעל רק בסביבה בטוחה ידועה, כמו iframe שעבר הרצה בארגז חול (sandboxing) משאר האינטרנט, הסיכונים האלה מצטמצמים מאוד. בהקשר הזה, אפשר להסיר את מדיניות אבטחת התוכן שחוסמת את השימוש בהערכה, וכך להריץ כל קוד JavaScript תקין.

אם יש לכם תרחיש לדוגמה שלא מופיע במלואו, תוכלו לפנות לצוות באמצעות רשימת התפוצה chromium-extensions כדי לקבל משוב, או לפתוח פנייה חדשה כדי לבקש הנחיות מהתמיכה של One Stop

מה לעשות אם לא מסכימים עם פסיקה

אכיפת המדיניות יכולה להיות מצומצמת והבדיקה כרוכה בקלט ידני, כך שמדי פעם הצוות של חנות האינטרנט של Chrome עשוי להסכים לשנות החלטה לגבי בדיקה. אם לדעתכם מדובר בטעות בבדיקה, תוכלו לערער על הדחייה באמצעות One Stop Support