deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

Cursor ve Claude Code, kullanıcıların kendilerini admin yapmasına olanak tanıyan mass-assignment açıklarını tekrar tekrar üretiyor

dev.to'da yayımlanan bir yazıya göre Cursor ve Claude Code tarafından yazılan profil güncelleme route'ları çoğu zaman ham request body'lerini doğrudan veritabanına iletiyor; böylece oturum açmış herhangi bir kullanıcı tek bir alan ekleyerek kendine admin yetkisi verebiliyor.

Cursor ve Claude Code, kullanıcıların kendilerini admin yapmasına olanak tanıyan mass-assignment açıklarını tekrar tekrar üretiyor

dev.to'da yazan bir geliştirici, Cursor veya Claude Code gibi yapay zekâ kodlama asistanlarından sıradan bir profil güncelleme endpoint'i yazmalarını istemenin rutin biçimde CWE-915 olarak takip edilen mass assignment açığı içeren kod ürettiğini bildiriyor — bu hata sınıfı, kimliği doğrulanmış herhangi bir kullanıcının kendi rolü dahil asla kontrol etmemesi gereken alanları yeniden yazabilmesine imkân tanıyor.

Yazar tekrarlanabilir bir testten bahsediyor: ad, bio ve avatar alanlarından oluşan basit bir ayarlar sayfası isteniyor. Editör formu, API route'unu ve veritabanı çağrısını bir dakikadan kısa sürede üretiyor ve hepsi çalışıyor. Ancak ortaya çıkan PATCH isteği tek bir ek alanla, "role": "admin" ile yeniden oynatıldığında sunucu bunu kabul ediyor. Route kimlik doğrulaması yapıyor, hatta yazma işlemini isteği yapan kullanıcının kendi kaydıyla sınırlıyordu; sadece hangi sütunların değişebileceğini kısıtlamamıştı.

Hata nasıl çalışıyor

Mass assignment, bir endpoint'in tüm request body'sini doğrudan bir veritabanı güncellemesine beslediği durumlarda ortaya çıkar. Tipik Node ve Prisma çıktısında handler, prisma.user.update'i data: req.body ile çağırır; böylece hangi niteliklerin yazılacağını fiilen istemci seçer. Yazıya göre aynı kusur Mongoose'ta da görülüyor; ham body ile çağırılan findByIdAndUpdate, şemada mevcut olan her alanı yazmaya devam ediyor. Aynı durum, payload üzerinde döngü kurup model üzerinde setattr çağıran Python handler'larında da geçerli.

Express varyantı bir de yardımcı kusur taşıyor: güncellenmiş kullanıcı nesnesini, password hash dahil, olduğu gibi tarayıcıya geri döndürüyor.

Yapay zekânın kendi çözümü bir denylist

Kullanıcıların kendi rollerini ayarlayabildiği söylendiğinde asistanlar tipik olarak yalnızca o tek alanı çıkarıyor — body'den role'ü destructure edip geri kalan her şeyi geçiriyorlar. Bu tek bir kapıyı kapatırken emailVerified, credits, plan, stripeCustomerId ve orgId alanlarını, bir de gelecek çeyrekte eklenecek hassas sütun neyse onu yazılabilir bırakıyor. Bir denylist, şema her değiştiğinde güncellenmek zorundadır ve yazara göre bunu kimse yapmıyor.

Prisma işleri daha da kötüleştiriyor, çünkü data nesnesi iç içe relation yazımlarını da kabul ediyor. Kullanıcıyı başka bir kuruluşun ID'sine bağlayan bir payload, role'e hiç dokunmadan saldırganı farklı bir tenant'a taşıyabilir.

Bu örüntü neden sürekli geri geliyor

Yazının açıklaması şu: tüm body'yi iletmek, özelliği çalıştıran en kısa kod ve eğitim verilerine hâkim olan CRUD örneklerini yansıtıyor. Bu hata ayrıca incelemede yakalanması zor. Route'ta kimlik doğrulama ve sahiplik kontrolleri var, form yalnızca birkaç alan gönderiyor ve tüm happy-path testleri geçiyor. TypeScript hiçbir koruma sunmuyor çünkü tipler runtime'da kayboluyor; Prisma ise bir alanın şemada var olmasıyla yetiniyor — role de öyle.

Bir de emsal var. 2012'de bir geliştirici GitHub'daki bir mass assignment açığını kullanarak kendi anahtarını Rails organizasyonuna ekledi ve Rails deposuna bir commit push'ladı; Rails 4 ardından strong parameters'ı varsayılan hale getirdi. Express, Fastify, Next.js route handler'ları ve FastAPI eşdeğer bir mekanizmayla gelmiyor; dolayısıyla koruma yalnızca biri elle yazarsa var — ve yapay zekâ yazmıyor.

Önerilen çözüm

Önerilen çare bir allowlist şeması: kullanıcının değiştirebileceği tek alanları adlandıran ve bilinmeyen anahtarları reddeden, .strict() ile yaklaşık on satırlık zod ya da extra="forbid" ile Pydantic v2. Veritabanına yalnızca parse edilmiş sonuç ulaşmalı, yalnızca admin'e ait alanlar kendi rol kontrollerine sahip ayrı route'larda bulunmalı ve yanıtlar hash'lerin asla dönmemesi için açık bir select kullanmalı. Yazar, kütüphanelerin bilinmeyen anahtarları sessizce yok sayma varsayılanını kabul etmek yerine bunları bilinçli olarak reddediyor: bir reddetme, keşif denemelerini loglardaki görünür bir 4xx'e dönüştürüyor ve yanlış şema bir route'a bağlandığında bir testin gürültülü biçimde başarısız olmasını sağlıyor.

Mevcut kod tabanları için yazı, data: req.body için, güncelleme çağrıları içindeki body'nin spread biçimleri için ve Python'daki setattr için hızlı bir grep öneriyor. OWASP'ın API Güvenliği İlk 10 listesi (2023) bu sorunu API3, Broken Object Property Level Authorization altında grupluyor. Bu editörlere eklenti yapan bir tarama aracı geliştiren yazar, bir tarayıcının yalnızca bu örüntüyü işaretleyebileceğini kabul ediyor; hangi alanlara kullanıcının dokunabileceğini bilme, yalnızca geliştiricinin sahip olduğu bir bilgi.

Neden önemli

Yapay zekâ asistanları artık CRUD altyapısını insan incelemesinin absorbe edebileceğinden daha hızlı üretiyor ve eğitim materyallerine gömülü güvensiz alışkanlıkları yeniden üretiyor. CWE-915, tek bir ekstra JSON alanıyla trivial biçimde istismar edilebilir ama auth kontrollerine, tip sistemlerine ve normal testlere görünmezdir; ayrıca yetki yükseltme veya hesapları tenant'lar arasında taşıma yapabilir. Rails bunu on yılı aşkın süre önce framework düzeyinde çözdü; mevcut JavaScript ve Python stack'leri hiçbir zaman varsayılan bir koruma almadı, dolayısıyla bu kontrolün elle yazılması gerekiyor. Yapay zekâ tarafından üretilen route'lar yayımlayan ekipler her yazma endpoint'inde katı bir allowlist'i temel gereklilik olarak görmeli ve bir saldırganın forma hiç gönderilmemiş bir alanla isteği yeniden oynatmasından önce mevcut kodda ham body güncellemeleri için denetim yapmalı.

  • #security
  • #ai-code-generation
  • #cursor
  • #claude-code
  • #prisma

İlgili yazılar