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

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

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

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

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

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

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

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

Есть ли способ сделать это из обработчика?

1246
задан Radu094 17 сент. '08 в 13:58
источник поделиться
36 ответов
  • 1
  • 2

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

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

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

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

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

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

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

946
ответ дан JacquesB 17 сент. '08 в 14:26
источник поделиться

Это другое решение этой ошибки, если вы используете ASP.NET MVC:

Пример Visual Basic:

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

Пример С#:

[HttpPost, ValidateInput(false)]
public ActionResult Edit(FormCollection collection)
{
    // ...
}
452
ответ дан Zack Peterson 09 окт. '09 в 1:56
источник поделиться

В ASP.NET MVC 3 вы можете добавить атрибут AllowHtml к свойству на вашей модели.

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

[AllowHtml]
public string Description { get; set; }
335
ответ дан Anthony Johnston 05 сент. '11 в 12:33
источник поделиться

Если вы используете .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"
198
ответ дан JordanC 30 июля '10 в 7:51
источник поделиться

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

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

99
ответ дан Carter Medlin 27 нояб. '12 в 20:22
источник поделиться

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

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

Это все еще проверяет все поля, кроме исключенного. Самое приятное в том, что ваши атрибуты проверки по-прежнему проверяют поле, но вы просто не получаете "исключение из потенциально опасного параметра Request.Form из клиентских" исключений.

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

67
ответ дан gligoran 06 нояб. '10 в 17:58
источник поделиться

В 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) {
    ...
}
46
ответ дан ranthonissen 30 нояб. '10 в 15:56
источник поделиться

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

44
ответ дан Pavel Chuchuva 17 сент. '08 в 14:20
источник поделиться

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

[ValidateInput (ложь)]

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

42
ответ дан A.Dara 29 янв. '14 в 12:40
источник поделиться

Вы можете поймать эту ошибку в 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
ответ дан BenMaddox 14 окт. '09 в 1:37
источник поделиться

Пожалуйста, имейте в виду, что некоторые элементы управления .NET автоматически кодируют HTML-код. Например, установка свойства .Text в элементе управления TextBox будет автоматически кодировать его. Это специально означает преобразование < в &lt;, > в &gt; и & в &amp;. Поэтому будьте осторожны с этим...

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

Однако свойство .Text для HyperLink, Literal и Label не будет кодировать HTML файлы, поэтому wraping Server.HtmlEncode(); вокруг чего-либо, установленного в этих свойствах, является обязательным, если вы хотите, чтобы <script> window.location = "http://www.google.com"; </script> не выводился на вашу страницу и впоследствии выполнялся.

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

32
ответ дан Dominic Pettifer 17 сент. '08 в 17:40
источник поделиться

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

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

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

26
ответ дан flakomalo 25 апр. '13 в 23:56
источник поделиться

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

Пример:

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>
24
ответ дан Mahdi jokar 15 марта '12 в 1:20
источник поделиться

Если вы не хотите отключать 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);")
20
ответ дан YORENGOY 12 янв. '09 в 20:35
источник поделиться

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

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

Я не знаю, есть ли недостатки, но для меня это работало потрясающе.

17
ответ дан Piercy 27 янв. '12 в 18:01
источник поделиться

Другое решение:

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;
    }
}
16
ответ дан Sel 08 дек. '13 в 8:39
источник поделиться

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

Отключение защиты на уровне страницы и последующее кодирование - лучший вариант.

Вместо использования Server.HtmlEncode вы должны посмотреть более новую, более полную анти-XSS-библиотеку из команды Microsoft ACE.

12
ответ дан blowdart 17 сент. '08 в 14:26
источник поделиться

В 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();
    }
}
12
ответ дан Jaider 17 июля '12 в 23:19
источник поделиться

Если вы используете фреймворк 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, так что просто добавьте rest = > EnableEventValidation="false"% >

Я рекомендую не делать этого.

10
ответ дан Durgesh Pandey 10 дек. '15 в 10:35
источник поделиться

Другие решения здесь приятны, однако немного королевской боли в тылу приходится применять [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 с Razor в любом случае, поэтому, если только по какой-то странной причине вы используете Html.Raw(), вы не должны использовать эту функцию.

10
ответ дан magritte 16 марта '12 в 17:34
источник поделиться

Причина

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 15 июня '15 в 9:44
источник поделиться

Отключите проверку страницы, если вам действительно нужны специальные символы, такие как >, < и т.д. Затем убедитесь, что при отображении пользовательского ввода данные кодируются в формате HTML.

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

Смотрите: http://www.procheckup.com/PDFs/bypassing-dot-NET-ValidateRequest.pdf

9
ответ дан woany 17 сент. '08 в 14:32
источник поделиться

Я тоже получал эту ошибку.

В моем случае пользователь ввел имя с символом á в имени роли (в отношении поставщика членства 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 Macaferi 14 авг. '12 в 18:27
источник поделиться

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

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

      function 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, они просто видят ошибку. Вы также можете сохранить все эти данные, закодированные в базе данных, затем отменить их (на стороне сервера) и проанализировать и проверить наличие атак до отображения в других местах.

7
ответ дан Jason Shuler 16 сент. '14 в 18:31
источник поделиться

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

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

7
ответ дан Trisped 11 февр. '12 в 5:33
источник поделиться

Я закончил с использованием 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 03 авг. '12 в 18:22
источник поделиться

Если вы просто хотите сказать своим пользователям, что < и > не должны использоваться НО, вы не хотите, чтобы вся форма обрабатывалась/отправлялась назад (и теряла все входные данные), прежде чем вы могли бы просто не помещать валидатор вокруг поля для экранирования для этих (и, возможно, других потенциально опасных)?

4
ответ дан Captain Toad 17 сент. '08 в 14:41
источник поделиться

Вы можете использовать что-то вроде:

var nvc = Request.Unvalidated().Form;

Позже nvc["yourKey"] должен работать.

4
ответ дан Ady Levy 01 июня '13 в 1:55
источник поделиться

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

4
ответ дан Mike S. 17 февр. '13 в 22:40
источник поделиться

Вам следует использовать метод Server.HtmlEncode для защиты вашего сайта от опасного ввода.

Дополнительная информация здесь

3
ответ дан bastos.sergio 17 сент. '08 в 14:21
источник поделиться
  • 1
  • 2

Другие вопросы по меткам