1

I have the following view model, which accepts a password change value. As such, it should accept special characters, including characters that trigger the HttpRequestValidationException - '<' and '>'. So I added the [AllowHtml] attribute on the appropriate properties:

    public class ChangePasswordModel
    {
        public bool ShowPassword { get; set; }

        public string UserMessage { get; set; }

        [Required]
        [StringLength(int.MaxValue, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 8)]
        [ValidPassword]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        [AllowHtml]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Required]
        [Display(Name = "Confirm password")]
        [Compare(nameof(Password), ErrorMessage = "The {1} and {0} do not match.")]
        [AllowHtml]
        public string ConfirmPassword { get; set; }
    }

Here ShowPassword and UserMessage are set on the server and used in the view.

When I enter a password such as "<Script/>1234" it all works fine, the model validates, the action is executed, the ViewResult is executed, and then, somewhere between the ViewResult and the client, an HttpRequestValidationException is thrown with this stack trace:

Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule.OnExecuteRequestStep(HttpContextBase context, Action step)
Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule.OnExecuteRequestStep(HttpContextBase context, Action step)

I'm catching it in Global.asax.cs in the Application_Error event, where it's too late to return any useful information to the user except a generic message.

What I tried:

  • I have a global HandleErrorAttribute where I detect an HttpRequestValidationException and return it to the user as a validation message in the view. This works fine with other models and views when the user enters HTML where he is not allowed to, but in this case the attribute's OnException override is not triggered.
  • I decorated the specific action with the above attribute
  • I implemented IResultFilter in the above attribute and overrode the OnResultExecuted, to test if the exception is thrown after the view execution. The ResultExecutedContext.Exception property was null.
  • I overrode the BindModel method of the DefaultModelBinder just to see if it throws an exception, but it doesn't.
  • I upgraded Application Insights, mentioned in the stack trace, to the latest version, from 2.16 to 2.20.
  • This model has its attributes directly on the properties. I tried moving them to a metadata type, using the [MetadataType] attribute. It worked, except that the exception was still thrown.

At this point, I'm out of ideas as to why the exception is thrown, and how to prevent or catch it. Any help is appreciated.

Tsahi Asher
  • 1,767
  • 15
  • 28

1 Answers1

0

It appears, that you just need to use the "[ValidateInput(false)]" attribute instead of the "[AllowHtml]" one if you need to allow the script(s) tag(s). Check out the ValidateInput(false) vs AllowHtml thread for more information.

Mikhail
  • 9,186
  • 4
  • 33
  • 49
  • I tried that. Amazingly, it didn't work. `ValidateInput` prevents request validation **before** the action, but in this case something is performing request validation **after** the action and the ActionResult execution. – Tsahi Asher Jan 04 '22 at 10:57
  • The only think that worked to disable request validation was setting ``, which of course disables it for the entire application. – Tsahi Asher Jan 04 '22 at 11:02