Vite has a `server.fs.deny` bypassed for `inline` and `raw` with `?import` query
Corrija agora. Ela está sob exploração confirmada pelo CISA e tem exploit funcional público.
Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.
Resumo
O dev server do Vite (a partir de certas versões 4.x a 6.x) expõe o conteúdo de arquivos arbitrários do sistema de arquivos mesmo quando esses caminhos estão explicitamente bloqueados por server.fs.deny, através de combinações de query string envolvendo os parâmetros internos ?inline e ?raw junto com ?import. A falha só importa em ambientes onde o dev server foi deliberadamente exposto na rede via --host ou server.host — no padrão (bind em localhost) o risco prático é bem menor. Está no catálogo KEV da CISA, com exploração confirmada, o que eleva sua prioridade mesmo com CVSS moderado (5.3).
Detalhamento técnico
O Vite dev server aplica controle de acesso a arquivos via server.fs.allow (diretórios liberados) e server.fs.deny (padrões bloqueados, como .env e chaves) dentro do middleware de transformação de módulos (transform.ts). Essa checagem é feita pela função ensureServingAccess, mas antes do patch ela só era invocada quando a query string da requisição continha os parâmetros ?raw ou ?url — usados pelos plugins internos do Vite para servir o conteúdo bruto de um arquivo ou sua URL pública em vez de transformá-lo como módulo JS.
O parâmetro ?inline, usado por outros plugins internos (por exemplo, inlining de assets/WASM em base64), não estava incluído nessa checagem. Um atacante podia requisitar um caminho absoluto via /@fs/?import&inline (o relatório original usava a forma ?import&?inline=1.wasm?init, que aciona o pipeline de inicialização WASM) e receber o conteúdo do arquivo, codificado em base64 — no caso do vetor WASM, era necessário decodificar base64 duas vezes — sem que ensureServingAccess fosse chamada em nenhum momento. O advisory também lista um segundo padrão, ?raw?import (com '?' duplicado em vez do '&' esperado entre parâmetros), que contornava a checagem mesmo com o rawRE original já existente; o mecanismo exato dessa diferença de parsing de query não é detalhado nas fontes oficiais.
As regras de acesso não exigem que o caminho esteja fora do project root: o advisory afirma explicitamente que /@fs/ não é necessário para reproduzir o problema em arquivos dentro da raiz do projeto — ou seja, arquivos sensíveis dentro do próprio projeto, mas listados em fs.deny (como .env), também eram expostos.
O fix (commit 5967313) adiciona uma terceira regex, inlineRE (/[?&]inline\b/), à condição que dispara ensureServingAccess, de modo que qualquer requisição ao middleware de transformação contendo ?raw, ?url ou ?inline passe pela checagem de fs.allow/fs.deny antes de qualquer conteúdo ser retornado. CWE-200 (exposição de informação sensível) e CWE-284 (controle de acesso impróprio).
Como é explorada
O pré-requisito determinante é a exposição do dev server na rede: por padrão o Vite escuta apenas em localhost, e só fica acessível remotamente quando o desenvolvedor usa a flag --host ou define server.host no config — cenário comum em ambientes de laboratório, VMs compartilhadas, containers com bind 0.0.0.0, ou desenvolvedores que expõem a porta 5173 por conveniência. Sem essa exposição a superfície de ataque prática é mínima.
Com o dev server acessível, a exploração é uma requisição HTTP GET simples contra uma URL como /@fs/?import&inline (ou variantes com ?raw?import), sem necessidade de autenticação (PR:N). O AC:H do CVSS reflete que o atacante precisa conhecer a estrutura de query específica que engana o middleware e, no caso do vetor original, decodificar base64 em duas camadas. O UI:R sugere que o padrão de exploração observado envolve a vítima com acesso à rede do dev server sendo induzida a acessar/carregar algo (ex.: um link ou página que dispara a requisição), e não necessariamente um ataque completamente sem interação.
O resultado final é leitura de arquivos arbitrários do sistema de arquivos do host onde o dev server roda — incluindo segredos, chaves privadas, arquivos .env e qualquer conteúdo acessível ao processo Node que executa o Vite. Não há impacto em integridade ou disponibilidade (I:N, A:N no vetor CVSS), é puramente divulgação de informação. A presença no catálogo KEV da CISA confirma exploração ativa observada, e existe template Nuclei público e PoC divulgada, o que reduz a barreira técnica para varreduras automatizadas contra instâncias expostas.
Versões
Como se proteger
Atualizar para a versão corrigida da respectiva linha: 6.2.4 ou superior, 6.1.3 (branch 6.1.x), 6.0.13 (branch 6.0.x), 5.4.16 (branch 5.x) ou 4.5.11 (branch 4.x). Não há necessidade de mudar de major version — cada ramo tem seu backport.
Se a atualização não for viável de imediato, o paliativo real é parar de expor o dev server na rede: remover a flag --host e a opção server.host da configuração, restringindo o acesso a localhost. Isso neutraliza o vetor por completo, já que a falha só é explorável quando o servidor está acessível remotamente. Reforçar ou revisar server.fs.deny não é mitigação eficaz aqui — é exatamente esse mecanismo que a falha contorna, então confiar apenas nele sem atualizar deixa o ambiente vulnerável.
Dev server do Vite nunca deve ser tratado como serviço de produção ou exposto sem controle de rede (firewall, VPN, allowlist de IP) — isso vale independentemente desta CVE específica, dado o histórico recorrente de bypass de fs.deny/fs.allow nessa ferramenta.
Como detectar
Em logs de acesso ao dev server (ou proxy na frente dele), procurar requisições cujo path inclua /@fs/ apontando para caminhos absolutos fora do diretório do projeto (ex.: /etc/passwd, chaves em /home, C:/windows/win.ini) combinados com query strings contendo inline junto com import, ou o padrão malformado raw?import (com '?' duplicado em vez de '&'). O padrão originalmente reportado, ?import&?inline=1.wasm?init, é um indicador de alta confiança de tentativa de exploração ou de uso do exploit público/template Nuclei conhecido.
Não há um único IOC de rede confiável além desses padrões de query, e como o Vite dev server normalmente não fica atrás de logging centralizado em ambientes de desenvolvimento, a ausência de log não indica ausência de tentativa — a visibilidade depende inteiramente de o operador ter exposto o processo Node com registro de acesso habilitado.