Mit Remote-Host-Code Verstöße beheben

Als „Remote Hosted Code“ (RHC) bezeichnet der Chrome Web Store alles, was vom Browser ausgeführt wird und von einem anderen Ort als den eigenen Dateien der Erweiterung geladen wird. Dazu gehören JavaScript und WASM. Sie enthält nicht Daten oder Dinge wie JSON oder CSS.

Warum ist RHC nicht mehr zulässig?

Bei Erweiterungen mit Manifest V3 muss sämtlicher verwendeter Code in der Erweiterung selbst enthalten sein. Bisher konnten Sie Script-Tags dynamisch von jeder URL im Web einfügen.

Mir wurde mitgeteilt, dass meine Erweiterung RHC hat. Was ist da los?

Wenn Ihre Erweiterung bei der Überprüfung mit dem Fehler Blue Argon abgelehnt wurde, gehen unsere Prüfer davon aus, dass Ihre Erweiterung remote gehosteten Code verwendet. Das ist in der Regel die Folge davon, dass eine Erweiterung versucht, ein Script-Tag mit einer Remote-Ressource hinzuzufügen (d.h. aus dem offenen Web und nicht aus den in der Erweiterung enthaltenen Dateien) oder eine Ressource abzurufen, um sie direkt auszuführen.

So erkennen Sie RHC

RHC zu erkennen ist nicht besonders schwierig, wenn Sie wissen, worauf Sie achten müssen. Suchen Sie zuerst in Ihrem Projekt nach den Strings „http://“ oder „https://“. Wenn Sie einen Verstoß gegen die Richtlinien für die Darstellung von Inhalten in Google-Produkten haben, können Sie ihn wahrscheinlich auf diese Weise finden. Wenn Sie ein vollständiges Build-System haben oder Abhängigkeiten von npm oder anderen Drittanbieterquellen verwenden, suchen Sie im kompilierten Code, da dieser vom Store ausgewertet wird. Wenn Sie das Problem immer noch nicht finden können, wenden Sie sich an den One-Stop-Support. Sie können die spezifischen Verstöße erläutern und erklären, was erforderlich ist, damit die Erweiterung so schnell wie möglich veröffentlicht werden kann.

Was tun, wenn eine Bibliothek den Code anfordert?

Unabhängig davon, woher der Code stammt, ist es nicht zulässig, RHC zu verwenden. Das gilt auch für Code, den Sie nicht selbst geschrieben haben, sondern nur als Abhängigkeit in Ihrem Projekt verwenden. Einige Entwickler, die Firebase verwenden, hatten dieses Problem, wenn Remote-Code für die Verwendung in Firebase Authentication eingebunden wurde. Obwohl es sich um eine Bibliothek von Google handelte, gibt es keine Ausnahme für RHC. Sie müssen den Code so konfigurieren, dass der RHC entfernt wird, oder Ihr Projekt so aktualisieren, dass der Code von vornherein nicht enthalten ist. Wenn das Problem auftritt, dass nicht Ihr Code, sondern eine von Ihnen verwendete Bibliothek RHC lädt, sollten Sie sich am besten an den Autor der Bibliothek wenden. Informieren Sie den Entwickler darüber und bitten Sie ihn entweder um eine Problemumgehung oder um Code-Updates, um das Problem zu beheben.

Was kann ich tun, wenn ich nicht auf ein Bibliotheksupdate warten kann?

Einige Bibliotheken werden fast sofort nach der Benachrichtigung aktualisiert, bei anderen kann es dauern, bis das Problem behoben wird, oder sie werden gar nicht mehr aktualisiert. Je nach Art des Verstoßes müssen Sie möglicherweise nicht warten, bis die Sperrung aufgehoben und die Überprüfung erfolgreich abgeschlossen wurde. Es gibt verschiedene Möglichkeiten, um schnell wieder loslegen zu können.

Code prüfen

Sind Sie sicher, dass der Code, der die Anfrage verursacht, benötigt wird? Wenn der Code einfach gelöscht oder eine Bibliothek, die das Problem verursacht, entfernt werden kann, löschen Sie den Code.

Gibt es eine andere Bibliothek, die dieselben Funktionen bietet? Auf npmjs.com, GitHub oder anderen Websites finden Sie möglicherweise andere Optionen, die dieselben Anwendungsfälle abdecken.

Bäume schütteln

Wenn der Code, der den RHC-Verstoß verursacht, nicht tatsächlich verwendet wird, kann er möglicherweise automatisch durch Tools gelöscht werden. Moderne Build-Tools wie webpack, Rollup und Vite (um nur einige zu nennen) haben eine Funktion namens Tree Shaking. Wenn Tree Shaking in Ihrem Build-System aktiviert ist, sollten alle nicht verwendeten Codepfade entfernt werden. Das kann bedeuten, dass Sie nicht nur eine konformere Version Ihres Codes erhalten, sondern auch eine schlankere und schnellere. Es ist wichtig zu beachten, dass nicht alle Bibliotheken durch Tree Shaking optimiert werden können, aber viele schon. Bei einigen Tools wie Rollup und Vite ist Tree Shaking standardmäßig aktiviert. Bei webpack muss es konfiguriert werden, damit es aktiviert wird. Wenn Sie kein Build-System als Teil Ihrer Erweiterung verwenden, aber Codebibliotheken, sollten Sie unbedingt ein Build-Tool in Ihren Workflow einbinden. Build-Tools helfen Ihnen, sicherere, zuverlässigere und wartungsfreundlichere Projekte zu schreiben.

Die genauen Details zur Implementierung von Treeshaking hängen von Ihrem jeweiligen Projekt ab. Ein einfaches Beispiel mit Rollup: Sie können Treeshaking hinzufügen, indem Sie einfach Ihren Projektcode kompilieren. Wenn Sie beispielsweise eine Datei haben, die sich nur bei Firebase Authentication anmeldet, z. B. „main.js“:

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

browser.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);
  }
});

Sie müssen Rollup dann nur noch die Eingabedatei, ein Plug-in zum Laden von Node-Dateien @rollup/plugin-node-resolve und den Namen der Ausgabedatei mitteilen, die generiert wird.

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

Wenn Sie diesen Befehl in einem Terminalfenster ausführen, erhalten Sie eine generierte Version unserer main.js-Datei, die in einer einzigen Datei mit dem Namen compiled.js kompiliert wird.

Rollup kann einfach sein, ist aber auch sehr konfigurierbar. Sie können alle Arten von komplexer Logik und Konfiguration hinzufügen. Weitere Informationen finden Sie in der Dokumentation. Durch das Hinzufügen solcher Build-Tools wird der Code kleiner und effizienter. In diesem Fall wird dadurch auch das Problem mit dem remote gehosteten Code behoben.

Dateien automatisch bearbeiten

Eine immer häufiger auftretende Möglichkeit, wie remote gehosteter Code in Ihre Codebasis gelangen kann, ist als untergeordnete Abhängigkeit einer Bibliothek, die Sie einbinden. Wenn die Bibliothek X die Bibliothek import Y über ein CDN laden möchte, müssen Sie sie trotzdem aktualisieren, damit sie von einer lokalen Quelle geladen wird. Mit modernen Build-Systemen können Sie ganz einfach Plug-ins erstellen, um eine Remote-Referenz zu extrahieren und direkt in Ihren Code einzufügen.

Bei folgendem Code:

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

Sie könnten ein kleines Rollup-Plug-in erstellen.

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

Wenn Sie den Build mit dem neuen Plug-in ausführen, wird jede Remote-import-URL erkannt, unabhängig davon, ob sie in unserem Code, einer untergeordneten Abhängigkeit, einer untergeordneten untergeordneten Abhängigkeit oder an einer anderen Stelle enthalten ist.

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

Dateien manuell bearbeiten

Am einfachsten ist es, den Code zu löschen, der den RHC verursacht. Öffnen Sie die Datei in einem Texteditor Ihrer Wahl und löschen Sie die Zeilen, die gegen die Richtlinien verstoßen. Das ist im Allgemeinen nicht empfehlenswert, da es fehleranfällig ist und vergessen werden kann. Wenn eine Datei mit dem Namen „library.min.js“ nicht „library.min.js“ ist, wird die Wartung Ihres Projekts erschwert. Anstatt die Rohdateien zu bearbeiten, ist es etwas wartungsfreundlicher, ein Tool wie patch-package zu verwenden. Mit dieser leistungsstarken Option können Sie Änderungen an einer Datei speichern, anstatt die Datei selbst. Es basiert auf Patchdateien, die auch in Versionskontrollsystemen wie Git oder Subversion verwendet werden. Sie müssen den Code, der gegen die Richtlinien verstößt, nur manuell ändern, die Diff-Datei speichern und patch-package mit den gewünschten Änderungen konfigurieren. Eine vollständige Anleitung finden Sie in der Readme-Datei des Projekts. Wenn Sie ein Projekt patchen, empfehlen wir Ihnen dringend, sich an das Projekt zu wenden und darum zu bitten, dass Änderungen upstream vorgenommen werden. Mit patch-package lassen sich Patches viel einfacher verwalten, aber noch besser ist es, wenn gar nichts gepatcht werden muss.

Was tun, wenn der Code nicht verwendet wird?

Wenn Codebases wachsen, können Abhängigkeiten (oder Abhängigkeiten von Abhängigkeiten usw.) dazu führen, dass Codepfade, die nicht mehr verwendet werden, erhalten bleiben. Wenn einer dieser Abschnitte Code zum Laden oder Ausführen von RHC enthält, muss er entfernt werden. Es spielt keine Rolle, ob es defekt oder ungenutzt ist. Wenn sie nicht verwendet wird, sollte sie entfernt werden, entweder durch Tree Shaking oder durch Patchen der Bibliothek.

Gibt es irgendeine Problemumgehung?

Im Allgemeinen nicht. RHC ist nicht zulässig. Es gibt jedoch eine kleine Anzahl von Fällen, in denen dies erlaubt ist. Das ist fast immer der Fall, wenn keine andere Option möglich ist.

User Scripts API

Nutzer-Scripts sind kleine Code-Snippets, die in der Regel vom Nutzer bereitgestellt werden und für Nutzer-Script-Manager wie TamperMonkey und Violentmonkey vorgesehen sind. Es ist für diese Manager nicht möglich, von Nutzern geschriebenen Code zu bündeln. Daher bietet die User Script API eine Möglichkeit, von Nutzern bereitgestellten Code auszuführen. Dies ist kein Ersatz für browser.scripting.executeScript oder andere Code-Ausführungsumgebungen. Nutzer müssen den Entwicklermodus aktivieren, um etwas auszuführen. Wenn das Chrome Web Store-Prüfteam der Ansicht ist, dass die Funktion anders verwendet wird als vorgesehen (z.B. für vom Nutzer bereitgestellten Code), kann die Erweiterung abgelehnt oder ihr Eintrag aus dem Store entfernt werden.

browser.debugger

Mit der browser.debugger API können Erweiterungen mit dem Chrome Devtools Protocol interagieren. Es ist dasselbe Protokoll, das für die DevTools von Chrome und eine Vielzahl anderer Tools verwendet wird. Damit kann eine Erweiterung Remote-Code anfordern und ausführen. Genau wie Nutzerskripts ist es kein Ersatz für browser.scripting und hat eine viel auffälligere Benutzeroberfläche. Während der Nutzung wird dem Nutzer oben im Fenster eine Warnleiste angezeigt. Wenn das Banner geschlossen oder verworfen wird, wird die Debugging-Sitzung beendet.

Screenshot der Adressleiste in Chrome mit der Meldung „Debugger-Erweiterung hat mit dem Debugging dieses Browsers begonnen“
Screenshot der Adressleiste in Chrome mit der Meldung „Debugger-Erweiterung hat mit dem Debugging dieses Browsers begonnen“

Sandbox-iFrames

Wenn Sie einen String als Code auswerten müssen und sich in einer DOM-Umgebung befinden (z.B. in einem Content-Script im Gegensatz zu einem Erweiterungs-Service-Worker), können Sie auch einen Sandboxed-iFrame verwenden. Erweiterungen unterstützen standardmäßig keine Elemente wie eval(), um die Sicherheit zu gewährleisten. Böswilliger Code kann die Sicherheit von Nutzern gefährden. Wenn der Code jedoch nur in einer bekannten sicheren Umgebung ausgeführt wird, z. B. in einem iFrame, das vom Rest des Webs isoliert wurde, werden diese Risiken erheblich reduziert. In diesem Kontext kann die Content Security Policy, die die Verwendung von „eval“ blockiert, aufgehoben werden, sodass Sie beliebigen gültigen JavaScript-Code ausführen können.

Wenn Sie einen Anwendungsfall haben, der nicht abgedeckt ist, können Sie sich über die Mailingliste chromium-extensions an das Team wenden, um Feedback zu erhalten, oder ein neues Ticket eröffnen, um One Stop Support um Unterstützung zu bitten.

Was Sie tun können, wenn Sie mit einem Urteil nicht einverstanden sind

Die Durchsetzung von Richtlinien kann nuanciert sein und die Überprüfung erfordert manuelle Eingaben. Das Chrome Web Store-Team kann daher manchmal zustimmen, eine Überprüfungsentscheidung zu ändern. Wenn Sie der Meinung sind, dass bei der Überprüfung ein Fehler gemacht wurde, können Sie über One Stop Support Einspruch gegen die Ablehnung einlegen.