Bağımlılık karışıklığı ve typosquatting
- Bağımlılık karışıklığı paketin kaynağını, typosquatting adını kandırır; ikisi de kurulum sırasında senin makinende kod çalıştırmayı hedefler.
- Bu derste paket yöneticisinin kaynak seçimini, kapsam sabitlemeyi, kilit dosyasında kaynak denetimini, kurulum betiklerini kapatmayı ve Shai-Hulud olayından çıkan dersleri öğrenirsin.
Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +55 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.
Altay Kargo'nun geliştiricileri iç kütüphanelerini özel bir kayıt sunucusunda tutar. Uygulamalar bu iç paketleri ve genel kayıttaki açık kaynak paketleri birlikte kurar. İki kaynağın buluştuğu bu nokta, tedarik zincirindeki en ucuz saldırıların hedefidir.
Saldırganın yazılımı kırması gerekmez; doğru adla bir paket yayımlaması yeter. Paket yöneticisi o paketi seçerse kod, kurulum sırasında geliştirici makinesinde ya da derleme sunucusunda çalışır.
Oradaki jetonlar, bulut anahtarları ve kaynak kod saldırganın eline geçer. Bu derste iki hileyi ayrı ayrı çözersin: adı taklit eden typosquatting ve kaynağı karıştıran bağımlılık karışıklığı (dependency confusion). Her biri için tespit izlerini ve savunmayı görürsün. Son bölümde kayıt sunucularının yanıtını ve kurum içi önlemleri incelersin.
Adı taklit etmek: typosquatting ve slopsquatting
Typosquatting, gerçek ve popüler bir paketin adına çok yakın bir ad kaydetmektir. Saldırgan bir harfi eksiltir, iki harfin yerini değiştirir ya da bir harf ekler: requests yerine reqeusts, django yerine djnago gibi. Kapsamlı paketlerde kapsam adını taklit eder: @altaykargo yerine @altay-kargo. Kurulum komutundaki tek bir yazım hatası ya da bir blog yazısından kopyalanan yanlış ad, sahte paketi projeye taşır.
Sahte paket çoğu zaman gerçeğinin işlevini de taşır ve ilk bakışta sorunsuz çalışır. Zararlı kısım ya kurulum betiğinde ya da ilk içe aktarmada çalışan küçük bir koddadır. Kayıtlar bazı varyantları engeller. PyPI adlarda tire, alt çizgi ve noktayı aynı sayar, büyük ve küçük harfi de ayırmaz.
Sahte paketi tanımanın birkaç işareti vardır. Ad, bilinen bir paketten bir iki harf farklıdır. Paket çok yenidir, indirme sayısı düşüktür ve tek bir sürümü vardır.
Depo bağlantısı yoktur ya da başka bir projenin deposunu gösterir. Paket, işiyle ilgisiz bir kurulum betiği taşır. OpenSSF'in package-analysis projesi bu son işareti geniş ölçekte arar.
Yeni yayımlanan paketleri yalıtılmış bir ortamda kurar; ağ bağlantılarını, dosya erişimini ve çalışan komutları kaydeder. Kurulurken dış bir adrese bağlanan ya da ev dizinindeki yapılandırma dosyalarını okuyan paket böylece göze batar. Senin tarafında da aynı mantık geçerlidir: bir paketin davranışı, adı kadar önemlidir.
Yapay zekâ kod asistanları bu tabloya yeni bir hile ekledi: slopsquatting. Model bazen var olmayan bir paket adı önerir. Ad kulağa doğru gelir, geliştirici de doğrulamadan kurar.
Saldırgan aynı uydurma adları toplayıp genel kayıtta yayımlarsa, öneriyi körü körüne izleyen herkes onun paketini kurar. USENIX Security 2025'te yayımlanan bir çalışma, 16 modelin Python ve JavaScript için ürettiği 576 bin kod örneğini inceledi. Uydurma paket oranı ticari modellerde ortalama en az yüzde 5,2, açık modellerde yüzde 21,7 çıktı.
Toplam 205.474 farklı uydurma ad bulundu. Savunma basittir ama disiplin ister. Asistanın önerdiği paketi kurmadan önce kayıtta var olup olmadığına, geçmişine ve bakımcısına bak.
Etkinlik 1 / 7
Paket adı çiftlerini gerçek paket ve typosquatting denemesi olarak ayır.
Önce bir seçeneğe, sonra aşağıdaki uygun kutuya bas. İstersen seçeneği kutuya sürükleyip bırak. Yerini değiştirmek için aynı işlemi tekrarla.
0/4 seçenek yerleşti.
Kaynağı karıştırmak: bağımlılık karışıklığı
Bağımlılık karışıklığı adı değil, kaynağı hedefler. Şirketin iç paketi, örneğin altaykargo-ic-arac, yalnız özel kayıtta bulunur. Bu ad çoğu zaman sızan bir package.json dosyasında, bir hata mesajında ya da herkese açık bir depoda görünür.
Saldırgan aynı adla genel kayda çok yüksek sürüm numaralı bir paket yayımlar, örneğin 99.0.0. Paket yöneticisi iki kaynağı birlikte sorguluyorsa ve kaynaklar arasında öncelik yoksa en yüksek sürümü seçer. Kurulum, genel kayıttaki sahte paketi getirir.
Python'da bu durumun bilinen kapısı --extra-index-url seçeneğidir. pip, bu seçenekle verilen ikinci kaynağı ana kaynakla eşit sayar. pip belgesi bu kullanımı açıkça bağımlılık karışıklığı riski olarak uyarır.
# Riskli: iki kaynak eşit sayılır, en yüksek sürüm kazanır pip install --extra-index-url https://pypi.altaykargo.example/simple altaykargo-ic-arac # Daha güvenli: tek kaynak; iç ayna onaylı genel paketleri de sunar pip install --index-url https://pypi.altaykargo.example/simple altaykargo-ic-arac
İlk komutta pip iki kaynağa da sorar. Genel kayıtta 99.0.0 sürümünü, iç kayıtta 3.1.0 sürümünü bulur ve yükseği seçer.
İkinci komutta tek kaynak vardır: kurumun iç aynası. Ayna, genel kayıttaki onaylı paketleri vekil olarak sunar, iç paketleri de doğrudan barındırır. Aynanın kendi kuralı da önemlidir.
İç adla gelen bir genel paketi hiçbir koşulda vekil olarak çekmemelidir. Aynı risk npm tarafında, iç ve genel kaynağı tek adreste birleştiren sanal depolarda görülür. Kurulum kayıtları bu saldırının izini taşır. İç ada sahip bir paketin genel kayıttan, beklenmedik yükseklikte bir sürümle geldiği satır, karışıklığın imzasıdır.
Savunmada bu izi beklemek yerine önden ararsın. Kurumun bütün iç paket adları zaten iç kayıtta listelidir. Küçük bir betik bu listeyi her gece genel kayda sorar. Ad genel kayıtta yoksa cevap 404 olur ve her şey yolundadır.
Ad bir gün genel kayıtta belirirse ve onu sen yayımlamadıysan, biri senin adını almış demektir. Bu kontrol, saldırı daha hiçbir kurulum kaydına düşmeden alarm üretir. Aynı betik, kapsam adının genel kayıtta kurumun hesabına ait olup olmadığını da sorar. Sonuç değişirse güvenlik ekibine bir kayıt açılır.
$ npm view altaykargo-ic-arac versions --registry=https://registry.ornekpaket.example/ npm error code E404 npm error 404 Not Found - GET https://registry.ornekpaket.example/altaykargo-ic-arac - Not found npm error 404 npm error 404 'altaykargo-ic-arac@*' is not in this registry.
Derinleş:2021 araştırması: iç adlar nereden sızdı
Bağımlılık karışıklığı, Şubat 2021'de bir güvenlik araştırmacısının yayımladığı çalışmayla geniş kitlelere ulaştı. Araştırmacı işe iç paket adlarını toplayarak başladı. Adları, şirketlerin herkese açık web sitelerinde sunduğu JavaScript dosyalarına gömülü package.json içeriklerinde, açık depolarda ve forum gönderilerinde buldu. Sonra aynı adlarla genel kayıtlara yüksek sürümlü paketler yayımladı.
Paketler zarar vermiyordu. Kurulduklarında yalnız makine adı, kullanıcı adı ve çalışma dizini gibi bilgileri DNS sorgularının içine gömüp araştırmacının sunucusuna gönderiyordu.
DNS seçimi bilinçliydi, çünkü çıkış trafiğini sıkı süzen ağlar bile DNS'i çoğu zaman açık bırakır. Çalışma, şirketlerin ödül programları kapsamında yapıldı ve otuz beşten fazla kuruluşun iç sistemlerinde kod çalıştırılabildiğini gösterdi. Sonrasında kayıtlar, paket yöneticileri ve ayna ürünleri kaynak önceliği ve kapsam eşlemesi konusunda belgelerini ve varsayılanlarını güncelledi.
Etkinlik 2 / 7
Kurulum kaydında, iç paket adı altaykargo-ic-arac'ı genel kayıt sunucusundan (registry.ornekpaket.example) çeken şüpheli satırları yakalayan bir düzenli ifade yaz.
Yazdıkça eşleşen satırlar işaretlenir. Hedef: yalnız doğru satırlar eşleşsin.
Kapsamı sabitle, kaynağı doğrula
npm'de en güçlü önlem kapsamlı ad (scope) kullanmaktır. İç paketler @altaykargo/ önekiyle adlandırılır ve .npmrc dosyasında bu kapsam yalnız iç kayda bağlanır. npm bir kapsam için tanımlı kaydı sorgular, genel kayda bakmaz. Kapsam adı genel kayıtta da kurumun hesabıyla alınır; böylece başka biri o kapsamda paket yayımlayamaz.
Kapsamsız eski iç paketler için iki yol vardır. Adı genel kayıtta boş bir yer tutucuyla ayırırsın ya da paketi kapsamlı bir ada taşırsın. Kayıt jetonu dosyaya yazılmaz, ortam değişkeninden okunur. Altay Kargo'nun düzeltilmiş yapılandırması ve iki doğrulama komutu aşağıdadır.
# .npmrc
registry=https://npm.altaykargo.example/
@altaykargo:registry=https://npm.altaykargo.example/
//npm.altaykargo.example/:_authToken=${NPM_TOKEN}
$ npm config get @altaykargo:registry
https://npm.altaykargo.example/
$ grep '"resolved"' package-lock.json | grep -v 'npm.altaykargo.example'
"resolved": "https://registry.ornekpaket.example/altaykargo-ic-arac/-/altaykargo-ic-arac-99.0.0.tgz",Komutları oku. npm config get, kapsamın hangi kayda bağlandığını gösterir; çıktı iç adres değilse yapılandırma yanlıştır.
İkinci komut kilit dosyasındaki bütün resolved alanlarını süzer ve iç aynadan gelmeyenleri bırakır. Geriye tek satır kalır ve o satır bir alarmdır. Kapsamsız iç paket genel kayıttan, 99.0.0 sürümüyle çözülmüştür. Kilit dosyası bu kaydı eski yapılandırmalı bir geliştirici makinesinde almıştır.
Satır kod incelemesine gelir ve çoğu zaman gözden kaçar, çünkü insanlar kilit dosyası farklarını okumaz. Aynı süzgeç CI'da bir kontrol adımı olarak çalışabilir. Beklenmeyen kaynak görülürse derleme durur ve paketin içeriği incelenir.
Etkinlik 3 / 7
Altay Kargo'nun paket yöneticisi yapılandırmasında eksik kapsam sabitlemesini bul.
Etkinlik 4 / 7
Kurulum kaydında, yalnız iç kullanım için ayrılmış bir paket adının genel kayıt sunucusundan, beklenenin çok üstünde bir sürümle geldiği görülüyor. En doğru ilk adım hangisidir?
Kurulum betikleri ve Shai-Hulud
Sahte paketin zarar vermesi için kodunun çalışması gerekir. En kısa yol kurulum betikleridir. npm, package.json içindeki preinstall, install ve postinstall betiklerini kurulum sırasında kendiliğinden çalıştırır. Varsayılan ayarda bu betiklerin çıktısını ekrana da basmaz.
Python'da kaynak dağıtımının derleme adımı aynı gücü taşır. Betik, kurulumu yapan kullanıcının yetkisiyle çalışır ve o ortamdaki her dosyayı okur. npm ci --ignore-scripts bütün betikleri kapatır. Kalıcı ayar için proje .npmrc dosyasına ignore-scripts=true yazılır.
Betiğe gerçekten ihtiyaç duyan birkaç paket, örneğin yerel modül derleyenler, bir izin listesiyle ayrıca çalıştırılır. OWASP'ın npm rehberi bu iş için @lavamoat/allow-scripts eklentisini örnek verir. pnpm 10 ise bağımlılık betiklerini varsayılan olarak çalıştırmaz.
$ npm ci --foreground-scripts > [email protected] postinstall > node kurulum.js added 214 packages in 6s $ npm ci --ignore-scripts added 214 packages in 4s
Eylül 2025'te npm ekosisteminde Shai-Hulud adı verilen, kendini çoğaltan bir solucan yayıldı. Saldırganlar önce bazı bakımcı hesaplarını ele geçirdi ve paketlerin yeni sürümlerine zararlı bir postinstall betiği ekledi. Betik, kurulduğu makinede açık kaynak bir sır tarama aracıyla GitHub jetonlarını, npm jetonlarını ve bulut anahtarlarını aradı. Bulduklarını saldırganın denetimindeki bir adrese ve herkese açık bir depoya gönderdi.
Çalınan npm jetonuyla o bakımcının yayımlama yetkisi olan başka paketlere bulaştı. CISA'ya göre beş yüzden fazla paket etkilendi. CISA'nın önerileri şunlardı: kilit dosyalarını etkilenen paketler için denetle, 16 Eylül 2025 öncesinde yayımlanan sürümlere sabitle, bütün geliştirici kimlik bilgilerini döndür, oltalamaya dayanıklı çok faktörlü doğrulamayı zorunlu kıl.
Etkinlik 5 / 7
Altay Kargo'nun derleme makinesindeki süreç ve çıkış vekili kaydında kimlik bilgisi sızdırmaya işaret eden satırları işaretle.
Şüpheli satırlara tıkla. Birden fazla olabilir.
Etkinlik 6 / 7
Altay Kargo'nun CI adımında kilit dosyasına birebir uyan, ama hiçbir paketin kurulum betiğini çalıştırmayan npm komutunu yaz.
Kayıt tarafının yanıtı ve kurum içi savunma
Kayıt sunucuları da Shai-Hulud'dan sonra kurallarını sıkılaştırdı. GitHub, Eylül 2025'te npm için bir güvenlik planı açıkladı. Plan, yerel yayımlamada iki faktörlü doğrulamayı zorunlu kılmayı, yayımlama jetonlarının ömrünü yedi günle sınırlamayı ve eski klasik jetonları kaldırmayı içeriyordu.
Güvenilir yayımlama (trusted publishing) öne çıktı. Bu modelde CI işi uzun ömürlü bir jeton tutmaz. OIDC ile o işe özel, kısa ömürlü bir kimlik alır ve paketi onunla yayımlar.
npm'de bu yol npm CLI 11.5.1 ve sonrasını ister; herkese açık bir depodan GitHub Actions ya da GitLab ile yayımlanan pakete kaynak kanıtını da kendiliğinden ekler. PyPI'da aynı modelin adı trusted publishers'tır. Bakımcının jetonu çalınsa bile yayımlama yolu kapalı kalır.
Kurum içinde üç katman birlikte çalışır. Birincisi iç aynadır. Geliştiriciler ve derleme makineleri yalnız iç aynadan paket çeker, ayna da genel kayıttan yalnız onaylı paketleri getirir.
OWASP'ın npm rehberi yeni sürümlere hemen geçmemeyi, onlara bir süre tanımayı öğütler; zararlı sürümler çoğu zaman ilk günlerde fark edilir. İkincisi kilit dosyası incelemesidir. Yeni bir bağımlılık ya da kaynak değişikliği kod incelemesinde ayrıca onay ister.
Üçüncüsü yapay zekâ asistanı kuralıdır. OpenSSF'in kod asistanları için yayımladığı güvenlik rehberi, asistana zararlı ya da uydurma olabilecek bağımlılık eklememesini söylemeyi öğütler. Yerleşik ve topluluğun güvendiği paketlerin seçilmesini de ister.
Etkinlik 7 / 7
Doğru mu, yanlış mı?
Bir konteyner temel imajını yalnız isme bakarak, yayıncı hesabını kontrol etmeden çekmek typosquatting riskine karşı güvenlidir.
Okumayı istediğin sırayla sürdürebilirsin. Ders, bütün etkinlikleri cevapladığında tamamlanır.
- Etkinlik 1· Adı taklit etmek: typosquatting ve slopsquatting
- Etkinlik 2· Kaynağı karıştırmak: bağımlılık karışıklığı
- Etkinlik 3· Kapsamı sabitle, kaynağı doğrula
- Etkinlik 4· Kapsamı sabitle, kaynağı doğrula
- Etkinlik 5· Kurulum betikleri ve Shai-Hulud
- Etkinlik 6· Kurulum betikleri ve Shai-Hulud
- Etkinlik 7· Kayıt tarafının yanıtı ve kurum içi savunma