ASP.NET MS11-100: gönderilen form değerleri maksimum sayısı sınırını nasıl değiştirebilirim?


196

Microsoft son zamanlarda (12-29-2011) .NET Framework'teki birçok ciddi güvenlik açığını gidermek için bir güncelleştirme yayımladı. MS11-100'ün getirdiği düzeltmelerden biri, karma tablo çarpışmalarını içeren potansiyel bir DoS saldırısını geçici olarak azaltır . Bu düzeltme, çok sayıda POST verisi içeren sayfaları kırar gibi görünüyor. Bizim durumumuzda, çok büyük onay kutusu listeleri olan sayfalarda. Neden böyle olsun?

Bazı resmi olmayan kaynaklar, MS11-100'ün geri gönderme öğelerine 500 sınırı koyduğunu gösteriyor. Bunu doğrulayan bir Microsoft kaynağı bulamıyorum. View State ve diğer çerçeve özelliklerinin bu sınırın bir kısmını yediğini biliyorum. Bu yeni limiti kontrol eden herhangi bir yapılandırma ayarı var mı? Onay kutularını kullanmaktan vazgeçebiliriz, ancak özel durumumuz için oldukça iyi çalışır. Yamayı da uygulamak istiyoruz çünkü diğer kötü şeylere karşı koruyor.

500 sınırını tartışan resmi olmayan kaynak:

Bülten, tek bir HTTP POST isteği için gönderilebilen değişken sayısı için bir sınır sağlayarak DOS saldırısı vektörünü düzeltir. Varsayılan sınır, normal web uygulamaları için yeterli olması gereken 500'dür, ancak yine de Almanya'daki güvenlik araştırmacıları tarafından açıklanan saldırıyı etkisiz hale getirecek kadar düşüktür.

DÜZENLEME: Limit örneği olan kaynak kodu (500 değil, 1.000 olarak görünüyor) Standart bir MVC uygulaması oluşturun ve ana dizin görünümüne aşağıdaki kodu ekleyin:

@using (Html.BeginForm()) 
{
    <fieldset class="fields">
        <p class="submit">
            <input type="submit" value="Submit" />
        </p>

        @for (var i = 0; i < 1000; i++)
        {
            <div> @Html.CheckBox("cb" + i.ToString(), true) </div>
        } 
    </fieldset>
}

Bu kod düzeltme ekinden önce çalıştı. Sonra işe yaramıyor. Hata:

[InvalidOperationException: Nesnenin geçerli durumu nedeniyle işlem geçerli değil.]
System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded () +82 System.Web.HttpValueCollection.FillFromEncodedBytes (Bayt [] bayt, = Kodlama1) kodlama
. HttpRequest.FillInFormCollection () +307


Bazı ek ayak işleri yapmaya ve özellikle 500 yazdığı bölümü yayınlamaya ne dersiniz?
OO

3
Mesele bu. Bölüm yok (Microsoft'tan). Sadece ne hakkında konuştuklarını bilmeyen veya bilmeyen resmi olmayan yorumculardan. Zaten bir link ve snippet yayınladım.
colithium

1
@Andrew: Düşünebildiğim tek "çoklu seçim listesi" SelectionMode Çoklu olarak ayarlanmış ListBox olurdu. Bu gerçekten de birden fazla değer gönderebilir. Ancak, soru "açılır listelerden" bahsediyor. Daha sonra soru yazarından herhangi bir yorum bekleyelim.
Wiktor Zychla

1
Bu konuyla ilgili yeni bir soru, düzeltmenin yazı sayısını sınırlandırarak DOS'u azalttığını belirledi.
John Saunders

1
Bkz support.microsoft.com/kb/2661403 Bu konuda ayrıntılı bilgi için.

Yanıtlar:


275

Bu ayarı web.config dosyasına eklemeyi deneyin. Ben sadece bir ASP.NET MVC 2 projesi ile .NET 4.0 üzerinde test ve bu ayar ile kod atmaz:

<appSettings>
  <add key="aspnet:MaxHttpCollectionKeys" value="1001" />
</appSettings>

Bu, sınırı değiştirmek için (güvenlik güncelleştirmesini uyguladıktan sonra) şimdi çalışmalıdır.


Makinemi henüz güncellememiştim, bu yüzden Reflector kullanarak HttpValueCollection sınıfını kontrol ettim ve ThrowIfMaxHttpCollectionKeysExceededyöntem yoktu :

resim açıklamasını buraya girin

Ben yüklü KB2656351 (.NET 4.0 için güncelleştirme), yansıtıcı içinde meclisleri yeniden ve yöntem ortaya çıktı:

resim açıklamasını buraya girin

Yani bu yöntem kesinlikle yeni. Reflektörde Sökme seçeneğini kullandım ve koddan söyleyebileceğim bir AppSetting'i kontrol ediyor:

if (this.Count >= AppSettings.MaxHttpCollectionKeys)
{
  throw new InvalidOperationException();
}

Web.config dosyasında değeri bulamazsa, değeri 1000 in System.Web.Util.AppSettings.EnsureSettingsLoaded(dahili bir statik sınıf) olarak ayarlar :

 _maxHttpCollectionKeys = 0x3e8;

Ayrıca, Alexey Gusarov iki gün önce bu ayarı tweetledi:

Ve burada Jonathan Ness (Güvenlik Geliştirme Müdürü, MSRC) ve Pete Voss (Sr. Response Communications Manager, Güvenilir Bilgi İşlem) ile bir soru-cevap bölümünden resmi bir cevap:

S: AppSettings.MaxHttpCollectionKeys maksimum form girişi sayısını içeren yeni parametreyi kullanıyor mu?

C: Evet öyle.


25
Olağanüstü. Bunlar bana stackoverflow'u
sevdiren

4
Gerçekten yardımcı oldu, keşke başka bir hesabım olsaydı +2 :) verebilirim
misha

1
Bu, tüm sunucu için applicationhost.config dosyasında güncellenebilir mi? veya machine.config?
andryuha

1
Bu limiti sayfa başına kontrol etmenin herhangi bir yolu var mı? ( Burada ve burada da sordum .)
Mike Guthrie

1
Bazı kişiler, web sayfasını bu kadar çok form alanı içermemesi gerektiği için incelemenizi önermiştir. Ancak bu hata için çok geçerli bir senaryo yaşadık - Müşterimizin e-Ticaret sitelerinden birinde alışveriş sepeti çok fazla öğe içeriyordu ve sayfaya erişirken bu hatayı günlüğe kaydettik. Bu gibi durumlarda, maksimum değerin geçersiz kılınması en iyi seçenektir.
Ankur-m

18

Hala .NET 1.1 kullananlarınız için, bu ayar web.config ile yapılandırılmamıştır - bu bir kayıt defteri ayarıdır (michielvoo'ya şapka ipucu, bunu sadece Reflector ile cevabı bulduğu şekilde keşfettiğim için). Aşağıdaki örnek MaxHttpCollectionKeysWindows'un 32 bit sürümlerinde 5000 olarak ayarlanmıştır:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\1.1.4322.0]
"MaxHttpCollectionKeys"=dword:00001388

64 bit Windows sürümü için anahtarı Wow6432Node altında ayarlayın:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\1.1.4322.0]
"MaxHttpCollectionKeys"=dword:00001388

5000'in, bu güvenlik düzeltmesinin hafifletmesi gereken DoS saldırısıyla ilgili olarak makul derecede güvenli bir değer olup olmadığı hakkında bilginiz var mı? Aynı 5000 değeri kullanıyoruz, ancak bir saldırıda istek başına tüketilen değer sayısı ve CPU zamanı arasındaki ilişki hakkında herhangi bir bilgi bulamıyorum ...
Tao

4

Garipliği gören insanlar için buraya 0.02 dolarımı eklemek istiyorum.

Uygulamanız sayfa bilgilerini ASP.NET ViewState'te saklar ve web sunucusu eşiğini aşarsa, bu sorunla karşılaşırsınız. Web.config düzeltme sorununu hemen uygulamak yerine, önce kodunuzu optimize etmeye göz atmak isteyebilirsiniz.

Kaynağı Görüntüle'yi tıklayın ve 1000'den fazla görüntülemede gizli alan olup olmadığına bakın ve sorununuzu çözdünüz.


1000'den fazla görüntüleme alanı alanı? Formda yalnızca bir ViewState alanı yok. Değer, form alanı sayısı arttıkça artan şeydir.
Ankur-m

3

ThrowIfMaxHttpCollectionKeysExceeded()de eklendi System.Web.HttpCookieCollection.

Ne zaman HttpCookieCollection.Get()çağrılmış gibi görünüyor , dahili olarak arıyor HttpCookieCollection.AddCookie(), o zaman çağırıyor ThrowIfMaxHttpCollectionKeysExceeded().

public HttpCookie Get(string name)
{
    HttpCookie cookie = (HttpCookie) base.BaseGet(name);
    if ((cookie == null) && (this._response != null))
    {
        cookie = new HttpCookie(name);
        this.AddCookie(cookie, true);
        this._response.OnCookieAdd(cookie);
    }
    return cookie;
}

internal void AddCookie(HttpCookie cookie, bool append)
{
    this.ThrowIfMaxHttpCollectionKeysExceeded();
    this._all = null;
    this._allKeys = null;
    if (append)
    {
        cookie.Added = true;
        base.BaseAdd(cookie.Name, cookie);
    }
    else
    {
        if (base.BaseGet(cookie.Name) != null)
        {
            cookie.Changed = true;
        }
        base.BaseSet(cookie.Name, cookie);
    }
}

Gördüğümüz şey, birkaç saatlik bir süre boyunca web sitesinin atılmaya başlayana kadar giderek daha yavaş ve üşütücü hale gelmesidir InvalidOperationExcpetion. Daha sonra, sorunu birkaç saat daha düzelten uygulama havuzunu geri dönüştürüyoruz.


Çerez sayım sınırı iyi bir yakalamadır; Açıkladığınız yavaşlama ve huzursuzluk için, isteklerde çerez sayımlarıyla gerçekten bir ilgisi olup olmadığını biliyor musunuz? Aldığınız müşteri taleplerini kontrol ettiniz mi? (uygulamanız bilerek çok sayıda çerez içeren bir şey yapıyor mu?)
Tao

1
Uygulama başlangıcında Request.Cookies koleksiyonuna yanlış bir şekilde tek bir referans gönderen özel bir CookieProvider'a sahip olduğumuz ortaya çıkıyor, daha sonraki her istekte, statik çerez koleksiyonunda bir veya daha fazla çerez olup olmadığını kontrol edecek ... Yukarıdaki koddan da görebileceğiniz gibi. Böylece, zaman içinde, her kullanıcı sisteme erişirken, bu singleton koleksiyonuna çeşitli çerezler ekleniyordu ... ve site çerezlerle veya çerezsiz çalışmak üzere tasarlandığından, bu hata asla (şimdiye kadar) tanımlanmadı
Joshua Barker
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.