Haziran 16 2026

Açık Kaynak Kodda ‘Miasma’ Tehlikesi: npm ve Red Hat Bağımlılık Güvenliğini Otomatize Etmek

Modern yazılım mimarilerinde production ortamlarının çökmesi artık yazdığınız hatalı döngülerden değil, güvendiğiniz üçüncü parti kütüphanelerin zehirlenmesinden kaynaklanıyor. Bir supply chain attack (tedarik zinciri saldırısı), siz daha kahvenizden ilk yudumu almadan tüm altyapınızı ele geçirebilir. Bu yüzden open source security (açık kaynak güvenliği) süreçlerini sadece bir compliance tiyatrosu olarak görmek yerine, CI/CD pipeline’ınızın merkezine koymalısınız. Bu yazıda, modern enterprise dünyasının iki büyük oyuncusu olan npm security pratiklerini ve kurumsal ortamlarda Red Hat ekosistemine entegre edilmiş dependency tracking (bağımlılık takibi) mekanizmalarını nasıl otomatize edeceğimizi teknik detaylarıyla inceliyoruz.

Miasma Etkisi: Transitive Dependency Zehirlenmesi

Yazılım dünyasında “Miasma”, doğrudan sizin çağırmadığınız ama bağımlılık ağacınızın (dependency tree) derinliklerinde yer alan, zamanla çürüyen veya kasıtlı olarak manipüle edilen kütüphanelerin yarattığı toksik ortamı ifade eder. Siz projenize sadece popüler bir HTTP istemcisi eklersiniz; o istemci arkada 50 farklı paket çeker, o 50 paket ise 500 pakete dallanır. Saldırganlar, bu derinliklerdeki az bilinen, bakımı aksatılmış paketlerin sahipliğini ele geçirerek (veya typosquatting ile benzer isimler türeterek) production ortamlarınıza sızar.

Peki neden standart kilit dosyaları (lockfiles) bizi kurtarmıyor? Çünkü lockfile bağımlılıkların versiyonlarını sabitler, ancak o versiyonların güvenli olduğunu garanti etmez. Dün güvenli olan bir SHA-512 karması, bugün ifşa olmuş bir zero-day ile sisteminizi açık hedef haline getirebilir.

npm Pipeline Güvenliğini Sertleştirmek (Hardening)

Herkes npm audit komutunu bilir ancak kurumsal pipeline süreçlerinde bu komutu doğrudan çalıştırmak tam bir kabustur. Geliştirme ortamına ait (devDependencies) önemsiz bir prototip paketindeki düşük seviyeli bir açık yüzünden pipeline’ın durması geliştirici motivasyonunu öldürür. Bize daha akıllı, filtrelenebilir ve esnek bir yapı gerekiyor.

Bu sorunu çözmek için endüstri standardı olan audit-ci aracını kullanacağız. Bu araç, kabul edilebilir riskleri (örneğin sadece prod bağımlılıklarını taramak veya belirli CVE’leri geçici olarak whitelist’e eklemek) yönetmemizi sağlar.

Adım 1: audit-ci Yapılandırması

Projenizin kök dizinine bir .audit-ci.json dosyası oluşturun. Bu dosya, pipeline’ınızın hangi durumlarda kırmızıya döneceğini belirleyen anayasanız olacak:

{
  "$schema": "https://github.com/IBM/audit-ci/raw/main/schema.json",
  "low": false,
  "medium": false,
  "high": true,
  "critical": true,
  "allowlist": [
    "GHSA-93g4-969f-4mc9",
    "CVE-2023-45133"
  ],
  "registry": "https://registry.npmjs.org/",
  "package-manager": "npm"
}

Burada kritik ayar: high ve critical seviyedeki açıkları kesinlikle blokluyoruz. Ancak production ortamını etkilemeyen, analiz ettiğimiz ve fix edilmesini beklediğimiz belirli CVE’leri allowlist içine alarak pipeline’ın gereksiz yere tıkanmasını önlüyoruz.

Red Hat Enterprise Linux (RHEL) ve UBI Dünyasında Bağımlılık Yönetimi

Kurumsal dünyada Node.js uygulamalarımızı genellikle Red Hat Universal Base Images (UBI) üzerinde koştururuz. Bu imajlar güvenlik standartları açısından mükemmel olsa da, OS seviyesindeki paketlerin (openssl, glibc vb.) ve bağımlılıkların takibi npm seviyesinden farklı bir yaklaşım gerektirir.

OS seviyesindeki bağımlılıkları ve npm paketlerini tek bir çatı altında izlemek için SBOM (Software Bill of Materials) üretmek zorundayız. SBOM, uygulamanızın DNA haritasıdır.

Syft ve Grype Entegrasyonu

Anchore tarafından geliştirilen syft ile imajımızın SBOM’unu çıkaracağız, ardından grype ile bu SBOM üzerinde Red Hat güvenlik veritabanını (RHSA) kullanarak tarama gerçekleştireceğiz.

Aşağıdaki komut bloku, UBI tabanlı Docker imajınızı tarar ve Red Hat güvenlik advisory’leri ile eşleştirerek rapor üretir:

# Syft ile SBOM üretimi (CycloneDX formatında)
syft power-node-app:latest -o cyclonedx-json=sbom.json

# Grype ile SBOM taraması ve sadece yüksek/kritik açıkların listelenmesi
grype sbom.json --fail-on high

Neden doğrudan imajı taramıyoruz da SBOM üzerinden gidiyoruz? Çünkü SBOM çıktısı deklaratiftir. Bir kez üretildikten sonra arşivlenebilir, imzalanabilir ve yıllar sonra bile “Biz 2024’te production’a ne çıkmıştık?” sorusuna net bir cevap verir.

Uçtan Uca CI/CD Pipeline Blueprint’i

Şimdi teoriyi ve lokal komutları bir kenara bırakıp, gerçek bir kurumsal pipeline senaryosu kuralım. Senaryomuzda GitLab CI kullanacağız. Pipeline’ımız hem npm paketlerini tarayacak, hem Docker imajını inşa edecek, hem de Red Hat tabanlı bu imajı SBOM süzgecinden geçirecek.

stages:
  - test
  - build
  - security

variables:
  IMAGE_NAME: "registry.kertenkerem.net/apps/secure-node"
  IMAGE_TAG: "$CI_COMMIT_SHORT_SHA"

npm_security_audit:
  stage: test
  image: node:20-alpine
  script:
    - npm ci
    - npx audit-ci --config .audit-ci.json

container_build:
  stage: build
  image: docker:24.0.5
  services:
    - docker:24.0.5-dind
  script:
    - docker build --no-cache -t $IMAGE_NAME:$IMAGE_TAG -f Dockerfile.ubi .
    - docker save $IMAGE_NAME:$IMAGE_TAG -o image.tar
  artifacts:
    paths:
      - image.tar
    expire_in: 1 hour

vulnerability_scan:
  stage: security
  image: anchore/grype:latest
  dependencies:
    - container_build
  script:
    - docker load -i image.tar
    - grype $IMAGE_NAME:$IMAGE_TAG --fail-on high --exclude './usr/share/doc'
  allow_failure: false

Bu pipeline konfigürasyonunda dikkat etmeniz gereken kritik nokta --exclude parametresidir. Red Hat imajlarında bazen dokümantasyon dizinleri altında yalancı pozitifler (false positives) tetiklenebilir. Bunları dışarıda bırakarak sinyal/gürültü oranını optimize ediyoruz.

Transitive Dependency Zehirlenmesini Kod Seviyesinde Aşmak

Bazen kullandığınız devasa bir framework’ün (örneğin NestJS veya Next.js) derinliklerindeki bir paket açık verir. Üst paketin geliştiricileri henüz güncelleme yayınlamamıştır ancak güvenlik ekibiniz production’a çıkmanıza izin vermez. Bu çıkmaz sokaktan nasıl kurtulursunuz?

Çözüm: npm’in v8 ile gelen overrides (veya Yarn kullanıyorsanız resolutions) özelliğidir. Bu özellik sayesinde, üst paketin ne istediğine bakılmaksızın, bağımlılık ağacındaki spesifik bir alt paketin sürümünü zorla ezebilirsiniz.

Aşağıdaki package.json kesiti, kritik bir açık barındıran minimist paketini, tüm alt kırılımlarda 1.2.8 sürümüne kilitler:

{
  "name": "enterprise-secure-app",
  "version": "1.0.0",
  "dependencies": {
    "some-legacy-framework": "2.4.0"
  },
  "overrides": {
    "some-legacy-framework": {
      "minimist": "1.2.8"
    }
  }
}

Neden böyle yapıyoruz? Çünkü kütüphane sahibinin PR’ı (Pull Request) kabul edip yeni sürüm yayınlamasını beklemek bir SRE/DevOps mühendisi için lükstür. “Overrides” geçici ama hayat kurtaran bir siperdir.

Sonuç: Güvenlik Bir State Değil, Process’tir

Yazılım tedarik zinciri güvenliği, bir kez yapılandırıp unutacağınız bir ayar değildir. Yarın sabah npm registry’sine yüklenecek yepyeni bir paket, mevcut tüm mimarinizi tehdit edebilir. Bu yüzden otomasyon şarttır. audit-ci ile uygulama katmanını, syft ve grype ikilisiyle ise Red Hat tabanlı konteyner katmanınızı sürekli denetim altında tutarak, ‘Miasma’ tehlikesini sistemlerinizden uzak tutabilirsiniz.

Etiketler: , , ,
Copyright 20254541. All rights reserved.

Posted 16 Haziran 2026 by Kerem Danış in category "Genel