NodeJS - __proto__ & prototype Pollution
Last updated
Last updated
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Eğitim AWS Kırmızı Takım Uzmanı (ARTE) GCP Hacking'i öğrenin ve pratik yapın: HackTricks Eğitim GCP Kırmızı Takım Uzmanı (GRTE)
JavaScript'teki nesneler esasen özellikler olarak bilinen anahtar-değer çiftlerinin koleksiyonlarıdır. Object.create
kullanarak null
argümanı ile bir nesne oluşturulabilir ve bu, boş bir nesne üretir. Bu yöntem, miras alınan özellikler olmadan bir nesne oluşturulmasına olanak tanır.
Boş bir nesne, {}
olarak temsil edilen boş bir sözlüğe benzer.
JavaScript'te, sınıflar ve fonksiyonlar yakından bağlantılıdır; fonksiyonlar genellikle sınıflar için yapıcılar olarak hizmet eder. JavaScript'in yerel sınıf desteği olmamasına rağmen, yapıcılar sınıf davranışını taklit edebilir.
JavaScript, prototip özelliklerinin çalışma zamanında değiştirilmesine, eklenmesine veya silinmesine izin verir. Bu esneklik, sınıf işlevselliklerinin dinamik olarak genişletilmesini sağlar.
toString
ve valueOf
gibi fonksiyonlar, davranışlarını değiştirmek için değiştirilebilir ve bu, JavaScript'in prototip sisteminin uyumlu doğasını gösterir.
Prototip tabanlı programlamada, özellikler/yöntemler nesneler tarafından sınıflardan miras alınır. Bu sınıflar, başka bir sınıfın bir örneğine veya boş bir nesneye özellikler/yöntemler eklenerek oluşturulur.
Bir nesneye (örneğin myPersonObj
) diğer nesneler için prototip olarak hizmet eden bir özellik eklendiğinde, miras alan nesneler bu yeni özelliğe erişim kazanır. Ancak, bu özellik açıkça çağrılmadıkça otomatik olarak görüntülenmez.
JavaScript nesneleri, anahtar-değer çiftleri ile tanımlanır ve JavaScript Nesne prototipinden miras alır. Bu, Nesne prototipinin değiştirilmesinin ortamda tüm nesneleri etkileyebileceği anlamına gelir.
Açıklamak için farklı bir örnek kullanalım:
Object prototipine erişim şu yollarla mümkündür:
Object prototipine özellikler ekleyerek, her JavaScript nesnesi bu yeni özellikleri miras alacaktır:
__proto__
kullanımının kısıtlandığı bir senaryo için, bir fonksiyonun prototipini değiştirmek bir alternatiftir:
Bu, yalnızca Vehicle
yapıcısından oluşturulan nesneleri etkiler ve onlara beep
, hasWheels
, honk
ve isElectric
özelliklerini verir.
Prototip kirliliği yoluyla JavaScript nesnelerini küresel olarak etkilemenin iki yöntemi şunlardır:
Object.prototype
'ı doğrudan kirletmek:
Yaygın olarak kullanılan bir yapının bir yapıcı prototipini kirletmek:
Bu işlemlerden sonra, her JavaScript nesnesi goodbye
ve greet
yöntemlerini çalıştırabilir.
Belirli bir nesneyi kirletebileceğiniz ve Object.prototype'a ulaşmanız gerektiği bir senaryoda, aşağıdaki gibi bir kod ile onu arayabilirsiniz:
JS'de nesnelerin niteliklerini kirletebildiğiniz gibi, bir diziye kirletme erişiminiz varsa, dizinin indeksler aracılığıyla erişilebilen değerlerini de kirletebilirsiniz (değerleri üzerine yazamayacağınızı unutmayın, bu nedenle bir şekilde kullanılan ancak yazılmayan indeksleri kirletmeniz gerekir).
JS aracılığıyla bir HTML elemanı oluştururken, keyfi HTML kodu yazmak için innerHTML
niteliğini üstüne yazmak mümkündür. Bu yazıdan fikir ve örnek.
Bir prototip kirlenmesi, Object.prototype
üzerindeki özelliklerin üzerine yazılmasına izin veren bir uygulama hatasından kaynaklanır. Bu, çoğu nesnenin özelliklerini Object.prototype
'dan türettiği anlamına gelir.
En basit örnek, kontrol edilecek bir nesnenin tanımsız bir niteliğine bir değer eklemektir, şöyle:
Eğer admin
niteliği tanımsızsa, bir PP'yi kötüye kullanmak ve onu True olarak ayarlamak mümkündür:
Bu mekanizma, bir saldırgan belirli girdiler üzerinde kontrol sahibi olduğunda, uygulamadaki tüm nesnelerin prototipini değiştirebilecek şekilde özellikleri manipüle etmeyi içerir. Bu manipülasyon genellikle __proto__
özelliğini ayarlamayı içerir; bu, JavaScript'te bir nesnenin prototipini doğrudan değiştirmekle eşanlamlıdır.
Bu saldırının başarılı bir şekilde gerçekleştirilebileceği koşullar, belirli bir çalışmada belirtildiği gibi şunlardır:
Rekürsif bir birleştirme gerçekleştirmek.
Bir yola dayalı olarak özellikler tanımlamak.
Nesneleri klonlamak.
Diğer payloadlar:
Daha fazla detay için bu makaleye bakın jQuery'de, $ .extend
fonksiyonu derin kopyalama özelliği yanlış kullanıldığında prototip kirlenmesine yol açabilir. Bu fonksiyon, nesneleri klonlamak veya varsayılan bir nesneden özellikleri birleştirmek için yaygın olarak kullanılır. Ancak, yanlış yapılandırıldığında, yeni bir nesne için tasarlanan özellikler prototipe atanabilir. Örneğin:
Bu zafiyet, CVE-2019–11358 olarak tanımlanmıştır ve derin bir kopyanın istemeden prototipi değiştirebileceğini, bu durumun da 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.
Daha fazla detay için bu makaleyi kontrol edin
Lodash, benzer prototip kirlenmesi zafiyetleri (CVE-2018–3721, CVE-2019–10744) ile karşılaşmıştır. Bu sorunlar 4.17.11 sürümünde ele alınmıştır.
Server-Side-Prototype-Pollution-Gadgets-Scanner: Web uygulamalarında sunucu tarafı prototip kirlenmesi zafiyetlerini tespit etmek ve analiz etmek için tasarlanmış Burp Suite uzantısı. Bu araç, potansiyel prototip kirlenmesi sorunlarını tanımlamak için istekleri tarama sürecini otomatikleştirir. Bilinen gadget'ları - prototip kirlenmesini kullanarak zararlı eylemler gerçekleştirme yöntemleri - özellikle Node.js kütüphanelerine odaklanarak kullanır.
server-side-prototype-pollution: Bu uzantı, sunucu tarafı prototip kirlenmesi zafiyetlerini tanımlar. Sunucu tarafı prototip kirlenmesi ile tanımlanan teknikleri kullanır.
NodeJS, JavaScript'te şablon motorları ve TypeScript gibi işlevler için Soyut Sözdizim Ağaçları (AST) kullanmaktadır. Bu bölüm, şablon motorlarındaki prototip kirlenmesi ile ilgili zafiyetleri, özellikle Handlebars ve Pug'u incelemektedir.
Handlebars şablon motoru, bir prototip kirlenmesi saldırısına karşı hassastır. Bu zafiyet, javascript-compiler.js
dosyasındaki belirli işlevlerden kaynaklanmaktadır. Örneğin, appendContent
işlevi, pendingContent
mevcutsa bunu birleştirirken, pushSource
işlevi kaynağı ekledikten sonra pendingContent
'i undefined
olarak sıfırlar.
Sömürü Süreci
Sömürü, Handlebars tarafından üretilen AST'yi (Soyut Sözdizim Ağacı) kullanarak şu adımları izler:
Parser'ın Manipülasyonu: İlk olarak, NumberLiteral
düğümü aracılığıyla parser, değerlerin sayısal olmasını zorunlu kılar. Prototip kirlenmesi bunu aşabilir ve sayısal olmayan dizelerin eklenmesine olanak tanır.
Derleyici Tarafından İşlenmesi: Derleyici, bir AST Objesini veya bir dize şablonunu işleyebilir. Eğer input.type
Program
'a eşitse, girdi önceden işlenmiş olarak kabul edilir ve bu durum sömürülebilir.
Kod Enjeksiyonu: Object.prototype
'ın manipülasyonu yoluyla, şablon işlevine rastgele kod enjekte edilebilir, bu da uzaktan kod yürütmeye yol açabilir.
Handlebars zafiyetinin sömürüsünü gösteren bir örnek:
Bu kod, bir saldırganın Handlebars şablonuna keyfi kod enjekte edebileceğini göstermektedir.
Dış Referans: 'flat' kütüphanesinde prototip kirlenmesi ile ilgili bir sorun bulundu, detaylar burada: GitHub'daki Sorun.
Dış Referans: ‘flat’ kütüphanesindeki prototip kirlenmesi ile ilgili sorun
Python'da prototip kirlenmesi istismarına örnek:
Pug, başka bir şablon motoru, prototip kirlenmesi riskiyle karşı karşıyadır. Ayrıntılı bilgi Pug'da AST Enjeksiyonu tartışmasında mevcuttur.
Pug'da prototip kirlenmesi örneği:
Prototip kirlenmesi riskini azaltmak için aşağıdaki stratejiler uygulanabilir:
Nesne Değişmezliği: Object.prototype
'ı Object.freeze
uygulayarak değişmez hale getirebilirsiniz.
Girdi Doğrulama: JSON girdileri, uygulamanın şemasına karşı titizlikle doğrulanmalıdır.
Güvenli Birleştirme Fonksiyonları: Güvensiz birleştirme fonksiyonlarının rekürsif kullanımından kaçınılmalıdır.
Prototipsiz Nesneler: Prototip özellikleri olmayan nesneler Object.create(null)
kullanılarak oluşturulabilir.
Map Kullanımı: Anahtar-değer çiftlerini depolamak için Object
yerine Map
kullanılmalıdır.
Kütüphane Güncellemeleri: Güvenlik yamaları, kütüphaneleri düzenli olarak güncelleyerek entegre edilebilir.
Linter ve Statik Analiz Araçları: Prototip kirlenmesi açıklarını tespit etmek ve önlemek için uygun eklentilere sahip ESLint gibi araçlar kullanılmalıdır.
Kod İncelemeleri: Prototip kirlenmesi ile ilgili potansiyel riskleri belirlemek ve düzeltmek için kapsamlı kod incelemeleri uygulanmalıdır.
Güvenlik Eğitimi: Geliştiricileri prototip kirlenmesi riskleri ve güvenli kod yazma en iyi uygulamaları hakkında eğitmek.
Kütüphaneleri Dikkatle Kullanma: Üçüncü taraf kütüphaneleri kullanırken dikkatli olun. Güvenlik duruşlarını değerlendirin ve özellikle nesneleri manipüle edenlerin kodunu gözden geçirin.
Çalışma Zamanı Koruması: Prototip kirlenmesi saldırılarını tespit ve önlemek için güvenlik odaklı npm paketleri kullanarak çalışma zamanı koruma mekanizmaları uygulayın.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)