it-swarm-ru.tech

От клиента было обнаружено потенциально опасное значение Request.Form

Каждый раз, когда пользователь публикует что-то, содержащее < или > на странице в моем веб-приложении, я получаю это исключение.

Я не хочу вдаваться в дискуссию о целесообразности создания исключения или сбоя всего веб-приложения, потому что кто-то ввел символ в текстовое поле, но я ищу элегантный способ справиться с этим.

Отслеживание исключения и отображение

Произошла ошибка. Вернитесь и введите заново всю форму, но на этот раз не используйте <

не кажется мне достаточно профессиональным.

Отключение пост-проверки (validateRequest="false") определенно позволит избежать этой ошибки, но сделает страницу уязвимой для ряда атак.

В идеале: когда происходит обратная запись, содержащая ограниченные символы HTML, это отправленное значение в коллекции Form будет автоматически закодировано в HTML . Поэтому свойство .Text моего текстового поля будет something & lt; html & gt;

Есть ли способ, которым я могу сделать это из обработчика?

1379
Radu094

Я думаю, что вы атакуете его с неправильной точки зрения, пытаясь закодировать все опубликованные данные.

Обратите внимание, что «<» также может поступать из других внешних источников, таких как поле базы данных, конфигурация, файл, канал и так далее. 

Кроме того, «<» по своей природе не опасен. Это опасно только в определенном контексте: при написании строк, которые не были закодированы в вывод HTML (из-за XSS).

В других контекстах разные подстроки опасны, например, если вы записываете предоставленный пользователем URL в ссылку, подстрока «javascript:» может быть опасной. Символ одинарной кавычки, с другой стороны, опасен при интерполяции строк в запросах SQL, но совершенно безопасен, если он является частью имени, переданного из формы или считанного из поля базы данных.

Суть в том, что вы не можете отфильтровать случайный ввод для опасных символов, потому что любой символ может быть опасным при правильных обстоятельствах. Вы должны кодировать в точке, где некоторые конкретные символы могут стать опасными, потому что они переходят на другой язык, где они имеют особое значение. Когда вы пишете строку в HTML, вы должны кодировать символы, которые имеют особое значение в HTML, используя Server.HtmlEncode. Если вы передаете строку в динамический оператор SQL, вы должны кодировать разные символы (или, лучше, позвольте платформе сделать это за вас, используя подготовленные операторы или тому подобное) ..

Когда вы уверены, что кодируете HTML везде, где вы передаете строки в HTML, тогда установите validateRequest="false" в директиву <%@ Page ... %> в ваших файлах .aspx.

В .NET 4 вам может потребоваться сделать немного больше. Иногда необходимо также добавить <httpRuntime requestValidationMode="2.0" /> в web.config ( reference ).

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, убедитесь, что вы добавили это в файл web.config внутри тегов <system.web>

<httpRuntime requestValidationMode="2.0" />

В .NET 2.0 проверка запросов применяется только к запросам aspx. В .NET 4.0 это было расширено, чтобы включить все запросы. Вы можете вернуться к only, выполняющему проверку XSS при обработке .aspx, указав:

requestValidationMode="2.0"

Вы можете отключить запрос проверки полностью, указав:

validateRequest="false"
206
JordanC

В 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, потому что на уровне сайта вы можете видеть, какие страницы допускают разметку в качестве входных данных.

Вам все еще нужно программно проверять ввод на страницах, где проверка запроса отключена.

108
Carter Medlin

Предыдущие ответы были хорошими, но никто не сказал, как исключить проверку одного поля для инъекций HTML/JavaScript. Я не знаю о предыдущих версиях, но в MVC3 Beta вы можете сделать это:

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

Это все еще проверяет все поля, кроме исключенного. Хорошая вещь об этом состоит в том, что ваши атрибуты проверки все еще проверяют поле, но вы просто не получаете исключение «потенциально опасное значение Request.Form было обнаружено из клиента».

Я использовал это для проверки правильности выражения. Я сделал свой собственный атрибут ValidationAttribute, чтобы проверить, является ли регулярное выражение допустимым или нет. Поскольку регулярные выражения могут содержать нечто, похожее на скрипт, я применил приведенный выше код - регулярное выражение все еще проверяется, действительно ли оно допустимо или нет, но не в том случае, если оно содержит скрипты или HTML.

70
gligoran

В 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) {
    ...
}
48
ranthonissen

Вы можете HTML кодировать текстовое поле, но, к сожалению, это не остановит исключение. По моему опыту нет никакого пути, и вы должны отключить проверку страницы. Делая это, вы говорите: «Я буду осторожен, я обещаю».

45
Pavel Chuchuva

Для MVC проигнорируйте проверку ввода, добавив 

[ValidateInput (ложь)]

над каждым действием в контроллере.

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-код. Например, установка свойства .Text в элементе управления TextBox автоматически закодирует его. Это, в частности, означает преобразование < в &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> на вашу страницу и последующее выполнение.

Сделайте небольшой эксперимент, чтобы увидеть, что кодируется, а что нет.

33
Dominic Pettifer

Ответ на этот вопрос прост:

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

Это отключило бы проверку для конкретного запроса.

31
flakomalo

В файле web.config в тегах вставьте элемент httpRuntime с атрибутом requestValidationMode = "2.0". Также добавьте атрибут validateRequest = "false" в элементе pages.

Пример:

<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

Кажется, никто еще не упомянул ниже, но это решает проблему для меня. И прежде чем кто-нибудь скажет: да, это Visual Basic ... хм.

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

Если вы используете framework 4.0, тогда запись в web.config (<pages validateRequest = "false" />)

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

Если вы используете framework 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 вы должны взглянуть на более новую, более полную библиотеку Anti-XSS от команды Microsoft ACE.

12
blowdart

Другие решения здесь - «Ницца», однако задним ходом немного неприятно, когда приходится применять [AllowHtml] к каждому отдельному свойству Model, особенно если у вас есть более 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 . Таким образом, он запрещает такой контент, выбрасывая вышеуказанное исключение. По умолчанию рекомендуется разрешить эту проверку при каждой обратной передаче.

Решение

Во многих случаях вам нужно отправить HTML-контент на вашу страницу через Rich TextBoxes или Rich Text Editors. В этом случае вы можете избежать этого исключения, установив для тега ValidateRequest в директиве @Page значение false.

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

Это отключит проверку запросов для страницы, для которой вы установили флаг ValidateRequest в значение false. Если вы хотите отключить это, проверьте в вашем веб-приложении; вам нужно установить значение false в вашем разделе web.config <system.web>

<pages validateRequest ="false" />

Для .NET 4.0 или более поздних платформ вам также необходимо добавить следующую строку в разделе <system.web>, чтобы вышеуказанная работа работала.

<httpRuntime requestValidationMode = "2.0" />

Это оно. Я надеюсь, что это поможет вам избавиться от вышеуказанной проблемы.

Ссылка: Ошибка ASP.Net: потенциально опасное значение Request.Form было обнаружено клиентом

9
vakeel

Я нашел решение, которое использует JavaScript для кодирования данных, которое декодируется в .NET (и не требует jQuery).

  • Сделайте текстовое поле элементом HTML (например, textarea) вместо элемента ASP.
  • Добавьте скрытое поле.
  • Добавьте следующую функцию JavaScript в свой заголовок.

    функция boo () { targetText = document.getElementById ("HiddenField1"); sourceText = document.getElementById ("userbox"); targetText.value = escape (sourceText.innerText); }

В вашей текстовой области включите onchange, который вызывает boo ():

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

Наконец, в .NET используйте

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

Я знаю, что это односторонний подход - если вам нужен двусторонний подход, вам придется проявить творческий подход, но это дает решение, если вы не можете редактировать файл web.config.

Вот пример, который я (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". Это значение с сущностью HTML &#225; было заблокировано ASP.NET MVC. Теперь я получаю значение параметра roleName таким, каким оно должно быть: roleName="Cadastro Básico" и механизм ASP.NET MVC больше не будет блокировать запрос.

9
Leniel Maccaferri

Вы также можете использовать JavaScript-функцию escape (string) для замены специальных символов. Затем на стороне сервера используйте Server. URLDecode (string) , чтобы переключить его обратно.

Таким образом, вам не нужно отключать проверку ввода, и другим программистам будет понятнее, что строка может иметь HTML-содержимое.

7
Trisped

Я заканчивал тем, что использовал JavaScript перед каждой обратной передачей, чтобы проверить символы, которые вам не нужны, например:

<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 </ textarea> вы были бы уязвимы, конечно). Это может упростить вашу ситуацию, но для чего угодно более использовать одно из других опубликованных решений.

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

Как указано в моем комментарии к ответ Села , это наше расширение для валидатора пользовательских запросов.

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; 

поищите различия между UrlDecode и UnescapeDataString

2
Wahid Masud

И последнее, но не менее важное: обратите внимание, что ASP.NET Data Binding автоматически контролирует encode values ​​во время привязки данных. Это изменяет поведение по умолчанию всех элементов управления ASP.NET (TextBox, Label и т.д.), Содержащихся в ItemTemplate. Следующий пример демонстрирует (для 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

Для тех из нас, кто все еще придерживается веб-форм, я нашел следующее решение, которое позволяет отключить проверку только в одном поле! (Я бы не хотел отключить его для всей страницы.)

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

C #:

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

Я знаю, что этот вопрос касается публикации формы, но я хотел бы добавить некоторые детали для людей, которые получили эту ошибку при других обстоятельствах. Это также может произойти в обработчике, используемом для реализации веб-службы. 

Предположим, что ваш веб-клиент отправляет POST или PUT-запросы с использованием ajax и отправляет в веб-службу текст json или xml или необработанные данные (содержимое файла). Поскольку вашей веб-службе не требуется получать какую-либо информацию из заголовка Content-Type, ваш код JavaScript не установил этот заголовок для вашего запроса ajax. Но если вы не установите этот заголовок в запросе ajax POST/PUT, Safari может добавить этот заголовок: «Content-Type: application/x-www-form-urlencoded». Я заметил, что на Safari 6 на iPhone, но другие версии Safari/OS или Chrome могут делать то же самое. Таким образом, при получении этого заголовка Content-Type некоторая часть .NET Framework предполагает, что структура данных тела запроса соответствует публикации формы html, в то время как это не так, и выдает исключение HttpRequestValidationException. Первое, что нужно сделать, это, очевидно, всегда устанавливать заголовок Content-Type на что-либо, кроме MIME-типа в форме запроса ajax POST/PUT, даже если это бесполезно для вашего веб-сервиса.

Я также обнаружил эту деталь:
При таких обстоятельствах возникает исключение HttpRequestValidationException, когда ваш код пытается получить доступ к коллекции HttpRequest.Params. Но, что удивительно, это исключение не возникает при доступе к коллекции 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();">

Функция довольно проста и может быть улучшена, но она делает свое дело.

Обратите внимание, что целью этого является не защита системы от взлома, а защита пользователей от плохой работы. Проверка запроса, выполненная на сервере, все еще включена, и это (часть) защиты системы (в той степени, в которой она способна это сделать). 

Причина, по которой я говорю «часть», заключается в том, что я слышал, что встроенной проверки запросов может быть недостаточно, поэтому для обеспечения полной защиты могут потребоваться другие дополнительные средства. Но, опять же, функция JavaScript, которую я здесь представляю, имеет ничего для защиты системы. Это только предназначено, чтобы гарантировать, что пользователи не будут иметь плохой опыт.

Вы можете попробовать это здесь:

    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