it-swarm-ko.tech

잠재적으로 위험한 Request.Form 값이 클라이언트에서 감지되었습니다.

사용자가 < 또는 >가 포함 된 내용을 웹 응용 프로그램의 페이지에 게시 할 때마다이 예외가 throw됩니다.

누군가가 텍스트 상자에 글자를 입력했기 때문에 예외를 던지거나 전체 웹 응용 프로그램을 충돌시키는 현명함에 대한 토론을하고 싶지는 않지만이를 처리하는 우아한 방법을 찾고 있습니다.

예외 트래핑 및 표시

오류가 발생했습니다. 다시 돌아가서 전체 양식을 다시 입력하십시오. 그러나 이번에는 <

나에게 충분히 전문적이지는 않아.

게시 유효성 검사 (validateRequest="false")를 비활성화하면이 오류가 발생하지 않게되지만 페이지를 여러 가지 공격에 취약하게 만듭니다.

이상적으로 : HTML로 제한된 문자가 포함 된 포스트 백이 발생하면 Form 컬렉션에 게시 된 값이 자동으로 HTML로 인코딩됩니다. 따라서 내 텍스트 상자의 .Text 속성은 something & lt; html & gt;

핸들러에서이 작업을 수행 할 수있는 방법이 있습니까?

1379
Radu094

게시 된 모든 데이터를 인코딩하려고 시도하여 잘못된 각도에서 공격하는 것 같습니다.

"<"는 데이터베이스 필드, 구성, 파일, 피드 등과 같은 다른 외부 소스에서도 올 수 있습니다. 

또한 "<"은 본질적으로 위험하지 않습니다. 특정 상황에서 위험합니다 : XSS 때문에 HTML 출력으로 인코딩되지 않은 문자열을 작성할 때.

다른 문맥에서는 다른 하위 문자열이 위험합니다. 예를 들어 사용자가 제공 한 URL을 링크에 쓰면 하위 문자열 "javascript:"이 위험 할 수 있습니다. 반면에 작은 따옴표 문자는 SQL 쿼리에서 문자열을 보간 할 때 위험하지만 양식에서 제출 된 이름의 일부이거나 데이터베이스 필드에서 읽은 경우 완벽하게 안전합니다.

결론은 위험한 문자에 대해 임의의 입력을 필터링 할 수 없다는 것입니다. 왜냐하면 어떤 상황에서는 적절한 문자가 위험 할 수 있기 때문입니다. 특정 특수 문자가 특별한 의미를 지닌 다른 하위 언어로 넘어 가기 때문에 특정 문자가 위험해질 수있는 지점에서 인코딩해야합니다. HTML에 문자열을 쓸 때 Server.HtmlEncode를 사용하여 HTML에서 특별한 의미를 갖는 문자를 인코딩해야합니다. 문자열을 동적 SQL 문에 전달하는 경우 다른 문자를 인코딩해야합니다 (또는 준비된 명령문 등을 사용하여 프레임 워크에서 처리하도록하십시오).

When 문자열을 HTML로 전달할 때마다 HTML 인코딩을하고, validateRequest="false" 파일의 <%@ Page ... %> 지시문에 .aspx를 설정하십시오.

.NET 4에서는 좀 더해야 할 필요가 있습니다. 때로는 web.config ( reference )에도 <httpRuntime requestValidationMode="2.0" />을 추가해야합니다.

1028
JacquesB

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
482
Zack Peterson

ASP.NET MVC (버전 3부터)에서는 모델의 속성에 AllowHtml 특성을 추가 할 수 있습니다.

속성에 대한 요청 유효성 검사를 건너 뛰어 모델 바인딩 중에 HTML 마크 업을 요청할 수 있습니다.

[AllowHtml]
public string Description { get; set; }
384
Anthony Johnston

.NET 4.0을 사용하는 경우 <system.web> 태그 안의 web.config 파일에 추가해야합니다.

<httpRuntime requestValidationMode="2.0" />

.NET 2.0에서는 요청 유효성 검사가 aspx 요청에만 적용됩니다. .NET 4.0에서는 all requests를 포함하도록 확장되었습니다. 다음을 지정하여 .aspx를 처리 할 때 only XSS 유효성 검사 수행으로 되돌릴 수 있습니다.

requestValidationMode="2.0"

다음을 지정하여 요청 유효성 검사 전체을 비활성화 할 수 있습니다.

validateRequest="false"
206
JordanC

ASP.NET 4.0의 경우 전체 사이트 대신 <location> 요소에 태그를 입력하여 마크 업을 특정 페이지의 입력으로 허용 할 수 있습니다. 이렇게하면 다른 모든 페이지가 안전한지 확인할 수 있습니다. .aspx 페이지에 ValidateRequest="false"를 넣을 필요는 없습니다.

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

Web.config 내에서 이것을 제어하는 ​​것이 안전합니다. 사이트 수준에서 마크 업을 입력으로 허용하는 페이지를 볼 수 있기 때문입니다.

요청 유효성 검사가 비활성화 된 페이지의 입력을 프로그래밍 방식으로 유효성을 검사해야합니다.

108
Carter Medlin

이전 답변은 훌륭하지만 아무도 HTML/JavaScript 삽입을 위해 단일 필드의 유효성을 검사하는 방법을 배제했습니다. 이전 버전에 대해서는 잘 모르겠지만 MVC3 베타에서는 다음과 같이 할 수 있습니다.

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

이것은 여전히 ​​제외 된 필드를 제외한 모든 필드의 유효성을 검사합니다. 이것에 대한 좋은 점은 유효성 검사 속성이 필드의 유효성을 검사하지만 "잠재적으로 위험한 Request.Form 값이 클라이언트에서 감지되었습니다"예외는 얻지 못한다는 것입니다.

정규 표현식의 유효성 검사에이 방법을 사용했습니다. 정규식이 유효한지 확인하기 위해 자체 ValidationAttribute를 만들었습니다. 정규 표현식은 스크립트처럼 보이는 것을 포함 할 수 있으므로 위의 코드를 적용했습니다. 정규 표현식은 유효한지 검사되었지만 스크립트 나 HTML이 포함되어 있지 않은 경우 검사되지 않습니다.

70
gligoran

ASP.NET MVC에서는 web.config에서 requestValidationMode = "2.0"및 validateRequest = "false"로 설정하고 컨트롤러 액션에 ValidateInput 특성을 적용해야합니다.

<httpRuntime requestValidationMode="2.0"/>

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

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

당신은 HTML encode text box 내용을 가질 수 있지만, 불행히도 예외가 발생하는 것을 막지는 못합니다. 제 경험상 주위에는 방법이 없기 때문에 페이지 유효성 검사를 비활성화해야합니다. 그렇게함으로써 당신은 말하고 있습니다 : "나는 조심 스러울거야, 약속 해."

45
Pavel Chuchuva

MVC의 경우 입력 추가를 무시하여 무시하십시오. 

[ValidateInput (false)]

컨트롤러의 각 액션 위.

42
A.Dara

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

41
BenMaddox

일부 .NET 컨트롤은 출력을 자동으로 HTML로 인코딩합니다. 예를 들어, TextBox 컨트롤의 .Text 속성을 설정하면 자동으로 인코딩됩니다. 즉, <&lt;로, >&gt;로, &&amp;로 변환하는 것을 의미합니다. 그래서이 일을하는 것을 조심하십시오 ...

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

그러나 HyperLink, Literal 및 Label의 .Text 속성은 HTML 인코딩을하지 않으므로 Server.HtmlEncode ()를 래핑합니다. <script> window.location = "http://www.google.com"; </script>가 페이지에 출력되지 않도록하려면이 속성에 설정된 항목이 필요합니다.

인코딩 된 내용과 그렇지 않은 내용을 약간 실험 해보십시오.

33
Dominic Pettifer

이 질문에 대한 대답은 간단합니다.

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

이렇게하면 특정 요청에 대한 유효성 검사가 비활성화됩니다.

31
flakomalo

Web.config 파일의 태그 내에서 requestValidationMode = "2.0"속성을 사용하여 httpRuntime 요소를 삽입하십시오. 또한 pages 요소에 validateRequest = "false"속성을 추가하십시오.

예:

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

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);")
23
YORENGOY

아직 아무도 아래에 언급하지 않은 것 같지만 문제가 해결됩니다. 그리고 누군가가 비주얼 베이직이라고 말하기 전에 ... 멍청이.

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

단점이 있는지 나는 모른다. 그러나 나를 위해 이것은 훌륭하게 작동했다.

20
Piercy

또 다른 해결책은 다음과 같습니다.

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

프레임 워크 4.0을 사용하는 경우 web.config (<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" %>

나는 그것을하지 않는 것이 좋습니다.

14
Durgesh Pandey

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
Jaider

나는 당신이 모듈에서 그것을 할 수 있다고 생각한다. 그러나 그것은 몇 가지 질문을 남긴다; 입력을 데이터베이스에 저장하려면 어떻게해야할까요? 갑자기 인코딩 된 데이터를 데이터베이스에 저장하기 때문에 결과적으로 입력을 신뢰하게됩니다. 이는 잘못된 생각 일 수 있습니다. 이상적인 경우 인코딩되지 않은 원시 데이터를 데이터베이스에 저장하고 매번 인코딩하는 것이 좋습니다.

페이지 수준에서 보호를 비활성화 한 다음 매번 인코딩하는 것이 더 좋습니다.

Server.HtmlEncode를 사용하는 대신 Microsoft ACE 팀에서 최신의보다 완벽한 Anti-XSS 라이브러리 를 찾아야합니다.

12
blowdart

다른 솔루션은 니스입니다. 그러나 후면 모델은 모든 모델 속성에 [AllowHtml]을 적용해야합니다. 특히 100 개 이상의 모델을 적절한 크기의 사이트에서 사용하는 경우에 특히 그렇습니다.

나 같은 사람이라면,이 사이트를 벗어나고 싶다면베이스 컨트롤러에서 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에서 기본적으로 Razor가있는 기본 동작입니다. 그렇기 때문에 Html.Raw ()를 사용하는 기괴한 이유가 아니라면 이 기능이 필요하지 않아야합니다.

10
magritte

>, < 등과 같은 특수 문자가 실제로 필요한 경우 페이지 유효성 검사를 비활성화하십시오. 그런 다음 사용자 입력이 표시 될 때 데이터가 HTML로 인코딩되는지 확인하십시오. 

페이지 유효성 검사에는 보안 취약점이 있으므로 무시할 수 있습니다. 또한 페이지 검증은 전적으로 의존해서는 안됩니다.

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

9
woany

원인

기본적으로 ASP.NET은 사이트 간 스크립팅 (XSS) 및 SQL 삽입 으로 이어질 수있는 잠재적으로 안전하지 않은 내용에 대한 모든 입력 컨트롤의 유효성을 검사합니다. 따라서 위의 예외를 throw하여 이러한 내용을 허용하지 않습니다. 기본적으로이 체크가 각 포스트 백에서 발생하도록 허용하는 것이 좋습니다.

솔루션

많은 경우에 서식있는 텍스트 상자 또는 서식있는 텍스트 편집기를 통해 페이지에 HTML 컨텐트를 제출해야합니다. 이 경우 @Page 지시문에서 ValidateRequest 태그를 false로 설정하여이 예외를 피할 수 있습니다.

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

이렇게하면 ValidateRequest 플래그를 false로 설정 한 페이지 요청에 대한 유효성 검사가 비활성화됩니다. 이 기능을 사용하지 않으려면 웹 응용 프로그램 전체에서 확인하십시오. web.config <system.web> 섹션에서 false로 설정해야합니다.

<pages validateRequest ="false" />

.NET 4.0 이상 프레임 워크의 경우 <system.web> 섹션에 다음 행을 추가하여 위의 작업을 수행해야합니다.

<httpRuntime requestValidationMode = "2.0" />

그게 전부 야. 위의 문제를 해결하는 데 도움이되기를 바랍니다.

참조 : ASP.Net 오류 : 잠재적으로 위험한 Request.Form 값이 클라이언트 에서 감지되었습니다

9
vakeel

.NET에서 디코딩 된 데이터를 인코딩하기 위해 JavaScript를 사용하는 솔루션을 발견했습니다 (jQuery가 필요하지 않습니다).

  • 텍스트 상자를 ASP 대신 HTML 요소 (예 : 텍스트 영역)로 만듭니다.
  • 숨겨진 필드를 추가하십시오.
  • 헤더에 다음 JavaScript 함수를 추가하십시오.

    function.boo () { targetText = document.getElementById ( "HiddenField1"); sourceText = document.getElementById ( "userbox" ); targetText.value = 이스케이프 (sourceText.innerText); }

텍스트 영역에서 boo ()를 호출하는 onchange를 포함합니다.

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

마지막으로 .NET에서

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

이것이 단방향이라는 것을 알고 있습니다. 양방향성이 필요하다면 창의력을 발휘해야하지만, web.config를 편집 할 수 없다면 해결책이 될 것입니다.

다음은 I (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를 우회하여 게시하려고하면 오류가 표시됩니다. 데이터베이스에 인코딩 된이 모든 데이터를 저장 한 다음 서버 측에서 이스케이프 처리하고 다른 위치에 표시하기 전에 공격을 구문 분석하고 확인합니다.

9
Jason Shuler

나는이 오류도 받고 있었다.

필자의 경우 사용자는 ASP.NET 멤버 자격 공급자와 관련된 역할 이름에 악센트 부호가있는 문자 á를 입력했습니다.

나는 그 역할에 사용자를 부여하는 방법에 역할 이름을 전달하고 $.ajax 게시물 요청은 비참하게 실패했다 ...

문제를 해결하기 위해이 작업을 수행했습니다.

대신에

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

이 작업을 수행

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

@Html.Raw이 (가) 트릭을했습니다.

HTML 이름 roleName="Cadastro b&#225;s"로 역할 이름을 가져오고있었습니다. &#225; HTML 엔터티가있는이 값은 ASP.NET MVC에 의해 차단되었습니다. 이제는 roleName 매개 변수 값을 가져야합니다. roleName="Cadastro Básico" 및 ASP.NET MVC 엔진은 더 이상 요청을 차단하지 않습니다.

9
Leniel Maccaferri

JavaScript의 이스케이프 (문자열) 함수를 사용하여 특수 문자를 대체 할 수도 있습니다. 그런 다음 서버 측에서 Server. URLDecode (문자열) 를 사용하여 다시 전환합니다.

이렇게하면 입력 유효성 검사를 끌 필요가 없으며 문자열에 HTML 콘텐츠가있을 수 있다는 것이 다른 프로그래머에게 분명해질 것입니다.

7
Trisped

각 포스트 백 (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;
}

부여 된 페이지는 대부분 데이터 항목이며 포스트 백을 수행하는 요소는 거의 없지만 최소한 데이터는 유지됩니다.

6
Ryan

이 문자들은 only "<"및 ">"(이중 따옴표 자체가 아닌) 문자이고 <input value = " this " />, 당신은 안전합니다 (물론 <textarea> this one </ textarea> 당신은 당연히 취약합니다). 그렇게하면 상황이 간단해질 수 있지만 anything은 다른 게시 된 솔루션 중 하나를 더 많이 사용합니다.

4
Paweł Hajdan

사용자에게 <와>를 사용하지 말라고 말하고 싶다면, 양식을 전체적으로 처리/게시하고 (모든 입력을 잃어 버리는 것을 원하지는 않습니다.) 손에 넣기 만하면됩니다. (그리고 아마도 다른 잠재적으로 위험한) 문자들을 검사하기 위해 현장 주변의 유효성 검사기를 사용하고 있습니까?

4
Captain Toad

다음과 같은 것을 사용할 수 있습니다 :

var nvc = Request.Unvalidated().Form;

나중에 nvc["yourKey"]가 작동해야합니다.

4
Ady Levy

나에게 도움이되는 제안은 없었습니다. 99 %의 시간 때문에 웹 양식에 HTML을 배치하지 않으려 고해서 전체 웹 사이트에서이 기능을 해제하고 싶지 않았습니다. 이 특정 응용 프로그램을 사용하는 유일한 방법이기 때문에 방금 메서드에 대한 내 자신의 작업을 만들었습니다. 코드를 HTML로 입력을 변환하여 데이터베이스에 삽입합니다.

4
Mike S.

사용자 정의 모델 바인더에서 자동으로 HTML 인코딩 필드를 사용할 수 있습니다. 내 솔루션이 다른데, 나는 ModelState에 오류를 넣고 필드 근처에 오류 메시지를 표시한다. 이 코드를 수정하여 자동으로 인코딩 할 수 있습니다. 

 public class AppModelBinder : DefaultModelBinder
    {
        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
            try
            {
                return base.CreateModel(controllerContext, bindingContext, modelType);
            }
            catch (HttpRequestValidationException e)
            {
                HandleHttpRequestValidationException(bindingContext, e);
                return null; // Encode here
            }
        }
        protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext,
            PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
        {
            try
            {
                return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
            }
            catch (HttpRequestValidationException e)
            {
                HandleHttpRequestValidationException(bindingContext, e);
                return null; // Encode here
            }
        }

        protected void HandleHttpRequestValidationException(ModelBindingContext bindingContext, HttpRequestValidationException ex)
        {
            var valueProviderCollection = bindingContext.ValueProvider as ValueProviderCollection;
            if (valueProviderCollection != null)
            {
                ValueProviderResult valueProviderResult = valueProviderCollection.GetValue(bindingContext.ModelName, skipValidation: true);
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
            }

            string errorMessage = string.Format(CultureInfo.CurrentCulture, "{0} contains invalid symbols: <, &",
                     bindingContext.ModelMetadata.DisplayName);

            bindingContext.ModelState.AddModelError(bindingContext.ModelName, errorMessage);
        }
    }

Application_Start에서 :

ModelBinders.Binders.DefaultBinder = new AppModelBinder();

양식 필드에만 작동한다는 점에 유의하십시오. 위험한 값은 컨트롤러 모델에는 전달되지 않지만 ModelState에 저장되며 오류 메시지와 함께 양식에 다시 표시 될 수 있습니다. 

URL의 위험한 문자는 다음과 같이 처리 할 수 ​​있습니다.

private void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    HttpContext httpContext = HttpContext.Current;

    HttpException httpException = exception as HttpException;
    if (httpException != null)
    {
        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        var httpCode = httpException.GetHttpCode();
        switch (httpCode)
        {
            case (int)HttpStatusCode.BadRequest /* 400 */:
                if (httpException.Message.Contains("Request.Path"))
                {
                    httpContext.Response.Clear();
                    RequestContext requestContext = new RequestContext(new HttpContextWrapper(Context), routeData);
                    requestContext.RouteData.Values["action"] ="InvalidUrl";
                    requestContext.RouteData.Values["controller"] ="Error";
                    IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
                    IController controller = factory.CreateController(requestContext, "Error");
                    controller.Execute(requestContext);
                    httpContext.Server.ClearError();
                    Response.StatusCode = (int)HttpStatusCode.BadRequest /* 400 */;
                }
                break;
        }
    }
}

ErrorController : 

public class ErrorController : Controller
 {
   public ActionResult InvalidUrl()
   {
      return View();
   }
}   
3
Sel

위험한 입력으로부터 사이트를 보호하려면 Server.HtmlEncode 메서드를 사용해야합니다.

자세한 정보는 여기에

3
bastos.sergio

Sel 's answer 에 대한 내 의견에 명시된 바와 같이, 이것은 맞춤 요청 검사기에 대한 Google의 확장입니다.

public class SkippableRequestValidator : RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        if (collectionKey != null && collectionKey.EndsWith("_NoValidation"))
        {
            validationFailureIndex = 0;
            return true;
        }

        return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
    }
}
2
Walden Leverich

모델 바인딩을 사용하지 않는 사용자의 경우 Request.Form에서 각 매개 변수를 추출하는 사용자는 입력 텍스트가 아무런 해를 입지 않을 것이라고 확신하는 다른 방법이 있습니다. 훌륭한 해결책은 아니지만 일을 할 것입니다. 

클라이언트 측에서 uri로 인코딩 한 다음 보내십시오.
예 : 

encodeURIComponent($("#MsgBody").val());  

서버 측에서 받아 들여서 uri로 해독하십시오.
예 : 

string temp = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["MsgBody"]) ?
System.Web.HttpUtility.UrlDecode(HttpContext.Current.Request.Form["MsgBody"]) : 
null;  

또는 

string temp = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["MsgBody"]) ?
System.Uri.UnescapeDataString(HttpContext.Current.Request.Form["MsgBody"]) : 
null; 

UrlDecodeUnescapeDataString의 차이점을 찾으십시오.

2
Wahid Masud

마지막으로 중요하지만 ASP.NET 데이터 바인딩 컨트롤은 데이터 바인딩 중에 자동으로 인코딩 값을 제어합니다. 이렇게하면 ItemTemplate에 포함 된 모든 ASP.NET 컨트롤 (TextBox, Label 등)의 기본 동작이 변경됩니다. 다음 샘플에서는 (ValidateRequest이 false로 설정 됨) 보여줍니다.

aspx

<%@ Page Language="C#" ValidateRequest="false" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication17._Default" %> <html> <body>
    <form runat="server">
        <asp:FormView ID="FormView1" runat="server" ItemType="WebApplication17.S" SelectMethod="FormView1_GetItem">
            <ItemTemplate>
                <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
                <asp:Label ID="Label1" runat="server" Text="<%#: Item.Text %>"></asp:Label>
                <asp:TextBox ID="TextBox2" runat="server" Text="<%#: Item.Text %>"></asp:TextBox>
            </ItemTemplate>
        </asp:FormView>
    </form> 

코드 숨김

public partial class _Default : Page
{
    S s = new S();

    protected void Button1_Click(object sender, EventArgs e)
    {
        s.Text = ((TextBox)FormView1.FindControl("TextBox1")).Text;
        FormView1.DataBind();
    }

    public S FormView1_GetItem(int? id)
    {
        return s;
    }
}

public class S
{
    public string Text { get; set; }
}
  1. 사례 제출 값 : &#39;

Label1.Text 값 : &#39;

TextBox2.Text 값 : &amp;#39;

  1. 사례 제출 값 : <script>alert('attack!');</script>

Label1.Text 값 : <script>alert('attack!');</script>

TextBox2.Text 값 : &lt;script&gt;alert(&#39;attack!&#39;);&lt;/script&gt;

1
dpant

우리 중 아직도 webforms에 붙어있어 당신은 하나의 필드에 유효성을 해제 할 수있는 다음과 같은 솔루션을 발견! (나는 전체 페이지를 위해 그것을 싫어할 것이다.)

VB.NET :

Public Class UnvalidatedTextBox
    Inherits TextBox
    Protected Overrides Function LoadPostData(postDataKey As String, postCollection As NameValueCollection) As Boolean
        Return MyBase.LoadPostData(postDataKey, System.Web.HttpContext.Current.Request.Unvalidated.Form)
    End Function
End Class

기음#:

public class UnvalidatedTextBox : TextBox
{
    protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    {
        return base.LoadPostData(postDataKey, System.Web.HttpContext.Current.Request.Unvalidated.Form);
    }
}

이제는 <prefix:UnvalidatedTextBox id="test" runat="server" /> 대신 <asp:TextBox를 사용하고 모든 문자를 허용해야합니다 (암호 필드에 적합 함).

1
Peter

이 질문은 양식 게시와 관련이 있습니다. 그러나 다른 사람들의 상황에이 오류가 발생한 사람들을위한 세부 정보를 추가하고 싶습니다. 또한 웹 서비스를 구현하는 데 사용되는 핸들러에서 발생할 수도 있습니다. 

웹 클라이언트가 ajax를 사용하여 POST 또는 PUT 요청을 보내고 json 또는 xml 텍스트 또는 원시 데이터 (파일 내용)를 웹 서비스로 보냈다고 가정합니다. 웹 서비스가 Content-Type 헤더에서 정보를 가져올 필요가 없기 때문에 JavaScript 코드가이 헤더를 사용자의 ajax 요청으로 설정하지 않았습니다. 그러나 POST/PUT ajax 요청에이 헤더를 설정하지 않으면 Safari에서 "Content-Type : application/x-www-form-urlencoded"헤더를 추가 할 수 있습니다. 나는 iPhone의 Safari 6에서이를 관찰했지만 다른 Safari 버전/OS 또는 Chrome에서도 동일한 기능을 수행 할 수 있습니다. 따라서이 Content-Type 헤더를 받으면 .NET Framework의 일부에서 요청 본문 데이터 구조가 html 형식 게시와 일치하는 것으로 가정하고 HttpRequestValidationException 예외를 발생시킵니다. 먼저해야 할 일은 분명히 항상 Content-Type 헤더를 POST/PUT 아약스 요청의 양식 MIME 유형으로 설정하는 것입니다. 이는 웹 서비스에는 쓸모가 없습니다.

나는 또한이 세부 사항을 발견했다.
이러한 상황에서 코드가 HttpRequest.Params 컬렉션에 액세스하려고하면 HttpRequestValidationException 예외가 발생합니다. 그러나 놀랍게도이 예외는 HttpRequest.ServerVariables 컬렉션에 액세스 할 때 상승하지 않습니다. 이 두 컬렉션은 거의 동일하게 보이지만 보안 검사를 통해 요청 데이터에 액세스하고 다른 데이터는 요청하지 않는다는 것을 보여줍니다.

1
figolu

.Net 4.0 이상에서는 일반적인 경우로 system.web에 다음 설정을 입력하십시오.

<system.web>
     <httpRuntime requestValidationMode="2.0" />
1
Kiran Chaudhari

내 경우에는 asp : Textbox 컨트롤 (Asp.net 4.5)을 사용하여 validateRequest="false" 의 모든 페이지를 설정하는 대신 

<asp:TextBox runat="server" ID="mainTextBox"
            ValidateRequestMode="Disabled"
 ></asp:TextBox>

예외를 일으킨 텍스트 상자에.

0
maozx

용액

게시물 유효성 검사 (validateRequest = "false")를 해제하고 싶지 않습니다. 반면 무고한 사용자가 <x 또는 무엇인가를 입력했기 때문에 응용 프로그램이 충돌하는 것은 허용되지 않습니다. 

따라서 예비 검사를 수행하는 클라이언트 측 javascript 함수 (xssCheckValidates)를 작성했습니다. 이 함수는 다음과 같이 양식 데이터를 게시하려고 할 때 호출됩니다.

<form id="form1" runat="server" onsubmit="return xssCheckValidates();">

이 기능은 매우 간단하고 개선 될 수 있지만 그 일을하고 있습니다.

이 목적은 시스템을 해킹으로부터 보호하는 것이 아니라 사용자를 나쁜 환경에서 보호하기위한 것입니다. 서버에서 수행 된 요청 유효성 검사는 여전히 켜져 있으며 이는 시스템 보호의 일부입니다 (가능한 한도 내에서). 

여기서 "부분"이라고 말한 이유는 내장 된 요청 유효성 검사로 충분하지 않을 수 있다고 들었기 때문입니다. 따라서 다른 보완적인 수단이 완전한 보호를 위해 필요할 수도 있습니다. 하지만, 다시 말하지만, 여기에 제시된 자바 스크립트 함수는 시스템 보호와 관련하여 아무것도 없습니다. 그것은 전용 의미는 사용자가 나쁜 경험을하지 않도록합니다.

당신은 그것을 여기에서 시험해 볼 수있다 :

    function xssCheckValidates() {
      var valid = true;
      var inp = document.querySelectorAll(
          "input:not(:disabled):not([readonly]):not([type=hidden])" +
          ",textarea:not(:disabled):not([readonly])");
      for (var i = 0; i < inp.length; i++) {
        if (!inp[i].readOnly) {
          if (inp[i].value.indexOf('<') > -1) {
            valid = false;
            break;
          }
          if (inp[i].value.indexOf('&#') > -1) {
            valid = false;
            break;
          }
        }
      }
      if (valid) {
        return true;
      } else {
        alert('In one or more of the text fields, you have typed\r\nthe character "<" or the character sequence "&#".\r\n\r\nThis is unfortunately not allowed since\r\nit can be used in hacking attempts.\r\n\r\nPlease edit the field and try again.');
        return false;
      }
    }
<form onsubmit="return xssCheckValidates();" >
  Try to type < or &# <br/>
  <input type="text" /><br/>
  <textarea></textarea>
  <input type="submit" value="Send" />
</form>

0
Magnus

Server.HtmlEncode("yourtext");을 사용하십시오.

0
Voigt

나는 이것에 대해 많이 쓰여진 것을보고 ... 나는 언급하지 않았다. 이것은 .NET Framework 4.5

ValidateRequestMode 컨트롤의 설정은 훌륭한 옵션입니다. 이렇게하면 페이지의 다른 컨트롤이 여전히 보호됩니다. web.config를 변경하지 않아도됩니다.

 protected void Page_Load(object sender, EventArgs e)
    {
             txtMachKey.ValidateRequestMode = ValidateRequestMode.Disabled;
    }
0
Chris Catignani