Cómo abordar incumplimientos de código alojados de manera remota

El código alojado de forma remota, o RHC, es lo que Chrome Web Store denomina cualquier elemento que ejecuta el navegador y que se carga desde un lugar que no son los archivos propios de la extensión. Cosas como JavaScript y WASM. No incluye datos ni elementos como JSON o CSS.

¿Por qué ya no se permite el RHC?

Con Manifest V3, las extensiones ahora deben incluir todo el código que usan dentro de la extensión. Anteriormente, podías insertar de forma dinámica etiquetas de secuencia de comandos desde cualquier URL de la Web.

Me dijeron que mi extensión tiene RHC. ¿Qué sucede?

Si se rechazó tu extensión durante la revisión con un error de Blue Argon, nuestros revisores creen que tu extensión usa código alojado de forma remota. Por lo general, esto se debe a que una extensión intenta agregar una etiqueta de secuencia de comandos con un recurso remoto (es decir, de la Web abierta, en lugar de los archivos incluidos en la extensión) o recupera un recurso para ejecutarlo directamente.

Cómo detectar el contenido generado por IA

Detectar el RHC no es particularmente difícil una vez que sabes qué buscar. Primero, busca las cadenas "http://" o "https://" en tu proyecto. Si tienes un incumplimiento de RHC, es probable que puedas ubicarlos encontrando eso. Si tienes un sistema de compilación completo o usas dependencias de npm o de otras fuentes de terceros, asegúrate de buscar la versión compilada del código, ya que es lo que evalúa la tienda. Si aún no puedes encontrar el problema, el siguiente paso es comunicarte con el equipo de asistencia integral. Podrán describir los incumplimientos específicos y lo que se necesita para publicar la extensión lo antes posible.

Qué hacer si una biblioteca solicita el código

Independientemente de dónde provenga el código, no se permite tener RHC. Esto incluye el código que no creaste, pero que usas como dependencia en tu proyecto. Algunos desarrolladores que usan Firebase tuvieron este problema cuando se incluía código remoto para usar en Firebase Auth. Aunque se trataba de una biblioteca propia (es decir, propiedad de Google), no se otorga ninguna excepción para RHC. Debes configurar el código para quitar el RHC o actualizar tu proyecto para que no incluya el código desde el principio. Si tienes un problema en el que no es tu código el que carga RHC, sino una biblioteca que estás usando, lo mejor es que te comuniques con el autor de la biblioteca. Infórmale que esto está sucediendo y pídele una solución alternativa o actualizaciones de código para quitarlo.

Qué sucede si no puedes esperar a que se actualice la biblioteca

Algunas bibliotecas publicarán una actualización casi inmediatamente después de recibir la notificación, pero otras pueden abandonarse o tardar en abordar el problema. Según lo que sucede en el incumplimiento específico, es posible que no debas esperar a que se desbloqueen y se complete una revisión exitosa. Existen varias opciones disponibles para volver a poner en funcionamiento tu dispositivo rápidamente.

Audita el código

¿Tienes la certeza de que se necesita el código que está causando la solicitud? Si solo se puede borrar o se puede quitar una biblioteca que lo causa, borra ese código y el trabajo estará listo.

¿Existe otra biblioteca que ofrezca las mismas funciones? Intenta consultar npmjs.com, GitHub o otros sitios para ver otras opciones que satisfagan los mismos casos de uso.

Eliminación de código no utilizado

Si el código que causa el incumplimiento de la RHC no se está usando, es posible que las herramientas lo borren automáticamente. Las herramientas de compilación modernas, como webpack, Rollup y Vite (por nombrar algunas), tienen una función llamada eliminación de código no utilizado. Una vez que se habilita en tu sistema de compilación, la eliminación de código no utilizado debería quitar cualquier ruta de código sin usar. Esto puede significar que no solo tienes una versión más compatible de tu código, sino también una más eficiente y rápida. Es importante tener en cuenta que no todas las bibliotecas se pueden eliminar con la eliminación de código no utilizado, pero muchas sí. Algunas herramientas, como Rollup y Vite, tienen habilitado el tree shaking de forma predeterminada. webpack debe configurarse para que se habilite. Si no usas un sistema de compilación como parte de tu extensión, pero usas bibliotecas de código, te recomendamos que investigues la posibilidad de agregar una herramienta de compilación a tu flujo de trabajo. Las herramientas de compilación te ayudan a escribir proyectos más seguros, confiables y fáciles de mantener.

Los detalles específicos de cómo implementar la eliminación de código no utilizado dependen de tu proyecto. Sin embargo, para tomar un ejemplo simple con Rollup, puedes agregar la eliminación de código no utilizado con solo compilar el código de tu proyecto. Por ejemplo, si tienes un archivo que solo accede a Firebase Auth, llamado 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);
  }
});

Luego, solo tendrías que indicarle a Rollup el archivo de entrada, un complemento necesario para cargar archivos de nodos @rollup/plugin-node-resolve y el nombre del archivo de salida que está generando.

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

Si ejecutas ese comando en una ventana de terminal, recibirás una versión generada de nuestro archivo main.js, todo compilado en un solo archivo llamado compiled.js.

El resumen puede ser simple, pero también es muy configurable. Puedes agregar todo tipo de lógica y configuración complejas. Solo consulta su documentación. Agregar herramientas de compilación como esta generará un código más pequeño y eficiente, y, en este caso, solucionará nuestro problema de código alojado de forma remota.

Edición automática de archivos

Una forma cada vez más común en que el código alojado de forma remota puede ingresar a tu base de código es como una subdependencia de una biblioteca que incluyes. Si la biblioteca X quiere import la biblioteca Y desde una CDN, deberás actualizarla para que se cargue desde una fuente local. Con los sistemas de compilación modernos, puedes crear complementos de forma trivial para extraer una referencia remota y, luego, incorporarla directamente en tu código.

Eso significaría que, dado un código como el siguiente:

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

Podrías crear un pequeño complemento de 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
    }
  }]
};

Una vez que ejecutes la compilación con el nuevo complemento, se detectará cada URL de import remota, independientemente de si se trata de nuestro código, una subdependencia, una subsubdependencia o cualquier otro elemento.

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

Cómo editar archivos de forma manual

La opción más simple es borrar el código que causa el RHC. Ábrelo en el editor de texto que prefieras y borra las líneas infractoras. En general, no es tan recomendable, ya que es frágil y podría olvidarse. Esto dificulta el mantenimiento de tu proyecto cuando un archivo llamado "library.min.js" en realidad no es library.min.js. En lugar de editar los archivos sin procesar, una opción un poco más fácil de mantener es usar una herramienta como patch-package. Esta es una opción muy potente que te permite guardar modificaciones en un archivo, en lugar del archivo en sí. Se basa en archivos de parche, el mismo tipo de archivos que impulsan los sistemas de control de versiones como Git o Subversion. Solo debes modificar manualmente el código infractor, guardar el archivo de diferencias y configurar patch-package con los cambios que deseas aplicar. Puedes leer un instructivo completo en el README del proyecto. Si estás aplicando parches a un proyecto, te recomendamos que te comuniques con el proyecto para solicitar que se realicen cambios en el código fuente. Si bien patch-package facilita mucho la administración de parches, no tener que aplicar parches es aún mejor.

Qué hacer si no se usa el código

A medida que crecen las bases de código, las dependencias (o la dependencia de una dependencia, o la dependencia de…) pueden mantener rutas de código que ya no se usan. Si una de esas secciones incluye código para cargar o ejecutar RHC, deberá quitarse. No importa si está agotada o no se usa. Si no se usa, se debe quitar, ya sea mediante la eliminación de código no utilizado o aplicando parches a la biblioteca para quitarlo.

¿Existe alguna solución alternativa?

En general, no. No se permite la RHC. Sin embargo, hay una pequeña cantidad de casos en los que se permite. Casi siempre se trata de casos en los que ninguna otra opción es posible.

API de User Scripts

Las secuencias de comandos del usuario son pequeños fragmentos de código que suelen proporcionar los usuarios y que están diseñados para administradores de secuencias de comandos del usuario, como TamperMonkey y Violentmonkey. Estos administradores no pueden agrupar el código escrito por los usuarios, por lo que la API de User Script expone una forma de ejecutar el código proporcionado por el usuario. Esto no es un sustituto de chrome.scripting.executeScript ni de otros entornos de ejecución de código. Los usuarios deben habilitar el modo de desarrollador para ejecutar cualquier acción. Si el equipo de revisión de Chrome Web Store considera que se usa de una manera diferente a la prevista (es decir, código proporcionado por el usuario), es posible que se rechace o que se quite su ficha de la tienda.

chrome.debugger

La API de chrome.debugger permite que las extensiones interactúen con el protocolo de Herramientas para desarrolladores de Chrome. Este es el mismo protocolo que se usa para las Herramientas para desarrolladores de Chrome y una gran cantidad de otras herramientas. Con él, una extensión puede solicitar y ejecutar código remoto. Al igual que los secuencias de comandos del usuario, no es un sustituto de chrome.scripting y tiene una experiencia del usuario mucho más notable. Mientras se usa, el usuario verá una barra de advertencia en la parte superior de la ventana. Si se cierra o descarta el banner, se finalizará la sesión de depuración.

Captura de pantalla de la barra de direcciones de Chrome que muestra el mensaje "La extensión Debugger comenzó a depurar este navegador"
Captura de pantalla de la barra de direcciones en Chrome que muestra el mensaje "La extensión Debugger comenzó a depurar este navegador"

Iframes en zona de pruebas

Si necesitas evaluar una cadena como código y estás en un entorno de DOM (p.ej., una secuencia de comandos de contenido, a diferencia de un service worker de extensión), otra opción es usar un iframe en zona de pruebas. Las extensiones no admiten elementos como eval() de forma predeterminada como medida de seguridad. El código malicioso podría poner en riesgo la seguridad y la protección de los usuarios. Sin embargo, cuando el código solo se ejecuta en un entorno seguro conocido, como un iframe que se aisló del resto de la Web, esos riesgos se reducen considerablemente. En este contexto, se puede anular la Política de seguridad del contenido que bloquea el uso de eval, lo que te permite ejecutar cualquier código JavaScript válido.

Si tienes un caso de uso que no se cubre, no dudes en comunicarte con el equipo a través de la lista de distribución de chromium-extensions para obtener comentarios o abrir un nuevo ticket para solicitar orientación de One Stop Support.

Qué hacer si no estás de acuerdo con un veredicto

La aplicación de políticas puede ser sutil, y la revisión implica la intervención manual, lo que significa que, en ocasiones, el equipo de Chrome Web Store puede aceptar cambiar una decisión de revisión. Si crees que se cometió un error en la revisión, puedes apelar el rechazo a través de la Asistencia integral.