Container ve IaC Scanning: Image Zafiyetleri, Base Image Seçimi ve Manifest Taraması
Image taraması, deploy edilen artifact'taki işletim sistemi paketlerini ve uygulama bağımlılıklarını birlikte denetler; bulguların çoğu kullanılmayan paketlerden gelir ve chiseled, non-root bir base image bunları büyük ölçüde ortadan kaldırır. Bookstore image'ında 42 bulgunun 6'ya inişini, Trivy ile Grype'ın farkını, Mart 2026 Trivy olayından sonra tarayıcıyı SHA ve cosign imzasıyla doğrulamayı, Dockerfile, Kubernetes ve Terraform taramasını gerçek çıktılarla gösteriyoruz.
Sürüm notu: Bu yazıdaki kodlar .NET 10 ile derlenip denenmiştir; image'lar mcr.microsoft.com/dotnet/aspnet:10.0 (Ubuntu 24.04) tabanlı, taramalar Trivy 0.76.2, Grype 0.121.3, hadolint 2.15.1 ve cosign 3.1.4 ile 13–14 Kasım 2026 tarihli zafiyet veritabanlarıyla çalıştırılmıştır.
Önce Tahmin Et
Bookstore API'nin image'ı yıllardır aynı Dockerfile'dan çıkıyor: tam aspnet base image'ı, health check için kurulmuş curl ve root kullanıcı. Kodun kendisinde bilinen bir zafiyet yok; NuGetAudit temiz. Tahmin et: Trivy bu image'da kaç zafiyet bulur? Base image'ı chiseled bir image ile değiştirince bu sayı ne olur? Ve bir soru daha: pipeline'daki tarayıcının action tag'i bir gece başka bir commit'e yönlendirilse, bunu fark eder misin?
Bu yazıda container image'larını ve IaC (Infrastructure as Code) dosyalarını tarıyoruz: image'daki işletim sistemi paketleri ile uygulama bağımlılıklarının farkı, chiseled image'ların saldırı yüzeyini nasıl küçülttüğü, iki tarayıcının aynı image için neden farklı sayılar verdiği, Dockerfile ve Kubernetes manifest kontrolleri ve Mart 2026'daki Trivy olayının bize öğrettiği şey: tarayıcının kendisi de supply chain'in parçası.
Image'da Ne Var: İşletim Sistemi Paketleri ve Uygulama Bağımlılıkları
Image'ın Dockerfile'ı şu (SDK aşamasında cross-compile için BUILDPLATFORM kullanılıyor; Dockerfile tasarımının ayrıntısı Docker serisinin konusu):
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:10.0 AS build
ARG TARGETARCH
WORKDIR /src
COPY . .
RUN dotnet publish src/Bookstore.Api -c Release -a $TARGETARCH -o /app
FROM mcr.microsoft.com/dotnet/aspnet:10.0
RUN apt-get update && apt-get install -y curl
WORKDIR /app
COPY --from=build /app .
HEALTHCHECK CMD curl -f http://localhost:8080/health || exit 1
ENTRYPOINT ["dotnet", "Bookstore.Api.dll"]
docker build --platform linux/amd64 -f Dockerfile.v1 -t bookstore-api:v1 .
trivy image --scanners vuln bookstore-api:v1
bookstore-api:v1 (ubuntu 24.04)
Total: 42 (UNKNOWN: 0, LOW: 5, MEDIUM: 37, HIGH: 0, CRITICAL: 0)
Kırk iki bulgunun hepsi Ubuntu paketlerinde: libc6, libgnutls30t64, tar, dash ve Kerberos kütüphaneleri gibi. Uygulamanın deps.json'ı ve .NET runtime'ının kendi deps.json dosyaları da tarandı ve temiz çıktı. Bir image tarayıcısı iki ayrı şeye bakar: paket yöneticisinin veritabanından okuduğu işletim sistemi paketleri ve dil ekosistemlerinin dosyalarından okuduğu uygulama bağımlılıkları. İkinci kısmı görmek için aynı uygulamayı eski SqlClient 5.1.1 ile build ettim:
app/Bookstore.Api.deps.json (dotnet-core)
Total: 6 (UNKNOWN: 0, LOW: 0, MEDIUM: 4, HIGH: 2, CRITICAL: 0)
Bunlar üçüncü yazıda NuGetAudit'in bulduğu advisory'lerin aynısı. Peki zaten restore'da yakalıyorsak image'da neden tekrar tarıyoruz? Çünkü image deploy edilen gerçek artifact'tır; bir publish ayarı, bir multi-stage hatası ya da başka bir projeden kopyalanan bir DLL restore'un görmediği bir şeyi image'a sokabilir. Image taraması, "ne çalıştırıyoruz" sorusunun son cevabı.
Base Image Seçimi: Chiseled ve Non-root
42 bulgunun çoğu, uygulamanın hiç kullanmadığı paketlerden geliyor. Microsoft'un chiseled image'ları Ubuntu'nun yalnız .NET'in çalışması için gereken parçalarını içerir: shell yok, paket yöneticisi yok, ve varsayılan olarak non-root bir kullanıcı tanımlı. Aynı uygulamanın ikinci Dockerfile'ı:
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:10.0 AS build
ARG TARGETARCH
WORKDIR /src
COPY . .
RUN dotnet publish src/Bookstore.Api -c Release -a $TARGETARCH -o /app
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled
WORKDIR /app
COPY --from=build /app .
USER $APP_UID
ENTRYPOINT ["dotnet", "Bookstore.Api.dll"]
| Image | Boyut | Kullanıcı | İşletim sistemi bulgusu | Fix'i olan |
|---|---|---|---|---|
v1: aspnet:10.0 + curl | 141 MB | root (uid=0) | 42 (37 medium, 5 low) | 13 |
v2: aspnet:10.0-noble-chiseled | 58.7 MB | 1654 | 6 (medium) | 6 |
Bulgu sayısı 42'den 6'ya, boyut 141 MB'tan 58.7 MB'a indi. v1'de docker run ... id uid=0(root) döndürdü; v2'de ise sh çalıştırma denemesi "executable file not found" ile reddedildi, çünkü image'da shell yok. Container'ı başlatıp /covers/1'e istek attım, uygulama 8080'de dinledi ve 404 döndü; yani non-root ve shell'siz image'da uygulama normal çalışıyor. Root olmayan kullanıcı, container'dan kaçış senaryolarında saldırganın elindeki yetkiyi azaltır; shell olmaması ise bir RCE (saldırganın sunucuda uzaktan kod çalıştırabilmesi) durumunda kullanılabilecek araçları ortadan kaldırır.
İki uyarı. Birincisi, chiseled image'larda DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true set edilmiş; ICU (dil ve kültür kurallarını uygulayan Unicode kütüphanesi) yok. Türkçe sıralama ve kültüre özgü biçimlendirme gereken Bookstore gibi bir uygulamada ICU ve saat dilimi verisini içeren -noble-chiseled-extra varyantını seç. İkincisi, kalan 6 bulgunun hepsi libc6 2.39-0ubuntu8.9'da ve fix'i 2.39-0ubuntu8.12'de. Chiseled image'da apt olmadığı için bunu image içinde yükseltemezsin; düzeltme base image'ın yeni sürümüyle gelir. Bu yüzden image'ı düzenli olarak yeniden build etmek, base image'ı seçmek kadar önemli.
Trivy ve Grype: Aynı Image, Farklı Sayılar
Aynı v2 image'ını Grype ile taradım:
grype bookstore-api:v2 --platform linux/amd64
NAME INSTALLED FIXED IN TYPE VULNERABILITY SEVERITY EPSS RISK
libc6 2.39-0ubuntu8.9 deb CVE-2026-100290 Medium 0.3% (27th) 0.2
libc6 2.39-0ubuntu8.9 2.39-0ubuntu8.12 deb CVE-2026-8674 Medium 0.3% (24th) 0.2
libc6 2.39-0ubuntu8.9 2.39-0ubuntu8.12 deb CVE-2026-84243 Medium 0.3% (22nd) 0.1
libc6 2.39-0ubuntu8.9 2.39-0ubuntu8.12 deb CVE-2026-97399 Medium 0.3% (20th) 0.1
libc6 2.39-0ubuntu8.9 deb CVE-2026-115819 Medium 0.3% (18th) 0.1
libc6 2.39-0ubuntu8.9 (won't fix) deb CVE-2016-20013 Negligible 2.2% (82nd) 0.1
libssl3t64 3.0.13-0ubuntu3.16 deb CVE-2026-95692 Medium 0.2% (11th) 0.1
openssl 3.0.13-0ubuntu3.16 deb CVE-2026-95692 Medium 0.2% (11th) 0.1
...
Grype 19 eşleşme verdi: 6'sı fix'li (Trivy'nin bulduğu 6 bulgunun aynısı), 12'si henüz fix'i olmayan, 1'i dağıtımın "düzeltilmeyecek" olarak işaretlediği bir bulgu. --only-fixed ile Grype da aynı 6 bulguya iniyor. Fark, tarayıcıların Ubuntu güvenlik verisini nasıl yorumladığında ve fix'i olmayan kayıtları varsayılan olarak gösterip göstermediğinde. Grype'ın ayrıca EPSS (bir zafiyetin istismar edilme olasılığını tahmin eden skor) sütunu ve bir risk skoru göstermesi, üçüncü yazıdaki önceliklendirmeyi doğrudan destekliyor.
Ders: tarayıcı sayılarını mutlak gerçek sayma, aynı image için iki tarayıcı arasında fark olması normal. Pipeline'da tek bir tarayıcıyı gate olarak seç ve onun davranışını iyi tanı; ikincisini periyodik bir karşılaştırma için kullan. Gate'i "fix'i olan critical ve high" üzerine kurmak bu farkların çoğunu nötrler: v1'de --ignore-unfixed ile 42 bulgu 13'e iniyor ve --severity CRITICAL,HIGH --ignore-unfixed --exit-code 1 her iki image için de 0 dönüyor. SqlClient 5.1.1'li image ise aynı gate'te 1 döndü.
Tarayıcı da Supply Chain'dir: Mart 2026 Trivy Olayı
Aqua Security'nin olay değerlendirmesine göre saldırganlar Şubat 2026'nın sonunda Trivy'nin GitHub Actions ortamındaki bir configuration hatasından yetkili bir token elde etti; 1 Mart'taki credential rotation eksik kaldı. 19 Mart 2026'da aquasecurity/trivy-action'ın 77 sürüm tag'inden 76'sı ve setup-trivy'nin bütün tag'leri kötü niyetli commit'lere yönlendirildi, aynı gün zararlı bir Trivy binary'si (0.69.4) yayımlandı; 22 Mart'ta Docker Hub'a zararlı 0.69.5 ve 0.69.6 image'ları kondu. Zararlı action, gerçek taramayı yapmadan önce runner'daki secret'ları toplayıp dışarı gönderiyordu, yani workflow'lar normal görünüyordu. Aqua'nın önerileri arasında güvenli sürümlere geçmek, etkilenmiş pipeline'ların erişebildiği bütün secret'ları rotate etmek ve action'ları tag yerine tam commit SHA'sıyla (yaygın kullanılan hash algoritması ailesi) sabitlemek vardı.
Buradan Bookstore için üç kural çıkıyor. Birincisi, action'ı tag'le değil SHA ile sabitle: bir tag taşınabilir, bir commit SHA'sı taşınamaz. Mekaniği GitHub Actions serisinin "GitHub Actions Güvenliği: SHA Pinning, Lockfile, pull_request_target ve Script Injection'dan Korunmak" yazısında. İkincisi, binary indiriyorsan imzasını doğrula. Trivy 0.68.1'den beri her release asset'i için bir Sigstore bundle'ı (.sigstore.json) yayımlıyor; cosign ile doğrulama, binary'nin Trivy'nin kendi release workflow'undan çıktığını kontrol eder:
cosign verify-blob trivy_0.76.2_Linux-64bit.tar.gz \
--bundle trivy_0.76.2_Linux-64bit.tar.gz.sigstore.json \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
--certificate-identity "https://github.com/aquasecurity/trivy/.github/workflows/reusable-release.yaml@refs/tags/v0.76.2"
Verified OK
Aynı komutu beklenen kimliği başka bir repo olarak yazarak çalıştırdım; cosign failed to verify certificate identity: no matching CertificateIdentity found hatasıyla 1 döndü. Yalnız checksum doğrulamak, checksum dosyası ile binary'yi aynı yerden indirdiğin için tek başına yetmez; ele geçirilmiş bir release ikisini birden değiştirebilir. İmza ise belirli bir workflow kimliğine bağlıdır. Keyless imzalamanın nasıl çalıştığını serinin sekizinci yazısında ayrıntılı görüyoruz. Üçüncüsü, tarama job'ına deploy credential'ı verme: tarayıcının ihtiyacı image ve okuma yetkisi; secret'a erişemeyen bir job'dan secret çalınamaz.
name: image
on:
push:
branches: [main]
permissions:
contents: read
jobs:
image:
runs-on: ubuntu-latest
env:
TRIVY_VERSION: 0.76.2
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: sigstore/cosign-installer@756fe2d284c7292c4e9b62c8a28f1e5629c59532 # v4.1.3
- name: Install and verify Trivy
run: |
base="https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}"
file="trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz"
curl -sSfL -o "$file" "$base/$file"
curl -sSfL -o "$file.sigstore.json" "$base/$file.sigstore.json"
cosign verify-blob "$file" --bundle "$file.sigstore.json" \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
--certificate-identity "https://github.com/aquasecurity/trivy/.github/workflows/reusable-release.yaml@refs/tags/v${TRIVY_VERSION}"
tar -xzf "$file" trivy
- run: docker build -t "bookstore-api:$GITHUB_SHA" .
# fix'i olan critical/high build'i kırar; gerisi raporlanır
- run: ./trivy image --exit-code 1 --severity CRITICAL,HIGH --ignore-unfixed "bookstore-api:$GITHUB_SHA"
- run: ./trivy config --exit-code 1 --severity CRITICAL,HIGH --ignorefile .trivyignore.yaml deploy
Workflow'u actionlint ile doğruladım; doğrulama komutunu Linux asset'i üzerinde yerelde çalıştırdım, iki tarama komutunu da Bookstore image'ı ve deploy klasörü üzerinde. Action kullanmayı tercih edersen aquasecurity/trivy-action'ı da tam SHA'yla sabitle; yazı yazılırken son sürüm v0.36.0'dı.
IaC: Dockerfile, Kubernetes Manifest'i ve Terraform
Image'ı oluşturan dosyalar da kod. Dockerfile linter'ı hadolint, v1 için dört kural ihlali buldu:
Dockerfile.v1:8 DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
Dockerfile.v1:8 DL3009 info: Delete the apt lists (/var/lib/apt/lists) after installing something
Dockerfile.v1:8 DL3015 info: Avoid additional packages by specifying `--no-install-recommends`
Dockerfile.v1:11 DL3025 warning: Use arguments JSON notation for CMD and ENTRYPOINT arguments
Trivy'nin config taraması aynı Dockerfile'da 27 kontrolün ikisini başarısız buldu, ikisi de high: DS-0002 (non-root bir USER yok) ve DS-0029 (--no-install-recommends eksik). v2'de tek bulgu DS-0026 (low): HEALTHCHECK yok. Bookstore Kubernetes'te çalıştığı ve Kubernetes Dockerfile'daki HEALTHCHECK'i değil kendi probe'larını kullandığı için bu bulguyu bilinçli olarak kabul ediyoruz. hadolint de v2 için USER $APP_UID satırında bir info notu (DL3066) düştü; hadolint'i --failure-threshold warning ile çalıştırınca bu satır build'i kırmıyor.
Kubernetes manifest'inde durum daha kötüydü. İlk deployment, birinin "dosya izni sorunu"nu çözmek için eklediği privileged: true dışında hiçbir güvenlik ayarı içermiyordu ve Trivy 18 bulgu verdi; aralarında high olarak KSV-0017 (privileged), KSV-0014 (root dosya sistemi yazılabilir) ve KSV-0118 (varsayılan security context) vardı. Kubernetes serisinin RBAC (kullanıcının rolüne göre yetki verme modeli) ve securityContext'i işleyen "Kubernetes Güvenliği: ServiceAccount, RBAC, Pod Security Standards, securityContext ve NetworkPolicy" yazısındaki restricted profile ayarlarıyla düzelttik:
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookstore-api
namespace: bookstore
spec:
replicas: 2
selector:
matchLabels:
app: bookstore-api
template:
metadata:
labels:
app: bookstore-api
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1654
runAsGroup: 1654
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: ghcr.io/bookstore/bookstore-api:1.4.0
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
Bulgu sayısı 18'den 3'e indi: iki low (KSV-0020 ve KSV-0021, UID (Linux'ta kullanıcı numarası) ve GID'nin (Linux'ta grup numarası) 10000'den büyük olmasını öneriyor) ve bir medium (KSV-0125, image'ların güvenilir registry'lerden gelmesi). readOnlyRootFilesystem için /tmp'e bir emptyDir bağladık; ASP.NET Core büyük request body'lerini ve bazı geçici dosyaları /tmp'ye yazabiliyor.
Terraform tarafına kısaca bakalım. Kapak resimlerini tutacak bir Azure storage account tanımı min_tls_version = "TLS1_0" ile yazılmıştı; Trivy altı bulgu verdi, ikisi critical: TLS 1.0 ve network kurallarında varsayılan erişimin açık olması. min_tls_version = "TLS1_2", https_traffic_only_enabled = true ve default_action = "Deny" olan bir network_rules bloğu ekleyince high olarak AZU-0010 (Azure servislerinin bypass erişimi) çıktı; bypass = ["AzureServices"] ile critical ve high bulgu kalmadı, logging, geo-redundancy ve infrastructure encryption için iki medium ve bir low raporda duruyor. Terraform dosyasını terraform plan ile denemedim, yalnız Trivy ile taradım; Terraform'un kendisi Infrastructure as Code: Terraform serisinin konusu.
İstisnalar: Gerekçeli ve Süreli .trivyignore.yaml
Kalan üç Kubernetes bulgusu için karar verdik: UID 1654, chiseled image'ın kendi app kullanıcısı ve onu remap etmek yerine olduğu gibi kullanıyoruz; registry kısıtını ise sekizinci yazıda admission policy ile cluster seviyesinde uygulayacağız. Trivy'nin YAML formatlı ignore dosyası her istisna için bir gerekçe (statement) ve bir son kullanma tarihi (expired_at) alabiliyor; Trivy dokümantasyonu bu formatı deneysel olarak işaretliyor:
misconfigurations:
- id: KSV-0020
paths: ["k8s/deployment.yaml"]
statement: The chiseled image's app user is UID 1654; we keep it instead of remapping.
- id: KSV-0021
paths: ["k8s/deployment.yaml"]
statement: Same as KSV-0020 for the app group.
- id: KSV-0125
statement: Admission policy restricts registries to ghcr.io/bookstore (post 8).
expired_at: 2027-03-31
İki deneme yaptım. expired_at'i 2026-11-01'e çekince KSV-0125 bulgusu geri geldi; süresi dolan istisna sessizce kalmıyor. İkincisi bir tuzaktı: taramayı deploy/k8s klasörüne karşı çalıştırdığımda KSV-0020 ve KSV-0021 bastırılmadı, çünkü paths taranan hedefe göre göreceli ve o taramada dosyanın yolu deployment.yaml idi. Taramayı her zaman aynı kökten (deploy) çalıştırınca üç istisna da doğru uygulandı ve Kubernetes manifest'i sıfır bulguyla geçti.
Build Anında mı, Registry'de mi? Fix'i Olmayan Zafiyetler
Build anındaki tarama, o günün zafiyet veritabanıyla yapılır. Bugün temiz geçen bir image, yarın yayımlanan bir CVE (yayımlanmış güvenlik açıklarının standart kimlik numarası) için hâlâ production'da çalışıyor olacak. Bu yüzden iki tarama gerekir: build anında, yeni zafiyetin production'a girmesini engelleyen gate; ve deploy edilmiş image'ları düzenli tarayan bir job. İkincisi için cloud registry'lerin kendi tarama özellikleri ya da deploy edilen image digest'lerini her gün tarayan zamanlanmış bir job kullanılabilir. Daha hafif bir yol da image yerine image'ın SBOM'unu (yazılımın içerdiği bileşenlerin listesi) saklamak ve onu taramak:
trivy image --format cyclonedx -o bookstore-api.cdx.json bookstore-api:legacy
trivy sbom --severity HIGH,CRITICAL bookstore-api.cdx.json
Total: 2 (HIGH: 2, CRITICAL: 0)
Image'ı yeniden çekmeden aynı iki high bulgu (Azure.Identity ve SqlClient) SBOM üzerinden geldi. SBOM'u üretmeyi, saklamayı ve sorgulamayı serinin yedinci yazısında ayrıntılı kuruyoruz.
Fix'i olmayan zafiyetlerle yaşamak da işin parçası. v2'deki Grype çıktısında 12 bulgunun henüz fix'i yok. Bunlar için gate'i kırmak hiçbir şey kazandırmaz, çünkü geliştiricinin yapabileceği bir şey yok; ama görmezden gelmek de doğru değil. Doğru yaklaşım bulguyu izlemek, fix yayımlandığında base image güncellemesiyle almak ve "bu bizi etkilemiyor, çünkü..." diyebildiğin durumları makine okunur bir beyana dönüştürmek. O beyanın adı VEX (bir zafiyetin üründe gerçekten istismar edilebilir olup olmadığını bildiren doküman) ve yedinci yazının konusu.
Üretimde Dikkat
Base image'ı digest ile sabitlemek tekrarlanabilirlik verir ama güncellemeyi senin sorumluluğuna bırakır. Tag kullanıyorsan image'ı düzenli rebuild et; digest kullanıyorsan Dependabot ya da Renovate gibi bir botun base image digest'ini güncellemesine izin ver. Her iki durumda da hedef, base image'daki düzeltmenin günler içinde production'a ulaşması.
Tarayıcı veritabanını da bir bağımlılık say. Trivy ve Grype taramadan önce zafiyet veritabanını indirip cache'te tutar; ağa erişimi kısıtlı runner'larda bu adım sessizce başarısız olup eski veritabanıyla tarama yapılmasına yol açabilir. Pipeline log'unda veritabanı tarihini gör; Grype'ın JSON (JavaScript Object Notation) çıktısındaki veritabanı build zamanı bunun için kullanışlı.
Aynı image'ı birden fazla job'ta tarıyorsan sonuçları SARIF (statik analiz sonuçları için standart JSON formatı) olarak code scanning'e yükleyip tek yerde görmek, dördüncü yazıdaki SAST (kaynak kodu çalıştırmadan tarayan güvenlik testi) bulgularıyla aynı triage akışını kullanmanı sağlar.
Sık Düşülen Tuzaklar
Birincisi, action'ı tag'le kullanmak. Mart 2026 olayı tag'lerin taşınabildiğini somut olarak gösterdi; SHA ile sabitle ve güncellemeyi bir PR ile al.
İkincisi, binary'yi yalnız checksum ile doğrulamak. Checksum ve binary aynı kaynaktan geliyorsa ele geçirilmiş bir release ikisini de değiştirir; imza doğrulaması beklenen workflow kimliğini de kontrol eder.
Üçüncüsü, chiseled image'a geçip globalization ayarını unutmak. Invariant mode'da Türkçe kültür kuralları çalışmaz; ICU gerekiyorsa -extra varyantını kullan.
Dördüncüsü, "image temiz" sonucunu kalıcı saymak. Bugünün taraması bugünün veritabanıyla yapıldı; registry'deki image'lar düzenli yeniden taranmalı.
Beşincisi, Kubernetes bulgularını privileged: true gibi kestirme ayarlarla susturmak. Bir izin sorununu privileged container'la çözmek, sorunu güvenlik açığına çevirir.
Küçük Bir Deneme
★☆☆ Projenin image'ını Trivy ile tara, bulguları işletim sistemi paketleri ve uygulama bağımlılıkları olarak ayır. Kaç tanesinin fix'i var?
★★☆ Aynı uygulamayı aspnet:10.0 ve aspnet:10.0-noble-chiseled-extra ile build et; boyut, kullanıcı ve bulgu sayısını karşılaştır, sonra uygulamanın chiseled image'da gerçekten çalıştığını bir istekle doğrula.
★★★ Pipeline'ındaki her tarayıcı action'ını ve indirilen her binary'yi listele. Hangileri tag ile kullanılıyor, hangilerinin imzası doğrulanıyor? Birini SHA'ya sabitle, bir binary için cosign verify-blob adımını ekle ve yanlış bir kimlikle adımın kırıldığını gör.
Image'ları ve altyapı dosyalarını statik olarak taradık; ama bazı açıklar ancak uygulama çalışırken görünür: eksik bir header, yanlış bir cookie flag'i, bir hata sayfasının sızdırdığı bilgi. Bir sonraki yazıda DAST'a (çalışan uygulamaya dışarıdan saldırarak yapılan güvenlik testi) geçip ZAP (açık kaynak web güvenlik tarama aracı) ile çalışan Bookstore'u tarayacağız.