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

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

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

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

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

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

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

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

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

30 ответов


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

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

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

в других контекстах разные подстроки опасны, например, если вы пишете предоставленный пользователем URL-адрес в ссылку, подстроку" (ы).

в .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.config внутри <system.web> теги:

<httpRuntime requestValidationMode="2.0" />

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

requestValidationMode="2.0"

вы можете отключить запрос validate полностью 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 вы можете сделать это:

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

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

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


In ASP.NET MVC вам нужно установить 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) {
    ...
}

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


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

[ValidateInput (false)]

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


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

    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.Raw () эта функция не требуется.


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

в моем случае пользователь ввел ударениеá в имени роли (относительно 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-контент на вашу страницу через Rich TextBoxes или Редакторы Rich Text. В этом случае вы можете избежать этого исключения, установив тег ValidateRequest в @Page директива false.

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

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

<pages validateRequest ="false" />

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

<httpRuntime requestValidationMode = "2.0" />

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

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


отключите проверку страницы, если вам действительно нужны специальные символы, такие как,>,,<, etc. Затем убедитесь, что при отображении пользовательского ввода данные кодируются в формате 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); }

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

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

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

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

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


вы также можете использовать 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"] должны работать.