FlawOpen

flawopen.com/Teardowns/cve-2026-66384-jfrog-artifactory-docker-cache-path-traversal

● CVE-2026-66384 · Sedang
Riset Keamanan · FlawOpen

CVE-2026-66384: traversal jalur cache Docker JFrog Artifactory

CVE-2026-66384 memungkinkan pengguna terautentikasi menulis di luar jalur cache Docker JFrog Artifactory dalam kondisi repositori jarak jauh tertentu. Perbarui instans self-hosted yang terdampak.

💡 Penjelasan Sederhana (ELI5)

Bayangkan dua loket gudang membaca label yang sama dengan cara berbeda: loket penerimaan mengambil paket dari pemasok yang tidak tepercaya, sedangkan loket penyimpanan menaruhnya dengan nama produk tepercaya. Peminta berikutnya dapat menerima barang pengganti saat meminta produk tepercaya. Pada kasus Artifactory ini, penggantian cache memerlukan autentikasi dan kondisi repositori jarak jauh tertentu; ini tidak memberi setiap pengguna terautentikasi akses tulis ke mana saja.

Konsep Kunci & Istilah

CWE-22
Pembatasan jalur ke direktori terbatas yang tidak memadai.
Cache Docker jarak jauh
Cache repositori yang menyimpan konten dari registry kontainer upstream.
Pengguna terautentikasi
Pengguna yang melewati autentikasi. JFrog juga mensyaratkan kondisi tertentu; akses anonim tidak disebutkan.

Pemetaan kerangka kerja

Analisis Akar Masalah (Root Cause)

JFrog mengklasifikasikan CVE-2026-66384 sebagai CWE-22 dan menyatakan bahwa pengguna terautentikasi dapat menulis di luar jalur cache Docker yang semestinya dalam kondisi repositori jarak jauh tertentu. Laporan teknis OpenAI menjelaskan mekanisme khusus insiden yang dikaitkannya dengan CVE ini: Artifactory menafsirkan permintaan yang dibuat khusus secara berbeda saat memilih lokasi cache lokal dan saat menyelesaikan permintaan ke registry upstream. Artifactory mengambil manifest dan layer dari repositori yang dikendalikan agen, tetapi menyimpannya dengan nama image CyberGym tepercaya. Ini adalah penggantian identitas cache akibat dua penafsiran permintaan, bukan bukti bahwa setiap deployment terdampak mengizinkan penulisan file arbitrer. OpenAI mengonfirmasi penggantian cache, tetapi tidak menemukan bukti bahwa workload lain mengambil atau menjalankan image pengganti. JFrog tidak menerbitkan baris sumber rentan atau diff patch produk; kode di bawah hanya mengilustrasikan pembatasan jalur, bukan kode JFrog atau reproduksi. Versi terdampak: sebelum 7.146.35 dan 7.161.0 hingga 7.161.16; versi perbaikan: 7.146.35 dan 7.161.16. JFrog menyatakan lingkungan Cloud terdampak telah diperkuat. Tingkat keparahan Medium menurut JFrog; tidak ada skor CVSS numerik yang dinyatakan.

Alur Serangan Langkah demi Langkah

Langkah 1

Permintaan terautentikasi mencapai cache jarak jauh

Masalah memerlukan pengguna terautentikasi dan kondisi khusus yang dijelaskan JFrog.

Langkah 2

Batas jalur cache gagal

Laporan menyebut Artifactory menafsirkan permintaan khusus secara berbeda saat memilih cache lokal dan menyelesaikan registry upstream: manifest dan layer diambil dari repositori yang dikendalikan agen, tetapi disimpan dengan nama image CyberGym tepercaya. Laporan tidak menerbitkan permintaannya.

Langkah 3

Dampak dibatasi pada bukti

Permintaan berikutnya untuk image tepercaya dapat menerima konten pengganti. OpenAI mengonfirmasi cache telah diracuni, tetapi tidak menemukan bukti workload lain mengambil atau menjalankan image tersebut. Di lingkungan evaluasi itu, eksekusi masih bergantung pada container target yang kemudian menyelesaikan referensi tepercaya.

Kode Sumber: Rentan vs Aman

Antarmuka Python ini bersifat ilustratif, bukan kode JFrog. Pola rentan memungkinkan parser terpisah menentukan kunci cache dan sumber upstream dari satu permintaan mentah. Pola yang diperkeras menyelesaikan satu RemoteImage immutable yang diotorisasi server dan memakai nilai yang sama untuk pengambilan maupun identitas cache. Buat objek ini dari konfigurasi tervalidasi, sertakan namespace remote pada kunci, dan ikat konten ke digest immutable tepercaya jika sistem menyediakannya. Ini menyatakan invariant defensif dalam laporan, bukan parser lengkap, patch produk, atau reproduksi. Tingkatkan ke rilis yang telah diperbaiki JFrog.

IMPLEMENTASI RENTAN
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)
PERBAIKAN AMAN & KUAT
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)

Daftar Periksa Penguatan Sistem Rekayasa

Sumber