Gestire le violazioni del codice ospitato da remoto

Il codice ospitato in remoto, o RHC, è il termine utilizzato dal Chrome Web Store per indicare qualsiasi elemento eseguito dal browser che viene caricato da una posizione diversa dai file dell'estensione. Ad esempio JavaScript e WASM. Non include dati o elementi come JSON o CSS.

Perché l'RHC non è più consentito?

Con Manifest V3, le estensioni devono ora includere tutto il codice che utilizzano all'interno dell'estensione stessa. In passato, era possibile inserire dinamicamente tag script da qualsiasi URL sul web.

Mi è stato comunicato che la mia estensione ha RHC. Che cosa succede?

Se la tua estensione è stata rifiutata durante la revisione con un errore Blue Argon, allora i nostri revisori ritengono che la tua estensione stia utilizzando codice ospitato in remoto. In genere, ciò è dovuto al fatto che un'estensione tenta di aggiungere un tag di script con una risorsa remota (ovvero dal web aperto, anziché dai file inclusi nell'estensione) o di recuperare una risorsa da eseguire direttamente.

Come individuare l'RHC

Individuare l'RHC non è particolarmente difficile una volta che sai cosa cercare. Innanzitutto, cerca le stringhe "http://" o "https://" nel tuo progetto. Se hai una violazione dell'RHC, probabilmente potrai individuarle trovando queste stringhe. Se hai un sistema di compilazione completo o utilizzi dipendenze da npm o altre fonti di terze parti, assicurati di cercare la versione compilata del codice, poiché è quella che viene valutata dallo store. Se non riesci ancora a trovare il problema, il passaggio successivo è contattare l'assistenza centralizzata. Potranno illustrare le violazioni specifiche e cosa è necessario fare per pubblicare l'estensione il prima possibile.

Che cosa fare se una libreria richiede il codice

Indipendentemente dalla provenienza del codice, non è consentito avere RHC. Ciò include il codice che non hai creato, ma che utilizzi come dipendenza nel tuo progetto. Alcuni sviluppatori che utilizzano Firebase hanno riscontrato questo problema quando il codice remoto veniva incluso per l'utilizzo in Firebase Auth. Anche se si trattava di una libreria di prime parti (ovvero di proprietà di Google), non viene concessa alcuna eccezione per l'RHC. Devi configurare il codice in modo da rimuovere l'RHC o aggiornare il progetto in modo che non includa il codice. Se riscontri un problema in cui non è il tuo codice a caricare l'RHC, ma una libreria che stai utilizzando, la cosa migliore da fare è contattare l'autore della libreria. Comunicagli che si sta verificando questo problema e chiedi una soluzione alternativa o aggiornamenti del codice per rimuoverlo.

Che cosa fare se non puoi attendere l'aggiornamento di una libreria

Alcune librerie pubblicheranno un aggiornamento quasi immediatamente dopo aver ricevuto la notifica, ma altre potrebbero essere abbandonate o richiedere tempo per risolvere il problema. A seconda di cosa sta succedendo nella violazione specifica, potresti non dover attendere che vengano sbloccate e completare una revisione con esito positivo. Sono disponibili diverse opzioni per riprendere rapidamente l'attività.

Eseguire un audit del codice

Sei sicuro che il codice che causa la richiesta sia necessario? Se può essere eliminato o se la libreria che lo causa può essere rimossa, elimina il codice e il gioco è fatto.

In alternativa, esiste un'altra libreria che offre le stesse funzionalità? Prova a controllare npmjs.com, GitHub o altri siti per trovare altre opzioni che soddisfino gli stessi casi d'uso.

Tree shaking

Se il codice che causa la violazione dell'RHC non viene effettivamente utilizzato, potrebbe essere possibile eliminarlo automaticamente tramite gli strumenti. Gli strumenti di build moderni come webpack, Rollup e Vite (solo per citarne alcuni) hanno una funzionalità chiamata tree shaking. Una volta attivato nel sistema di compilazione, il tree shaking dovrebbe rimuovere tutti i percorsi del codice inutilizzati. Ciò significa che non solo avrai una versione del codice più conforme, ma anche più snella e veloce. È importante notare che non tutte le librerie possono essere sottoposte a tree shaking, ma molte sì. Alcuni strumenti, come Rollup e Vite, hanno il tree shaking attivato per impostazione predefinita. Per attivare webpack , è necessario configurarlo. Se non utilizzi un sistema di build come parte dell'estensione, ma utilizzi librerie di codice, ti consigliamo vivamente di valutare l'aggiunta di uno strumento di build al tuo flusso di lavoro. Gli strumenti di build ti aiutano a scrivere progetti più sicuri, affidabili e gestibili.

I dettagli specifici su come implementare il tree shaking dipendono dal tuo progetto specifico. Tuttavia, per fare un semplice esempio con Rollup, puoi aggiungere il tree shaking semplicemente compilando il codice del progetto. Ad esempio, se hai un file che esegue solo l'accesso a Firebase Authentication, chiamato main.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);
  }
});

A questo punto, non devi fare altro che indicare a Rollup il file di input, un plug-in necessario per caricare i file dei nodi @rollup/plugin-node-resolve e il nome del file di output che sta generando.

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

Eseguendo questo comando in una finestra del terminale, riceverai una versione generata del file main.js, compilata in un unico file denominato compiled.js.

Rollup può essere semplice, ma è anche molto configurabile. Puoi aggiungere tutti i tipi di logica e configurazione complesse, basta consultare la documentazione. L'aggiunta di strumenti di build come questo comporterà un codice più piccolo ed efficiente e, in questo caso, risolverà il problema del codice ospitato in remoto.

Modificare automaticamente i file

Un modo sempre più comune in cui il codice ospitato in remoto può entrare nella tua codebase è come dipendenza secondaria di una libreria che stai includendo. Se la libreria X vuole import la libreria Y da una CDN, dovrai comunque aggiornarla per fare in modo che venga caricata da una fonte locale. Con i sistemi di build moderni, puoi creare facilmente plug-in per estrarre un riferimento remoto e incorporarlo direttamente nel codice.

Ciò significa che, dato il codice simile a questo:

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

Potresti creare un piccolo plug-in di 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
    }
  }]
};

Dopo aver eseguito la build con il nuovo plug-in, ogni URL import remoto viene rilevato indipendentemente dal fatto che si tratti del nostro codice, di una dipendenza secondaria, di una dipendenza secondaria o di qualsiasi altro elemento.

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

Modificare manualmente i file

L'opzione più semplice è eliminare il codice che causa l'RHC. Apri l'editor di testo che preferisci ed elimina le righe che violano le norme. In genere, questa operazione non è consigliabile, perché è fragile e potrebbe essere dimenticata. Rende più difficile la manutenzione del progetto quando un file denominato "library.min.js" non è effettivamente library.min.js. Anziché modificare i file non elaborati, un'opzione leggermente più gestibile è utilizzare uno strumento come patch-package. Si tratta di un'opzione molto potente che ti consente di salvare le modifiche a un file, anziché al file stesso. Si basa su file patch, lo stesso tipo di file che alimenta i sistemi di controllo della versione come Git o Subversion. Devi solo modificare manualmente il codice che viola le norme, salvare il file diff e configurare patch-package con le modifiche che vuoi applicare. Puoi leggere un tutorial completo nel file README del progetto. Se stai applicando una patch a un progetto, ti consigliamo vivamente di contattare il progetto per richiedere che le modifiche vengano apportate a monte. Sebbene patch-package semplifichi notevolmente la gestione delle patch, è ancora meglio non dover applicare alcuna patch.

Che cosa fare se il codice non viene utilizzato

Man mano che le codebase crescono, le dipendenze (o la dipendenza di una dipendenza, o la dipendenza di…) possono mantenere i percorsi di codice che non vengono più utilizzati. Se una di queste sezioni include codice per caricare o eseguire RHC, dovrà essere rimossa. Non importa se è inattivo o inutilizzato. Se non viene utilizzato, deve essere rimosso, tramite tree shaking o applicando una patch alla libreria per rimuoverlo.

Esiste una soluzione alternativa?

In generale, no. L'RHC non è consentito. Esiste, tuttavia, un piccolo numero di casi in cui è consentito. Quasi sempre si tratta di casi in cui non è possibile utilizzare altre opzioni.

API User Scripts

Gli script utente sono piccoli snippet di codice in genere forniti dall' utente, destinati a gestori di script utente come TamperMonkey e Violentmonkey. Questi gestori non possono includere il codice scritto dagli utenti, quindi l'API User Scripts espone un modo per eseguire il codice fornito dall'utente. Non si tratta di un sostituto di chrome.scripting.executeScript o di altri ambienti di esecuzione del codice. Gli utenti devono attivare la modalità sviluppatore per eseguire qualsiasi operazione. Se il team di revisione del Chrome Web Store ritiene che questa API venga utilizzata in modo diverso da quello previsto (ovvero codice fornito dall'utente), la richiesta potrebbe essere rifiutata o la scheda potrebbe essere rimossa dallo store.

chrome.debugger

L'API chrome.debugger consente alle estensioni di interagire con il protocollo Chrome DevTools. Si tratta dello stesso protocollo utilizzato per Chrome DevTools e per un numero incredibile di altri strumenti. Con questa API, un'estensione può richiedere ed eseguire codice remoto. Come gli script utente, non è un sostituto di chrome.scripting e ha un'esperienza utente molto più evidente. Durante l'utilizzo, l'utente vedrà una barra di avviso nella parte superiore della finestra. Se il banner viene chiuso o ignorato, la sessione di debug verrà terminata.

Screenshot della barra degli indirizzi di Chrome con il messaggio "L'estensione di debug ha iniziato il debug di questo browser"
Screenshot della barra degli indirizzi di Chrome con il messaggio "L'estensione Debugger ha iniziato il debug di questo browser"

Iframe in sandbox

Se devi valutare una stringa come codice e ti trovi in un ambiente DOM (ad es. uno script di contenuti, anziché un service worker dell'estensione), un'altra opzione è utilizzare un iframe in sandbox. Per impostazione predefinita, le estensioni non supportano elementi come eval() come misura di sicurezza. Il codice dannoso potrebbe mettere a rischio la sicurezza degli utenti. Tuttavia, quando il codice viene eseguito solo in un ambiente sicuro noto, come un iframe in sandbox dal resto del web, questi rischi vengono notevolmente ridotti. In questo contesto, i criteri di sicurezza dei contenuti che bloccano l'utilizzo di eval possono essere rimossi, consentendoti di eseguire qualsiasi codice JavaScript valido.

Se hai un caso d'uso non trattato, non esitare a contattare il team utilizzando la mailing list chromium-extensions per ricevere feedback o aprire un nuovo ticket per richiedere assistenza da One Stop Support

Che cosa fare se non sei d'accordo con un verdetto

L'applicazione delle norme può essere complessa e la revisione comporta l'inserimento manuale, il che significa che il team del Chrome Web Store a volte può accettare di modificare una decisione di revisione. Se ritieni che sia stato commesso un errore durante la revisione, puoi presentare ricorso contro il rifiuto utilizzando l'assistenza centralizzata