views:

382

answers:

5

The infamous A potentially dangerous Request.Form value was detected from the client question :)

Here's my use case: I have a FCKEditor control on a webpage, that allows users to type HTML. That precise webpage has validation turned off to allow its use, but my masterpage has linkbuttons that can raise postbacks on other pages.

I obviously don't want to turn validation off needlessly on every page of my site, but I'd want to be able to sanitize the input 'silently' (either by removing the faulty field from the request form, or by validating it).

I see that one can override OnInit or ProcessRequest on the page, but I'd like to do that on the master page if it is possible. (I'm not even sure I can recover from a HttpRequestValidationException)

Any idea on how I could do that?

Edit: I've been playing with Page_Error, which successfully catches the error but I can't find how to resume processing after I checked the request was in fact legit.

+3  A: 

Turn off validation, because it validates at the wrong stage in the process.

Input validation is inherently flawed; you actually need output validation. This means that you take in any data, but you encode it, before printing it, for the relevant context that it will be displayed. So for direct writing to a HTML page, you use HttpUtility.HtmlEncode, and other such encoding techniques depending on the context.

Noon Silk
Unfortunately this is not really an option without rewriting the whole application :)
Luk
Well, even still, you must then accept that you're application is not ideally secure. In this case, the same rules apply. You still turn off request validation (because it's still wrong), and validate as you receive it, and **make sure** you only use it in the correct context.
Noon Silk
A: 

If you want to deal with the exception in a particular way and check the request during this process you may want to consider global exception handling. There is a brief article here on it:

http://www.developer.com/net/asp/article.php/961301

Hope this helps.

Richard
Unfortunately, once I'm in Application_Error, there's no way back: the request has failed and I won't be able to recover. (Unless I am mistaken)
Luk
+1  A: 

I think you should be able to use the global exception handling that Richard mentions, but may need to add a call to ClearError to get rid of the HttpRequestValidationException and continue with the request. Something like this might do the trick:

protected void Application_Error(object sender, EventArgs e) {
    Exception ex = Server.GetLastError().GetBaseException();
    if (ex.Message.StartsWith("A potentially dangerous Request.Form value was detected")) {
        Server.ClearError();
    }
}

It might be worth checking the Request.Url and / or the Request.UrlReferer to make sure the request originates from your FCKEditor page as well.

Hope this helps.

Ian Oxley
I'd avoid the string comparison (assumes an English OS), and use "if (ex is HttpRequestValidationException)" instead.
devstuff
Sounds a very good plan, but in that case the page is not processed (apparently): I end up with a blank page
Luk
A: 

Do your link buttons need to be buttons (post) or can you turn them into actual links (get)? If you aren't passing any data back and you don't need to know which button was clicked, then I'd suggest just using the links. A get request will not carry with it any of the form data on the page so you won't get the error on the other pages. Use CSS styling on the link to get a button look if you need it.

tvanfosson
Yes unfortunately
Luk
A: 

Edit: I've been playing with Page_Error, which successfully catches the error but I can't find how to resume processing after I checked the request was in fact legit:

    protected void Page_Error(object sender, EventArgs e)
    {
        if (Server.GetLastError() is HttpRequestValidationException)
        {
            Server.ClearError();
            //CreateChildControls();
            base.OnPreInit(e); //yeah, ugly as hell
        }
    }

doesn't work

Luk