views:

21288

answers:

15

Everytime a user posts something containing < or > in a page in my webapp, I get this exception thrown.

I don't want to go into the discussion about the smartness of throwing an exception or crashing an entire webapp because somebody entered a character in a textbox, but I am looking for an elegant way to handle this.

Trapping the exception and showing "An error has occured please go back and re-type your entire form again, but this time please do not use <" doesn't seem professional enough to me

Disabling post validation ( validateRequest="false" ) will definitelly avoid this error, but it will leave the page vulnerable to a number of attacks.

Ideally: when a postback occurs containing HTML restricted caracters, that posted value in the Form collection will be automatically HTML encoded. So the .Text property of my text-box will be " something & lt; html & gt; "

Any way I can do this from a handler?

+10  A: 

You can HtmlEncode text box content but unfortunately that won't stop the exception from happening. In my experience there is no way around and you have to disable page validation. By doing that you're saying: "I'll be careful, I promise."

Pavel Chuchuva
+2  A: 

You should use the Server.HtmlEncode method to protect your site from dangerous input.

More info here

+52  A: 

I think you are attacking it from the wrong angle by trying to encode all posted data.

Note that a "<" could also come from other outside sources, like a database field, a configuration, a file, a feed and so on.

Furthermore, "<" is not inherently dangerous, its only dangerous in a specific context: when writing unencoded strings to HTML output (because of XSS). In other contexts different substrings are dangerous, e.g. if you write an user-provided URL into a link, the substring "javascript:" may be dangerous. The single quote character on the other hand is dangerous when interpolating strings in SQL queries, but perfectly safe if it is a part of a name submitted from a form or read from a database field.

The bottom line is: you can't filter random input for dangerous characters, because any charater may be dangerous under the right circumstances. You should encode at the point where some specific characters may become dangerous because they cross into a different sublanguage where they have special meaning. When you write a string to HTML, you should encode characters that have special meaning in HTML, using Server.HtmlEncode. If you pass a string to a dyamic SQL statement, you should encode different characters (or better, let the framework do it for you by using prepared statements or the like).

When you are sure you HTML-encode everywhere you pass strings to HTML, then set validateRequest="false".

JacquesB
excellent answer!
Joel Spolsky
In .NET 4 you may need to do a little more. Sometimes it's necessary to also add <httpRuntime requestValidationMode="2.0" /> to web.config. See http://www.asp.net/(S(ywiyuluxr3qb2dfva1z5lgeg))/learn/whitepapers/aspnet4/breaking-changes/
Hightechrider
@Hightechrider thanks for that link. Simple setting validateRequest="false" doesn't work for a view in ASP.Net MVC@olavk - Nice. Joel took the time to comment on your answer.
NTulip
To those coming in late: validateRequest="false" goes in the Page directive (first line of your .aspx file)
MGOwen
+2  A: 

I guess you could do it in a module; but that leaves open some questions; what if you want to save the input to a database? Suddenly because you're saving encoded data to the database you end up trusting input from it which is probably a bad idea, ideally you store raw unencoded data in the database and the encode every time.

Disabling the protection on a per page level and then encoding each time is a better option.

Rather than using Server.HtmlEncode you should look at the newer, more complete Anti-XSS library from the Microsoft ACE team.

blowdart
+1  A: 

As long as these are only "<" and ">" (and not the double quote itself) characters and you're using them in context like <input value="this" />, you're safe (while for <textarea>this one</textarea> you would be vulnerable of course). That may simplify your situation, but for anything more use one of other posted solutions.

phjr
+2  A: 

Disable the page validation if you really need the special characters like > and < etc. Then ensure that when the user input is displayed, the data is HTML encoded.

There is a security vuln with the page validation, so it can be bypassed. Also the page validation shouldn't be solely relied on.

See: http://www.procheckup.com/PDFs/bypassing-dot-NET-ValidateRequest.pdf

woany
+1  A: 

If you're just looking to tell your users that < and > are not to be used BUT, you don't want the entire form processed/posted back (and lose all the input) before-hand could you not simply put in a validator around the field to screen for those (and maybe other potentially dangerous) characters?

Captain Toad
+5  A: 

Please bear in mind that some .NET controls will automatically HTML encode the output. For instance setting the .Text property on a TextBox control will automatically encode it, that specifically means converting < into & lt; > into & gt; and & into & amp; (spaces added to prevent encoding, doh!) So be wary of doing this...

myTextBox.Text = Server.HtmlEncode(myStringFromDatabase); // Pseudo code

However, the .Text property for HyperLink, Literal and Label won't HTML Encode things so wrapping Server.HtmlEncode(); around anything being set on these properties is a must if you want to prevent <script> window.location = 'http://www.po rn.com'; </script> from being output into your page and subsequently executed (space added to prevent porn link being generated, doh again!).

Do a little experimenting to see what gets Encoded and what doesn't.

+2  A: 

Hi:

first of all sorry my english.

If you don´t want to disable ValidateRequest you need to implement a javascript function in order to avoid the exception, is not the best option, but it´s works.

function AlphanumericValidation(evt) {

        var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode :
  ((evt.which) ? evt.which : 0));         

        //User type Enter key
         if (charCode == 13)
        {

            //Do something, set controls focus or do anything
            return false;
        }
        //User can not type non alphanumeric chacacters
        if ((charCode < 48) || (charCode > 122) ||  ((charCode > 57) && (charCode <  65)) ||  ((charCode > 90) && (charCode < 97))   )
        {
            //Show message or do something
         return false;
        }  
    }

then in code behind, on PageLoad event, add the atribute to your control with the next code:

Me.TextBox1.Attributes.Add("OnKeyPress", "return AlphanumericValidation(event);")

This will still leave the app vulnerable from made-up POST requests. A regular user will have problems entering characters like , : or quotes, but a regular hacker will have no problems POSTing malformed data to the server. I'd vode this waaay down.
Radu094
+28  A: 

There's a different solution to this error if you're using ASP.NET MVC:

Visual Basic sample:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function

C# sample:

[HttpPost, ValidateInput(False)]
public ActionResult Edit(FormCollection collection)
{
    // ...
}
Zack Peterson
the solution for ASP.NET MVC is just what i needed, thanks!
Lucas
+2  A: 

You can catch that error in Global.asax. I still want to validate, but show an appropriate message. On the blog listed below, a sample like this was available.

    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();
        }
    }

Redirecting to another page also seems like a reasonable response to the exception.

http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html

BenMaddox
A: 

There is no problem to validate user's entry on key press... something like that: function documentOnKeyPress() { var charCode = window.event.keyCode; var elementType = window.event.srcElement.type;

if ( (13 == charCode)) // replace Enter with TAB { window.event.keyCode = 9; } if ( (60 == charCode)) //replace < with space { window.event.keyCode = 32; } if ( (62 == charCode)) //replace > with space { window.event.keyCode = 32; } } You would be able to catch < and >. However... what about user's copy and paste text like into text box? Anyone? And yes, I can catch it on Application_Error in Global.asax , but that's not exactly the solution I'm looking for.

    Dim ex As Exception = Server.GetLastError 'HttpRequestValidationException 'Exception

    If (TypeOf (ex) Is HttpRequestValidationException) Then

        Response.Clear()
        Response.StatusCode = 200
        Response.Write("A potentially dangerous Request.Form value was detected from the client. " & vbCrLf & _
        " Please remove < and > from your entry and re-submit information")
        Response.End()

End if \

PS I'm new to WEB development and I would really appreciate any idea on resolving this issue. thnx NK

NK_ATL
+8  A: 

If you are on .net 4.0 make sure you add this in your web.config

<httpRuntime requestValidationMode="2.0" />
JordanC
A: 
<httpRuntime requestValidationMode="2.0" />

`

This worked for me! Thanks!

Douglas
This should have been a comment on JordanC's, rather than your own answer.
StriplingWarrior