Wednesday, November 21, 2012

Etisalat Post Pay Bill Viewer

Application Download Link: http://www.mediafire.com/?vq0zp3tdjn7746h

*** This does not work anymore. Etisalat guys have fixed this security hole within 24hrs since I released this! Impressive! So kudos to them :) And cheers to anyone who got lucky and had fun while it lasted ;) ***

Suddenly my Etisalat data package stopped working so I logged in using my other Airtel connection to check what's wrong. After bit of Googling, found this official portal which lets you view your current and previous bills. While on it, it appeared that their portal is easily vulnerable to exploit. Although you need authentication to view the bills, but once you know the bill URL and get the hang of how they are classified, getting the  customer data out is a piece of cake!

After checking few bills of random users, I thought of writing a utility which can be used to check the outstanding bill amount when a customer number is given. Customer number is printed as 'Customer No' in your actual bill. You can download the application  here. You can use it to view your previous bills too. But the best part is you can check details of other random users. Just for the kicks, I decided to reveal their name, address, post pay plan and the actual phone number. So have fun while it lasts ;)

The application has a simple interface. You will have to enter your customer number and choose the month and year of the bill which you want to see. When you click 'Get Bill Details' button, it will get busy for a while and display details if available. Check out the screenshot.


Do try out the app and comment if you need any improvements to be added in the later versions. Also comment if there are any bugs. Enjoy!

Application Download Link: http://www.mediafire.com/?vq0zp3tdjn7746h

Monday, November 19, 2012

C#: Handling the “The remote host closed the connection” exception in WCF REST

In a recent project, I was involved in developing WCF Restful services for mobile clients. There were some services where the clients send files as multi-part POST requests. In some cases the file data parsing on the server fails due to missing form data fields or missing file data but those scenarios ended up throwing exception on the server. It was the most common communication exception 'The remote host closed the connection'.

The WCF method signature looked like this:
public bool SaveImage(Stream stream)

And inside the method, there is absolutely nothing special I am doing when parsing fails. I am returning true when parsing failed and false otherwise. But when it fails, it throws this exception for no reason.
After much of Googling, I found that when client is no longer connected to the service this exception may occur on the server. And the solution was to check Response.IsClientConnected property and act accordingly if its false. When I checked it, to my surprise it was false even when the method itself gets called! That is only when the parsing failed. So my conclusion was that the WCF infrastructure takes care of those requests which are not legit at the very beginning of its pipeline and releases the client to free its connection pool. But I still wonder why it passes the context to the method, if it is not willing to listen for the response.
So to fix this I added this method to my base service class:
protected bool IsClientConnected
{
    get { return HttpContext.Current.Response.IsClientConnected; }
}
In every method which takes in a Stream, I call this method and make sure client is still listening and return the response. So what do I return when client is not connected? Just null. This gets rid of getting the nasty 'remote host' exception and you can save you logs from overflowing with that.
Happy coding!
PS: The downside of using this method is that you have to use HttpContext which forces you to use AspNetCompatibilityRequirementsMode.Required, in your service which will prevent you from self-hosting it. But then again I don think clients would be disconnected in this fashion unless in that case. So I guess it's fair enough :)