Rahasia kini tertata, tetapi image katalog-web:2.0 yang siap naik ke produksi masih menyimpan satu blind spot: isinya sendiri. Image itu kita bangun dari node:22-alpine, menambah dependensi express dan pg, dan menutupnya dengan HEALTHCHECK — tetapi tidak satu pun langkah itu memeriksa apa yang dibawa paket-paket di dalamnya. Setiap paket di image adalah kode orang lain: musl yang menjadi libc, busybox yang menyediakan perintah dasar, libssl3 yang mengurus enkripsi. Sebagian dari paket itu, pada versi tertentu, membawa cacat yang sudah dikenal dunia — lengkap dengan nomor identitas, skor keparahan, dan catatan cara mengeksploitasinya. Chapter ini memperkenalkan pemindaian image: apa itu CVE, bagaimana SBOM menjadi fondasinya, bagaimana Docker Scout membaca isi image dalam tiga perintah, dan — yang tidak kalah penting — bagaimana membaca hasilnya dengan bijak alih-alih panik.

CVE: Cacat yang Sudah Dikenal #

CVE (Common Vulnerabilities and Exposures) adalah katalog dunia untuk cacat keamanan perangkat lunak: setiap cacat yang dilaporkan dan dikonfirmasi mendapat nomor identitas seperti CVE-2025-31221, deskripsi cara mengeksploitasinya, dan skor dari 0 sampai 10 lewat sistem CVSS. Skor itulah yang diringkas menjadi empat tingkat keparahan:

TingkatCirinyaKebijakan umum
CRITICALsering dieksploitasi dari jarak jauh tanpa autentikasiblokir rilis
HIGHdieksploitasi dengan pra-syarat ringanperbaiki sebelum rilis
MEDIUMbutuh akses lokal atau kondisi khususjadwalkan perbaikan
LOWdampak terbatas atau sulit dieksploitasicatat dan pantau

Poin pentingnya: scanner tidak menemukan bug baru. Scanner mencocokkan isi image dengan katalog cacat yang sudah diketahui — dan pekerjaan itu menuntut inventoris isi image lebih dulu.

SBOM: Inventaris Sebelum Pemindaian #

Pemindaian dimulai dari SBOM (Software Bill of Materials): daftar seluruh paket dan berkas yang menyusun sebuah image, lengkap dengan nama, versi, dan asal-usulnya — paket apk dari Alpine, modul dari npm, berkas biner hasil build. Scanner bekerja dua langkah: menyusun SBOM dari isi image, lalu mencocokkan setiap entrinya dengan database CVE. Tanpa SBOM, tidak ada yang bisa dipindai; sebaliknya SBOM juga berharga sendiri sebagai dokumen audit — kegunaan yang akan kita rangkai penuh pada dua chapter berikutnya.

Docker Scout #

Docker Scout adalah pemindai yang menyatu dengan ekosistem Docker dan aktif dikembangkan pada 2026 — tersedia lewat CLI docker scout dan membaca image lokal maupun di registry. Tiga perintahnya membentuk ritual dari ringkas ke rinci, dan kita jalankan ketiganya pada image yang sama.

Perintah pertama memberi gambaran sepuluh detik:

bash
$ docker scout quickview katalog-web:2.0

Output yang Dihasilkan:

text
    ✓ Base image is up to date
    ⚠️  This image contains 9 packages with vulnerabilities

    1C     3H     9M     23L

Mari kita telaah tiga baris ringkas tersebut:

  1. ✓ Base image is up to date — node:22-alpine yang menjadi fondasi image ini adalah build terbaru dari tag-nya; kabar baik, karena sebagian besar paket sistem berasal dari sana.
  2. 9 packages with vulnerabilities — dari seluruh paket di dalam image, sembilan membawa minimal satu cacat yang dikenal; sisanya bersih menurut database.
  3. 1C 3H 9M 23L — rekapitulasi temuan per tingkat: satu CRITICAL, tiga HIGH, sembilan MEDIUM, dua puluh tiga LOW; total 36 temuan yang menunggu penelusuran.

Perintah kedua membuka tabel lengkapnya:

bash
$ docker scout cves katalog-web:2.0

Output yang Dihasilkan (dipotong):

text
### Overview

target:
  └─ katalog-web:2.0

    digest      sha256:4d8b2e7f1a6c9e3b5d7f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b
    os          alpine 3.20
    size        142MB
    packages    118
...
### CVEs found: 36 (1C 3H 9M 23L)

CVE ID          SEVERITY    AFFECTED PACKAGE    FIXED IN
CVE-2025-31221  CRITICAL    libssl3              3.3.2-r0
CVE-2025-31104  HIGH        libcrypto3           3.3.2-r0
CVE-2024-45578  HIGH        busybox              1.36.1-r8
CVE-2025-31087  MEDIUM      curl                 8.12.1-r1
CVE-2024-46381  MEDIUM      musl                 1.2.5-r2
...

Mari kita telaah bagian-bagian penting output tersebut:

  1. digest sha256:4d8b... — hasil pemindaian terikat pada digest image, bukan sekadar tag 2.0; ini janji yang sama dengan immutable identity pada Chapter Image Digest: tabel ini berlaku untuk byte-byte ini, dan tidak bisa digeser diam-diam.
  2. os alpine 3.20 — scanner tahu distribusi dan rilisnya, sehingga bisa mencocokkan advisori khusus Alpine; tanpa info OS — misalnya image distroless — pemetaan versi jauh lebih sulit.
  3. packages 118 — jumlah entrinya SBOM: gabungan paket apk dari Alpine dan modul dari npm; angka ini adalah bukti bahwa pemindaian benar-benar menyusuri isi, bukan sekadar label image.
  4. Kolom FIXED IN — versi tempat cacat diperbaiki: libssl3 3.3.2-r0, busybox 1.36.1-r8; kolom ini yang mengubah temuan menjadi pekerjaan — kita tahu harus naik ke versi apa.
  5. Satu upgrade menutup banyak temuan — libssl3 dan libcrypto3 berasal dari paket openssl yang sama; menaikkan keduanya ke 3.3.2-r0 sekaligus menyingkirkan temuan CRITICAL dan satu HIGH dari daftar.

Perintah ketiga memberi rekomendasi perbaikan, bukan sekadar daftar cacat:

bash
$ docker scout recommendations katalog-web:2.0

Output yang Dihasilkan (dipotong):

text
### Overview

target:
  └─ katalog-web:2.0

base:
  └─ node:22-alpine
...
### Recommendations

  1. Pin your base image by digest
  2. Rebase to node:23-alpine to resolve 4 vulnerabilities
...

Dua baris rekomendasi itu saling melengkapi: pindah ke base yang lebih segar (node:23-alpine) membawa paket sistem yang lebih baru dan menutup empat temuan sekaligus, sementara mematok base berdasarkan digest — pola dari Chapter Image Digest — memastikan image berikutnya dibangun dari fondasi byte yang persis sama dengan yang kita periksa hari ini.

Membaca Hasil dengan Bijak #

Tabel 36 temuan itu bukan vonis kematian; tabel itu adalah sinyal yang menuntut penilaian. Tiga pertanyaan menentukan prioritas setiap baris. Pertama, apakah kolom FIXED IN terisi? Cacat tanpa versi perbaikan tidak bisa ditutup dengan upgrade — pilihannya menunggu rilis, mengganti paket, atau menerima risiko secara sadar. Kedua, exploitability: apakah paket yang bermasalah benar-benar terpakai oleh aplikasi? curl yang terpasang hanya untuk HEALTHCHECK dan busybox yang menyediakan wget keduanya hadir karena alasan yang berbeda-beda; cacat pada paket yang tidak pernah dieksekusi tetap dicatat, tetapi risikonya jauh lebih rendah. Ketiga, exposure: apakah container ini menerima koneksi dari jaringan publik, atau hanya dari jaringan internal? CRITICAL pada libssl3 bermakna berbeda untuk service yang melayani internet dan untuk worker yang hanya bicara dengan database di network internal.

Kapan Memindai #

Pemindaian paling berharga tepat sebelum image naik ke produksi — itulah gerbang terakhir yang masih murah. Setelah itu, pemindaian menjadi rutinitas berjalan: setiap build di CI dipindai otomatis dengan ambang yang menolak atau meloloskan rilis — ritual yang dibangun tuntas pada Chapter Image Scanning di CI/CD — dan image yang sudah lama beredar dipindai ulang secara berkala, karena database CVE tumbuh terus: paket yang bersih hari ini bisa berstatus cacat besok pagi tanpa satu byte image berubah.

Bagi yang membutuhkan pemindai open source yang berdiri sendiri tanpa akun layanan apa pun, Trivy adalah alternatif yang banyak dipakai: trivy image katalog-web:2.0 mencetak daftar kerentanan yang dikelompokkan per tingkat keparahan dari database publiknya.

Kebijakan Toleransi Kerentanan #

Angka-angka quickview hanya berguna bila ada kebijakan yang menafsirkannya. Kebijakan yang lazim berbentuk ambang dan pengecualian:

Aturan kebijakanNilai yang lazim
Ambang CRITICAL0 — rilis ditolak otomatis
Ambang HIGHmaksimal 5, wajib tiket perbaikan
MEDIUM dan LOWdipantau, dibereskan pada siklus berikutnya
Pengecualiantercatat dengan alasan dan tanggal kedaluwarsa

Baris terakhir yang paling sering dilupakan: pengecualian tanpa batas waktu adalah cara halus berkata “kami tahu dan membiarkannya selamanya”. Pengecualian yang sehat mencantumkan alasan — misalnya paket tidak terpakai — dan tanggal kedaluwarsa yang memaksa keputusan diulang saat keadaan berubah.

Pemindaian menjawab satu pertanyaan besar — cacat apa yang dibawa image ini — dengan jawaban yang terikat pada digest tertentu. Tetapi pertanyaan lain sama pentingnya tetap menggantung: image ini dibangun oleh siapa, dari source apa, dengan builder yang bagaimana? Tag 2.0 bisa ditiru siapa pun yang punya akses push, dan tabel CVE tidak membedakan image asli dari tiruannya. Chapter Image Provenance membuktikan asal-usul image lewat attestation yang lahir bersama build: provenance, SBOM, dan tanda tangan yang terikat pada digest.

Referensi #