NodeJS - __proto__ & prototype Pollution
JavaScript'te Nesneler
JavaScript'te nesneler temelde özellikler olarak bilinen anahtar-değer çiftlerinin koleksiyonlarıdır. Bir nesne, miras alınmış özelliklere sahip olmayan boş bir nesne oluşturmak için Object.create
kullanılarak null
argümanı ile oluşturulabilir. Bu yöntem, miras alınmış özelliklere sahip olmayan bir nesnenin oluşturulmasına izin verir.
JavaScript'te Fonksiyonlar ve Sınıflar
JavaScript'te, sınıflar ve fonksiyonlar sıkı bir şekilde bağlantılıdır, fonksiyonlar genellikle sınıflar için yapılandırıcılar olarak hizmet eder. JavaScript'in yerel sınıf desteğinin olmamasına rağmen, yapılandırıcılar sınıf davranışını taklit edebilir.
Prototipler JavaScript'te
JavaScript, prototip özelliklerinin çalışma zamanında değiştirilmesine, eklenmesine veya silinmesine izin verir. Bu esneklik, sınıf işlevlerinin dinamik olarak genişletilmesini sağlar.
toString
ve valueOf
gibi işlevlerin davranışlarını değiştirmek için değiştirilebileceğinden, JavaScript'in prototip sisteminin uyarlanabilir doğasını gösterir.
Kalıtım
Prototip tabanlı programlamada, özellikler/metodlar sınıflardan nesnelere miras alınır. Bu sınıflar, özellikler/metodlar ya başka bir sınıfın bir örneğine ya da boş bir nesneye eklenerek oluşturulur.
Bir nesnenin prototip olarak hizmet veren bir nesneye (örneğin myPersonObj
) bir özellik eklenirse, miras alan nesneler bu yeni özelliğe erişir. Ancak, bu özellik otomatik olarak görüntülenmez, açıkça çağrılmadıkça.
__proto__ kirliliği
JavaScript'te Prototip Kirliliğini Keşfetme
JavaScript nesneleri anahtar-değer çiftleri tarafından tanımlanır ve JavaScript Object prototipinden miras alır. Bu, Object prototipinin değiştirilmesinin çevredeki tüm nesneleri etkileyebileceği anlamına gelir.
Bunu açıklamak için farklı bir örnek kullanalım:
Erişim, Object prototipi üzerinden mümkündür:
Object prototipine özellikler ekleyerek, her JavaScript nesnesi bu yeni özellikleri miras alacaktır:
prototype pollution
__proto__
kullanımının kısıtlandığı bir senaryo için, bir fonksiyonun prototype'ini değiştirmek alternatif bir yöntemdir:
Bu yalnızca Vehicle
yapıcısından oluşturulan nesneleri etkiler, onlara beep
, hasWheels
, honk
ve isElectric
özelliklerini verir.
JavaScript nesnelerini genel olarak etkilemek için iki yöntem şunlardır:
Doğrudan
Object.prototype
'yi kirletmek:
Sıkça kullanılan bir yapının yapıcı prototipini kirletme:
Diğer nesneleri kirletme
Bir sınıftan Object.prototype'a
Belirli bir nesneyi kirletebileceğiniz ve Object.prototype
'e ulaşmanız gereken bir senaryoda, aşağıdaki gibi bir kod parçasıyla onu arayabilirsiniz:
Dizi elemanları kirliliği
JS'de nesnelerin özelliklerini kirletme yeteneğine sahip olduğunuz gibi, bir diziyi kirletebilirseniz, dizi değerlerini de indeksler aracılığıyla erişilebilir şekilde kirletebilirsiniz (değerleri üzerine yazamazsınız, bu yüzden kullanılan ancak yazılmayan indeksleri kirletmeniz gerekir).
Html elemanları kirliliği
JS aracılığıyla bir HTML elemanı oluşturulurken, innerHTML
özniteliğini üzerine yazmak ve keyfi HTML kodu yazdırmak mümkündür. Fikir ve örnek bu yazıdan alınmıştır.
Örnekler
Temel Örnek
Prototip kirliliği, uygulamadaki bir hatadan kaynaklanır ve Object.prototype
üzerindeki özelliklerin üzerine yazılmasına izin verir. Bu, çoğu nesnenin özelliklerini Object.prototype
'den türettiği anlamına gelir.
En basit örnek, kontrol edilecek bir nesnenin tanımsız bir özelliğine bir değer eklemektir, örneğin:
Eğer admin
özelliği tanımsız ise, bir PP'yi istismar etmek ve şuna benzer bir şeyle True olarak ayarlamak mümkündür:
Bu mekanizmanın arkasındaki şey, saldırganın belirli girdiler üzerinde kontrol sahibi olduğunda, uygulamadaki tüm nesnelerin prototipini değiştirebileceği özellikleri manipüle etmeyi içerir. Bu manipülasyon genellikle JavaScript'te bir nesnenin prototipini doğrudan değiştirmekle eş anlamlı olan __proto__
özelliğinin ayarlanmasını içerir.
Bu saldırının başarılı bir şekilde gerçekleştirilebileceği koşullar, belirli bir çalışmada belirtildiği şekilde şunları içerir:
Yinelemeli bir birleştirme gerçekleştirme.
Bir yol temelinde özellikler tanımlama.
Nesneleri klonlama.
Fonksiyonu geçersiz kılma
Proto Kirliliği ile Uzaktan Kod Çalıştırma (RCE)
pagePrototype Pollution to RCEDiğer yükler:
İstemci tarafı proto kirliliği ile XSS
pageClient Side Prototype PollutionCVE-2019–11358: jQuery $ .extend ile Proto Kirliliği Saldırısı
Daha fazla detay için bu makaleye bakın jQuery'de, $ .extend
fonksiyonu derin kopya özelliği yanlış kullanıldığında proto kirliliğine yol açabilir. Bu fonksiyon genellikle nesneleri klonlamak veya varsayılan bir nesneden özellikleri birleştirmek için kullanılır. Ancak yanlış yapılandırıldığında, yeni bir nesne için amaçlanan özellikler prototipe atanabilir. Örneğin:
Bu zafiyet, CVE-2019–11358 olarak tanımlanmış olup, derin kopyalamanın yanlışlıkla prototype'ı değiştirebileceğini ve isAdmin
gibi özelliklerin uygun varlık doğrulaması olmadan kontrol edilmesi durumunda yetkisiz yönetici erişimi gibi potansiyel güvenlik risklerine yol açabileceğini göstermektedir.
CVE-2018–3721, CVE-2019–10744: lodash üzerinden Prototype pollution saldırısı
Daha fazla detay için bu makaleye bakabilirsiniz
Lodash, benzer prototype pollution zafiyetleri (CVE-2018–3721, CVE-2019–10744) ile karşılaşmıştır. Bu sorunlar 4.17.11 sürümünde çözülmüştür.
CVE'ler ile ilgili başka bir rehber
Prototype Pollution tespit etmek için Araçlar
Server-Side-Prototype-Pollution-Gadgets-Scanner: Web uygulamalarındaki sunucu tarafı prototype pollution zafiyetlerini tespit etmek ve analiz etmek için tasarlanmış Burp Suite eklentisi. Bu araç, potansiyel prototype pollution sorunlarını belirlemek için tarama işlemini otomatikleştirir. Bilinen gadget'ları kullanır - zararlı eylemleri gerçekleştirmek için prototype pollution'ı kullanan yöntemler - özellikle Node.js kütüphanelerine odaklanır.
server-side-prototype-pollution: Bu eklenti, sunucu tarafı prototype pollution zafiyetlerini tanımlar. Sunucu tarafı prototype pollution başlıklı teknikleri kullanır.
NodeJS'te AST Prototype Pollution
NodeJS, template motorları ve TypeScript gibi işlevler için JavaScript'te Abstract Syntax Trees (AST) kullanır. Bu bölüm, template motorları Handlebars ve Pug özelinde prototype pollution ile ilgili zafiyetleri keşfeder.
Handlebars Zafiyet Analizi
Handlebars template motoru, prototype pollution saldırısına açıktır. Bu zafiyet, javascript-compiler.js
dosyasındaki belirli fonksiyonlardan kaynaklanmaktadır. Örneğin, appendContent
fonksiyonu, pendingContent
varsa birleştirirken, pushSource
fonksiyonu kaynağı ekledikten sonra pendingContent
'i undefined
olarak sıfırlar.
Sömürü Süreci
Sömürü, Handlebars tarafından üretilen AST (Abstract Syntax Tree) kullanılarak şu adımları izler:
Ayrıştırıcının Manipülasyonu: İlk olarak, ayrıştırıcı,
NumberLiteral
düğümü aracılığıyla değerlerin sayısal olmasını zorlar. Prototype pollution, sayısal olmayan dizelerin eklenmesine olanak tanıyarak bunu atlayabilir.Derleyici Tarafından İşlenme: Derleyici, bir AST Objesi veya bir dize şablonunu işleyebilir.
input.type
Program
olduğunda, giriş önceden ayrıştırılmış olarak işlenir ve bu sömürülebilir.Kod Enjeksiyonu:
Object.prototype
'nin manipülasyonu aracılığıyla, şablon fonksiyonuna keyfi kod enjekte edilebilir ve bu da uzaktan kod yürütmeyle sonuçlanabilir.
Handlebars zafiyetinin sömürülmesini gösteren bir örnek:
Bu kod, bir saldırganın Handlebars şablonuna keyfi kod enjekte edebileceğini göstermektedir.
Harici Referans: 'flat' kütüphanesinde bulunan prototype kirliliği ile ilgili bir sorun, şurada detaylı olarak açıklanmıştır: GitHub'daki Sorun.
Harici Referans: 'flat' kütüphanesindeki prototype kirliliği ile ilgili sorun: GitHub'daki Sorun
Python'da prototype kirliliği sömürüsü örneği:
Pug Güvenlik Zafiyeti
Pug, başka bir şablon motoru, prototip kirliliği riskiyle karşı karşıyadır. Ayrıntılı bilgi, Pug'da AST Enjeksiyonu başlıklı tartışmada bulunabilir.
Pug'da prototip kirliliği örneği:
Önleyici Önlemler
Prototip kirliliği riskini azaltmak için aşağıdaki stratejiler uygulanabilir:
Nesne Değişmezliği:
Object.prototype
Object.freeze
uygulanarak değişmez hale getirilebilir.Giriş Doğrulaması: JSON girişleri uygulamanın şemasına karşı sıkı bir şekilde doğrulanmalıdır.
Güvenli Birleştirme Fonksiyonları: Güvensiz şekilde özyinelemeli birleştirme fonksiyonlarının kullanımı kaçınılmalıdır.
Prototipsiz Nesneler: Prototip özellikleri olmayan nesneler
Object.create(null)
kullanılarak oluşturulabilir.Map Kullanımı:
Object
yerine anahtar-değer çiftlerini depolamak içinMap
kullanılmalıdır.Kütüphane Güncellemeleri: Güvenlik yamaları düzenli olarak kütüphanelere entegre edilebilir.
Linter ve Statik Analiz Araçları: Prototype kirliliği zafiyetlerini tespit etmek ve önlemek için ESLint gibi uygun eklentilere sahip araçlar kullanılmalıdır.
Kod İncelemeleri: Prototip kirliliği ile ilgili potansiyel riskleri belirlemek ve gidermek için detaylı kod incelemeleri uygulanmalıdır.
Güvenlik Eğitimi: Geliştiricileri prototip kirliliği riskleri ve güvenli kod yazma en iyi uygulamaları konusunda eğitin.
Dikkatli Kütüphane Kullanımı: Üçüncü taraf kütüphaneleri kullanırken dikkatli olun. Güvenlik durumlarını değerlendirin ve özellikle nesneleri manipüle eden kütüphanelerin kodlarını gözden geçirin.
Çalışma Zamanı Koruması: Güvenlik odaklı npm paketleri gibi prototip kirliliği saldırılarını tespit edip önleyebilen mekanizmaları kullanın.
Referanslar
Last updated