Mit Remote-Host-Code Verstöße beheben

Als „Remote Hosted Code“ (RHC) wird im Chrome Web Store alles bezeichnet, 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 gebündelt werden. Bisher konnten Sie Script-Tags dynamisch von einer beliebigen URL im Web einfügen.

Mir wurde gesagt, 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

Es ist nicht besonders schwierig, RHC zu erkennen, 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 Nutzung von KI-Modellen 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 unbedingt in der kompilierten Version des Codes, da diese vom Store ausgewertet wird. Wenn Sie das Problem immer noch nicht finden können, wenden Sie sich an den One-Stop-Support. Dort kann man Ihnen die konkreten Verstöße nennen und Ihnen sagen, was Sie tun müssen, damit die Erweiterung so schnell wie möglich veröffentlicht wird.

Was tun, wenn eine Bibliothek den Code anfordert?

Unabhängig davon, woher der Code stammt, ist RHC nicht zulässig. Dazu gehört auch 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 Auth enthalten war. Obwohl es sich um eine Bibliothek von Google handelte, wird für RHC keine Ausnahme gemacht. Sie müssen den Code so konfigurieren, dass entweder der RHC entfernt wird oder Ihr Projekt so aktualisiert wird, dass der Code von vornherein nicht enthalten ist. Wenn das Problem auftritt, weil nicht Ihr Code, sondern eine von Ihnen verwendete Bibliothek RHC lädt, sollten Sie sich am besten an den Autor der Bibliothek wenden. Informiere sie darüber und bitte sie um eine Problemumgehung oder Code-Updates, um das Problem zu beheben.

Was passiert, wenn Sie nicht auf ein Bibliotheksupdate warten können?

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 unterstützt. Je nachdem, was bei dem jeweiligen Verstoß passiert ist, müssen Sie möglicherweise nicht warten, bis die Inhalte entsperrt und eine erfolgreiche Überprüfung abgeschlossen ist. 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 erfüllen.

Tree-Shaking

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 per Tree Shaking optimiert werden können, aber viele. 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 nutzen, sollten Sie unbedingt ein Build-Tool in Ihren Workflow einbinden. Build-Tools helfen Ihnen, sicherere, zuverlässigere und wartungsfreundlichere Projekte zu schreiben.

Wie genau das funktioniert, hängt 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 namens „main.js“ haben, in der nur die Anmeldung bei Firebase Auth protokolliert wird:

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

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

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 Datei main.js, 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. Sehen Sie sich dazu einfach die Dokumentation an. 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 Bibliothek X die Bibliothek import Y von einem 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 einem Code, der so aussieht:

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

Sobald 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 Unterabhängigkeit, einer Unterunterabhängigkeit oder an einer anderen Stelle enthalten ist.

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

Dateien manuell bearbeiten

Die einfachste Option ist, 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 könnte. 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 einfacher, 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 Patch-Dateien, die auch in Versionskontrollsystemen wie Git oder Subversion verwendet werden. Sie müssen den entsprechenden Code 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 es ist noch besser, 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 beibehalten werden, die nicht mehr verwendet werden. Wenn einer dieser Abschnitte Code zum Laden oder Ausführen von RHC enthält, muss er entfernt werden. Dabei spielt es keine Rolle, ob der Akku leer oder ungenutzt ist. Wenn sie nicht verwendet wird, sollte sie entfernt werden, entweder durch Treeshaking oder durch Patchen der Bibliothek.

Gibt es eine 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 chrome.scripting.executeScript oder andere Codeausfü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 aus dem Store entfernt werden.

chrome.debugger

Mit der chrome.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 chrome.scripting und bietet eine deutlich bessere Nutzererfahrung. 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“

iFrames mit Sandbox-Attribut

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 ein Sandboxed-iFrame verwenden. Aus Sicherheitsgründen werden Dinge wie eval() in Erweiterungen standardmäßig nicht unterstützt. Schadcode 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, der 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 ö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.