Một giá trị Request.Form nguy hiểm tiềm tàng đã được phát hiện từ máy khách


1471

Mỗi khi người dùng đăng một cái gì đó có chứa <hoặc >trong một trang trong ứng dụng web của tôi, tôi sẽ bị ném ngoại lệ này.

Tôi không muốn đi vào cuộc thảo luận về sự thông minh của việc ném một ngoại lệ hoặc đánh sập toàn bộ ứng dụng web vì ai đó đã nhập một ký tự vào hộp văn bản, nhưng tôi đang tìm kiếm một cách thanh lịch để xử lý việc này.

Bẫy ngoại lệ và hiển thị

Đã xảy ra lỗi, vui lòng quay lại và nhập lại toàn bộ biểu mẫu của bạn, nhưng lần này vui lòng không sử dụng <

dường như không đủ chuyên nghiệp với tôi.

Vô hiệu hóa xác thực bài đăng ( validateRequest="false") chắc chắn sẽ tránh được lỗi này, nhưng nó sẽ khiến trang dễ bị tấn công.

Lý tưởng nhất: Khi một bài đăng trở lại có chứa các ký tự bị giới hạn HTML, giá trị được đăng trong bộ sưu tập Biểu mẫu sẽ được mã hóa HTML tự động. Vì vậy, .Texttài sản của hộp văn bản của tôi sẽ làsomething & lt; html & gt;

Có cách nào tôi có thể làm điều này từ một người xử lý?


68
Lưu ý rằng bạn có thể gặp lỗi này nếu bạn có tên thực thể HTML (& amp;) hoặc số thực thể (& # 39;) trong đầu vào của bạn.
vẽ Noakes

18
Chà, vì đó là câu hỏi của tôi, tôi cảm thấy mình có thể xác định được vấn đề thực sự là gì: làm hỏng toàn bộ quá trình ứng dụng và trả về một thông báo lỗi chung vì ai đó đã gõ '<' là quá mức cần thiết. Đặc biệt là vì bạn biết hầu hết mọi người sẽ chỉ 'validateRequest = false' để thoát khỏi nó, do đó mở lại lỗ hổng
Radu094

7
@DrewNoakes: tên thực thể (& amp;) dường như không phải là vấn đề theo các thử nghiệm của tôi (được thử nghiệm trong .Net 4.0), mặc dù số thực thể (& # 39;) không xác thực (như bạn đã nói). Nếu bạn tháo rời phương thức System.Web.CrossSiteScriptingValidation.IsDangerousString bằng cách sử dụng .Net Reflector, bạn sẽ thấy mã trông đặc biệt cho các thẻ html (bắt đầu bằng <) và số thực thể (bắt đầu bằng & #)
Gyum Fox

5
Tạo một trang web mới trong VS2014 bằng dự án MVC mặc định và chạy nó. Nhấp vào liên kết đăng ký, thêm bất kỳ email nào và sử dụng "<P455-0r [!" làm mật khẩu Cùng một lỗi, không cố làm gì độc hại, trường mật khẩu sẽ không được hiển thị nên sẽ không phải là một cuộc tấn công XSS, nhưng cách duy nhất để khắc phục là xóa hoàn toàn xác thực với ValidateInput (false) ? Đề xuất AllowHtml không hoạt động trong tình huống này, vẫn xảy ra lỗi tương tự. Giá trị Request.Form nguy hiểm tiềm tàng được phát hiện từ máy khách (Mật khẩu = "<P455-0r [!").
stephenbayer

TL; DR đưa <httpRuntime requestValidationMode="2.0" />vào web.config

Câu trả lời:


1080

Tôi nghĩ rằng bạn đang tấn công nó từ góc độ sai bằng cách cố gắng mã hóa tất cả dữ liệu được đăng.

Lưu ý rằng " <" cũng có thể đến từ các nguồn bên ngoài khác, như trường cơ sở dữ liệu, cấu hình, tệp, nguồn cấp dữ liệu, v.v.

Hơn nữa, " <" vốn không nguy hiểm. Nó chỉ nguy hiểm trong một ngữ cảnh cụ thể: khi viết các chuỗi chưa được mã hóa thành đầu ra HTML (vì XSS).

Trong các bối cảnh khác, các chuỗi con khác nhau rất nguy hiểm, ví dụ: nếu bạn viết URL do người dùng cung cấp vào một liên kết, chuỗi con " javascript:" có thể nguy hiểm. Mặt khác, ký tự trích dẫn là nguy hiểm khi nội suy các chuỗi trong các truy vấn SQL, nhưng hoàn toàn an toàn nếu đó là một phần của tên được gửi từ một biểu mẫu hoặc đọc từ trường cơ sở dữ liệu.

Điểm mấu chốt là: bạn không thể lọc đầu vào ngẫu nhiên cho các ký tự nguy hiểm, bởi vì bất kỳ ký tự nào cũng có thể nguy hiểm trong các trường hợp phù hợp. Bạn nên mã hóa tại điểm mà một số ký tự cụ thể có thể trở nên nguy hiểm vì chúng chuyển sang một ngôn ngữ phụ khác, nơi chúng có ý nghĩa đặc biệt. Khi bạn viết một chuỗi thành HTML, bạn nên mã hóa các ký tự có ý nghĩa đặc biệt trong HTML, sử dụng Server.HtmlEncode. Nếu bạn chuyển một chuỗi cho một câu lệnh SQL động, bạn nên mã hóa các ký tự khác nhau (hoặc tốt hơn, hãy để khung làm việc đó cho bạn bằng cách sử dụng các câu lệnh đã chuẩn bị hoặc tương tự) ..

Khi bạn chắc chắn rằng bạn mã hóa HTML ở mọi nơi bạn chuyển chuỗi sang HTML, sau đó đặt validateRequest="false"trong lệnh <%@ Page ... %>trong .aspx(các) tệp của bạn .

Trong .NET 4 bạn có thể cần phải làm nhiều hơn một chút. Đôi khi, cũng cần phải thêm <httpRuntime requestValidationMode="2.0" />vào web.config ( tham khảo ).


74
Đối với những người đến muộn: validateRequest = "false" đi theo chỉ thị Trang (dòng đầu tiên của tệp .aspx của bạn)
MGOwen

56
Mẹo: Đặt <httpRuntime requestValidationMode="2.0" />vào thẻ vị trí để tránh giết chết sự bảo vệ hữu ích được cung cấp bởi xác thực từ phần còn lại của trang web của bạn.
Brian

298
Trong MVC3, đây là [AllowHtml]thuộc tính mô hình.
Jeremy Holovacs

2
Để vô hiệu hóa nó trên toàn cầu cho MVC 3 bạn cũng cần GlobalFilters.Filters.Add(new ValidateInputAttribute(false));trong Application_Start().
Alex

15
@MGOwen bạn cũng có thể thêm các chỉ thị trang để web.config qua <pages validateRequest="false" />trong <system.web />. Làm như vậy sẽ áp dụng tài sản cho tất cả các trang.
oliver-clare

504

Có một giải pháp khác cho lỗi này nếu bạn đang sử dụng ASP.NET MVC:

Mẫu C #:

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

Mẫu Visual Basic:

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

vấn đề có thể xảy ra khi nó cần trên một trang của toàn bộ ứng dụng

3
Bạn cũng có thể thêm thuộc tính [ValidateInput (false)] ở cấp độ lớp. Nếu bạn thêm nó vào lớp trình điều khiển cơ sở, nó sẽ áp dụng cho tất cả các hành động của phương thức điều khiển.
Shan Plourde

@Zack Cảm ơn giải pháp. Mặt khác, tôi tự hỏi liệu [AllowHtml]có tốt hơn không ValidateInput(false), bởi vì [AllowHtml]được xác định cùng một lúc cho một thuộc tính tức là trường Editor và bất cứ khi nào nó được sử dụng, không cần sử dụng nó cho một số hành động. Bạn có đề nghị gì?
Jack

@Zack Peterson Có an toàn khi sử dụng không? Không có vấn đề bảo mật?
Shrey Pav

417

Trong ASP.NET MVC (bắt đầu từ phiên bản 3), bạn có thể thêm AllowHtmlthuộc tính vào một thuộc tính trên mô hình của mình.

Nó cho phép một yêu cầu bao gồm đánh dấu HTML trong quá trình ràng buộc mô hình bằng cách bỏ qua xác thực yêu cầu cho thuộc tính.

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

12
Tốt hơn nhiều để làm điều này decarativly hơn trong bộ điều khiển!
Andiih

29
Câu trả lời đúng duy nhất! vô hiệu hóa xác nhận trên hành động của bộ điều khiển là hacky. Và để vô hiệu hóa xác nhận ở cấp ứng dụng, các nhà phát triển phải bị treo!
trailmax

Điều này đã biến mất trong MVC 4?
granadaCoder

1
Sự khác biệt giữa ValidateInput(false)và là AllowHtmlgì? Lợi thế của cái này hơn cái kia là gì? Khi nào tôi muốn sử dụng AllowHtmlthay vì ValidateInput(false)? Khi nào tôi muốn sử dụng ValidateInput(false)hơn AllowHtml? Khi nào tôi muốn sử dụng cả hai? Liệu nó có ý nghĩa để sử dụng cả hai?
Ian Boyd

3
ValidateInput là trên phương thức, AllowHtml là thuộc tính của mô hình - vì vậy bạn chỉ cho phép cái mà bạn mong đợi có html - không phải tất cả
Anthony Johnston

213

Nếu bạn đang dùng .NET 4.0, hãy đảm bảo bạn thêm tệp này vào tệp web.config bên trong các <system.web>thẻ:

<httpRuntime requestValidationMode="2.0" />

Trong .NET 2.0, xác thực yêu cầu chỉ áp dụng cho aspxcác yêu cầu. Trong .NET 4.0, điều này đã được mở rộng để bao gồm tất cả các yêu cầu. Bạn có thể hoàn nguyên để chỉ thực hiện xác thực XSS khi xử lý .aspxbằng cách chỉ định:

requestValidationMode="2.0"

Bạn có thể vô hiệu hóa yêu cầu xác thực hoàn toàn bằng cách chỉ định:

validateRequest="false"

30
Bên trong các <system.web>thẻ.
Hosam Aly

8
Tôi đã đặt cái này vào web.config, nhưng vẫn gặp lỗi "Giá trị Request.Form nguy hiểm tiềm tàng"
Filip

20
Có vẻ như <httpR.78 requestValidationMode = "2.0" /> chỉ hoạt động khi khung 2.0 được cài đặt trên máy. Điều gì sẽ xảy ra nếu khung 2.0 hoàn toàn không được cài đặt mà chỉ có khung 4.0 được cài đặt?
Samuel

Điều này hoàn toàn làm việc cho tôi. Không có tài liệu nào trong các bước trong các câu trả lời khác là cần thiết (bao gồm cảateateRequest = "false")!
tom redfern

112

Đối với ASP.NET 4.0, bạn có thể cho phép đánh dấu làm đầu vào cho các trang cụ thể thay vì toàn bộ trang bằng cách đặt tất cả trong một <location>phần tử. Điều này sẽ đảm bảo tất cả các trang khác của bạn được an toàn. Bạn KHÔNG cần phải đặt ValidateRequest="false"trong trang .aspx của bạn.

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

Việc kiểm soát điều này trong web.config sẽ an toàn hơn, bởi vì bạn có thể thấy ở cấp độ trang web cho phép đánh dấu là đầu vào.

Bạn vẫn cần xác nhận hợp lệ đầu vào theo chương trình trên các trang nơi xác thực yêu cầu bị vô hiệu hóa.


Thông tin thêm về requestValidationMode = 2 | 4 tại đây: msdn.microsoft.com/en-us/l
Library / ám

Đáng buồn là điều này sẽ không hoạt động với ASP.net 2.0. Xóa dòng httpR.78 và nó sẽ hoạt động.
Fandango68

Tôi đã thêm một cảnh báo nhắc nhở mọi người xác thực thủ công nhập liệu khi xác thực bị tắt.
Carter Medlin

72

Các câu trả lời trước đây rất hay, nhưng không ai nói làm thế nào để loại trừ một trường duy nhất khỏi bị xác thực cho việc tiêm HTML / JavaScript. Tôi không biết về các phiên bản trước, nhưng trong MVC3 Beta, bạn có thể làm điều này:

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

Điều này vẫn xác nhận tất cả các trường ngoại trừ trường bị loại trừ. Điều thú vị ở đây là các thuộc tính xác thực của bạn vẫn xác thực trường, nhưng bạn không nhận được ngoại lệ "Giá trị Request.Form nguy hiểm tiềm tàng được phát hiện từ máy khách".

Tôi đã sử dụng điều này để xác nhận một biểu thức chính quy. Tôi đã tạo Xác thực hợp lệ của riêng mình để xem biểu thức chính quy có hợp lệ hay không. Vì các biểu thức thông thường có thể chứa một cái gì đó trông giống như một tập lệnh mà tôi đã áp dụng đoạn mã trên - biểu thức thông thường vẫn đang được kiểm tra xem nó có hợp lệ hay không, nhưng không phải nếu nó chứa tập lệnh hoặc HTML.


10
Đáng buồn thay, có vẻ như tính năng Loại trừ đã bị xóa khỏi MVC 3 RTW :(
Matt Greer

2
Nó cũng không được bao gồm trong MVC 4
wilsjd

9
Sử dụng [AllowHtml]trên các thuộc tính của mô hình thay vì [ValidateInput]trên Hành động để đạt được kết quả cuối cùng.
Ông trùm

2
@Christof Lưu ý rằng câu trả lời của tôi là 5 tuổi. Tôi đã không gặp phải vấn đề này trong một thời gian dài, vì vậy có thể có nhiều cách tốt hơn để giải quyết nó. Về hai lựa chọn này tôi nghĩ nó phụ thuộc vào tình huống của bạn. Có thể bạn phơi bày mô hình đó trong nhiều hành động và ở một số nơi, HTML có được phép hay không. Trong trường hợp như vậy [AllowHtml]không phải là một lựa chọn. Tôi khuyên bạn nên kiểm tra bài viết này: weblogs.asp.net/imranbaloch/ , nhưng nó cũng hơi cũ và có thể đã lỗi thời.
gligoran

1
Vẫn còn một cách để loại trừ các tham số phương thức cụ thể khỏi xác thực, hãy xem câu trả lời của tôi ở đây: stackoverflow.com/a/50796666/56621
Alex

51

Trong ASP.NET MVC, bạn cần đặt requestValidationMode = "2.0" và validateRequest = "false" trong web.config và áp dụng thuộc tính ValidateInput cho hành động điều khiển của bạn:

<httpRuntime requestValidationMode="2.0"/>

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

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

2
Đối với tôi, validateRequest="false"không cần thiết, chỉrequestValidationMode="2.0"
tom redfern

requestValidationMode = "2.0" vẫn tạo ra lỗi với dữ liệu HTMLencoding. Không có giải pháp nào ngoại trừ cơ sở mã hóa mọi thứ, sau đó gửi nó đi cùng.
MC9000

48

Bạn có thể mã hóa HTML nội dung hộp văn bản, nhưng thật không may, điều đó sẽ không ngăn chặn ngoại lệ xảy ra. Theo kinh nghiệm của tôi, không có cách nào khác, và bạn phải vô hiệu hóa xác nhận trang. Bằng cách làm điều đó bạn đang nói: "Tôi sẽ cẩn thận, tôi hứa."


43

Đối với MVC, bỏ qua xác thực đầu vào bằng cách thêm

[ValidateInput (sai)]

phía trên mỗi Hành động trong Bộ điều khiển.


Điều này dường như không hoạt động trong trường hợp nó đến phương thức điều khiển thông qua một tuyến được cấu hình.
PandaWood

Trên thực tế, lời giải thích kỹ thuật là điều này chỉ hoạt động khi ký tự vi phạm nằm trong "chuỗi truy vấn" ... nếu trong đường dẫn yêu cầu, thuộc tính Xác thực không hoạt động
PandaWood

42

Bạn có thể bắt lỗi đó trong Global.asax. Tôi vẫn muốn xác nhận, nhưng hiển thị một thông điệp thích hợp. Trên blog được liệt kê dưới đây, một mẫu như thế này đã có sẵn.

    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();
        }
    }

Chuyển hướng đến một trang khác cũng có vẻ như là một phản ứng hợp lý cho ngoại lệ.

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


40

Câu trả lời cho câu hỏi này là đơn giản:

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

Điều này sẽ vô hiệu hóa xác nhận cho các yêu cầu cụ thể.


1
Chỉ áp dụng cho ASP.NET 4.5 (và, có lẽ, bất cứ điều gì sẽ đến sau nó.) Pre 4.5 không hỗ trợ điều này.
Beska

3
Tôi ước tôi có thể tăng theo cách này. Tôi đang sử dụng .NET 4.5 và đây chính xác là những gì tôi cần vì tôi không sử dụng MVC và tôi không thể thay đổi web.config.
Chris Gillum

1
Vâng, nhưng nếu bạn đang sử dụng .Net 2 thì sao? Một số người trong chúng ta không có sự lựa chọn
Fandango68

cái này được tham số POST hoặc GET?
max4ever

Bạn đang nói điều này ngăn chặn một ngoại lệ đã được ném? Hoặc .net 4.5 trì hoãn ngoại lệ và xác thực cho đến khi dữ liệu thực sự được đọc từ Request?
ebyrob

34

Xin lưu ý rằng một số điều khiển .NET sẽ tự động mã hóa HTML đầu ra. Chẳng hạn, đặt thuộc tính .Text trên điều khiển TextBox sẽ tự động mã hóa nó. Điều đó đặc biệt có nghĩa là chuyển đổi <thành &lt;, >vào &gt;&thành &amp;. Vì vậy, hãy cảnh giác khi làm điều này ...

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

Tuy nhiên, thuộc tính .Text cho HyperLink, Nghĩa đen và Nhãn sẽ không mã hóa mọi thứ HTML, do đó, bao bọc Server.HtmlEncode (); xung quanh bất cứ điều gì được đặt trên các thuộc tính này là bắt buộc nếu bạn muốn ngăn <script> window.location = "http://www.google.com"; </script>không cho xuất ra trang của mình và sau đó được thực thi.

Làm một thử nghiệm nhỏ để xem những gì được mã hóa và những gì không.


29

Trong tệp web.config, trong các thẻ, chèn phần tử httpR.78 với thuộc tính requestValidationMode = "2.0". Đồng thời thêm thuộc tính validateRequest = "false" trong phần tử trang.

Thí dụ:

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

1
Đối với tôi, validateRequest = "false" là không cần thiết, chỉ requestValidationMode = "2.0"
tom redfern

3
Phần "trang" phải nằm trong phần "system.web".
Carter Medlin

Câu trả lời nguy hiểm, một lần nữa.
MC9000

Tôi cần cả hai. Cảm ơn
Jack

23

Nếu bạn không muốn vô hiệu hóa ValidateRequest, bạn cần triển khai một hàm JavaScript để tránh ngoại lệ. Nó không phải là lựa chọn tốt nhất, nhưng nó hoạt động.

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

Sau đó, trong mã phía sau, trên sự kiện PageLoad, hãy thêm thuộc tính vào điều khiển của bạn bằng mã tiếp theo:

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

4
Điều này sẽ vẫn khiến ứng dụng dễ bị tổn thương từ các yêu cầu POST đã tạo. Một người dùng thông thường sẽ gặp vấn đề khi nhập các ký tự như: hoặc trích dẫn, nhưng một hacker thông thường sẽ không gặp vấn đề gì khi gửi dữ liệu không đúng định dạng lên máy chủ. Tôi sẽ vode này waaay xuống.
Radu094

13
@ Radu094: Giải pháp này cho phép bạn giữ ValidateRequest = true, điều đó có nghĩa là tin tặc vẫn sẽ tấn công vào bức tường đó. Bỏ phiếu LÊN, vì điều này khiến bạn ít bị tổn thương hơn là tắt ValidateRequest.
jbehren

21

Có vẻ như chưa có ai đề cập đến những điều dưới đây, nhưng nó đã khắc phục vấn đề cho tôi. Và trước khi bất cứ ai nói vâng, đó là Visual Basic ... yuck.

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

Tôi không biết có bất kỳ nhược điểm nào không, nhưng đối với tôi điều này thật tuyệt vời.


Hoạt động cho các biểu mẫu web c # hoặc VB
TheAlbear

19

Một giải pháp khác là:

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

Đẹp! Không biết về khả năng thay thế Trình xác thực yêu cầu. Thay vì chỉ nói "ok" như bạn, tôi đã mở rộng ý tưởng này để không xác thực các trường kết thúc bằng "_Không xác thực" như tên của chúng. Mã dưới đây.
Walden Leverich

Walden Leverich, để thực hiện điều này, hãy xem phần giới thiệu [AllowHtml]
Sel

Sel, có trong một môi trường MVC sẽ làm việc. Nhưng trong một ứng dụng webforms tôi không có một mô hình để làm điều đó. :-)
Walden Leverich

15

Nếu bạn đang sử dụng khung 4.0 thì mục nhập trong web.config (<PagesterateRequest = "false" />)

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

Nếu bạn đang sử dụng framework 4.5 thì mục trong web.config (requestValidationMode = "2.0")

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

Nếu bạn chỉ muốn một trang duy nhất, Trong tệp aspx của bạn, bạn nên đặt dòng đầu tiên như sau:

<%@ Page EnableEventValidation="false" %>

nếu bạn đã có một cái gì đó như <% @ Trang, vì vậy chỉ cần thêm phần còn lại => EnableEventValidation="false"%>

Tôi khuyên bạn không nên làm điều đó.


13

Trong ASP.NET, bạn có thể bắt ngoại lệ và làm một cái gì đó về nó, chẳng hạn như hiển thị một thông báo thân thiện hoặc chuyển hướng đến một trang khác ... Ngoài ra, có khả năng bạn có thể tự xử lý xác thực ...

Hiển thị tin nhắn thân thiện:

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

Tôi đoán bạn có thể làm điều đó trong một mô-đun; nhưng điều đó để lại một số câu hỏi; Điều gì nếu bạn muốn lưu đầu vào vào cơ sở dữ liệu? Đột nhiên vì bạn đang lưu dữ liệu được mã hóa vào cơ sở dữ liệu nên cuối cùng bạn tin tưởng đầu vào từ đó có lẽ là một ý tưởng tồi. Lý tưởng nhất là bạn lưu trữ dữ liệu chưa được mã hóa thô trong cơ sở dữ liệu và mã hóa mỗi lần.

Vô hiệu hóa bảo vệ ở cấp độ trên mỗi trang và sau đó mã hóa mỗi lần là một lựa chọn tốt hơn.

Thay vì sử dụng Server.HtmlEncode, bạn nên xem thư viện Anti-XSS mới hơn, đầy đủ hơn từ nhóm Microsoft ACE.


12

Nguyên nhân

ASP.NET theo mặc định xác nhận tất cả các điều khiển đầu vào cho các nội dung có khả năng không an toàn có thể dẫn đến kịch bản chéo trang (XSS) và SQL tiêm . Do đó, nó không cho phép nội dung như vậy bằng cách ném ngoại lệ trên. Theo mặc định, nên cho phép kiểm tra này xảy ra trên mỗi postback.

Giải pháp

Trong nhiều trường hợp, bạn cần gửi nội dung HTML đến trang của mình thông qua Rich TextBoxes hoặc Rich Text Editorors. Trong trường hợp đó, bạn có thể tránh ngoại lệ này bằng cách đặt thẻ ValidateRequest trong lệnh @Pagethành false.

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

Điều này sẽ vô hiệu hóa xác thực các yêu cầu cho trang bạn đã đặt cờ ValidateRequest thành false. Nếu bạn muốn vô hiệu hóa điều này, hãy kiểm tra trong suốt ứng dụng web của bạn; bạn sẽ cần đặt nó thành false trong phần web.config <system.web> của bạn

<pages validateRequest ="false" />

Đối với các khung công tác .NET 4.0 trở lên, bạn cũng cần thêm dòng sau vào phần <system.web> để thực hiện công việc trên.

<httpRuntime requestValidationMode = "2.0" />

Đó là nó. Tôi hy vọng điều này sẽ giúp bạn thoát khỏi vấn đề trên.

Tham khảo bởi: Lỗi ASP.Net : Đã phát hiện giá trị Request.Form nguy hiểm tiềm tàng từ máy khách


10

Tôi đã tìm thấy một giải pháp sử dụng JavaScript để mã hóa dữ liệu, được giải mã bằng .NET (và không yêu cầu jQuery).

  • Biến hộp văn bản thành một phần tử HTML (như textarea) thay vì tệp ASP.
  • Thêm một trường ẩn.
  • Thêm chức năng JavaScript sau vào tiêu đề của bạn.

    hàm boo () {targetText = document.getEuityById ("HiddenField1"); sourceText = document.getEuityById ("hộp người dùng"); targetText.value = esc (sourceText.innerText); }

Trong textarea của bạn, bao gồm một onchange gọi boo ():

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

Cuối cùng, trong .NET, sử dụng

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

Tôi biết rằng đây là một chiều - nếu bạn cần hai chiều, bạn sẽ phải sáng tạo, nhưng điều này cung cấp giải pháp nếu bạn không thể chỉnh sửa web.config

Đây là một ví dụ tôi (MC9000) đã đưa ra và sử dụng thông qua 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
    });


});

Và đánh dấu:

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

Điều này làm việc tuyệt vời. Nếu một hacker cố gắng đăng bài thông qua bỏ qua JavaScript, họ sẽ chỉ thấy lỗi. Bạn cũng có thể lưu tất cả dữ liệu được mã hóa trong cơ sở dữ liệu, sau đó hủy bỏ nó (ở phía máy chủ) và phân tích & kiểm tra các cuộc tấn công trước khi hiển thị ở nơi khác.


Đây là một giải pháp tốt. Đó là một cách thủ công thích hợp để tự kiểm soát nó và không làm mất hiệu lực toàn bộ trang web hoặc trang
Fandango68

Đảm bảo sử dụng đánh dấu HTML, không phải điều khiển ASP.Net (tức là không có runat = "server") cho vùng văn bản, sau đó sử dụng điều khiển ẩn ASP.Net cho ẩn. Đây là giải pháp tốt nhất mà tôi thấy không thỏa hiệp bất cứ điều gì. Đương nhiên, bạn muốn phân tích dữ liệu của mình cho XSS, SQL Injection ở phía máy chủ, nhưng ít nhất bạn có thể đăng HTML
MC9000

escape(...)có thể mất nhiều thời gian Trong trường hợp của tôi, đánh dấu là toàn bộ tệp XML (2MB). Bạn có thể hỏi, "Tại sao bạn không sử dụng <input type="file"...và ... Tôi đồng ý với bạn :)
Hạt đậu đỏ

10

Các giải pháp khác ở đây rất hay, tuy nhiên có một chút đau đớn ở phía sau khi phải áp dụng [AllowHtml] cho mọi thuộc tính Mô hình duy nhất, đặc biệt là nếu bạn có hơn 100 mô hình trên một trang web có kích thước khá.

Nếu giống như tôi, bạn muốn tắt tính năng (IMHO khá vô nghĩa) này ra khỏi trang web, bạn có thể ghi đè phương thức Execute () trong bộ điều khiển cơ sở của bạn (nếu bạn chưa có bộ điều khiển cơ bản tôi khuyên bạn nên tạo một, chúng có thể khá hữu ích cho việc áp dụng chức năng phổ biến).

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

Chỉ cần đảm bảo rằng bạn đang mã hóa HTML mọi thứ được đưa ra cho các lượt xem xuất phát từ đầu vào của người dùng (dù sao đó là hành vi mặc định trong ASP.NET MVC 3 với Dao cạo, vì vậy trừ khi vì một lý do kỳ quái nào đó bạn đang sử dụng Html.Raw () không nên yêu cầu tính năng này.


9

Tôi đã nhận được lỗi này quá.

Trong trường hợp của tôi, một người dùng đã nhập một ký tự có dấu ávào Tên vai trò (liên quan đến nhà cung cấp thành viên ASP.NET).

Tôi chuyển tên vai trò cho một phương thức để cấp cho Người dùng vai trò đó và $.ajaxyêu cầu bài đăng đã thất bại thảm hại ...

Tôi đã làm điều này để giải quyết vấn đề:

Thay vì

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

Làm cái này

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

@Html.Raw đã lừa

Tôi đã nhận được tên Vai trò là giá trị HTML roleName="Cadastro b&#225;s". Giá trị này với thực thể HTML &#225;đã bị ASP.NET MVC chặn. Bây giờ tôi nhận được roleNamegiá trị tham số theo cách nó phải là: roleName="Cadastro Básico"và công cụ ASP.NET MVC sẽ không chặn yêu cầu nữa.


9

Vô hiệu hóa xác nhận trang nếu bạn thực sự cần những nhân vật đặc biệt như, >,, <, vv Sau đó, đảm bảo rằng khi người dùng nhập vào sẽ được hiển thị, dữ liệu là HTML mã hóa.

Có một lỗ hổng bảo mật với xác nhận trang, vì vậy nó có thể được bỏ qua. Ngoài ra, xác nhận trang không nên chỉ dựa vào.

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


Liên kết bị hỏng.
Peter Mortensen

7

Bạn cũng có thể sử dụng chức năng thoát (chuỗi) của JavaScript để thay thế các ký tự đặc biệt. Sau đó, phía máy chủ sử dụng Máy chủ. URLDecode (chuỗi) để chuyển đổi lại.

Bằng cách này, bạn không phải tắt xác thực đầu vào và sẽ rõ ràng hơn với các lập trình viên khác rằng chuỗi có thể có nội dung HTML.


7

Tôi đã kết thúc việc sử dụng JavaScript trước mỗi lần đăng lại để kiểm tra các ký tự bạn không muốn, chẳng hạn như:

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

Cấp cho trang của tôi chủ yếu là nhập dữ liệu, và có rất ít yếu tố thực hiện postback, nhưng ít nhất dữ liệu của họ được giữ lại.


Nên có dấu ngoặc lớn thay vì dấu ngoặc nhỏ. Giống như `if (tbs [i] .type == 'text') {` thay cho` if (tbs (i) .type == 'text') {`
Shilpa Soni

5

Bạn có thể sử dụng một cái gì đó như:

var nvc = Request.Unvalidated().Form;

Sau này, nvc["yourKey"]nên làm việc.


Cảm ơn, câu trả lời của bạn đã tiết kiệm rất nhiều thời gian của tôi
habib

4

Miễn là đây chỉ là các ký tự "<" và ">" (chứ không phải là trích dẫn kép) và bạn đang sử dụng chúng trong ngữ cảnh như <input value = " this " />, bạn vẫn an toàn (trong khi đối với <textarea > cái này </ textarea> dĩ nhiên bạn sẽ dễ bị tổn thương). Điều đó có thể đơn giản hóa tình huống của bạn, nhưng đối với bất cứ điều gì nhiều hơn, hãy sử dụng một trong những giải pháp được đăng khác.


4

Nếu bạn chỉ muốn nói với người dùng của mình rằng <và> không được sử dụng NHƯNG, bạn không muốn toàn bộ biểu mẫu được xử lý / đăng lại (và mất tất cả đầu vào) trước đó, bạn không thể đơn giản đưa vào trình xác nhận xung quanh trường để sàng lọc các ký tự đó (và có thể nguy hiểm khác)?


bài đăng cho biết "trình xác nhận" xin vui lòng
mxmissile

4

Không có gợi ý nào làm việc cho tôi. Dù sao thì tôi cũng không muốn tắt tính năng này cho toàn bộ trang web vì 99% tôi không muốn người dùng của mình đặt HTML trên các biểu mẫu web. Tôi chỉ tạo ra công việc của riêng mình xung quanh phương pháp vì tôi là người duy nhất sử dụng ứng dụng cụ thể này. Tôi chuyển đổi đầu vào thành HTML ở mã phía sau và chèn nó vào cơ sở dữ liệu của tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.