Thursday, 11 September 2008

Sharing too much with the world

There is a lot to be said for good error messages. The more diagnostic information that I have, the easier it is to diagnose what went wrong. A full stack would be nice. The names of any resources used would be helpful. I love rich debugging information.

Of course, so do hackers.

There are a number of ways of attacking a website. You can try for directory traversal where you try to get the web server to serve up things that are not what the admin intended. In an extreme case, you could possibly persuade it to serve up the results of running an arbitrary command in a command shell. However, such vulnerabilities are rare though tools such as the Goolag scanner make it easier to find them. The easiest ways are normally cross side scripting attacks or XSS for short. SQL injection attacks are just a special case of cross side scripting.

Of course, if you were attacking a website, the more that you knew about the target, the better you will like it. I am not advocating security by obscurity because we all know that this doesn’t really work but I am all in favour of not making it any easier for the bad people than it needs to be.

So, imagine that we give really good error information in our error messages. It is great for your developers to know the exact SQL code that resulted when a malformed text field was appended into a SQL statement and what function failed but it also tells an attacker what is happening to the text that he entered and what tables he is working with and what database and data access technology you are using. It is great to have this level of detail when debugging but better to write this to the application log and not to the users screen. Even if you assume that every user is a nice person who has no interest in hurting you (and wouldn’t that be nice?), is the average website visitor going to find it helpful to know that his request caused SQL server to throw a specific exception because there was no valid SQL after the semicolon and that this occurred in MyOrg.Bibliophile.Inventory.GetBookListEx() and the first part of the SQL was accessing the Titles table? A generic “Oops – sorry, I couldn’t do that. Try asking for something else” type error would be better and look more professional.

Of course, you might give no error information at all to the user. What does that mean in practice? Well, they might just get a message saying that there was an Error 500 – Internal Server Error. Ok, tatty but serviceable. When you see an application give a response like this, it probably doesn’t have a great deal of error handling and just failed the request. Hopefully it survived the error and the webserver didn’t restart. If it did then you have a vulnerability to a denial of service since it is trivial to fire of multiple requests a second and you can’t normally cycle the server that quickly. You probably need to dig deeper if someone has been able to break the server that way.

What happens if you do nothing at all with regard to unexpected exceptions? Well, that depends on what you are using for your web server and what is happening under the covers but let's look at ASP.NET since that is a pretty popular solution these days. If you don’t have anything specific in place, the web.config will determine what will happen. There is an overview of the file here but the critical setting for us is “debug=true” or “debug=false”. If debug is set to true, it will spit out lovely rich diagnostic information to our dear friends in far away countries. If it is set to false then the end user gets a generic “Oops – that didn’t work” type error. Oh, there are also some other very good reasons not to ever want debug=true in a production environment and the incredibly clever Tess Ferandez discusses them here and I will not steal her thunder other than to say that it will kill your performance and scalability.

Oh, and why would a production server ever be set to debug? Typically because the application was copied verbatim from the development server and no-one noticed the scalability issues when there was insufficient load testing. I have seen that one a few times.

Anyway, I shall leave you with the wonderful words of Will Durant:
"Nothing is often a good thing to do and always a good thing to say."
Signing off

Mark Long, Digital Looking Glass

No comments: