Sahte 'evet': .NET 10 MCP sunucusundaki insan onayına yapılan 6 saldırı
Bir geliştirici, ASP.NET Core ve resmi C# MCP SDK'sı (ModelContextProtocol 2.3.0) ile kurduğu para iadesi sunucusundaki onay adımını kırmak için altı saldırı denedi. requestState'in şifrelenmemesi, başka kullanıcının onayının tekrar oynatılması, form alanlarına enjekte edilen değerler ve varsayılanı işaretli onay kutusu gibi açıkların her birine karşı sunucuda somut savunmalar kuruldu.
Kilit noktalar
- requestState düz JSON veya base64 olarak taşınmamalı; Data Protection ile mühürlenip tool, argüman özeti, kullanıcı ve son kullanma süresiyle bağlanmalı
- State olmadan gelen inputResponses reddedilmeli, aksi halde cevapların hangi soruya ait olduğu kanıtlanamaz
- SDK'nın IsAccepted değeri büyük/küçük harf duyarsız; "ACCEPT" de geçer, bu yüzden onay kontrolü olarak kullanılmamalı
- Onay alanları zorunlu ve varsayılansız olmalı: SDK istemcisi varsayılanları kabul edilen cevaba doldurduğu için işaretlenmemiş kutu onaya dönüşebilir
- Yanıt geldiğinde form güncel veriyle yeniden kurulup parmak izi karşılaştırılmalı; değiştiyse kullanıcıya tekrar sorulmalı
- IBAN gibi gizli bilgiler form modunda değil, URL modunda ve aynı kullanıcı doğrulamasıyla toplanmalı
- Birden fazla instance'a düşen retry'lar için tüm sunucularda aynı Data Protection key ring ve uygulama adı gerekli
MCP'de (Model Context Protocol) bir tool, stateless sunucuda cevabı bekleyemez: çağrıyı input_required, gösterilecek bir form ve opak bir requestState ile bitirir; istemci formu gösterip aynı argümanlarla tool'u yeniden çağırır ve cevapları inputResponses içinde yollar. Yazarın 2026-07-28 spesifikasyonundaki Multi Round-Trip Requests akışını kullanan para iadesi sunucusunda onay, modelin değil insanın ürettiği bir "evet" olmalı. Saldırılar tam da bu iki parçaya, yani cevaplara ve state'e yöneliyor.
Savunmaların özü şu: requestState, ASP.NET Core Data Protection ile mühürleniyor ve tool adı, kanonik argümanların SHA-256 özeti, kullanıcı ve son kullanma süresiyle bağlanıyor; böylece tutarı değiştirmek veya başkasının onayını tekrar göndermek reddediliyor. SDK'nın büyük/küçük harf duyarsız IsAccepted değeri onay kontrolü olarak kullanılmıyor; form ve doğrulayıcı tek bir FormSpec'ten üretiliyor, onay alanları zorunlu ve varsayılansız tutuluyor, form yanıt geldiğinde güncel veriyle yeniden kurulup parmak izi karşılaştırılıyor. IBAN gibi gizli bilgiler form yerine URL modunda, aynı kullanıcı kontrolüyle toplanıyor. Açık kalan tek konu, aynı geçerli state ile gelen dürüst çift gönderimin parayı yalnızca bir kez hareket ettirmesi.
Gerçek dünyada kullanımı
- Para iadesi, hesap kapatma veya yapılandırma silme gibi geri alınamaz işlemleri onaylatan bir MCP tool'u yazmak
- Çok instance'lı, stateless bir ASP.NET Core MCP sunucusunda onay state'ini güvenli biçimde taşımak
- Ödeme hesabı, IBAN gibi hassas verileri sohbete düşürmeden toplamak için URL modlu elicitation kullanmak
- Kendi MCP tool'larınıza uygulayacağınız bir red-team kontrol listesi ve başlangıçta çalışan form lint kuralları kurmak
Neden önemli
Modelin ürettiği "evet" onay sayılmadığı sürece, onay adımının kendisi bir saldırı yüzeyi olur; buradaki hatalar doğrudan para veya veri kaybına yol açabilir.