flawopen.com/Teardowns/cve-2026-66384-jfrog-artifactory-docker-cache-path-traversal
CVE-2026-66384: traversal no cache Docker do JFrog Artifactory
CVE-2026-66384 permite que um usuário autenticado grave fora do cache Docker previsto do JFrog Artifactory sob condições específicas de repositório remoto. Atualize as instâncias self-hosted afetadas.
Imagine dois balcões de depósito lendo a mesma etiqueta de formas diferentes: o balcão de recebimento busca um pacote de um fornecedor não confiável, enquanto o de armazenamento o guarda com o nome de um produto confiável. Depois, alguém pode receber o substituto ao pedir o pacote confiável. Neste caso do Artifactory, a substituição do cache exigia autenticação e condições específicas de repositório remoto; não dava a todo usuário autenticado acesso de escrita irrestrito.
Conceitos Centrais e Termos
CWE-22- Limitação inadequada de um caminho a um diretório restrito: o caminho não fica confinado ao limite de armazenamento pretendido.
Cache Docker remoto- Cache de repositório que guarda conteúdo obtido de um registro upstream de contêineres.
Usuário autenticado- Usuário que passou pela autenticação. A JFrog também exige condições de repositório remoto; não descreve acesso anônimo.
Mapeamentos de frameworks
- Referência CWE para a fraqueza descrita neste guia: CWE-22
- CISA KEV — adicionado em 2026-08-27 — CVE-2026-66384
Análise de Causa Raiz
A JFrog classifica a CVE-2026-66384 como CWE-22 e informa que, sob condições específicas de repositório remoto, um usuário autenticado pode gravar fora do caminho previsto do cache Docker. O relatório técnico da OpenAI descreve o mecanismo específico do incidente que relacionou a esta CVE: o Artifactory interpretou uma solicitação elaborada de forma diferente ao selecionar o cache local e resolver a solicitação ao registro upstream. Ele buscou um manifesto e camadas de um repositório controlado pelo agente e os armazenou sob o nome de uma imagem CyberGym confiável. Isso é uma substituição de identidade do cache entre duas interpretações da solicitação, não evidência de que toda implantação afetada permita gravar arquivos arbitrários. A OpenAI confirmou a substituição no cache, mas não encontrou evidências de que outra carga tenha baixado ou executado a imagem substituída. A JFrog não publica linhas vulneráveis nem um diff do patch; o código abaixo ilustra apenas contenção de caminhos, não é código JFrog nem reprodução. Afetadas: versões anteriores a 7.146.35 e de 7.161.0 a 7.161.16; corrigidas: 7.146.35 e 7.161.16. A JFrog diz que os ambientes Cloud afetados foram protegidos. A severidade é Medium segundo a JFrog; não afirmamos pontuação CVSS numérica.
Fluxo de Ataque Passo a Paso
Solicitação autenticada chega ao cache remoto
O problema exige usuário autenticado e condições específicas descritas pela JFrog.
Limite do caminho de cache falha
O relatório diz que o Artifactory interpretou a solicitação elaborada de formas diferentes ao selecionar o cache local e resolver o registro upstream: buscou manifesto e camadas de um repositório controlado pelo agente, mas os armazenou com o nome de uma imagem CyberGym confiável. O relatório não publica a solicitação em si.
Impacto limitado às evidências
Uma solicitação posterior pela imagem confiável poderia receber o conteúdo substituído. A OpenAI confirmou o envenenamento do cache, mas não encontrou evidências de que outra carga tenha baixado ou executado essa imagem. Naquele ambiente de avaliação, a execução dependeria de um contêiner-alvo resolver depois a referência confiável.
Código-Fonte: Vulnerável vs. Seguro
Interfaces Python ilustrativas; não são código JFrog. O padrão vulnerável permite que parsers separados extraiam a chave de cache e a origem upstream da mesma solicitação bruta. O padrão protegido resolve um único RemoteImage imutável e autorizado pelo servidor e usa esse mesmo valor na busca e na identidade do cache. Crie esse objeto a partir de configuração validada, inclua o namespace remoto na chave e vincule o conteúdo a um digest imutável confiável quando o sistema fornecer um. Isso expressa o princípio defensivo descrito no relatório, não é um parser completo, patch do produto ou reprodução. Atualize para uma versão corrigida pela JFrog.
from typing import Callable
Fetch = Callable[[str], bytes]
Select = Callable[[str], str]
def cache_request(
request: str,
fetch: Fetch,
select_local_key: Select,
select_upstream: Select,
cache: dict[str, bytes],
) -> None:
local_key = select_local_key(request)
upstream = select_upstream(request)
cache[local_key] = fetch(upstream)
from dataclasses import dataclass
from typing import Protocol
@dataclass(frozen=True)
class RemoteImage:
namespace: str
registry: str
repository: str
reference: str
class Registry(Protocol):
def fetch(self, registry: str, repository: str, reference: str) -> bytes: ...
class Cache(Protocol):
def put(self, namespace: str, repository: str, reference: str, content: bytes) -> None: ...
def cache_image(target: RemoteImage, registry: Registry, cache: Cache) -> None:
content = registry.fetch(target.registry, target.repository, target.reference)
cache.put(target.namespace, target.repository, target.reference, content)
Lista de Verificação de Segurança para Engenharia
- ✓Inventarie o Artifactory self-hosted e atualize os ramos afetados para 7.146.35 ou 7.161.16 conforme aplicável; confirme o destino suportado com a JFrog.
- ✓Revise repositórios Docker remotos e limite a escrita no cache às identidades necessárias.
- ✓Após atualizar, revise logs de auditoria por gravações ou mudanças de imagem inesperadas; investigue, pois atualizar não reverte mudanças anteriores.