ASP.NET MVC Потенційно небезпечне значення Request.Form було виявлено у клієнта під час користувальницького підшивки моделей


95

Отримання помилки тут:

ValueProviderResult value = bindingContext.ValueProvider.GetValue("ConfirmationMessage");

Як дозволити лише вибір значень? тобто

[ValidateInput(false)]
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    ValueProviderResult value = bindingContext.ValueProvider.GetValue("ConfirmationMessage");
    ValueProviderResult value2 = bindingContext.ValueProvider.GetValue("ConfirmationMessage2");
}

1
Можливий дублікат потенційно небезпечного запиту. Значення форми було виявлено у клієнта , не має значення, це веб-форми чи MVC.
Ерік Філіпс,

2
Дякую, але ви не розглядали мою проблему як іншу
DW

Точно така ж коренева проблема, єдина відмінність полягає в тому, що можуть бути специфічні способи боротьби з нею.
Ерік Філіпс,

При використанні EF см bizzehdee відповідь тут stackoverflow.com/questions/17964313 / ...
Петро

Відповіді:


223

У вас є кілька варіантів.

У моделі додайте цей атрибут до кожного властивості, яке вам потрібно, щоб дозволити HTML - найкращий вибір

using System.Web.Mvc;

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

До дії контролера додайте цей атрибут, щоб дозволити весь HTML

[ValidateInput(false)]
public ActionResult SomeAction(MyViewModel myViewModel)

Груба сила в web.config - однозначно не рекомендується

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

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

Докладніше: http://davidhayden.com/blog/dave/archive/2011/01/16/AllowHtmlAttributeASPNETMVC3.aspx

Вищезазначене працює для звичок типового в’яжучого моделей.

Спеціальний ModelBinder

Здається, що виклик bindingContext.ValueProvider.GetValue () у наведеному вище коді завжди перевіряє дані, незалежно від будь-яких атрибутів. Копаючись у джерелах ASP.NET MVC, виявляється, що DefaultModelBinder спочатку перевіряє, чи потрібна перевірка запиту, а потім викликає метод bindingContext.UnvalidatedValueProvider.GetValue () із параметром, який вказує, чи потрібна перевірка чи ні.

На жаль, ми не можемо використовувати будь-який фреймворк-код, оскільки він запечатаний, приватний чи що завгодно, щоб захистити незнаючих розробників від небезпечних дій, але не надто складно створити робочу підшивку власної моделі, яка поважає атрибути AllowHtml та ValidateInput:

public class MyModelBinder: IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // First check if request validation is required
        var shouldPerformRequestValidation = controllerContext.Controller.ValidateRequest && bindingContext.ModelMetadata.RequestValidationEnabled;

        // Get value
        var valueProviderResult = bindingContext.GetValueFromValueProvider(shouldPerformRequestValidation);
        if (valueProviderResult != null)
        {
            var theValue = valueProviderResult.AttemptedValue;

            // etc...
        }
    }
}

Інший необхідний фрагмент - це спосіб отримати неперевірене значення. У цьому прикладі ми використовуємо метод розширення для класу ModelBindingContext:

public static class ExtensionHelpers
{
    public static ValueProviderResult GetValueFromValueProvider(this ModelBindingContext bindingContext, bool performRequestValidation)
    {
        var unvalidatedValueProvider = bindingContext.ValueProvider as IUnvalidatedValueProvider;
        return (unvalidatedValueProvider != null)
          ? unvalidatedValueProvider.GetValue(bindingContext.ModelName, !performRequestValidation)
          : bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
    }
}

Детальніше про це на веб-сайті http://blogs.taiga.nl/martijn/2011/09/29/custom-model-binders-and-request-validation/


у мене це на контролері [HttpPost, ValidateInput (false)], і я все ще отримую помилку
DW

Дивіться мою переглянуту відповідь із цим способом, коли ви використовуєте користувальницький підшивку
ericdc

Дякую, але йому не подобається цей рядок bindingContext.GetValueFromValueProvider
DW

GetValueFromValueProvider повинен бути у загальнодоступному статичному класі. Перевірте редагування вище.
ericdc

Ta, valueProviderResult reutrns null tho? var valueProviderResult = bindingContext.GetValueFromValueProvider (shouldPerformRequestValidation);
DW

31

Спробуйте:

HttpRequestBase request = controllerContext.HttpContext.Request;
string re = request.Unvalidated.Form.Get("ConfirmationMessage")

Коли я спробую це, я отримую виняток, який говорить: не викликається член 'System.web.HttpRequestBase.Unvalidated' не може використовуватися як метод. Чи змінилася ця річ?
Stack0verflow

7
Другий рядок справді повинен бутиvar re = request.Unvalidated.Form["ConfirmationMessage"];
Stack0verflow

5

Розширюючи відповідь від @DW, у моєму контролері редагування, перебираючи значення форми, мені довелося замінити всі екземпляри Request.Params.AllKeysз Request.Unvalidated.Form.AllKeysі всі екземпляри Request[key]з Request.Unvalidated.Form[key].

Це було єдине рішення, яке працювало для мене.


0

Як писав Майк Годін, навіть якщо ви встановите атрибут [ValidateInput (false)], вам доведеться використовувати Request.Unvalidated.Form замість Request.Form Це спрацювало для мене з ASP.NET MVC 5


1
Це насправді була корисна порада, оскільки при доступі до даних базового контролера (тобто з метою журналу або налагодження) будь-який доступ до Request.Form видає виняток, навіть якщо модель має цей атрибут.
nsimeonov

-5

Ось кроки для кодування на рівні клієнта та декодування на рівні сервера:

  1. Опублікуйте форму, використовуючи метод подання jquery.

  2. У кнопці jquery натисніть метод події, кодуючи поле, яке ви хочете опублікувати на сервері. Приклад:

    $("#field").val(encodeURIComponent($("#field").val()))
    $("#formid").submit();
  3. На рівні контролера отримуйте доступ до всіх значень ідентифікатора форми за допомогою

    HttpUtility.UrlDecode(Request["fieldid"])

Приклад прикладу:

  • Рівень контролера:

    public ActionResult Name(string id)
    {
    
        CheckDispose();
        string start = Request["start-date"];
        string end = Request["end-date"];
        return View("Index", GetACPViewModel(HttpUtility.UrlDecode(Request["searchid"]), start, end));
    }
  • Клієнтський рівень:

    <% using (Html.BeginForm("Name", "App", FormMethod.Post, new { id = "search-form" }))
    { %>
    <div>
    <label  for="search-text" style="vertical-align: middle" id="search-label" title="Search for an application by name, the name for who a request was made, or a BEMSID">App, (For Who) Name, or BEMSID: </label>
    <%= Html.TextBox("searchid", null, new {value=searchText, id = "search-text", placeholder = "Enter Application, Name, or BEMSID" })%>
    </div>
    <div>
    <input id="start-date" name="start-date" class="datepicker" type="text"  placeholder="Ex: 1/1/2012"/>
    </div>
    <div>
    <input id="end-date" name="end-date" class="datepicker" type="text"  placeholder="Ex: 12/31/2012"/>
    </div>
    <div>
    <input type="button" name="search" id="btnsearch" value="Search" class="searchbtn" style="height:35px"/>
    </div> 
    <% } %>

У функції Готовий документ:

$(function () {     
  $("#btnsearch").click(function () {  
    $("#search-text").val(encodeURIComponent($("#search-text").val()));
    $("#search-form").submit();
  });
});

4
Технологія Jquery та клієнтська сторона не має нічого спільного з MVC, перевірка відбувається на стороні сервера з платформою MVC. Це не правильна відповідь
diegosasw

1
Враховуючи те, що Microsoft буквально ігнорує атрибут AllowHtml, і враховуючи, що єдиним дієвим рішенням на стороні сервера є заміна функціональних можливостей прив'язки моделей за замовчуванням, я б стверджував, що кодування на стороні клієнта є цілком допустимим варіантом.
Джонатан,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.