От клиента было обнаружено потенциально опасное значение Request.Form - PullRequest
1397 голосов
/ 17 сентября 2008

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

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

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

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

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

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

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

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

Ответы [ 43 ]

1041 голосов
/ 17 сентября 2008

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

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

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

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

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

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

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

489 голосов
/ 09 октября 2009

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

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

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

[AllowHtml]
public string Description { get; set; }
209 голосов
/ 30 июля 2010

Если вы используете .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"
109 голосов
/ 27 ноября 2012

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

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

70 голосов
/ 06 ноября 2010

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

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

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

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

48 голосов
/ 30 ноября 2010

В 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) {
    ...
}
45 голосов
/ 17 сентября 2008

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

42 голосов
/ 29 января 2014

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

[ValidateInput (ложь)]

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

41 голосов
/ 14 октября 2009

Вы можете отловить эту ошибку в 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

...