處理遠端代管程式碼違規問題

遠端代管程式碼 (或稱 RHC) 是指 Chrome 線上應用程式商店呼叫瀏覽器執行的任何項目,如果不是擴充功能本身的檔案,瀏覽器會呼叫這些內容。像是 JavaScript 和 WASM 等等。而「不」包含 JSON 或 CSS 等資料或內容。

為什麼不再允許 RHC?

使用 Manifest V3 擴充功能現在,需要封裝擴充功能本身中使用的所有程式碼。過去,您可以從網路上的任何網址動態插入指令碼標記。

我被告知擴充功能支援 RHC。為什麼會發生這種情況?

如果擴充功能在審查期間遭拒,且出現 Blue Argon 錯誤,審查人員就會認為擴充功能使用的是遠端代管的程式碼。這通常是擴充功能嘗試透過遠端資源 (例如從開放網路新增指令碼,而非擴充功能中包含的檔案) 來新增指令碼標記的結果,或是「擷取」直接執行的資源。

如何辨識 RHC

只要知道要尋找什麼問題,發現 RHC 就不是特別困難。首先,請檢查專案中是否含有「http://」或「https://」字串。如果有 RHC 違規問題,應該就能找到這些違規事項。如果您有完整的建構系統,或者使用 npm 或其他第三方來源的依附元件,請務必搜尋程式碼的編譯版本,因為這是商店評估的內容。如果仍然找不到問題,下一步就是聯絡 One Stop 支援團隊。他們可以概略說明具體違規事項,以及盡快發布擴充功能的必要事項。

如果程式庫要求程式碼,該怎麼做

無論程式碼的來源為何,皆不得包含 RHC。其中包含非您編寫的程式碼,只是將程式碼當做專案中的依附元件使用。使用 Firebase部分開發人員會在 Firebase 驗證中加入遠端程式碼時,發生這個問題。雖然這是第一方 (即 Google 擁有) 的程式庫,但無法處理 RHC。您必須設定程式碼,以移除 RHC 或更新片段,避免包含該程式碼的開頭。如果所遇到的問題並非「您的」程式碼會載入 RHC,而是您使用的程式庫,最好的解決方式是聯絡程式庫的作者。請告知對方這個情形正在發生,並要求提供解決方法或程式碼更新以將其移除。

如果您迫不及待程式庫更新,該怎麼辦?

部分程式庫會在收到通知後幾乎立即發布更新,但其他程式庫可能會遭到捨棄,或是需要一些時間來解決問題。視特定違規事項的情況而定,您可能不需要等待網頁解除封鎖並完成審查。系統提供多種快速備份和執行作業的選項。

稽核程式碼

您是否確定了造成要求的程式碼?如果可以刪除專案,或刪除造成其影響的程式庫,請刪除該程式碼,工作即可完成工作。

或者,有其他程式庫提供相同的功能嗎?請嘗試查看 npmjs.com、GitHub 或其他網站,瞭解執行相同用途的其他選項。

搖樹

如果造成 RHC 違規事項的程式碼實際上並未使用,則工具可能自動刪除該程式碼。WebpackRollupVite (僅列舉幾項) 等現代建構工具,都有名為「搖晃」的功能。在建構系統上啟用樹狀結構後,搖動樹狀結構應移除所有未使用的程式碼路徑。這可能表示您不僅擁有更合規的程式碼版本,也會建構更精簡、速度更快的程式碼!請特別注意,並非所有程式庫都能搖動樹狀結構,但有許多程式庫。部分工具 (例如 Rollup 和 Vite) 預設為啟用樹狀圖。您必須設定 webpack 才能加以啟用。如果您未將建構系統當做擴充功能使用,但「確實」使用程式碼程式庫,則強烈建議您調查在工作流程中新增建構工具的問題。建構工具可協助您編寫更安全、更可靠且易於維護的專案。

實作樹林的具體方法取決於您的特定專案。不過,如要使用 Rollup 來執行簡單的範例,只要編譯專案程式碼,就能加入樹景。舉例來說,如果您的檔案只會記錄到名為 main.js 的 Firebase 驗證:

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 的單一檔案。

匯總作業可以很簡單,但也「非常」可設定。您可以新增各種類型的複雜邏輯和設定,只需參閱其說明文件即可。像這樣新增建構工具會產生更小、更有效率的程式碼,並能修正遠端託管的程式碼問題。

自動編輯檔案

遠端代管程式碼進入程式碼集的常見方式,已經成為內含程式庫的附屬方法。如果 X 程式庫想從 CDN 取得 import 程式庫 Y,您還是需要進行更新,才能從本機來源載入程式庫。使用新型建構系統時,您可以快速建立外掛程式來擷取遠端參照,並直接內嵌至程式碼中。

這表示指定的程式碼如下所示:

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

使用新外掛程式執行建構作業後,無論其是程式碼、子依附元件、子依附元件還是其他位置,系統都會探索每個遠端 import 網址。

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

手動編輯檔案

最簡單的方法是刪除造成 RHC 的程式碼。請在所選文字編輯器中開啟,然後刪除違規的行。這種做法通常不應該建議,因為其中很脆弱,可能會被遺忘。當名為「library.min.js」的檔案不是「實際」library.min.js 時,這個程式庫會增加您維護專案的難度。與其編輯原始檔案,更易於維護的選項是使用 patch-package 等工具。這是一種非常強大的選項,可讓您將「修改內容」儲存至檔案,而非檔案本身。它以「修補檔案」為基礎建構而成,就像支援 GitSubversion 等版本管控系統的方法一樣。您只需手動修改違規的程式碼、儲存差異檔案,並根據要套用的變更設定修補程式套件,如需專案 README 的完整教學課程,請參閱。如果您要修補專案,強烈建議您與專案聯絡,要求進行上游變更。雖然修補套件讓修補程式管理起來更加輕鬆,但沒有修補的也更棒。

未用到代碼時的處理方式

隨著程式碼集不斷增加,依附元件 (或依附元件的依附元件或依附元件...) 可能會保留不再使用的程式碼路徑。如果其中一個區段包含要載入或執行 RHC 的程式碼,則應用程式「必須」將其移除。無論是否已死亡或未使用都沒有關係。如果沒用到這個程式碼,請將其移除,例如樹幹,或修補程式庫以將其移除。

任何解決方法嗎?

一般而言,不允許使用 RHC。不過,只有少數情況「允許」。在大多數情況下,其他選項都不可能。

User Scripts API

使用者指令碼是小型的程式碼片段,通常會由使用者提供,適用於使用者指令碼管理工具,例如 TamperMonkeyViolentmonkey。這些管理工具無法封裝使用者編寫的程式碼,因此 User Script API 可公開執行使用者提供的程式碼。這個做法無法取代 chrome.scripting.executeScript,或其他程式碼執行環境。使用者必須啟用開發人員模式才能執行任何內容。如果 Chrome 線上應用程式商店審查團隊認為使用方式並非預期用途 (例如使用者提供的程式碼),則可能會遭到拒絕或從商店下架。

chrome.debugger

chrome.debugger API 可讓擴充功能與 Chrome 開發人員工具通訊協定互動。這與 Chrome 開發人員工具使用的通訊協定相同,同時也是許多其他工具。透過它,擴充功能可以要求並執行遠端程式碼。就像使用者指令碼一樣,這項工具無法取代 chrome.scripting,且具有更加顯著的使用者體驗。在使用期間,使用者會在視窗頂端看到警告列。如果橫幅關閉或關閉,偵錯工作階段就會終止。

Chrome 網址列的螢幕截圖,顯示「Debugger Extension start debugging」訊息
Chrome 網址列螢幕截圖顯示「Debugger Extension start this browser'」訊息

沙箱 iframe

如果您需要將字串評估為程式碼,而且位於 DOM 環境中 (例如內容指令碼,而非擴充功能服務工作站),另一個選項是使用沙箱 iframe。為了安全起見,擴充功能不支援 eval() 這類功能。惡意程式碼可能會危害使用者的安全不過,如果程式碼只在已知的安全環境中執行 (例如 iframe 已從網路的其他部分採用沙箱機制),這些風險可大幅降低。在這種情況下,您可以解除禁止使用 eV 的內容安全政策,讓您可以執行任何有效的 JavaScript 程式碼。

如果其中未涵蓋您需要的用途,可以透過 chromium-extensions 郵寄清單與團隊聯絡來取得意見回饋。您也可以建立新支援單,向 One Stop 支援團隊尋求協助

不同意判定結果時的處理方式

強制執行政策時,可能會有條不紊,而且需要手動輸入。也就是說,Chrome 線上應用程式商店團隊有時可能會同意變更審查決定。如果您認為審查結果有誤,可以使用 One Stop 支援針對拒絕處置提出申訴。