Yazılara geri dön
Yazı

CI/CD Pipeline Güvenlik Açıkları: DevOps Süreçlerinde Sızan Zafiyetler

CI/CD süreçlerinde sızan secret'lardan yetki aşımı yapmış runner'lara kadar güvenlik açıklarını ve pipeline'ınızı sağlamlaştırmak için pratik adımları anlatıyorum.

DevopsDevOpsCI/CD SecurityPipeline VulnerabilitiesSecret ManagementSupply Chain SecurityDevSecOpsArtifact Signing

DevOps süreçlerindeki güvenlik açıkları genelde tek bir büyük hatadan doğmaz. CI/CD zincirinizdeki küçük yanlış yapılandırmalar birikiyor — YAML dosyalarına gömülmüş secret'lar, çok yetkili runner'lar üzerinde çalışan güvenilmeyen kod, imza doğrulaması olmayan artifact registry'leri ve repo erişimi olan herkesin okuyabileceği plaintext'te duran deployment credential'ları. Bu desenleri pek çok ortamda tekrar tekrar gördüm ve kök neden neredeyse her zaman hızın güvenliğe tercih edilmesi.

Daha önce DevOps kültürü hakkındaki yazımda da değindiğim gibi (https://furkanikkan.com/urun/devops-kulturu-nedir-yazilim-ekiplerini-nasil-degistirir-42), daha hızlı teslim etme baskısı işe yarıyor — ta ki yaramayana kadar. Pipeline'ınız artık altyapınızdaki en yetkili sistem — production'a deploy edebilir, veritabanlarına erişebilir, image push'layabilir. Bu da onu birincil hedef yapıyor.

CI/CD Yapılandırma Dosyalarından Sızan Secret'lar

En sık gördüğüm zafiyet, secret'ların doğrudan pipeline tanımlarında saklanması. Geliştiriciler API key'lerini, veritabanı şifrelerini ve cloud credential'larını doğrudan .gitlab-ci.yml, Jenkinsfile veya GitHub Actions workflow'larına yapıştırıyorlar — çünkü hızlı ve kendi makinelerinde çalışıyor.

Sorun o dosya version control'e düştüğünde patlıyor. Artık secret'larınız git history'sinde sonsuza dek duruyor — mevcut sürümden kaldırsanız bile.

# Git history'sinde secret sızdırıp sızdırmadığınızı kontrol edin
git log -p | grep -iE '(password|secret|token|api_key|AWS_SECRET)'

Bunun yerine CI platformunuzun secret yönetimini kullanın — GitLab CI/CD değişkenleri, GitHub encrypted secret'ları, Jenkins credential store'u. Maskeli olarak işaretleyin ki log'larda görünmesinler. Ve version control'e commit edilmiş her secret'ı rotate edin, çünkü zaten compromise edildiğini varsaymanız gerekiyor.

Aşırı Yetkili CI Runner'ları ve Build Agent'ları

Bu konu geceleri uyutmuyor beni. CI runner'ınız repodan rastgele kod çalıştırıyor — build script'leri, test komutları, npm paketlerinden post-install hook'ları. O runner'ın production deployment erişimi varsa veya root olarak çalışıyorsa, compromise edilmiş bir dependency'den production ortamınıza giden düz bir yolu saldırgana teslim etmişsiniz demektir.

Benim ortamımda şunları yapıyorum:

  • Build agent'larını her işten sonra yok edilen izole container veya VM'lerde çalıştırıyorum
  • Runner'lara asla uzun ömürlü cloud credential'ı vermiyorum — OIDC federation veya kısa ömürlü token kullanıyorum
  • Build runner'ları ile deploy runner'larını ayırıyorum — kod build etmek ve kod deploy etmek aynı kimliği paylaşmamalı
  • Runner'lardan egress trafiğini kısıtlıyorum, böylece compromise edilseler bile kolayca dışarı bağlanamazlar

Daha önce sudo ile en az yetki konusunu işlerken söylediğim gibi (https://furkanikkan.com/urun/root-yetkisi-vermeden-linux-sistem-yonetimi-sudo-ile-en-az-yetki-46), aynı prensip burada da geçerli: pipeline bileşenlerinize yalnızca kesinlikle ihtiyaç duydukları erişimi verin, fazlasını değil.

Güvenilmeyen Dependency'ler ve Supply Chain Saldırıları

Pipeline'ınız otomatik olarak yüzlerce dependency çekiyor. npm paketleri, PyPI modülleri, Docker base image'ları, Terraform provider'ları — her biri potansiyel bir giriş noktası. Solarwinds saldırısı, compromise edilmiş bir build toolchain'inin ne kadar yıkıcı olabileceğini gösterdi ve benzer saldırılar npm ve PyPI paketlerini düzenli olarak vuruyor.

Korkutucu olan kısım, kötü niyetli paketi doğrudan kullanmanız gerekmemesi. Transitive dependency — gerçekten kullandığınız bir kütüphanenin çektiği bir şey — yeterli.

Yardımcı olan birkaç şey:

  • Dependency sürümlerini lockfile'larla sabitleyin (package-lock.json, poetry.lock, hash'li requirements.txt)
  • Pipeline'ınızda dependency taraması açın — Dependabot, Snyk, GitLab Dependency Scanning
  • Docker base image'larında latest çekmek yerine digest doğrulaması yapın
  • Kritik Python deployment'larında pip install --require-hashes kullanın
# Örnek: pipeline'da digest ile sabitleme
image:
  name: myregistry.com/app-base:latest
  # Kötü - tag üzerine yazılabilir

image:
  name: myregistry.com/app-base@sha256:abc123...
  # İyi - değiştirilemez digest

Artifact Tampering ve İmzasız Deployment'lar

Çalıştığım ekiplerin çoğu Docker image build edip hiç imzalamadan registry'ye push'luyor. Birisi sızdırılmış credential'lar, compromise edilmiş CI hesabı veya yanlış yapılandırılmış IAM policy'si aracılığıyla o registry'ye yazma erişimi kazanırsa, production image'ınızı kötü niyetli biriyle değiştirebilir ve pipeline'ınız onu memnuniyetle deploy eder.

Artifact signing tam burada devreye giriyor. Cosign (Sigstore'un parçası) veya Notary gibi araçlar build zamanında image'leri imzalamanızı, deploy zamanında doğrulamanızı sağlar. İmza eşleşmezse, deployment durur.

# Cosign ile image imzalama
cosign sign --key cosign.key myregistry.com/app:v1.2.3

# Deploy etmeden önce doğrulama
cosign verify --key cosign.pub myregistry.com/app:v1.2.3

Pipeline'ınıza bir adım ekliyor, evet. Ama alternatif, her seferinde doğrulanmamış kodu production'a deploy etmek.

Pipeline as Code: CI Konfig'iniz Saldırı Yüzeyi Olduğunda

Ekiplerin gözden kaçırdığı bir şey daha var: pipeline yapılandırma dosyalarınızın kendisi kod ve uygulama kodunuzla aynı incelemeyi gerektiriyor. Kötü niyetli bir pull request, CI konfig'ini değiştirip secret'ları dışarı sızdırabilir, test'leri atlayabilir veya build sürecine komut enjekte edebilir.

CI/CD konfig dosyalarındaki her değişiklik için onay şartı koyuyorum. Branch protection rule'ları, zorunlu review'lar ve pipeline tanımlarını kimlerin değiştirebileceğini kısıtlamak — bunlar bürokratik yük değil, güvenlik kontrolüdür.

# Workflow dosyaları için GitHub branch protection
paths:
  - '.github/workflows/*'
  - 'Jenkinsfile'
  - '.gitlab-ci.yml'
required_reviews: 2
restrict_pushes: true

Pipeline Aktivitesini İzleme ve Anomali Tespiti

İzlemediğiniz şeyi güvene alamazsınız. Tüm CI/CD log'larını merkezi bir logging sistemine gönderiyorum ve olağandışı desenler için alert'ler kuruyorum — mesai saatleri dışında çalışan bir pipeline, aniden yeni secret'lara erişmeye başlayan bir job, deploy etmemesi gereken branch'lerden gelen deployment'lar.

Bu, saldırganların şirketleri nasıl ihlal ettiği hakkındaki yazımla bağlantılı (https://furkanikkan.com/urun/saldirganlar-sirketleri-nasil-ihlal-eder-gercek-saldiri-senaryolari-41) — ilk erişim genelde sessiz oluyor ve hasar, pivot atabilecekleri yetkili bir sistem bulduklarında gerçekleşiyor. CI/CD pipeline'ınız tam olarak böyle bir sistem.

İpucu: Yeni runner kaydı, repolara eklenen yeni deploy key'leri veya pipeline yetkilerindeki değişiklikler için notification kurun. Bunlar düşük frekanslı, yüksek sinyalli olaylar ve genelde araştırmaya değer bir şeyler olduğunu gösterir.

Pipeline'ınızı Bugün Sağlamlaştırmak İçin Pratik Adımlar

Bunu okuyorsanız ve pipeline'ınızda açıklar olduğunu fark ediyorsanız, panik yapmayın. Şuradan başlardım ben:

  1. trufflehog veya gitleaks gibi araçlarla repolarınızı commit edilmiş secret'lar için denetleyin
  2. Version control'de bulunmuş her secret'ı rotate edin — sızdırılmış varsayın
  3. CI runner'larınızın gerçekten sahip olduğu yetkiler ile ihtiyaç duyduğu yetkileri karşılaştırın
  4. Henüz yapmadıysanız pipeline'ınızda SAST ve dependency taraması açın
  5. Bir sonraki production deploy'undan önce image signing uygulayın
  6. Pipeline yapılandırma dosyalarını kimlerin değiştirebileceğini kısıtlayın

Mükemmel güvenli bir pipeline hedefi değil — öyle bir şey yok. Amaç saldırı yüzeyini küçültmek, böylece bir şeyler ters gittiğinde — ve gidecek — patlama yarıçapı kontrol edilebilir boyutta kalır.

CI/CD pipeline'ınız artık altyapınızın kritik bir parçası. Ona göre davranın.


Kapak görseli: HD Wallpapers · CC0 (Openverse / kamu malı) · https://stocksnap.io/photo/light-abstract-V9L6XXK3LB