Потенциально опасный запрос.Значение формы было обнаружено от клиента


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

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

захват исключения и показ

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

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

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

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

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

30 1345

30 ответов:

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

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

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

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

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

, когда вы уверены вы HTML-кодируете везде, где вы передаете строки в HTML, а затем устанавливаете validateRequest="false" на (ы).

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

есть другое решение этой ошибки, если вы используете 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

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

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

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

если вы находитесь на .NET 4.0 убедитесь, что вы добавляете это в свой web.конфигурации внутри <system.web> теги:

<httpRuntime requestValidationMode="2.0" />

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

requestValidationMode="2.0"

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

validateRequest="false"

для 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>

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

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

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

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

это по-прежнему проверяет все поля, кроме исключенного. Хорошая вещь об этом заключается в том, что ваши атрибуты проверки по-прежнему проверяют поле, но вы просто не получаете "потенциально опасный запрос.Значение формы было обнаружено от клиента" исключения.

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

In ASP.NET MVC вам нужно установить requestValidationMode= "2.0"и validateRequest=" false " в web.сконфигурируйте и примените атрибут ValidateInput к действию контроллера:

<httpRuntime requestValidationMode="2.0"/>

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

и

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

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

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

[ValidateInput (false)]

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

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

    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

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

myTextBox.Text = Server.HtmlEncode(myStringFromDatabase); // Pseudo code
действие .Свойство Text для гиперссылки, литерала и метки не будет HTML-кодировать вещи, поэтому сервер обертывания.HtmlEncode (); вокруг всего сущего установить эти свойства необходимо, если вы хотите предотвратить <script> window.location = "http://www.google.com"; </script> от вывода на вашу страницу и последующего выполнения.

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

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

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

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

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

пример:

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

Если вы не хотите отключать 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);")

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

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

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

другое решение-это:

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

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

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

отключение защиты на уровне страницы, а затем кодирование каждый раз является лучшим вариантом.

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

если вы используете framework 4.0, то запись в интернете.config ()

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

если вы используете framework 4.5, то запись в интернете.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" %>

если у вас уже есть что-то вроде EnableEventValidation="false"%>

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

другие решения здесь хороши, однако это немного королевская боль в тылу, чтобы применить [AllowHtml] к каждому свойству модели, особенно если у вас есть более 100 моделей на приличном сайте.

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

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

просто убедитесь, что вы кодируете HTML все, что выкачивается в представления, которые пришли из пользовательского ввода (это поведение по умолчанию в ASP.NET MVC 3 с бритвой в любом случае, так что если по какой-то странной причине вы используете Html.Сырье() вы не должны требовать эту функцию.

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

в моем случае пользователь ввел ударениеá в имени роли (относительно ASP.NET поставщик членства).

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

Я сделал это, чтобы решить проблему:

вместо

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

этого

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

@Html.Raw сделал свое дело.

I был получить имя роли-значение в формате HTML roleName="Cadastro b&#225;s". Это значение с HTML entity &#225; был заблокирован ASP.NET MVC. Теперь я получаю roleName значение параметра должно быть: roleName="Cadastro Básico" и ASP.NET MVC engine больше не будет блокировать запрос.

причина

ASP.NET по умолчанию проверяет все входные элементы управления на наличие потенциально опасного содержимого, которое может привести к межсайтовый скриптинг (XSS) и SQL инъекции. Таким образом, он запрещает такое содержание, бросая вышеупомянутое исключение. По умолчанию рекомендуется разрешить эту проверку для каждой обратной передачи.

решение

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

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

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

<pages validateRequest ="false" />

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

<httpRuntime requestValidationMode = "2.0" />

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

ссылка по: ASP.Net ошибка: потенциально опасный запрос.Значение формы было обнаружено от клиента

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

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

см.:http://www.procheckup.com/PDFs/bypassing-dot-NET-ValidateRequest.pdf

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

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

    функция бу() { targetText = документ.getElementById ("HiddenField1"); sourceText = документ.getElementById ("userbox"); targetText.value = escape (sourceText.через свойство innerText); }

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

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

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

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

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

вот пример, который я (MC9000) придумал и использовал через jQuery:

$(document).ready(function () {

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

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


});

и разметка:

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

это прекрасно работает. Если хакер попытается опубликовать сообщение в обход JavaScript, они просто увидят ошибку. Вы также можете сохранить все эти данные, закодированные в базе данных, а затем отменить их (на стороне сервера) и проанализировать и проверить атаки перед отображением в другом месте.

вы также можете использовать JavaScript escape (string)

я использовал 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;
}

конечно, моя страница в основном ввод данных, и есть очень мало элементов, которые делают обратные передачи, но по крайней мере их данные сохраняются.

пока это только " "(а не сама двойная кавычка) символы, и вы используете их в контексте, как , вы в безопасности (в то время как для

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

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

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

var nvc = Request.Unvalidated().Form;

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