ASP.NET MS11-100: ฉันจะเปลี่ยนข้อ จำกัด เกี่ยวกับจำนวนสูงสุดของค่าแบบฟอร์มที่โพสต์ได้อย่างไร


196

Microsoft เมื่อเร็ว ๆ นี้ (12-29-2011) เปิดตัวการปรับปรุงเพื่อแก้ไขช่องโหว่ความปลอดภัยที่ร้ายแรงหลายประการใน. NET Framework หนึ่งในการแก้ไขที่แนะนำโดยMS11-100ช่วยลดการโจมตี DoS ที่อาจเกิดขึ้นชั่วคราวซึ่งเกี่ยวข้องกับการชนกันของตารางแฮช ดูเหมือนว่าการแก้ไขนี้แบ่งหน้าที่มีข้อมูล POST จำนวนมาก ในกรณีของเราบนหน้าเว็บที่มีรายการช่องทำเครื่องหมายที่ใหญ่มาก ทำไมถึงเป็นเช่นนี้?

แหล่งข้อมูลที่ไม่เป็นทางการดูเหมือนจะบ่งบอกว่า MS11-100 มีขีด จำกัด 500 รายการในรายการหลัง ฉันไม่พบแหล่งที่มาของ Microsoft ที่ยืนยันสิ่งนี้ ฉันรู้ว่ามุมมองสถานะและคุณสมบัติกรอบงานอื่น ๆ กินข้อ จำกัด นี้บางส่วน มีการตั้งค่าใด ๆ ที่ควบคุมขีด จำกัด ใหม่นี้หรือไม่? เราสามารถเปลี่ยนจากการใช้ช่องทำเครื่องหมาย แต่ใช้งานได้ดีสำหรับสถานการณ์เฉพาะของเรา เราต้องการใช้ชุดข้อมูลแก้ไขเนื่องจากป้องกันสิ่งที่น่ารังเกียจอื่น ๆ

แหล่งที่มาไม่เป็นทางการพูดถึงขีด จำกัด 500:

บูเลทีนแก้ไขเวกเตอร์การโจมตีของ DOS โดยการ จำกัด จำนวนตัวแปรที่สามารถส่งสำหรับการร้องขอ HTTP POST เดียว ขีด จำกัด เริ่มต้นคือ 500 ซึ่งควรเพียงพอสำหรับเว็บแอปพลิเคชันทั่วไป แต่ก็ยังต่ำพอที่จะต่อต้านการโจมตีดังที่อธิบายโดยนักวิจัยด้านความปลอดภัยในเยอรมนี

แก้ไข: ซอร์สโค้ดพร้อมตัวอย่างของขีด จำกัด (ซึ่งดูเหมือนจะเป็น 1,000 ไม่ใช่ 500) สร้างแอป MVC มาตรฐานและเพิ่มรหัสต่อไปนี้ลงในมุมมองดัชนีหลัก:

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

รหัสนี้ทำงานก่อนแพทช์ มันไม่ทำงานหลังจาก ข้อผิดพลาดคือ:

[InvalidOperationException: การดำเนินการไม่ถูกต้องเนื่องจากสถานะปัจจุบันของวัตถุ]
System.Web.HttpValueCollection การเข้ารหัสโดยไบต์หากการเข้ารหัสสูงสุดโดยการเข้ารหัสแบบดั้งเดิม
[การเข้ารหัสแบบดั้งเดิม] HttpRequest.FillInFormCollection () +307


วิธีการเกี่ยวกับการทำ legwork เพิ่มเติมและโพสต์ในส่วนที่ระบุเฉพาะ 500
OO

3
นั่นคือสิ่งที่ ไม่มีส่วน (จาก Microsoft) จากนักวิจารณ์ที่ไม่เป็นทางการซึ่งอาจจะหรืออาจไม่รู้ว่าพวกเขากำลังพูดถึงอะไร ฉันโพสต์ลิงก์และตัวอย่างแล้ว
colithium

1
@ แอนดรูว์: "รายการเลือกหลายรายการ" เดียวที่ฉันนึกได้ก็คือกล่องรายการที่มี SelectionMode ตั้งเป็นหลายรายการ นี่อาจเป็นไปได้ว่าโพสต์หลายค่า อย่างไรก็ตามคำถามที่กล่าวถึง "รายการแบบเลื่อนลง" จากนั้นเราจะรอความเห็นจากผู้เขียนคำถาม
Wiktor Zychla

1
คำถามล่าสุดในหัวข้อนี้ระบุว่าการแก้ไขทำให้ DOS ลดลงโดย จำกัด จำนวนการโพสต์
John Saunders

1
ดูsupport.microsoft.com/kb/2661403สำหรับรายละเอียดเกี่ยวกับเรื่องนี้

คำตอบ:


275

ลองเพิ่มการตั้งค่านี้ใน web.config ฉันเพิ่งทดสอบสิ่งนี้ใน. NET 4.0 กับโครงการ ASP.NET MVC 2 และด้วยการตั้งค่ารหัสของคุณจะไม่โยน:

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

สิ่งนี้ควรใช้งานได้ในขณะนี้ (หลังจากที่คุณใช้การปรับปรุงความปลอดภัย) เพื่อเปลี่ยนขีด จำกัด


ฉันยังไม่ได้อัปเดตเครื่องของฉันดังนั้นเมื่อใช้ Reflector ฉันจึงตรวจสอบคลาส HttpValueCollection และไม่มีThrowIfMaxHttpCollectionKeysExceededวิธีการ:

ป้อนคำอธิบายรูปภาพที่นี่

ฉันติดตั้งKB2656351 (อัพเดตสำหรับ. NET 4.0) โหลดแอสเซมบลีใน Reflector อีกครั้งและวิธีปรากฏขึ้น:

ป้อนคำอธิบายรูปภาพที่นี่

ดังนั้นวิธีการนี้จึงเป็นของใหม่แน่นอน ฉันใช้ตัวเลือกDisassembleใน Reflector และจากสิ่งที่ฉันสามารถบอกได้จากโค้ดมันจะตรวจสอบ AppSetting:

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

หากไม่พบค่าในไฟล์ web.config มันจะตั้งค่าเป็น 1,000 ในSystem.Web.Util.AppSettings.EnsureSettingsLoaded(คลาสคงที่ภายใน):

 _maxHttpCollectionKeys = 0x3e8;

นอกจากนี้ Alexey Gusarov ยังได้เริ่มทวีตเกี่ยวกับการตั้งค่านี้เมื่อสองวันที่ผ่านมา:

และนี่คือคำตอบอย่างเป็นทางการจากคำถามและคำตอบกับ Jonathan Ness (ผู้จัดการฝ่ายพัฒนาความปลอดภัย MSRC) และ Pete Voss (ผู้จัดการแผนกสื่อสารการตอบสนองของ Sr. , Trustworthy Computing):

Q: AppSettings.MaxHttpCollectionKey เป็นพารามิเตอร์ใหม่ที่มีจำนวนรายการฟอร์มสูงสุดหรือไม่

ตอบ: ใช่


25
ยอดเยี่ยม เหล่านี้คือคำตอบที่ทำให้ฉันชอบ stackoverflow
colithium

4
มันช่วยจริงๆฉันต้องการฉันมีบัญชีอื่นเพื่อที่ฉันจะให้ 2 :)
misha

1
สามารถอัปเดตนี้ใน applicationhost.config สำหรับเซิร์ฟเวอร์ทั้งหมดได้หรือไม่ หรือ machine.config?
andryuha

1
มีวิธีควบคุมขีด จำกัด นี้ในระดับต่อหน้าหรือไม่ (ถามที่นี่และที่นี่ด้วย)
Mike Guthrie

1
บางคนแนะนำให้ตรวจสอบหน้าเว็บเนื่องจากไม่ควรมีฟิลด์ฟอร์มจำนวนมากเหล่านี้ แต่เรามีสถานการณ์ที่ถูกต้องมากสำหรับข้อผิดพลาดนี้ - ตะกร้าสินค้าในไซต์อีคอมเมิร์ซของลูกค้าของเรามีรายการจำนวนมากและเราพบข้อผิดพลาดนี้เมื่อเธอเข้าสู่หน้าเว็บ ในกรณีเช่นนี้การแทนที่ค่าสูงสุดเป็นตัวเลือกที่ดีที่สุด
Ankur-m

18

สำหรับผู้ที่ยังใช้. NET 1.1 การตั้งค่านี้ไม่ได้กำหนดค่าผ่าน web.config - เป็นการตั้งค่ารีจิสตรี (ปลายหมวกของมิเชลโวฉันเพิ่งค้นพบสิ่งนี้ผ่านตัวสะท้อนแบบเดียวกับที่เขาพบคำตอบ) ตัวอย่างด้านล่างตั้งค่าMaxHttpCollectionKeysเป็น 5000 ใน Windows รุ่น 32 บิต:

Windows Registry Editor Version 5.00

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

สำหรับ Windows รุ่น 64 บิตให้ตั้งค่าคีย์ภายใต้ Wow6432Node:

Windows Registry Editor Version 5.00

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

คุณมีข้อมูลใด ๆ เกี่ยวกับว่า 5000 เป็นค่าที่ปลอดภัยพอสมควรหรือไม่เกี่ยวกับการโจมตี DoS ที่ควรแก้ไขเพื่อความปลอดภัยนี้ เรากำลังมองหาที่ใช้ค่า 5000 เดียวกัน แต่ฉันไม่สามารถหาข้อมูลใด ๆ เกี่ยวกับความสัมพันธ์ระหว่างจำนวนค่าและเวลา CPU ที่ใช้ต่อคำขอในการโจมตี ...
Tao

4

ฉันแค่ต้องการเพิ่ม $ 0.02 ของฉันที่นี่สำหรับผู้ที่เห็นความแปลกประหลาด

หากแอปพลิเคชันของคุณหยุดข้อมูลหน้าลงใน ASP.NET ViewState และเกินกว่าขีด จำกัด ของเว็บเซิร์ฟเวอร์คุณจะพบปัญหานี้ แทนที่จะใช้ปัญหาการแก้ไข web.config ทันทีคุณอาจต้องการดูการเพิ่มประสิทธิภาพรหัสของคุณก่อน

ดูแหล่งที่มาและค้นหาเขตข้อมูลที่ซ่อนอยู่ 1,000+ สถานะและคุณมีปัญหา


เขตข้อมูล viewstate มากกว่า 1,000 รายการ ไม่มี ViewState เพียงฟิลด์เดียวในแบบฟอร์ม ค่าคือสิ่งที่เพิ่มขึ้นเมื่อจำนวนเขตข้อมูลฟอร์มเพิ่มขึ้น
Ankur-m

3

ThrowIfMaxHttpCollectionKeysExceeded() ถูกเพิ่มไปยัง System.Web.HttpCookieCollectionยังได้รับการเพิ่ม

ดูเหมือนว่าเมื่อHttpCookieCollection.Get()ถูกเรียกมันเป็นการโทรภายในHttpCookieCollection.AddCookie()ซึ่งจะเป็นการโทร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);
    }
}

สิ่งที่เราเห็นก็คือว่ากำลังในช่วงสองสามชั่วโมงเว็บไซต์ที่ได้รับความก้าวหน้าช้าลงและ buggier InvalidOperationExcpetionจนกระทั่งมันเริ่มขว้างปา จากนั้นเราจะรีไซเคิลแอพพูลซึ่งจะแก้ไขปัญหาได้อีกไม่กี่ชั่วโมง


ขีด จำกัด การนับคุกกี้เป็นสิ่งที่ดี สำหรับการชะลอตัวและ bugginess ที่คุณอธิบายคุณรู้หรือไม่ว่าจริง ๆ แล้วมันมีส่วนเกี่ยวข้องกับการนับคุกกี้ในคำขอหรือไม่ คุณตรวจสอบคำขอของลูกค้าที่คุณได้รับหรือไม่? (แอปของคุณตั้งใจทำบางสิ่งบางอย่างกับคุกกี้จำนวนมากใช่ไหม)
Tao

1
ปรากฎว่าเรามี CookieProvider ที่กำหนดเองซึ่งได้รับการอ้างอิงเดี่ยวไปยังคอลเลกชัน Request.Cookies ในการเริ่มต้นแอพจากนั้นทุกครั้งที่มีการร้องขอในภายหลังมันจะตรวจสอบเพื่อดูว่ามีคุกกี้หนึ่งรายการหรือมากกว่านั้น ... ตามที่คุณเห็นจากโค้ดด้านบน,. สุทธิ ADDS คุกกี้นั้นตามค่าเริ่มต้นหากไม่พบ เมื่อเวลาผ่านไปเนื่องจากผู้ใช้แต่ละรายกำลังเข้าถึงระบบคุกกี้ต่างๆจึงถูกเพิ่มเข้ามาในคอลเล็กชั่นซิงเกิลนี้ ... และเนื่องจากเว็บไซต์ได้รับการออกแบบให้ทำงานโดยมีหรือไม่มีคุกกี้ข้อผิดพลาดนี้ก็ไม่เคยถูกระบุ (จนถึงตอนนี้)
Joshua Barker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.