Gérer les cas de non-respect du code hébergé à distance

Le code hébergé à distance (RHC, Remote Hosted Code) est le nom donné par le Chrome Web Store à tout ce qui est exécuté par le navigateur et chargé à partir d'un emplacement autre que les fichiers de l'extension. comme JavaScript et WASM. Elle n'inclut pas les données ni les éléments tels que JSON ou CSS.

Pourquoi le RHC n'est-il plus autorisé ?

Avec Manifest V3, les extensions doivent désormais regrouper tout le code qu'elles utilisent dans l'extension elle-même. Auparavant, vous pouviez injecter dynamiquement des balises de script à partir de n'importe quelle URL sur le Web.

On m'a dit que mon extension était conforme au RHC. Que se passe-t-il ?

Si votre extension a été refusée lors de l'examen avec une erreur Blue Argon, cela signifie que nos examinateurs pensent qu'elle utilise du code hébergé à distance. Cela est généralement dû à une extension qui tente d'ajouter une balise de script avec une ressource distante (c'est-à-dire à partir du Web ouvert, plutôt que des fichiers inclus dans l'extension) ou qui récupère une ressource à exécuter directement.

Identifier les contenus générés par IA

Il n'est pas particulièrement difficile de repérer les contenus haineux une fois que vous savez ce qu'il faut rechercher. Tout d'abord, recherchez les chaînes "http://" ou "https://" dans votre projet. Si vous avez enfreint le règlement sur le contenu à caractère haineux, vous devriez pouvoir le trouver. Si vous disposez d'un système de compilation complet ou si vous utilisez des dépendances provenant de npm ou d'autres sources tierces, assurez-vous de rechercher la version compilée du code, car c'est celle qui est évaluée par le Play Store. Si vous ne parvenez toujours pas à identifier le problème, l'étape suivante consiste à contacter l'assistance centralisée. Il pourra vous indiquer les cas spécifiques de non-respect et ce qui est nécessaire pour publier l'extension le plus rapidement possible.

Que faire si une bibliothèque demande le code ?

Quelle que soit la provenance du code, il n'est pas autorisé d'avoir du contenu généré par l'IA. Cela inclut le code que vous n'avez pas créé, mais que vous utilisez simplement comme dépendance dans votre projet. Certains développeurs utilisant Firebase ont rencontré ce problème lorsque du code à distance était inclus pour être utilisé dans Firebase Auth. Même s'il s'agissait d'une bibliothèque propriétaire (c'est-à-dire appartenant à Google), aucune exception n'est accordée pour RHC. Vous devez configurer le code pour supprimer le RHC ou mettre à jour votre projet afin de ne pas inclure le code au départ. Si vous rencontrez un problème où ce n'est pas votre code qui charge RHC, mais une bibliothèque que vous utilisez, la meilleure chose à faire est de contacter l'auteur de la bibliothèque. Indiquez-lui que cela se produit et demandez-lui de vous proposer une solution de contournement ou des mises à jour du code pour le supprimer.

Que faire si vous ne pouvez pas attendre la mise à jour d'une bibliothèque ?

Certaines bibliothèques publieront une mise à jour presque immédiatement après avoir été averties, mais d'autres peuvent être abandonnées ou prendre du temps pour résoudre le problème. Selon ce qui se passe dans le cas de non-respect spécifique, vous n'aurez peut-être pas besoin d'attendre que la page soit déplacée pour être débloquée et que l'examen soit effectué. Plusieurs options sont disponibles pour vous permettre de vous remettre rapidement au travail.

Auditer le code

Êtes-vous certain que le code à l'origine de la demande est nécessaire ? Si le code peut simplement être supprimé ou si une bibliothèque à l'origine du problème peut être supprimée, supprimez ce code.

Existe-t-il une autre bibliothèque qui offre les mêmes fonctionnalités ? Essayez de consulter npmjs.com, GitHub ou d'autres sites pour trouver d'autres options qui répondent aux mêmes cas d'utilisation.

Tree shaking

Si le code à l'origine du non-respect des règles RHC n'est pas utilisé, il peut être supprimé automatiquement par les outils. Les outils de compilation modernes tels que webpack, Rollup et Vite (pour n'en citer que quelques-uns) disposent d'une fonctionnalité appelée tree-shaking. Une fois activé sur votre système de compilation, le tree shaking devrait supprimer tous les chemins de code inutilisés. Cela peut signifier que vous disposez non seulement d'une version plus conforme de votre code, mais aussi d'une version plus légère et plus rapide. Il est important de noter que toutes les bibliothèques ne peuvent pas être élaguées, mais que beaucoup le peuvent. Certains outils, comme Rollup et Vite, ont le tree shaking activé par défaut. webpack doit être configuré pour qu'il soit activé. Si vous n'utilisez pas de système de compilation dans votre extension, mais que vous utilisez des bibliothèques de code, nous vous encourageons vivement à envisager d'ajouter un outil de compilation à votre workflow. Les outils de compilation vous aident à écrire des projets plus sûrs, plus fiables et plus faciles à gérer.

Les spécificités de l'implémentation du treeshaking dépendent de votre projet. Mais pour prendre un exemple simple avec Rollup, vous pouvez ajouter le treeshaking en compilant simplement le code de votre projet. Par exemple, si vous avez un fichier qui se connecte uniquement à Firebase Auth, appelé 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);
  }
});

Il vous suffira ensuite d'indiquer à Rollup le fichier d'entrée, un plug-in nécessaire pour charger les fichiers de nœud @rollup/plugin-node-resolve et le nom du fichier de sortie qu'il génère.

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

Si vous exécutez cette commande dans une fenêtre de terminal, vous recevrez une version générée de notre fichier main.js, le tout compilé dans un seul fichier nommé compiled.js.

Le regroupement peut être simple, mais il est également très configurable. Vous pouvez ajouter toutes sortes de logiques et de configurations complexes. Pour en savoir plus, consultez la documentation. L'ajout d'outils de compilation comme celui-ci permet d'obtenir un code plus petit et plus efficace, et dans ce cas, de résoudre notre problème de code hébergé à distance.

Modifier automatiquement des fichiers

Le code hébergé à distance peut de plus en plus souvent entrer dans votre codebase en tant que sous-dépendance d'une bibliothèque que vous incluez. Si la bibliothèque X souhaite import la bibliothèque Y à partir d'un CDN, vous devrez toujours la mettre à jour pour qu'elle se charge à partir d'une source locale. Avec les systèmes de compilation modernes, vous pouvez facilement créer des plug-ins pour extraire une référence distante et l'intégrer directement dans votre code.

Cela signifie que, pour un code qui se présente comme suit :

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

Vous pouvez créer un petit plug-in Rollup.

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

Une fois la compilation exécutée avec le nouveau plug-in, chaque URL import distante est détectée, qu'il s'agisse de notre code, d'une sous-dépendance, d'une sous-sous-dépendance ou de tout autre élément.

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

Modifier manuellement des fichiers

L'option la plus simple consiste à supprimer le code qui provoque la RHC. Ouvrez-le dans l'éditeur de texte de votre choix et supprimez les lignes concernées. Cette approche n'est généralement pas recommandée, car elle est fragile et peut être oubliée. Il est plus difficile de gérer votre projet lorsqu'un fichier nommé "library.min.js" n'est pas library.min.js. Au lieu de modifier les fichiers bruts, une option légèrement plus facile à gérer consiste à utiliser un outil tel que patch-package. Il s'agit d'une option très puissante qui vous permet d'enregistrer les modifications apportées à un fichier, plutôt que le fichier lui-même. Il est basé sur des fichiers de correctifs, le même type de fichiers que celui utilisé par les systèmes de contrôle des versions tels que Git ou Subversion. Il vous suffit de modifier manuellement le code non conforme, d'enregistrer le fichier diff et de configurer patch-package avec les modifications que vous souhaitez appliquer. Vous pouvez lire un tutoriel complet dans le fichier README du projet. Si vous corrigez un projet, nous vous encourageons vivement à contacter le projet pour demander que les modifications soient apportées en amont. Bien que patch-package facilite grandement la gestion des correctifs, il est encore mieux de ne rien avoir à corriger.

Que faire si le code n'est pas utilisé ?

À mesure que les bases de code se développent, les dépendances (ou dépendances de dépendances, etc.) peuvent conserver des chemins de code qui ne sont plus utilisés. Si l'une de ces sections inclut du code permettant de charger ou d'exécuter RHC, elle devra être supprimée. Peu importe si elle est déchargée ou inutilisée. S'il n'est pas utilisé, il doit être supprimé, soit par treeshaking, soit en corrigeant la bibliothèque pour le supprimer.

Existe-t-il une solution de contournement ?

En règle générale, non. Les RHC ne sont pas autorisées. Toutefois, dans un petit nombre de cas, cela est autorisé. Il s'agit presque toujours de cas où aucune autre option n'est possible.

API User Scripts

Les scripts utilisateur sont de petits extraits de code généralement fournis par l'utilisateur et destinés aux gestionnaires de scripts utilisateur tels que TamperMonkey et Violentmonkey. Ces gestionnaires ne peuvent pas regrouper le code écrit par les utilisateurs. L'API User Script permet donc d'exécuter le code fourni par l'utilisateur. Il ne remplace pas browser.scripting.executeScript ni d'autres environnements d'exécution de code. Les utilisateurs doivent activer le mode développeur pour exécuter quoi que ce soit. Si l'équipe d'examen du Chrome Web Store estime que le code est utilisé d'une manière autre que celle prévue (c'est-à-dire le code fourni par l'utilisateur), il peut être refusé ou sa fiche peut être supprimée du Store.

browser.debugger

L'API browser.debugger permet aux extensions d'interagir avec le protocole Chrome DevTools. Il s'agit du même protocole que celui utilisé pour les outils de développement Chrome et un nombre incroyable d'autres outils. Avec cette API, une extension peut demander et exécuter du code à distance. Tout comme les scripts utilisateur, il ne remplace pas browser.scripting et offre une expérience utilisateur beaucoup plus notable. Lorsqu'il est utilisé, une barre d'avertissement s'affiche en haut de la fenêtre. Si la bannière est fermée ou ignorée, la session de débogage est interrompue.

Capture d'écran de la barre d'adresse de Chrome affichant le message "L'extension Debugger a commencé à déboguer ce navigateur"
Capture d'écran de la barre d'adresse de Chrome affichant le message "L'extension Debugger a commencé à déboguer ce navigateur"

iFrames en bac à sable

Si vous devez évaluer une chaîne en tant que code et que vous vous trouvez dans un environnement DOM (par exemple, un script de contenu, par opposition à un service worker d'extension), vous pouvez également utiliser un iframe en bac à sable. Par mesure de sécurité, les extensions ne sont pas compatibles avec des éléments tels que eval() par défaut. Un code malveillant peut mettre en danger la sécurité des utilisateurs. Toutefois, lorsque le code n'est exécuté que dans un environnement sûr connu, comme un iFrame mis en bac à sable par rapport au reste du Web, ces risques sont considérablement réduits. Dans ce contexte, la règle de sécurité du contenu qui bloque l'utilisation d'eval peut être levée, ce qui vous permet d'exécuter n'importe quel code JavaScript valide.

Si vous avez un cas d'utilisation qui n'est pas couvert, n'hésitez pas à contacter l'équipe à l'aide de la liste de diffusion chromium-extensions pour obtenir des commentaires, ou ouvrez une nouvelle demande pour obtenir des conseils auprès de l'assistance centralisée.

Que faire si vous n'êtes pas d'accord avec un verdict ?

L'application des règles peut être nuancée et l'examen implique une saisie manuelle. Cela signifie que l'équipe du Chrome Web Store peut parfois accepter de modifier une décision d'examen. Si vous pensez qu'une erreur a été commise lors de l'examen, vous pouvez faire appel du refus à l'aide de l'assistance centralisée.