Laravel-Lang paketlerinin saldırıya uğradığına dair bir Twitter gönderisi gördüm. Bu durum ilk başta “Ben bu paketi kullanmıyorum.” gibi basit bir tepkiye yol açtı.
Ancak çalıştığım projede composer.json dosyasını açtığımda require-dev bölümünde bunu buldum:
"laravel-lang/lang": "^14.8",
"laravel-lang/publisher": "^16.8",
Olayları değiştiren bir durumdu.
Gerçekten Ne Oldu
Gerçekten Ne Oldu
Saldırı, laravel-lang paketlerini dağıtım kanalı olarak kullandı. Gizli kısmı: ana repository dalı tamamen temiz görünüyordu. Şüpheli commit yoktu, yeni kod yoktu. Kötü niyetli yükleme, fork’lar üzerinde git etiketleri aracılığıyla yapıldı.
Çoğu geliştirici bunu fark etmeyecekti. Normal bir composer update işlemi, her zamanki gibi.
Yüklendikten sonra, yükleme autoload zamanı geldiğinde yürütüldü. Bu da her php artisan komutu, kuyruk işçisi veya o kod tabanını çalıştıran web isteği, public/index.php dosyasında require_once __DIR__.'/../vendor/autoload.php' kodu PHP tarafından yürütülürken kötü amaçlı yazılımı tetikledi. Sessizce, hata olmadan, kırmızı ekran olmadan, hiçbir şey olmadan.
Kötü niyetli yazılım, bir kimlik bilgisi çalıcısıydı. Makinedeki şu dosyaları aradı:
.envdosyaları- AWS erişim anahtarları ve oturum belirteçleri
- SSH özel anahtarları
- GitHub CLI anahtarları
- NPM belirteçleri
- Altyapı gizli bilgiler
Bu, veritabanı satırlarınızla oynayan bir SQL enjeksiyonu değil. Bu, makinenizde çalışan ve bulduğu her şeyi alan bir anahtar çalıcısı.
Aikido Security bunu yakaladı ve Packagist’e bildirdi. Packagist, etkilenen sürümleri kaldırdı. Ancak bu süre zarfında composer update çalıştırdıysanız, ifşa oldunuz.
Tedarik Zinciri Saldırıları Neden Farklı
Tedarik Zinciri Saldırıları Neden Farklı
Klasik Laravel güvenlik konuşmaları SQL enjeksiyonu, XSS, CSRF hakkında. Bunlar, dış kullanıcıların uygulamanıza kötü amaçlı girişlerde bulunduğu saldırılardır.
Tedarik zinciri saldırıları, kendi geliştirme sürecinizin içinden gelir. Saldırgan, kodunuzda bir güvenlik açığı bulmak zorunda değildir. Bir paket bakımcısında bir geliştirici hesabını ele geçirmesi yeterlidir. O pakete bağlı her proje şimdi açığa çıkmaktadır.
Yapay zeka araçları ile bu saldırılar daha karmaşık ve daha sık hale geliyor. JavaScript ekosistemi benzer olaylarla başa çıkmakta. PHP maalesef geriden geliyor.
Gerçekten Ne Değiştirdim
Gerçekten Ne Değiştirdim
Bir projede düzenli olarak composer update çalıştırıyorduk. Bu olaydan sonra oturup tüm süreci yazdım.
Tüm iş akışı artık şu şekilde:
# 1. Docker içinde composer update çalıştırın
docker compose exec app composer update
# 2. jack raise-to-installed kullanarak kesin sürümleri kilitleyin
docker compose exec app vendor/bin/jack raise-to-installed --dry-run # önizleme için
docker compose exec app vendor/bin/jack raise-to-installed # uygulama
# 3. kilit hash'ini güncelleyin
docker compose exec app composer update --lock
# 4. Her şeyi commit edin
git add composer.json composer.lock
git commit -m "chore: bağımlılıkları güncelle"
rector/jack aracı, composer.json dosyasındaki sürüm yönetimini sağlıyor. raise-to-installed komutu, mevcut olanı alır ve kısıtlamaları tam olarak eşleşecek şekilde yükseltir. Örneğin, "guzzlehttp/guzzle": "^7.10" yerine "guzzlehttp/guzzle": "^7.11" alırsınız. Her gelecekteki composer update, yalnızca açıkça izin verdiğiniz sürümlere ulaşır. Bu standart Composer uygulaması değildir. Yükseltme kolaylığı karşılığında beklenmedik atlamalar üzerindeki kapsama alanını daraltır.
Yaşadığımız bir sorun: bir Laravel 10 projesinde, yalnızca composer update çalıştırmak bir kısımda engelleyici bir blok ile başarısız olabilir. Çözüm, bunu composer.json ayarlarına eklemektir:
"config": {
"audit": {
"abandoned": "report"
},
"policy": {
"advisories": {
"block": false
}
}
}
Advisories rapor edilecek, ama engellenmeyecek. Hala göreceksiniz ve buna göre hareket etmek zorundasınız. Güncelleme sadece çalışacaktır.
Her zaman güncellemeden önce nelerin değiştiğini kontrol edin. O projede PHP 8.1 çalıştırdığı için, 8.2+ gerektiren paketler izin verilmemelidir. raise-to-installed kuru çalıştırdıktan sonra, yüksek PHP sürümüne geçmediğinden emin olun.
Bir önemli uyarı: bu iş akışı, Laravel-Lang olayını önlemez. jack raise-to-installed çalıştığında, enfekte olan sürüm çoktan kurulmuştur. raise-to-installed daha sonra o enfekte sürümü yeni temel sürüm olarak kilitler. Yükleme zamanındaki gerçek defanslar sınırlıdır. composer audit bilinen advisories’a karşı yazılımlar arasında bilgi sağlar, ancak birkaç dakika önce ele geçirilmiş bir kötü niyetli paket karşısında önlem almaz. Yine de bunu çalıştırın. Güncellemeden önce topluluk raporlarına dikkat edin.
composer audit
composer audit
Güncellemeden önce şunu çalıştırın:
composer audit
Yüklenen paketleri PHP Güvenlik Advisories Veritabanı ile kontrol eder. Yeni bir projede hiçbir şey görünmez. Eski bir projede şu tarz bir öneri görebilirsiniz:
Found 3 security vulnerability advisories affecting 2 packages:
Package symfony/http-kernel
CVE-2026-XXXXX: ...
Package league/commonmark
CVE-2026-XXXXX: ...
Güncellemeden önce ve sonra çalıştırın. Ne tür sorunları düzeltmiş olduğunuzu belirtecek ve çözümleri onaylayacaktır.
Her Bağımlılığı Sorgula
Her Bağımlılığı Sorgula
Her bağımlılık başka bir güven ilişkisidir. Biri eklemeden önce sorun: bütün pakete mi ihtiyacım var, yoksa sadece bir fonksiyona mı?
Her şey değiştirilemeyecek. intervention/image veya maatwebsite/excel? Hayır. Ama bunun üzerinde gerçekten düşündünüz mü, yoksa bir refleks olarak mı composer require yaptınız?
Daha az paket, daha az saldırı yüzeyi demektir. Bir sonraki Laravel büyük sürümü çıktığında daha az bozuk güncellemeyle karşılaşılır.
Güncellemeden Önce Sosyal Medyayı Kontrol Edin
Güncellemeden Önce Sosyal Medyayı Kontrol Edin
Laraevl güvenlik araştırmacılarını ve paket bakımcılarını sosyal medyada takip edin. Büyük olaylar, resmi duyurular gelmeden önce burada gündeme gelir. Laravel-Lang saldırısı iyi bir örnektir.
Packagist Ne Yapıyor
Packagist Ne Yapıyor
Composer 2.10, Aikido kötü amaçlı yazılım tespitiyle Packagist’e entegre edilmiş durumda. Her sürüm etiketi artık otomatik olarak taranmaktadır.
Stabil sürüm değiştirilemezliği ayrıca geliyor: bir sürüm yayınlandığında, sessizce üzerine yazılamaz. Laravel-Lang saldırısındaki hilelerden biri, mevcut etiketleri yeniden yazarak kötü amaçlı yazılımlar eklemekteydi, bu da daha önce güvendiğiniz bir sürüm gibi görünüyordu.
Minimum yayın yaşı geliyor: yeni sürümler composer update içinde görünmeden önce bir karantina süresinde bekler. Güvenlik yamaları da öyle. Bu da bir ticaret. Ancak sıfır gün ekleme riski azalır.
Uzun vadeli plan, iki aşamalı bir yayın akışıdır: bir sürümü etiketle, MFA onay talebi al. Çalınan bir hesap, yalnızca bir yayını itmek için yeterli olmayacaktır.
İyi bir ilerleme. Ekosistem büyük, ancak bunlar hemen sağlanmaz.
Kısaca
Kısaca
Standart uygulama:
composer.lock‘u her zaman commit edin.- Güncellemeden önce ve sonra
composer auditçalıştırın. - Mümkünse belirli paketleri güncelleyin, her şeyi bir anda değil.
- Her yeni bağımlılığı sorgulayın. Bir sınıf, tam bir pakete ihtiyaç duymaz.
- Composer 2.10, Aikido kötü amaçlı yazılım taraması ve stabil sürüm değiştirilemezliğini ekledi.
Kişisel iş akışı eklemeleri:
- Her
composer updatesonrasında kısıtlamaları yüklenmiş sürümlere sabitlemek içinjack raise-to-installedkullanın. Bu standart uygulama değildir — gelişim kolaylığı karşılığında dar bir maruz kalma sağlar. Sizi çektiğiniz bir kötü niyetli sürümden korumaz. - Her güncellemeden sonra, paketlerin PHP sürüm sınırını aşmadığını doğrulayın.
- Laravel güvenlik araştırmacılarını sosyal medyada takip edin. Olaylar resmi duyurulardan önce burada ortaya çıkar.
Tedarik zinciri saldırıları artık yalnızca JavaScript’e özgü bir sorun değil. Laravel-Lang olayı, PHP ekosistemlerinin güvencesiz olmadığını gösterdi. Yukarıdaki iş akışı güvenlik garantisi vermez. Ancak, bir sonraki güncellemede maruz kaldığınız yüzeyi azaltır.
Kaynaklar:
Yazar Notu
Yazar Notu
Okuduğunuz için teşekkürler!
Beni dev.to, linkedin veya github adreslerinden bulabilirsiniz.
Laravel, güzel bir yolculuğun ardından.
Kaynak: Orijinal Makale


