ASP.NET MS11-100: bagaimana saya bisa mengubah batas jumlah maksimum nilai formulir yang diposting?

196

Microsoft baru-baru ini (12-29-2011) merilis pembaruan untuk mengatasi beberapa kerentanan keamanan serius dalam .NET Framework. Salah satu perbaikan yang diperkenalkan oleh MS11-100 sementara mengurangi potensi serangan DoS yang melibatkan tabrakan tabel hash. Tampaknya perbaikan ini merusak halaman yang berisi banyak data POST. Dalam kasus kami, pada halaman yang memiliki daftar kotak centang sangat besar. Mengapa demikian?

Beberapa sumber non-resmi tampaknya menunjukkan bahwa MS11-100 menempatkan batas 500 pada item pos balik. Saya tidak dapat menemukan sumber Microsoft yang mengkonfirmasi ini. Saya tahu bahwa Lihat Status dan fitur kerangka kerja lainnya memakan sebagian dari batas ini. Apakah ada pengaturan konfigurasi yang mengontrol batas baru ini? Kami dapat beralih dari menggunakan kotak centang tetapi ini bekerja dengan baik untuk situasi khusus kami. Kami juga ingin menerapkan tambalan karena melindungi terhadap beberapa hal buruk lainnya.

Sumber tidak resmi membahas batas 500:

Buletin memperbaiki vektor serangan DOS dengan memberikan batasan jumlah variabel yang dapat diajukan untuk satu permintaan HTTP POST. Batas default adalah 500 yang seharusnya cukup untuk aplikasi web normal, tetapi masih cukup rendah untuk menetralisir serangan seperti yang dijelaskan oleh para peneliti keamanan di Jerman.

EDIT: Kode sumber dengan contoh batas (yang tampaknya 1.000, bukan 500) Buat aplikasi MVC standar dan tambahkan kode berikut ke tampilan indeks utama:

@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>
}

Kode ini berfungsi sebelum tambalan. Itu tidak berhasil setelah itu. Kesalahannya adalah:

[InvalidOperationException: Operasi ini tidak berlaku karena keadaan saat ini objek.]
System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded () 82 System.Web.HttpValueCollection.FillFromEncodedBytes (Byte [] byte, Encoding encoding) 111
System.Web. HttpRequest.FillInFormCollection () +307

colithium
sumber
Bagaimana kalau melakukan kerja keras tambahan dan memposting bagian di mana ia mengatakan secara khusus 500.
OO
3
Itu masalahnya. Tidak ada bagian (dari Microsoft). Hanya dari komentator tidak resmi yang mungkin atau mungkin tidak tahu apa yang mereka bicarakan. Saya tetap memposting tautan dan cuplikan.
colithium
1
@Andrew: Satu-satunya "daftar multi-pilih" yang dapat saya pikirkan adalah ListBox dengan SelectionMode yang diatur ke Banyak. Ini memang mungkin dapat memposting beberapa nilai. Namun, pertanyaannya menyebutkan "daftar dropdown". Mari kita tunggu komentar dari penulis pertanyaan.
Wiktor Zychla
1
Pertanyaan terbaru tentang topik ini menentukan bahwa perbaikan memitigasi DOS dengan membatasi jumlah posting.
John Saunders
1
Lihat support.microsoft.com/kb/2661403 untuk detailnya.

Jawaban:

275

Coba tambahkan pengaturan ini di web.config. Saya baru saja menguji ini pada. NET 4.0 dengan proyek ASP.NET MVC 2 dan dengan pengaturan ini kode Anda tidak melempar:

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

Itu seharusnya berfungsi sekarang (setelah Anda menerapkan pembaruan keamanan) untuk mengubah batas.


Saya belum memperbarui mesin saya, jadi menggunakan Reflector saya memeriksa kelas HttpValueCollection, dan tidak memiliki ThrowIfMaxHttpCollectionKeysExceededmetode:

masukkan deskripsi gambar di sini

Saya menginstal KB2656351 (pembaruan untuk .NET 4.0), memuat ulang rakitan di Reflector dan metode muncul:

masukkan deskripsi gambar di sini

Jadi metode itu pasti baru. Saya menggunakan opsi Disassemble di Reflector, dan dari apa yang saya tahu dari kode itu memeriksa AppSetting:

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

Jika tidak menemukan nilai di file web.config, itu akan menetapkannya menjadi 1000 in System.Web.Util.AppSettings.EnsureSettingsLoaded(kelas statis internal):

 _maxHttpCollectionKeys = 0x3e8;

Juga, Alexey Gusarov tweet tentang pengaturan ini dua hari lalu:

Dan berikut ini adalah jawaban resmi dari tanya jawab dengan Jonathan Ness (Manajer Pengembangan Keamanan, MSRC) dan Pete Voss (Manajer Komunikasi Respons Sr, Komputasi yang Dapat Dipercaya):

T: Apakah AppSettings.MaxHttpCollectionKeys parameter baru yang berisi jumlah maksimum entri formulir?

A: Ya itu.

Michiel van Oosterhout
sumber
25
Hebat. Ini adalah jenis jawaban yang membuat saya suka stackoverflow
colithium
4
Itu sangat membantu, saya berharap saya punya akun lain sehingga saya bisa memberi +2 :)
misha
1
dapatkah ini diperbarui di applicationhost.config untuk seluruh server? atau machine.config?
andryuha
1
Adakah cara untuk mengontrol batas ini pada level per halaman? (Juga bertanya di sini dan di sini .)
Mike Guthrie
1
Beberapa orang menyarankan untuk meninjau halaman web karena seharusnya tidak mengandung banyak bidang formulir ini. Tetapi kami memiliki skenario yang sangat valid untuk kesalahan ini - Keranjang belanja di salah satu situs eCommerce klien kami memiliki banyak item dan kesalahan ini telah dicatat saat dia mengakses halaman. Dalam kasus seperti itu, mengganti nilai maks adalah pilihan terbaik.
Ankur-m
18

Bagi Anda yang masih menggunakan .NET 1.1, pengaturan ini tidak dikonfigurasi melalui web.config - ini adalah pengaturan registri (ujung topi untuk michielvoo, karena saya hanya menemukan ini melalui Reflektor dengan cara yang sama ia menemukan jawabannya). Contoh di bawah ini diatur MaxHttpCollectionKeyske 5000 pada Windows edisi 32-bit:

Windows Registry Editor Version 5.00

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

Untuk edisi Windows 64-bit, atur kunci di bawah Wow6432Node:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\1.1.4322.0]
"MaxHttpCollectionKeys"=dword:00001388
terranwannabe
sumber
Apakah Anda memiliki informasi apakah 5000 adalah nilai yang cukup aman sehubungan dengan serangan DoS yang seharusnya dimitigasi oleh perbaikan keamanan ini? Kami sedang mencari menggunakan nilai 5000 yang sama, tetapi saya tidak dapat menemukan informasi tentang hubungan antara jumlah nilai dan waktu CPU yang dikonsumsi per permintaan dalam serangan ...
Tao
4

Saya hanya ingin menambahkan $ 0,02 saya di sini untuk orang-orang melihat keanehan.

Jika aplikasi Anda menyimpan informasi halaman ke dalam ASP.NET ViewState, dan melebihi ambang batas server web, Anda akan mengalami masalah ini. Daripada menerapkan masalah perbaikan web.config langsung, Anda mungkin ingin melihat mengoptimalkan kode Anda terlebih dahulu.

Lihat Sumber, dan cari 1000+ bidang tampilan tersembunyi, dan Anda punya masalah.

Keinginan tanpa mata
sumber
1000+ bidang kondisi tampilan? Tidak ada hanya satu bidang kondisi tampilan di formulir. Nilainya adalah apa yang bertambah ketika jumlah bidang formulir meningkat.
Ankur-m
3

ThrowIfMaxHttpCollectionKeysExceeded()juga telah ditambahkan ke System.Web.HttpCookieCollection.

Sepertinya ketika HttpCookieCollection.Get()dipanggil, itu panggilan internal HttpCookieCollection.AddCookie(), yang kemudian memanggil 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);
    }
}

Apa yang kami lihat adalah bahwa selama beberapa jam situs web semakin lambat dan buggier, sampai mulai melempar InvalidOperationExcpetion. Kami kemudian mendaur ulang kumpulan aplikasi, yang memperbaiki masalah selama beberapa jam lagi.

Joshua Barker
sumber
Batas jumlah cookie adalah tangkapan yang bagus; Untuk pelambatan dan bugginess yang Anda gambarkan, apakah Anda tahu apakah itu benar-benar ada hubungannya dengan jumlah cookie dalam permintaan? Apakah Anda memeriksa permintaan klien yang Anda terima? (Apakah aplikasi Anda sengaja melakukan sesuatu dengan sejumlah besar cookie?)
Tao
1
ternyata kami memiliki CookieProvider khusus yang salah mengambil referensi tunggal untuk koleksi Request.Cookies saat aplikasi dimulai, kemudian pada setiap permintaan berikutnya, itu akan memeriksa untuk melihat apakah ada satu atau lebih cookie yang ada dalam koleksi cookie statis ... seperti yang dapat Anda lihat dari kode di atas, .Net ADDS cookie itu secara default jika tidak ditemukan. Jadi seiring waktu, ketika setiap pengguna mengakses sistem, berbagai cookie ditambahkan ke koleksi tunggal ini ... dan karena situs dirancang untuk bekerja dengan atau tanpa cookie, bug ini tidak pernah diidentifikasi (sampai sekarang)
Joshua Barker