ตรวจพบคำขอ Request.Form ที่เป็นอันตรายจากไคลเอ็นต์


1471

ทุกครั้งที่ผู้ใช้โพสต์สิ่งที่มี<หรือ>ในหน้าเว็บแอปพลิเคชันของฉันฉันได้รับข้อยกเว้นนี้

ฉันไม่ต้องการพูดคุยเกี่ยวกับความฉลาดของการโยนข้อยกเว้นหรือหยุดแอปพลิเคชั่นเว็บทั้งหมดเพราะมีคนป้อนอักขระในกล่องข้อความ แต่ฉันกำลังมองหาวิธีที่สง่างามในการจัดการสิ่งนี้

วางกับดักข้อยกเว้นและแสดง

เกิดข้อผิดพลาดโปรดย้อนกลับไปและพิมพ์ทั้งฟอร์มของคุณอีกครั้ง แต่คราวนี้โปรดอย่าใช้ <

ดูเหมือนมืออาชีพไม่พอสำหรับฉัน

การปิดใช้งานการตรวจสอบความถูกต้องของโพสต์ ( validateRequest="false") จะหลีกเลี่ยงข้อผิดพลาดนี้ได้อย่างแน่นอน แต่จะทำให้หน้าเว็บมีความเสี่ยงต่อการถูกโจมตีเป็นจำนวนมาก

อุดมคติ: เมื่อมีการโพสต์ย้อนกลับที่มีอักขระที่ จำกัด HTML ค่าที่โพสต์ในคอลเลกชันฟอร์มจะถูกเข้ารหัส HTML โดยอัตโนมัติ ดังนั้น.Textคุณสมบัติของกล่องข้อความของฉันจะเป็นsomething & lt; html & gt;

มีวิธีที่ฉันสามารถทำได้จากตัวจัดการ?


68
โปรดทราบว่าคุณสามารถรับข้อผิดพลาดนี้ได้หากคุณมีชื่อเอนทิตี HTML (& amp;) หรือหมายเลขเอนทิตี (& # 39;) ในข้อมูลที่คุณป้อนด้วย
Drew Noakes

18
ดีเพราะมันเป็นคำถามของฉันฉันรู้สึกว่าฉันสามารถกำหนดสิ่งที่เป็นจริง: crashing กระบวนการสมัครทั้งหมดและกลับข้อผิดพลาดทั่วไปเพราะมีคนพิมพ์ '<' เป็น overkill โดยเฉพาะอย่างยิ่งเมื่อคุณรู้ว่าคนส่วนใหญ่จะเพียงแค่ 'validateRequest = false' เพื่อกำจัดมันจึงเปิดช่องโหว่ใหม่อีกครั้ง
Radu094

7
@DrewNoakes: ชื่อเอนทิตี (& amp;) ดูเหมือนจะไม่เป็นปัญหาตามการทดสอบของฉัน (ทดสอบใน. Net 4.0) แม้ว่าหมายเลขเอนทิตี (& # 39;) จะไม่ผ่านการตรวจสอบความถูกต้อง (ตามที่คุณกล่าว) หากคุณถอดเมธอด System.Web.CrossSiteScriptingValidation.IsDangerousString โดยใช้. Net Reflector คุณจะเห็นว่ารหัสนั้นมีลักษณะเฉพาะสำหรับแท็ก html (เริ่มต้นด้วย <) และหมายเลขเอนทิตี (เริ่มต้นด้วย & #)
Gyum Fox

5
สร้างไซต์ใหม่ใน VS2014 โดยใช้โครงการ MVC เริ่มต้นและเรียกใช้ คลิกที่ลิงค์ลงทะเบียนเพิ่มอีเมลใด ๆ และใช้ "<P455-0r [!" เป็นรหัสผ่าน ข้อผิดพลาดเดียวกันออกมาจากกล่องไม่พยายามทำสิ่งที่เป็นอันตรายฟิลด์รหัสผ่านจะไม่ปรากฏดังนั้นจึงไม่ใช่การโจมตี XSS แต่วิธีเดียวที่จะแก้ไขได้คือลบการตรวจสอบความถูกต้องทั้งหมดด้วย ValidateInput (false) ? คำแนะนำ AllowHtml ไม่ทำงานในสถานการณ์นี้ แต่ยังคงมีข้อผิดพลาดเดียวกันอยู่ ตรวจพบคำขอ Request.Form ที่เป็นอันตรายจากไคลเอ็นต์ (รหัสผ่าน = "<P455-0r [!")
stephenbayer

TL; DR วาง<httpRuntime requestValidationMode="2.0" />ใน web.config

คำตอบ:


1080

ฉันคิดว่าคุณกำลังโจมตีจากมุมที่ผิดโดยพยายามเข้ารหัสข้อมูลที่โพสต์ทั้งหมด

โปรดทราบว่า " <" อาจมาจากแหล่งภายนอกอื่น ๆ เช่นฟิลด์ฐานข้อมูลการกำหนดค่าไฟล์ฟีดและอื่น ๆ

นอกจากนี้ " <" ไม่เป็นอันตรายโดยเนื้อแท้ มันอันตรายเฉพาะในบริบทที่ระบุ: เมื่อเขียนสตริงที่ไม่ได้เข้ารหัสไปยังเอาต์พุต HTML (เนื่องจาก XSS)

ในบริบทอื่นสตริงย่อยที่แตกต่างกันมีอันตรายตัวอย่างเช่นถ้าคุณเขียน URL ที่ผู้ใช้ระบุลงในลิงก์ซับสตริง " javascript:" อาจเป็นอันตราย อักขระอัญประกาศเดี่ยวในอีกทางหนึ่งเป็นอันตรายเมื่อทำการแทรกสตริงในแบบสอบถาม SQL แต่ปลอดภัยอย่างสมบูรณ์หากเป็นส่วนหนึ่งของชื่อที่ส่งมาจากแบบฟอร์มหรืออ่านจากเขตข้อมูลฐานข้อมูล

บรรทัดล่างคือ: คุณไม่สามารถกรองอินพุตแบบสุ่มสำหรับอักขระอันตรายเนื่องจากอักขระใด ๆ อาจมีอันตรายภายใต้สถานการณ์ที่เหมาะสม คุณควรเข้ารหัส ณ จุดที่อักขระบางตัวอาจเป็นอันตรายเนื่องจากอักขระเหล่านั้นข้ามไปเป็นภาษาย่อยอื่นที่มีความหมายพิเศษ เมื่อคุณเขียนสตริงเป็น HTML คุณควรเข้ารหัสอักขระที่มีความหมายพิเศษใน HTML โดยใช้ Server.HtmlEncode หากคุณส่งสตริงไปยังคำสั่ง SQL แบบไดนามิกคุณควรเข้ารหัสอักขระที่แตกต่างกัน (หรือดีกว่าปล่อยให้กรอบทำเพื่อคุณโดยใช้คำสั่งที่เตรียมไว้หรือสิ่งที่คล้ายกัน)

เมื่อคุณแน่ใจว่าคุณเข้ารหัส HTML ทุกที่ที่คุณส่งสตริงไปยัง HTML จากนั้นตั้งค่าvalidateRequest="false"ใน<%@ Page ... %>คำสั่งใน.aspxไฟล์ของคุณ

ใน. NET 4 คุณอาจต้องทำมากกว่านี้ บางครั้งก็จำเป็นต้องเพิ่ม<httpRuntime requestValidationMode="2.0" />web.config ด้วย ( อ้างอิง )


74
สำหรับผู้ที่มาสาย: validateRequest = "false" จะอยู่ใน Page directive (บรรทัดแรกของไฟล์. aspx ของคุณ)
MGOwen

56
เคล็ดลับ: ใส่<httpRuntime requestValidationMode="2.0" />แท็กตำแหน่งเพื่อหลีกเลี่ยงการฆ่าการป้องกันที่มีประโยชน์ที่ได้รับจากการตรวจสอบจากส่วนที่เหลือของไซต์
ไบรอัน

297
ใน MVC3 นี่เป็น[AllowHtml]คุณสมบัติของโมเดล
Jeremy Holovacs

2
ปิดการใช้งานทั่วโลกสำหรับ MVC 3 คุณยังต้องในGlobalFilters.Filters.Add(new ValidateInputAttribute(false)); Application_Start()
Alex

15
@MGOwen คุณยังสามารถเพิ่มคำสั่งหน้าเพื่อ web.config ผ่านทางใน<pages validateRequest="false" /> <system.web />การทำเช่นนั้นจะใช้คุณสมบัตินี้กับทุกหน้า
oliver-clare

504

มีวิธีแก้ไขข้อผิดพลาดนี้แตกต่างกันหากคุณใช้ ASP.NET MVC:

ตัวอย่าง C #:

[HttpPost, ValidateInput(false)]
public ActionResult Edit(FormCollection collection)
{
    // ...
}

ตัวอย่าง Visual Basic:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function

ปัญหาอาจเกิดขึ้นได้เมื่อต้องการในหนึ่งหน้าของการสมัครทั้งหมด

3
นอกจากนี้คุณยังสามารถเพิ่มแอตทริบิวต์ [ValidateInput (false)] ที่ระดับชั้นเรียน ถ้าคุณเพิ่มลงในคลาสตัวควบคุมพื้นฐานของมันมันจะนำไปใช้กับการกระทำวิธีการควบคุมทั้งหมด
Shan Plourde

@ แซคขอบคุณสำหรับการแก้ปัญหา ในทางกลับกันฉันสงสัยว่า[AllowHtml]ดีกว่าValidateInput(false)เพราะ[AllowHtml]ถูกกำหนดในครั้งเดียวสำหรับคุณสมบัติเช่นฟิลด์ตัวแก้ไขและเมื่อใดก็ตามที่มีการใช้งานไม่จำเป็นต้องใช้มันสำหรับการกระทำหลายอย่าง คุณแนะนำอะไร?
แจ็ค

@Zack Peterson ปลอดภัยไหมที่จะใช้? ไม่มีปัญหาด้านความปลอดภัย?
shrey Pav

416

ใน ASP.NET MVC (เริ่มต้นในเวอร์ชัน 3) คุณสามารถเพิ่มแอAllowHtmlททริบิวให้กับคุณสมบัติในโมเดลของคุณ

จะช่วยให้การร้องขอที่จะรวมมาร์กอัป HTML ในระหว่างการผูกแบบจำลองโดยการข้ามการตรวจสอบคำขอสำหรับคุณสมบัติ

[AllowHtml]
public string Description { get; set; }

12
ดีกว่าที่จะทำอย่างนี้มากกว่าในคอนโทรลเลอร์!
Andiih

29
คำตอบที่ถูกต้องเท่านั้น! การปิดใช้งานการตรวจสอบความถูกต้องเกี่ยวกับการกระทำของคอนโทรลเลอร์นั้นเป็นการแฮ็ก และสำหรับการปิดใช้งานการตรวจสอบความถูกต้องของระดับแอปพลิเคชันนั้น devs ต้องถูกแขวน!
trailmax

สิ่งนี้หายไปใน MVC 4 หรือไม่
granadaCoder

1
ความแตกต่างระหว่างValidateInput(false)และAllowHtmlคืออะไร? ข้อดีของอีกด้านหนึ่งคืออะไร เมื่อฉันต้องการที่จะใช้AllowHtmlแทนValidateInput(false)? เมื่อไหร่ที่ฉันจะต้องการใช้ValidateInput(false)มากกว่าAllowHtml? เมื่อใดที่ฉันต้องการใช้ทั้งสอง มันสมเหตุสมผลไหมที่จะใช้ทั้งสองอย่าง?
Ian Boyd

3
ValidateInput เป็นวิธีการที่ AllowHtml อยู่ในคุณสมบัติของแบบจำลอง - ดังนั้นคุณจะอนุญาตเฉพาะสิ่งที่คุณคาดหวังว่าจะมี html - ไม่ใช่ทั้งหมด
Anthony Johnston

213

หากคุณใช้งาน. NET 4.0 ต้องแน่ใจว่าคุณเพิ่มสิ่งนี้ลงในไฟล์web.configภายใน<system.web>แท็ก:

<httpRuntime requestValidationMode="2.0" />

ใน. NET 2.0 การตรวจสอบคำขอจะถูกนำไปใช้กับaspxการร้องขอเท่านั้น ใน. NET 4.0 นี้ถูกขยายเพื่อรวมคำขอทั้งหมด คุณสามารถย้อนกลับไปใช้การตรวจสอบความถูกต้อง XSS เมื่อดำเนินการ.aspxโดยระบุ:

requestValidationMode="2.0"

คุณสามารถปิดใช้งานการตรวจสอบคำขอทั้งหมดโดยระบุ:

validateRequest="false"

30
ภายใน<system.web>แท็ก
Hosam Aly

8
ฉันได้ใส่ไว้ใน web.config แต่ยังคงมีข้อผิดพลาด "คำขอที่อาจเป็นอันตรายค่ารูปแบบ"
Filip

20
ดูเหมือนว่า <httpRuntime requestValidationMode = "2.0" /> จะทำงานเฉพาะเมื่อมีการติดตั้งเฟรมเวิร์ก 2.0 บนเครื่อง จะเกิดอะไรขึ้นถ้า 2.0 Framework ไม่ได้ถูกติดตั้งเลย แต่มีการติดตั้ง 4.0 framework เท่านั้น?
ซามูเอล

ทั้งหมดนี้ใช้งานได้สำหรับฉัน ไม่มีเอกสารขั้นตอนในคำตอบอื่น ๆ ที่จำเป็น (รวมถึง validateRequest = "false")!
ทอม redfern

112

สำหรับ ASP.NET 4.0 คุณสามารถอนุญาตให้มาร์กอัปเป็นข้อมูลป้อนเข้าสำหรับหน้าเว็บเฉพาะแทนที่จะเป็นทั้งไซต์ได้โดยใส่ไว้ใน<location>องค์ประกอบ สิ่งนี้จะทำให้แน่ใจว่าหน้าอื่น ๆ ของคุณปลอดภัย คุณไม่จำเป็นต้องใส่ValidateRequest="false"ในหน้า. aspx ของคุณ

<configuration>
...
  <location path="MyFolder/.aspx">
    <system.web>
      <pages validateRequest="false" />
      <httpRuntime requestValidationMode="2.0" />
    </system.web>
  </location>
...
</configuration>

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

คุณยังต้องตรวจสอบข้อมูลโดยทางโปรแกรมในหน้าที่ปิดใช้งานการตรวจสอบคำขอ


ข้อมูลเพิ่มเติมเกี่ยวกับ requestValidationMode = 2 | 4 ที่นี่: msdn.microsoft.com/en-us/library/…
GlennG

น่าเศร้าที่นี่ไม่สามารถทำงานกับ ASP.net 2.0 ได้ ลบบรรทัด httpRuntime และจะใช้งานได้
Fandango68

ฉันได้เพิ่มคำเตือนให้เตือนผู้คนให้ตรวจสอบอินพุตด้วยตนเองเมื่อปิดใช้งานการตรวจสอบความถูกต้อง
Carter Medlin

72

คำตอบก่อนหน้านี้ยอดเยี่ยม แต่ไม่มีใครพูดถึงวิธีการยกเว้นเขตข้อมูลเดียวจากการตรวจสอบความถูกต้องสำหรับการฉีด HTML / JavaScript ฉันไม่รู้เกี่ยวกับเวอร์ชันก่อนหน้า แต่ใน MVC3 Beta คุณสามารถทำได้:

[HttpPost, ValidateInput(true, Exclude = "YourFieldName")]
public virtual ActionResult Edit(int id, FormCollection collection)
{
    ...
}

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

ฉันใช้สิ่งนี้เพื่อตรวจสอบการแสดงออกปกติ ฉันสร้าง ValidationAttribute ของตัวเองขึ้นมาเพื่อดูว่านิพจน์ปกตินั้นใช้ได้หรือไม่ เนื่องจากนิพจน์ทั่วไปสามารถมีบางสิ่งที่ดูเหมือนว่าสคริปต์ที่ฉันใช้โค้ดด้านบน - นิพจน์ทั่วไปยังคงถูกตรวจสอบว่ามันถูกต้องหรือไม่ แต่ไม่ใช่ถ้ามันมีสคริปต์หรือ HTML


10
น่าเสียดายที่ดูเหมือนว่าคุณลักษณะการยกเว้นถูกลบออกจาก MVC 3 RTW :(
Matt Greer

2
และไม่รวมอยู่ใน MVC 4
wilsjd

9
ใช้[AllowHtml]คุณสมบัติของโมเดลแทน[ValidateInput]การกระทำเพื่อให้ได้ผลลัพธ์ที่เหมือนกัน
Mrchief

2
@Christof โปรดทราบว่าคำตอบของฉันคือ 5 ปี ฉันไม่ได้เจอปัญหานี้มานานมากดังนั้นอาจมีวิธีที่ดีกว่าในการจัดการกับมัน เกี่ยวกับสองตัวเลือกนี้ฉันคิดว่ามันขึ้นอยู่กับสถานการณ์ของคุณ บางทีคุณอาจเปิดเผยรูปแบบนั้นมากกว่าหนึ่งการกระทำและในบางสถานที่อนุญาตให้ใช้ HTML ได้หรือไม่ ในกรณีเช่นนี้[AllowHtml]จะไม่มีตัวเลือก ฉันขอแนะนำให้ตรวจสอบบทความนี้: weblogs.asp.net/imranbaloch/ …แต่มันค่อนข้างเก่าและอาจล้าสมัย
gligoran

1
ยังคงมีวิธีที่จะแยกพารามิเตอร์วิธีเฉพาะออกจากการตรวจสอบตรวจสอบคำตอบของฉันที่นี่: stackoverflow.com/a/50796666/5/52121
อเล็กซ์

51

ใน ASP.NET MVC คุณต้องตั้งค่า requestValidationMode = "2.0" และ validateRequest = "false" ใน web.config และใช้แอตทริบิวต์ ValidateInput กับการกระทำของคอนโทรลเลอร์:

<httpRuntime requestValidationMode="2.0"/>

<configuration>
    <system.web>
        <pages validateRequest="false" />
    </system.web>
</configuration>

และ

[Post, ValidateInput(false)]
public ActionResult Edit(string message) {
    ...
}

2
สำหรับฉันvalidateRequest="false"ไม่จำเป็นเท่านั้นrequestValidationMode="2.0"
tom redfern

requestValidationMode = "2.0" ยังคงสร้างข้อผิดพลาดด้วยข้อมูล HTML ที่เข้ารหัส ไม่มีวิธีแก้ปัญหายกเว้น base64 เข้ารหัสทุกอย่างจากนั้นส่งพร้อม
MC9000

48

คุณสามารถHTML เข้ารหัสเนื้อหาของกล่องข้อความได้ แต่น่าเสียดายที่นั่นจะไม่หยุดข้อยกเว้นเกิดขึ้น จากประสบการณ์ของฉันไม่มีทางและคุณต้องปิดการใช้งานการตรวจสอบหน้า เมื่อทำอย่างนั้นคุณจะพูดว่า: "ฉันจะระวังให้ดีฉันสัญญา"


43

สำหรับ MVC ให้ละเว้นการตรวจสอบอินพุตโดยเพิ่ม

[ValidateInput (เท็จ)]

ด้านบนแต่ละแอคชั่นในคอนโทรลเลอร์


ดูเหมือนว่ามันจะไม่ทำงานในกรณีที่ไปถึงวิธีการควบคุมผ่านเส้นทางที่กำหนดไว้
PandaWood

ที่จริงแล้วคำอธิบายทางเทคนิคคือการทำงานเฉพาะเมื่อตัวละครที่ละเมิดอยู่ใน "สตริงการสืบค้น" ... ถ้ามันอยู่ในเส้นทางคำขอแอตทริบิวต์การตรวจสอบไม่ทำงาน
PandaWood

42

คุณสามารถตรวจจับข้อผิดพลาดนั้นได้ใน Global.asax ฉันยังต้องการตรวจสอบ แต่แสดงข้อความที่เหมาะสม ในบล็อกที่แสดงด้านล่างมีตัวอย่างเช่นนี้ให้บริการ

    void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError();

        if (ex is HttpRequestValidationException)
        {
            Response.Clear();
            Response.StatusCode = 200;
            Response.Write(@"[html]");
            Response.End();
        }
    }

การเปลี่ยนเส้นทางไปยังหน้าอื่นนั้นดูเหมือนว่าเป็นการตอบสนองที่สมเหตุสมผลต่อข้อยกเว้น

http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html


40

คำตอบสำหรับคำถามนี้ง่ายมาก:

var varname = Request.Unvalidated["parameter_name"];

สิ่งนี้จะปิดใช้งานการตรวจสอบความถูกต้องสำหรับคำขอเฉพาะ


1
ใช้งานได้กับ ASP.NET 4.5 เท่านั้น (และสันนิษฐานว่าจะเกิดอะไรขึ้นหลังจากนั้น) 4.5 รุ่นก่อนไม่รองรับสิ่งนี้
Beska

3
ฉันหวังว่าฉันจะชนอย่างนี้ได้ ฉันใช้. NET 4.5 และนี่คือสิ่งที่ฉันต้องการเนื่องจากฉันไม่ได้ใช้ MVC และฉันไม่สามารถเปลี่ยน web.config ได้
Chris Gillum

1
ใช่ แต่ถ้าคุณใช้. Net 2 พวกเราบางคนไม่มีทางเลือก
Fandango68

สิ่งนี้รับพารามิเตอร์ POST หรือ GET หรือไม่
max4ever

คุณกำลังพูดนี้ป้องกันข้อยกเว้นที่ถูกโยนไปแล้ว? หรือไม่ .net 4.5 ล่าช้ายกเว้นและการตรวจสอบจนกว่าข้อมูลที่เป็นจริงอ่านจากRequest?
ebyrob

34

โปรดทราบว่าตัวควบคุม. NET บางตัวจะเข้ารหัส HTML เอาท์พุทโดยอัตโนมัติ ยกตัวอย่างเช่นการตั้งค่าคุณสมบัติ. Text ใน TextBox control จะทำการเข้ารหัสโดยอัตโนมัติ นั่นหมายถึงเฉพาะการแปลง<เข้า&lt;, >เข้า&gt;และออกเป็น& &amp;ดังนั้นจงระวังที่จะทำสิ่งนี้ ...

myTextBox.Text = Server.HtmlEncode(myStringFromDatabase); // Pseudo code

อย่างไรก็ตามคุณสมบัติ. Text สำหรับ HyperLink, Literal และ Label จะไม่เข้ารหัส HTML ดังนั้นให้ทำการตัด Server.HtmlEncode (); สิ่งใดก็ตามที่ถูกตั้งค่าบนคุณสมบัติเหล่านี้เป็นสิ่งจำเป็นหากคุณต้องการป้องกันไม่ให้<script> window.location = "http://www.google.com"; </script>มีการแสดงผลในหน้าของคุณ

ทำการทดลองเล็ก ๆ น้อย ๆ เพื่อดูว่าอะไรถูกเข้ารหัสและอะไรไม่ได้


29

ในไฟล์ web.config ภายในแท็กแทรกองค์ประกอบ httpRuntime ด้วยแอตทริบิวต์ requestValidationMode = "2.0" ยังเพิ่มแอตทริบิวต์ validateRequest = "false" ในองค์ประกอบหน้า

ตัวอย่าง:

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>

1
สำหรับฉัน validateRequest = "false" ไม่จำเป็นต้องร้องขอ requestValidationMode = "2.0"
tom redfern

3
ส่วน "หน้า" จะต้องอยู่ในส่วน "system.web"
Carter Medlin

คำตอบที่เป็นอันตรายอีกครั้ง
MC9000

ฉันต้องการทั้งคู่ ขอบคุณ
แจ็ค

23

หากคุณไม่ต้องการปิดการใช้งาน ValidateRequest คุณต้องใช้ฟังก์ชั่น JavaScript เพื่อหลีกเลี่ยงข้อยกเว้น มันไม่ใช่ตัวเลือกที่ดีที่สุด แต่ใช้งานได้

function AlphanumericValidation(evt)
{
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode :
        ((evt.which) ? evt.which : 0));

    // User type Enter key
    if (charCode == 13)
    {
        // Do something, set controls focus or do anything
        return false;
    }

    // User can not type non alphanumeric characters
    if ( (charCode <  48)                     ||
         (charCode > 122)                     ||
         ((charCode > 57) && (charCode < 65)) ||
         ((charCode > 90) && (charCode < 97))
       )
    {
        // Show a message or do something
        return false;
    }
}

จากนั้นในโค้ดด้านหลังในเหตุการณ์ PageLoad ให้เพิ่มแอททริบิวในการควบคุมของคุณด้วยโค้ดถัดไป:

Me.TextBox1.Attributes.Add("OnKeyPress", "return AlphanumericValidation(event);")

4
วิธีนี้จะทำให้แอพมีความเสี่ยงจากคำขอ POST ที่สร้าง ผู้ใช้ทั่วไปจะมีปัญหาในการป้อนตัวอักษรเช่น: หรือคำพูด แต่แฮกเกอร์ปกติจะไม่มีปัญหาในการโพสต์ข้อมูลที่มีรูปแบบไม่ถูกต้องไปยังเซิร์ฟเวอร์ ฉันจะทำลายมัน waaay ลง
Radu094

13
@ Radu094: วิธีนี้ช่วยให้คุณตรวจสอบ ValidateRequest = true ซึ่งหมายความว่าแฮกเกอร์จะยังคงโจมตีกำแพงนั้นอยู่ ลงคะแนนเนื่องจากสิ่งนี้ทำให้คุณมีความเสี่ยงน้อยกว่าการปิดใช้งาน ValidateRequest
jbehren

21

ดูเหมือนว่ายังไม่มีใครได้กล่าวถึงด้านล่าง แต่มันแก้ไขปัญหาสำหรับฉัน และก่อนใครบอกว่าใช่มันเป็น Visual Basic ... yuck

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Example.aspx.vb" Inherits="Example.Example" **ValidateRequest="false"** %>

ฉันไม่ทราบว่ามีข้อเสียหรือไม่ แต่สำหรับฉันมันใช้งานได้ดีมาก


ใช้งานได้กับเว็บฟอร์ม c # หรือ VB
TheAlbear

19

ทางออกอื่นคือ:

protected void Application_Start()
{
    ...
    RequestValidator.Current = new MyRequestValidator();
}

public class MyRequestValidator: RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        bool result = base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);

        if (!result)
        {
            // Write your validation here
            if (requestValidationSource == RequestValidationSource.Form ||
                requestValidationSource == RequestValidationSource.QueryString)

                return true; // Suppress error message
        }
        return result;
    }
}

ดี! ไม่ทราบถึงความสามารถในการแทนที่ Request Validator แทนที่จะพูดว่า "ตกลง" เหมือนกับที่คุณทำฉันขยายแนวคิดนี้เพื่อไม่ตรวจสอบความถูกต้องของฟิลด์ที่ลงท้ายด้วย "_NoValidation" เป็นชื่อของพวกเขา รหัสด้านล่าง
Walden Leverich

Walden Leverich การทำเช่นนี้ดู [AllowHtml] attribure
Sel

ใช่ในสภาพแวดล้อม MVC ที่จะทำงาน แต่ในแอปพลิเคชัน webforms ฉันไม่มีโมเดลให้ทำ :-)
Walden Leverich

15

หากคุณใช้กรอบงาน 4.0 รายการใน web.config (<pages validateRequest = "false" />)

<configuration>
    <system.web>
        <pages validateRequest="false" />
    </system.web>
</configuration>

หากคุณใช้เฟรมเวิร์ก 4.5 ดังนั้นรายการใน web.config (requestValidationMode = "2.0")

<system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" requestValidationMode="2.0"/>
</system.web>

ถ้าคุณต้องการเพียงหน้าเดียวในไฟล์ aspx คุณควรใส่บรรทัดแรกดังนี้:

<%@ Page EnableEventValidation="false" %>

หากคุณมีสิ่งที่ชอบ <% @ Page อยู่แล้วให้เพิ่มที่เหลือ => EnableEventValidation="false"%>

ฉันไม่แนะนำให้ทำ


13

ใน ASP.NET คุณสามารถตรวจจับข้อยกเว้นและทำบางสิ่งกับมันได้เช่นการแสดงข้อความที่เป็นมิตรหรือเปลี่ยนเส้นทางไปยังหน้าอื่น ... นอกจากนี้ยังมีความเป็นไปได้ที่คุณสามารถจัดการการตรวจสอบด้วยตัวเอง ...

แสดงข้อความที่เป็นมิตร:

protected override void OnError(EventArgs e)
{
    base.OnError(e);
    var ex = Server.GetLastError().GetBaseException();
    if (ex is System.Web.HttpRequestValidationException)
    {
        Response.Clear();
        Response.Write("Invalid characters."); //  Response.Write(HttpUtility.HtmlEncode(ex.Message));
        Response.StatusCode = 200;
        Response.End();
    }
}

13

ฉันเดาว่าคุณสามารถทำได้ในโมดูล แต่นั่นเปิดคำถามบางอย่าง; ถ้าคุณต้องการบันทึกอินพุตไปยังฐานข้อมูล ทันใดนั้นเนื่องจากคุณกำลังบันทึกข้อมูลที่เข้ารหัสลงในฐานข้อมูลคุณจะเชื่อใจข้อมูลที่ป้อนเข้าซึ่งอาจเป็นความคิดที่ไม่ดี เป็นการดีที่คุณจะเก็บข้อมูลดิบที่ไม่มีการเข้ารหัสในฐานข้อมูลและการเข้ารหัสทุกครั้ง

ปิดการใช้งานการป้องกันในระดับต่อหน้าแล้วเข้ารหัสในแต่ละครั้งเป็นตัวเลือกที่ดีกว่า

แทนที่จะใช้ Server.HtmlEncode คุณควรดูไลบรารี Anti-XSSที่ใหม่กว่าและสมบูรณ์กว่าจากทีม Microsoft ACE


12

สาเหตุ

ASP.NET โดยค่าเริ่มต้นตรวจสอบควบคุมการนำเข้าทั้งหมดของเนื้อหาที่อาจไม่ปลอดภัยที่สามารถนำไปสู่การcross-site scripting (XSS) และการฉีด SQL ดังนั้นจึงไม่อนุญาตเนื้อหาดังกล่าวโดยการโยนข้อยกเว้นข้างต้น โดยค่าเริ่มต้นขอแนะนำให้อนุญาตให้การตรวจสอบนี้เกิดขึ้นในแต่ละ postback

สารละลาย

ในหลายโอกาสคุณต้องส่งเนื้อหา HTML ไปยังหน้าของคุณผ่าน Rich TextBox หรือ Rich Text Editors ในกรณีนั้นคุณสามารถหลีกเลี่ยงข้อยกเว้นนี้ได้โดยการตั้งค่าแท็ก ValidateRequest ใน@Pageคำสั่งเป็นเท็จ

<%@ Page Language="C#" AutoEventWireup="true" ValidateRequest = "false" %>

สิ่งนี้จะปิดใช้งานการตรวจสอบคำขอสำหรับหน้าเว็บที่คุณตั้งค่าสถานะ ValidateRequest เป็นเท็จ หากคุณต้องการปิดใช้งานสิ่งนี้ให้ตรวจสอบตลอดทั้งเว็บแอปพลิเคชันของคุณ คุณจะต้องตั้งค่าเป็นเท็จในส่วน web.config <system.web> ของคุณ

<pages validateRequest ="false" />

สำหรับ. NET 4.0 หรือเฟรมเวิร์กที่สูงกว่าคุณจะต้องเพิ่มบรรทัดต่อไปนี้ในส่วน <system.web> เพื่อให้การทำงานด้านบน

<httpRuntime requestValidationMode = "2.0" />

แค่นั้นแหละ. ฉันหวังว่านี่จะช่วยคุณในการกำจัดปัญหาข้างต้น

การอ้างอิงโดย: ข้อผิดพลาด ASP.Net: ตรวจพบค่า Request.Form ที่เป็นอันตรายจากไคลเอ็นต์


10

ฉันพบโซลูชันที่ใช้ JavaScript เพื่อเข้ารหัสข้อมูลซึ่งถอดรหัสใน. NET (และไม่ต้องการ jQuery)

  • ทำให้กล่องข้อความเป็นองค์ประกอบ HTML (เช่น textarea) แทน ASP หนึ่ง
  • เพิ่มเขตข้อมูลที่ซ่อนอยู่
  • เพิ่มฟังก์ชั่น JavaScript ต่อไปนี้ในส่วนหัวของคุณ

    ฟังก์ชัน boo () {targetText = document.getElementById ("HiddenField1"); sourceText = document.getElementById ("userbox"); targetText.value = escape (sourceText.innerText); }

ใน textarea ของคุณรวม onchange ที่เรียก boo ():

<textarea id="userbox"  onchange="boo();"></textarea>

ในที่สุดใน. NET ใช้

string val = Server.UrlDecode(HiddenField1.Value);

ฉันรู้ว่านี่เป็นแบบทางเดียว - หากคุณต้องการสองทางคุณจะต้องมีความคิดสร้างสรรค์ แต่นี่เป็นวิธีแก้ปัญหาหากคุณไม่สามารถแก้ไขเว็บได้

นี่คือตัวอย่างฉัน (MC9000) มาพร้อมกับและใช้งานผ่าน jQuery:

$(document).ready(function () {

    $("#txtHTML").change(function () {
        var currentText = $("#txtHTML").text();
        currentText = escape(currentText); // Escapes the HTML including quotations, etc
        $("#hidHTML").val(currentText); // Set the hidden field
    });

    // Intercept the postback
    $("#btnMyPostbackButton").click(function () {
        $("#txtHTML").val(""); // Clear the textarea before POSTing
                               // If you don't clear it, it will give you
                               // the error due to the HTML in the textarea.
        return true; // Post back
    });


});

และมาร์กอัป:

<asp:HiddenField ID="hidHTML" runat="server" />
<textarea id="txtHTML"></textarea>
<asp:Button ID="btnMyPostbackButton" runat="server" Text="Post Form" />

มันใช้งานได้ดี หากแฮกเกอร์พยายามโพสต์ผ่านทาง JavaScript พวกเขาจะเห็นข้อผิดพลาด คุณสามารถบันทึกข้อมูลทั้งหมดที่เข้ารหัสไว้ในฐานข้อมูลได้เช่นกันจากนั้นยกเลิกการปิดบังข้อมูล (ด้านเซิร์ฟเวอร์) และแยกวิเคราะห์และตรวจสอบการโจมตีก่อนที่จะแสดงที่อื่น


นี่เป็นทางออกที่ดี มันเป็นวิธีที่ถูกต้องในการควบคุมด้วยตนเองและไม่ทำให้เว็บไซต์หรือหน้าทั้งหมดใช้งานไม่ได้
Fandango68

ตรวจสอบให้แน่ใจว่าใช้มาร์กอัพ HTML ไม่ใช่ตัวควบคุม ASP.Net (เช่น no runat = "server") สำหรับ textarea จากนั้นใช้ตัวควบคุม ASP.Net ที่ซ่อนอยู่เพื่อซ่อน นี่เป็นทางออกที่ดีที่สุดที่ฉันเคยเห็นโดยไม่กระทบอะไรเลย โดยปกติคุณต้องการแยกวิเคราะห์ข้อมูลของคุณสำหรับ XSS, SQL Injection ที่ฝั่งเซิร์ฟเวอร์ แต่อย่างน้อยคุณก็สามารถโพสต์ HTML ได้
MC9000

escape(...)อาจใช้เวลานาน ในกรณีของฉันมาร์กอัพเป็นไฟล์ XML ทั้งหมด (2MB) คุณอาจถามว่า "ทำไมคุณไม่ใช้<input type="file"...และฉันเห็นด้วยกับคุณ :)
Red Pea

10

วิธีแก้ปัญหาอื่น ๆ ที่นี่เป็นสิ่งที่ดี แต่มันก็เป็นความเจ็บปวดเล็กน้อยที่ต้องใช้ [AllowHtml] กับทุกรุ่นของคุณสมบัติโดยเฉพาะอย่างยิ่งถ้าคุณมีโมเดลกว่า 100 แบบในไซต์ที่มีขนาดเหมาะสม

ถ้าชอบฉันคุณต้องการที่จะปิดฟีเจอร์นี้ (IMHO สวยไร้จุดหมาย) กว้างไซต์คุณสามารถแทนที่ Execute () วิธีการในตัวควบคุมฐานของคุณ (ถ้าคุณยังไม่มีตัวควบคุมฐานฉันขอแนะนำให้คุณทำมัน ค่อนข้างมีประโยชน์สำหรับการใช้ฟังก์ชั่นทั่วไป)

    protected override void Execute(RequestContext requestContext)
    {
        // Disable requestion validation (security) across the whole site
        ValidateRequest = false;
        base.Execute(requestContext);
    }

ตรวจสอบให้แน่ใจว่าคุณเข้ารหัส HTML ทุกอย่างที่ถูกบีบอัดไปยังมุมมองที่มาจากการป้อนข้อมูลของผู้ใช้ (เป็นพฤติกรรมเริ่มต้นใน ASP.NET MVC 3 ที่มีมีดโกนอยู่แล้วดังนั้นเว้นแต่เหตุผลแปลก ๆ ที่คุณใช้ Html.Raw () ไม่ควรต้องใช้คุณสมบัตินี้


9

ฉันได้รับข้อผิดพลาดนี้ด้วย

ในกรณีของฉันผู้ใช้ป้อนอักขระเน้นเสียงáในชื่อบทบาท (เกี่ยวข้องกับผู้ให้บริการสมาชิก ASP.NET)

ฉันส่งชื่อบทบาทไปยังวิธีการที่ให้สิทธิ์ผู้ใช้ในบทบาทนั้นและ$.ajaxคำขอโพสต์ล้มเหลวอย่างน่าสังเวช ...

ฉันทำสิ่งนี้เพื่อแก้ปัญหา:

แทน

data: { roleName: '@Model.RoleName', users: users }

ทำเช่นนี้

data: { roleName: '@Html.Raw(@Model.RoleName)', users: users }

@Html.Raw ทำเคล็ดลับ

roleName="Cadastro b&#225;s"ผมได้รับการชื่อบทบาทเป็นค่า HTML ค่านี้ด้วยเอนทิตี HTML &#225;ถูกบล็อคโดย ASP.NET MVC ตอนนี้ฉันได้รับroleNameค่าพารามิเตอร์อย่างที่ควรจะเป็น: roleName="Cadastro Básico"และเอ็นจิ้น ASP.NET MVC จะไม่ปิดกั้นคำขออีกต่อไป


9

ปิดการใช้งานการตรวจสอบหน้าถ้าคุณต้องการตัวอักษรพิเศษจริงๆเช่น>, <เป็นต้นจากนั้นให้แน่ใจว่าเมื่อผู้ใช้ป้อนข้อมูลจะแสดงข้อมูลที่ถูกเข้ารหัสแบบ HTML

มีช่องโหว่ด้านความปลอดภัยที่มีการตรวจสอบความถูกต้องของหน้าเว็บดังนั้นจึงสามารถข้ามได้ นอกจากนี้การตรวจสอบหน้าไม่ควรเชื่อถือ แต่เพียงผู้เดียว

ดู: http://web.archive.org/web/20080913071637/http://www.procheckup.com:80/PDFs/bypassing-dot-NET-ValidateRequest.pdf



7

คุณสามารถใช้ฟังก์ชันescape (สตริง)ของ JavaScript เพื่อแทนที่อักขระพิเศษ จากนั้นฝั่งเซิร์ฟเวอร์ใช้เซิร์ฟเวอร์ URLDecode (สตริง)เพื่อสลับกลับ

วิธีนี้คุณไม่จำเป็นต้องปิดการตรวจสอบความถูกต้องของอินพุตและจะชัดเจนยิ่งขึ้นต่อโปรแกรมเมอร์อื่น ๆ ที่สตริงอาจมีเนื้อหา HTML


7

ฉันลงเอยด้วยการใช้ JavaScript ก่อนแต่ละ postback เพื่อตรวจสอบอักขระที่คุณไม่ต้องการเช่น:

<asp:Button runat="server" ID="saveButton" Text="Save" CssClass="saveButton" OnClientClick="return checkFields()" />

function checkFields() {
    var tbs = new Array();
    tbs = document.getElementsByTagName("input");
    var isValid = true;
    for (i=0; i<tbs.length; i++) {
        if (tbs(i).type == 'text') {
            if (tbs(i).value.indexOf('<') != -1 || tbs(i).value.indexOf('>') != -1) {
                alert('<> symbols not allowed.');
                isValid = false;
            }
        }
    }
    return isValid;
}

ที่ได้รับหน้าของฉันส่วนใหญ่คือการป้อนข้อมูลและมีองค์ประกอบน้อยมากที่ postbacks แต่อย่างน้อยข้อมูลของพวกเขาจะถูกเก็บไว้


ควรมีวงเล็บใหญ่แทนที่จะเป็นวงเล็บเหลี่ยมเล็ก เช่น `if (tbs [i] .type == 'text') {` แทนที่ `if (tbs (i) .type == 'text') {`
Shilpa Soni

5

คุณสามารถใช้สิ่งที่ชอบ:

var nvc = Request.Unvalidated().Form;

ต่อมาnvc["yourKey"]ควรทำงาน


ขอบคุณคำตอบของคุณช่วยประหยัดเวลาของฉันได้มาก
habib

4

ตราบใดที่สิ่งเหล่านี้เป็นเพียงอักขระ "<" และ ">" (ไม่ใช่เครื่องหมายอัญประกาศคู่) และคุณใช้มันในบริบทเช่น <input value = " this " /> คุณจะปลอดภัย (ในขณะที่ <textarea > อันนี้ </textarea> คุณจะต้องเสี่ยงแน่นอน) นั่นอาจทำให้สถานการณ์ของคุณง่ายขึ้น แต่สำหรับทุกสิ่งให้ใช้โซลูชันที่โพสต์อื่น ๆ


4

หากคุณเพียงแค่ต้องการบอกผู้ใช้ของคุณว่า <และ> จะไม่ถูกใช้ แต่คุณไม่ต้องการให้มีการประมวลผล / โพสต์แบบย้อนกลับทั้งรูปแบบ ใช้เครื่องมือตรวจสอบความถูกต้องรอบ ๆ สนามเพื่อคัดกรองอักขระ (และอาจเป็นอันตรายอื่น ๆ ) หรือไม่


โพสต์กล่าวว่า "ตัวตรวจสอบความถูกต้อง" โปรด
mxmissile

4

ไม่มีข้อเสนอแนะสำหรับฉันเลย ฉันไม่ต้องการปิดคุณสมบัตินี้สำหรับเว็บไซต์ทั้งหมดเพราะเวลา 99% ฉันไม่ต้องการให้ผู้ใช้ของฉันวาง HTML ในแบบฟอร์มบนเว็บ ฉันเพิ่งสร้างวิธีการแก้ไขของตัวเองเนื่องจากฉันเป็นคนเดียวที่ใช้แอปพลิเคชันนี้โดยเฉพาะ ฉันแปลงอินพุตเป็น HTML ในโค้ดด้านหลังและแทรกลงในฐานข้อมูลของฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.