kertenkerem_
· DevOps · 2 dk okuma

CI/CD pipeline güvenliği: bağımlılıklarınızı ghost paketlerden temizleyin

Modern bir devops pratiğinde yazılımın sadece derlenen kodu değil, o kodu taşıyan bağımlılık ağacı da bir saldırı vektörüdür. Pipeline güvenliği süreçlerinde genellikle yeni paketlerin taranmasına odaklanılırken, projelerin kıyısında köşesinde kalmış ve artık kimsenin dokunmadığı ghost paketler büyük bir risk oluşturur. Bu paketler yazılım güvenliği açısından supply chain saldırılarına davetiye çıkarır.

Ghost paketlerin yarattığı risk

Bir paket, package.json ya da requirements.txt dosyasında tanımlı olup hiçbir kod bloğunda çağrılmıyorsa ona ghost paket diyoruz. Bu paketler genellikle bir refactoring süreci sonrası temizlenmemiş artıklardır. Güvenlik tarayıcıları bu paketleri yüklü olarak gördüğü için bir CVE yayınlandığında CI/CD hattınız hata verir. Kullanmadığınız bir paket için yama yapmak, zaman kaybı olduğu kadar, gereksiz bir bağımlılığı sisteminizde tutmanın getirdiği risk yönetim zafiyetidir.

Kritik bir güvenlik zafiyeti, bağımlılık ağacının derinliklerinde bir ghost pakette ortaya çıkabilir. Eğer bu paket projenin runtime sürecinde yer almıyorsa, CI/CD pipeline süreçlerini boş yere durdurarak false positive vakaları oluşturur. Temiz bir dependency grafiği, saldırı yüzeyini daraltmanın en pratik yoludur.

Bağımlılıkları tespit etme

JavaScript ekosisteminde çalışan bir projede hangi paketlerin gerçekten import edildiğini bulmak için depcheck aracını kullanabilirsiniz. Bu araç, projeyi tarayarak kullanılan ve kullanılmayan paketleri listeler.

npx depcheck --ignores="eslint,jest"

Benzer şekilde Python projelerinde deptry, PEP 621 standartlarına uygun olarak hangi paketlerin gereksiz olduğunu tespit etmekte başarılıdır. deptry, kütüphanelerin import edildiği yerleri statik analiz ile tarar ve pyproject.toml dosyanızdaki tanımlarla karşılaştırır.

pip install deptry
deptry .

Pipeline içerisinde otomatize temizlik

Bu süreci bir pipeline aşaması haline getirmek, ghost paketlerin birikmesini engeller. Aşağıdaki örnek, bir GitLab CI job bloğunda depcheck kullanımını gösterir. Eğer kullanılmayan paketler bulunursa pipeline başarısız olur ve mühendisin manuel temizlik yapması sağlanır.

check-unused-deps:
  stage: test
  script:
    - npm install
    - npx depcheck --json > result.json
    - if [ $(jq '.dependencies | length' result.json) -gt 0 ]; then
        echo "Kullanılmayan paketler tespit edildi";
        exit 1;
      fi
  only:
    - merge_requests

Supply chain güvenliğini pekiştirme

Paket temizliği sadece unused paketleri silmek değildir. Kilitli (lock) dosyalarınızın güncelliği, doğrudan pipeline güvenliği ile ilgilidir. npm list ya da pip freeze çıktılarını kontrol ederek, geliştirme ortamında kalan ancak prod ortamına sızan bağımlılıkları ayırt etmek gerekir.

Özellikle monorepo yapılarında bir paketin bir microservice tarafından kullanılması, diğerleri tarafından kullanılmadığı anlamına gelir. Bu durumda dependency-cruiser gibi araçlarla bağımlılık grafiğini görselleştirmek ve hangi modülün hangi bağımlılığı tetiklediğini anlamak, ghost paketlerin neden temizlenemediğine dair bağlam sunar.

npx dependency-cruiser src --include-only "^src" --output-type dot | dot -T svg > dependencygraph.svg

Bakım stratejisi

Ghost paket temizliği, haftalık veya aylık periyodik görevler yerine pull request süreçlerine entegre edilmelidir. Yeni bir bağımlılık eklerken projenin genel yapısını bozmadığınızdan emin olun. Dependency track sistemleri, yalnızca kullanılan paketler üzerinde izleme yaptığında daha anlamlı raporlar sunar.

Sisteminizi temiz tutmak, ileride yaşanacak bir CVE vakasında yama yapma sürenizi doğrudan kısaltır. Pipeline içerisindeki "noise"u azaltmak, SRE ekiplerinin gerçek alarmlara odaklanmasını sağlar. Eğer projenizde uzun süredir dokunulmayan bir paket grubu varsa, bunları önce dev ortamında kaldırıp kapsamlı bir test suite çalıştırmak en güvenli yaklaşımdır.