Misfit Geek

Fustrated by Design !

MaximumASP

So I’m building an ASP.NET application to host Podcasts and in the post submission logic I want folks to be able to submit markup, but not JavaScript.

image

ASP.NET automatically traps suspicious posts to the server, but the results have to unfortunate defines.

First is the ugly resulting page. We’ve all seen them.

image

And the second is that I may want to be able to add some SPECIFIC logic to handling that Security exception because it probably means someone is intentionally trying to hack my web site.

It turns out that this is another that ASP.NET makes easy to solve.

First, add a Global.asax file to your solution and code the global Application_Error event handler as follows.

   1:  protected void Application_Error(object sender, EventArgs e)
   2:  {
   3:      Exception objErr = Server.GetLastError().GetBaseException();
   4:      string err = objErr.Message.ToString();
   5:   
   6:      string secError = "A potentially dangerous Request.Form value was detected";
   7:      string baseUrl = Request.Url.Scheme + "://" + Request.Url.Authority +
                                                  Request.ApplicationPath.TrimEnd('/') + '/';
   8:      Server.ClearError();
   9:   
  10:      if (err.IndexOf(secError) != -1)
  11:      {
  12:          Response.Redirect(baseUrl + "SecurityError.aspx");
  13:      }
  14:      else
  15:      {
  16:   
  17:          Response.Redirect(baseUrl + "Error.aspx");
  18:      }
  19:  }

 

 

When the specific form validation error is encountered we redirect to a specific web page. (SecurityError.aspx)

The user gets a much better experience.

image 

This solves the second problem with the default handling. Even without additional work on my part the IIS Server Logs will be able to tell me how many times this happens along with information about the requests that generate them.

If I want to get more specific I can forward the originals HTTP request and exception info to SecurityError.aspx and take some action.

If the form can only be submitted by a user who is logged in to my application, even better. I can count how many times then cause this eror to happen and then based on that data I can warn them, log them off or ban them from my site completely

Do you add security specific error handling to your site ? If so, let me know.

 

Similar Posts:

Comments

There are 26 comments for this post.

  1. Trapping Intentional Cross Site Scripting (XSS) Attempts in ASP.NET : Misfit Geek on February 10, 2010 4:15 pm

    RE: Trapping Intentional Cross Site Scripting (XSS) Attempts in ASP.NET

    Pingback from Trapping Intentional Cross Site Scripting (XSS) Attempts in ASP.NET : Misfit Geek

  2. Alex on February 10, 2010 4:58 pm

    Maybe you can catch the Exception type instead of a simple string. If the application is configured in another language (not English) this code would fail. Try this:

    Exception objErr = Server.GetLastError().GetBaseException();

    if (objErr is HttpRequestValidationException)

    {…}

    For the baseUrl or maybe the complete url you could try this:

    Page page = HttpContext.Current.Handler as Page;

    string errorUrl = page.ResolveUrl("~/SecurityError.aspx");

    Greetings

    Alex

  3. The Other Joe on February 10, 2010 5:04 pm

    I capture a little bit more information and then send it to the webmaster

    void Application_Error(object sender, EventArgs e)

    {

    // Code that runs when an unhandled error occurs

    if (Environment.MachineName.ToLower() == "PRODUCTION_SERVER")

    {

    System.Net.Mail.MailMessage m = new System.Net.Mail.MailMessage(ConfigurationManager.AppSettings["emailSender"], ConfigurationManager.AppSettings["webmasterEmail"]);

    m.Subject = "[WEBSITE NAME] Error Message";

    m.IsBodyHtml = true;

    m.Body += "<h2>User</h2>";

    m.Body += "Username: " + User.Identity.Name+"<br/>";

    m.Body += "IP Address: " + Request.ServerVariables["REMOTE_ADDR"] + "<br/>";

    m.Body += "User_agent: " + Request.ServerVariables["HTTP_USER_AGENT"] + "<br/>";

    m.Body += "<h2>Location</h2>";

    m.Body += "Server: " + Environment.MachineName + "<br/>";

    m.Body += "URL: " + Request.Url.AbsoluteUri + "<br/>";

    m.Body += "<h2>Error Message</h2>";

    m.Body += Server.GetLastError().ToString().Replace("\n","<br/>");

    m.Body += "<h2>Request Params</h2>";

    foreach (var v in Request.Params.Keys)

    {

    m.Body += v.ToString() + " = ";

    foreach (var i in Request.Params.GetValues(v.ToString()))

    {

    m.Body += i.ToString() + " | ";

    }

    m.Body += "<br/>";

    }

    System.Net.Mail.SmtpClient c = new System.Net.Mail.SmtpClient();

    c.Send(m);

    }

    }

  4. Neal Blomfield on February 10, 2010 5:55 pm

    Or simply disable validation for that request and html encode the content of the input …

  5. Joe Stagner on February 10, 2010 6:37 pm

    Neal, that doesn’t acocomplish nearly the same thing,

  6. Danny117 on February 10, 2010 8:12 pm

    Code pair not me processed

  7. Richard Lennox on February 11, 2010 3:49 am

    Would you use an HTTP module for this rather than the global.asax?

  8. kshitij kumar on February 11, 2010 5:25 am

    Well from my point of view, if i am running a system especially on web where my system is open for anyone to take inputs, i will never apply any limitation on the input, handling inputs is the concern of my system. Especially in the case of XSS, always allow the input from user but filter that input at your end. A very common example, if i storing the user input in database then in the case of FW 2.0 i will use command objects, data adapters, stored procedures to handle the input and the database part and in 3.0 or 3.5 we have LINQ that manages such thing upto some extent.

    Restricting user on input may affect the scope of the system.

    –Advices are always welcome–

  9. Ryan Heath on February 11, 2010 6:18 am

    You will annoy people that just type the *wrong* characters …

    Whats wrong with " When 10 < 20 then … " but ASP.NET will mark it as a "potentially dangerous request" …

    Better is to accept the user input *but* (html)encode it whenever it is outputted on your website.

    // Ryan

  10. Joe Stagner on February 11, 2010 8:13 am

    Alvaro – you’re right, I liked the self documenting nature of trapping the message and I know that my server is English but it my application were going to be for redistribution it wouldn’t work on NON-English Servers.

    Richard – You could use an HTTP module (and there are some4 advantages) but using an HTTP module won’t work in a lot of shared hosting scenarios becuase the user won’t have access to IIS to install a custom HTTP module.

    kshitij – WHERE you handle potential hacking attempts is a matter of preference but writing a security filter is a NON trivial exersize. In this application there is no reason to accept JavaScript input so this method is simple and meets my requirements.

    Ryan – You’e mistaken. "When 10 < 20 then" will not trigger the ASP.NET 4 request filter becuase it is far more than a simple character string search.

  11. Voytek on February 11, 2010 10:14 am

    When you say "I want folks to be able to submit markup" what markup you have in mind ? HTML tags? I am looking for a solution that will allow all HTML tags but will trigger an error when JavaScrip is submited.

  12. Joe Stagner on February 11, 2010 10:16 am

    Jane – yes that is exactly how my app currently works.

  13. Voytek on February 11, 2010 10:39 am

    Does it mean that the error message: "A potentially dangerous Request.Form value was detected" is specific to the JavaScript injection? Not the HTML tags?

  14. Joe Stagner on February 11, 2010 10:49 am

    Jane – No, but usting the Edito Control from the ACT, the editor handles the HTML encoding.

  15. Voytek on February 11, 2010 11:43 am

    Now I am quite confused. Is this just an error handler for ValidateRequest="true"

    What is "Edito Control from the ACT" ? Tried Google to no avail.

  16. kss on February 11, 2010 11:47 am

    Great video, where can I get the examples that the video said would be avaliable. Thanks,

  17. Joe Stagner on February 11, 2010 11:57 am

    The Editor Control from the ACT (Ajax Contol Toolkit) can be seenin action here. http://www.asp.net/…/HTMLEditor.aspx

    The error is thrown when request validation fails so setting ValidateRequest="false" tells the runtime to bypass this security check and send the request on to your code without checking it.

    However in ASP.NET you can’t just turn request validation off. If you set the attribute to off you will still get the exception message with the following advisement.

    To allow pages to override application request validation settings, set the requestValidationMode attribute in the httpRuntime configuration section to requestValidationMode="2.0". Example: <httpRuntime requestValidationMode="2.0" />.

    However that may not be desireable.

    I think this will be a good topic for a more extended tutorial.

  18. Joe Stagner on February 11, 2010 11:58 am

    kss – the videos will start being published next month.

  19. rickj on February 11, 2010 1:16 pm

    hey Joe any thoughts on a live video broadcast that is lightweight enough to broad cast live event on a small scale for less than a million dollars

    have you looked at something like this

    team.silverlight.net/…/multicast-comes

    the code is here

    projectstarlight.codeplex.com

    the code is free but I think it might cost money to make it work form here

    http://www.qumu.com/…/274-microsoft-s

    I won’t give them a bunch of my personal info to find out how much it cost or maybe live streaming if you can find a delivery system that will talk to a small player for less than a million

    and by the way looking forward to the tutorials good work

  20. Alex on February 11, 2010 2:17 pm

    Have been handling errors in global.asax since ages :-)

    Many developers are not aware of this though and will help them.

  21. Balachandran on February 11, 2010 3:07 pm

    I am a student. Now i am developing a web application in asp.net. I want to get windows login username (i.e.) Client System Login username. But it display iis login name. I am Hosting a website in

    http://www.aspspider.com/ . They Provide free account for students. My website url is http://aspspider.info/balaji87. I can’t change the settings in iis.

    Thanks.

  22. BestDotNet on February 12, 2010 5:19 pm

    Nice post. May be title needs a little adjustment. It gives an impression that the post tell the users how to accept markups and get through ASP.net validation.

  23. Voytek on February 12, 2010 5:24 pm

    The idea of extended tutorial is an excellent one. My scenario is: Accept HTML but raise an error when there is attempt to add JavaScript in any form including most of the stuff listed here: http://ha.ckers.org/xss.html

  24. Christopher Brown on February 12, 2010 7:52 pm

    Have you heard of the Anti-XSS library that’s on MSDN:

    http://www.microsoft.com/…/details.aspx

    I’ve used it before, and it’s extremely simple to implement.

  25. Christopher Brown on February 12, 2010 7:52 pm

    Have you heard of the Anti-XSS library that’s on MSDN:

    http://www.microsoft.com/…/details.aspx

    I’ve used it before, and it’s extremely simple to implement.

  26. Voytek on February 13, 2010 12:42 pm

    Yes. But it works only in full trust. It is pretty much useless for most of the hosting environments.

Write a Comment

Let me know what you think?