Подтвердить что ты не робот

Можно ли переопределить параметр ValidateRequest страницы?

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

Чтобы попытаться обойти это, я поместил ValidateRequest = "false" в директиву страницы.

Только проблема: я все еще получаю ошибку!

Теперь все было хорошо, пока я не обновился до ASP.NET MVC RC этим утром, и (согласно readme) разместил в представлении web.config следующее:

<pages validateRequest="false" 
       pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
       pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
       userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
    <controls>
        <add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
    </controls>
</pages>

Итак, validateRequest должен быть ложным для всех страниц, не так ли? Что мне не хватает?

4b9b3361

Ответ 1

В MVC проверка выполняется на уровне контроллера, а не на уровне страницы. Чтобы понять, почему это так, подумайте, что во время выполнения действия контроллера мы не знаем, какой вид будет выбран для рендеринга. (Фактически, действие контроллера может даже не отображать представление вообще). Вместо этого он может открыть приглашение загрузки файла на клиенте.) Кроме того, если пользователь отправляет вредоносный ввод на сервер, к моменту отображения представления он слишком поздно, чтобы что-то сделать. Контроллер уже проведет опасный ввод в базу данных.

Вместо этого, пожалуйста, украсьте контроллер или действие атрибутом [ValidateInput (false)]. Это заставит нас подавить проверку запроса для этого контроллера или действия.

Ответ 2

Нужно украсить контроллер или действие атрибутом [ValidateInput (false)] и добавить requestValidationMode = "2.0" в файл web.config: Пример:

Контроллер:

    [ValidateInput(false)]
    public class MensajesController : Controller
    {
        //or in an action
        [ValidateInput(false)]
        [HttpPost]
        public ActionResult Create(FormCollection collection)
        {
        }
    }

Файл конфигурации:

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

Ответ 3

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

    protected override void Initialize(RequestContext requestContext)
    {
        // no client input will be checked on any controllers
        ValidateRequest = false;
        base.Initialize(requestContext);
    }

Просто убедитесь, что вы проверяете все входные данные от клиента!

Ответ 4

У меня была аналогичная проблема с использованием ASP.NET MVC 3 с .NET 4.0 и Windows Azure Access Control Service v2, где я получил бы ошибку:

System.Web.HttpRequestValidationException: A potentially dangerous Request.Form value was detected from the client (wresult="<t:RequestSecurityTo...").

и нашел лучшее решение, чем отключить проверку, было реализовать пользовательский RequestValidator, как описано в этой статье:

http://social.technet.microsoft.com/wiki/contents/articles/windows-identity-foundation-wif-a-potentially-dangerous-request-form-value-was-detected-from-the-client-wresult-quot-lt-t-requestsecurityto-quot.aspx

public class SampleRequestValidator : RequestValidator
{
    protected override bool IsValidRequestString( HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex )
    {
        validationFailureIndex = 0;
        if ( requestValidationSource == RequestValidationSource.Form && collectionKey.Equals( WSFederationConstants.Parameters.Result, StringComparison.Ordinal ) )
        {
            SignInResponseMessage message = WSFederationMessage.CreateFromFormPost( context.Request ) as SignInResponseMessage;
            if ( message != null )
            {
                return true;
            }
        }
        return base.IsValidRequestString( context, value, requestValidationSource, collectionKey, out validationFailureIndex );
    }
}

Единственная причина, по которой я смотрел дальше, чем отключение проверки, заключалась в том, что я видел, как это работает, не отключая проверку, следуя этому руководству в учебном комплекте платформы Windows Azure:

http://msdn.microsoft.com/en-us/WAZPlatformTrainingCourse_IntroToACSLabsV2

В любом случае, мы надеемся, что это будет полезно для кого-то и может обеспечить более подробный подход к решению этой проблемы в будущем. Следует отметить, что requestValidationMode = "2.0" не требуется, если вы реализуете пользовательский RequestValidator.