« Tüm yayınlar

Node.js Prototip Kirliliğine Karşı Güçlendirilemez

Node.js'te prototip kirliliği gadget'ları neden bir güvenlik açığı değil, uygulama sınırındaki bir hatanın semptomu olduğunu inceliyoruz.

Node.js core'da veya bağımlılıklarda düzenli olarak yeni bir 'gadget' bulunur: beklenmeyen bir özelliğin okunup tehlikeli şekilde kullanıldığı bir nokta. Ancak bu raporların tamamı aynı ön koşulu varsayar: uygulamada zaten bir prototip kirliliği vardır. Bu doğruysa bulunan gadget zafiyet değil, semptomdur; arkasında core'da, o kütüphanede ve diğer tüm bağımlılıklarda sayısız benzeri bulunur. Tek bir gadget'ı kapatmak hiçbir şeyi çözmez.

JavaScript, prototip zincirini her yerde okur ve bunu sadece metod çağrılarıyla değil, destructuring, spread, for...of, thenable çözümleme gibi sözdizimsel yapılarla da yapar. Core'un oluşturduğu her {} nesnesi Object.prototype'tan miras alır. Gerçekten korunmak için core'un ayırdığı her nesneyi null-prototip yapması, prototip yuvasına dokunan her sözdizimsel yapıdan kaçınması ve tüm bağımlılıkların da aynısını yapması gerekir — bu bir sertleştirme değil, farklı bir dildir. Primordials bile bunu çözmez: bunlar bütünlük sağlar, güvenlik değil; Node'un çökmemesini garanti eder, uygulamanızın güvenli olmasını değil.

Bu yüzden Node.js, core'daki prototip kirliliğini güvenlik açığı olarak kabul etmiyor. Asıl düzeltme sınırda yatar: güvenilmeyen baytların nesneye dönüştüğü tam nokta. JSON.parse tek başına zarar vermez; zarar, recursive merge veya Object.assign gibi işlemlerin __proto__ anahtarını gerçek prototip zincirine taşımasıyla oluşur. Bu yüzden Fastify istek gövdelerinde secure-json-parse'ı varsayılan olarak çalıştırır ve __proto__/constructor.prototype üzerine yazmayı hatayla reddeder. Saldırgan prototipinize yazabiliyorsa oyun zaten bitmiştir; asıl iş o yazmayı asla mümkün kılmamaktır.