One Line of Code Could Have Prevented the eThekwini Leak
The dust has settled on the eThekwini Municipality blunder so I thought I would take a minute and do a post on how they could have prevented leaking that data in the first place, and as you can imagine it’s not that difficult. There are actually tons of things they could have done better but today I am going to speak about about a few crucial ones.
The eServices website was using a bastardized version of ASP.Net Identity, to the point where they had modified the default implementation to store passwords in plain text. Why you would take the time to change a secure implementation of something and completely mess it up in the process, is beyond me. By default, ASP.Net uses a Key Derivation Function with a random salt to produce a hash of the password. While I am not going to dive into the implementation details, what I will say is that if they had not changed anything out of the box they would not have been able to email people their passwords in plain text. This would have saved them time when developing the system, as well as saved them from the initial embarrassment.
There is also the fact that anyone could create an account. While this isn’t a security flaw per se, they should definitely be checking if your ID number is on the system during registration. This would prevent duplicate accounts and stopped a lot of people who had no business accessing the system, from accessing it in the first place.
This is the big one. Even if we pretend for a second that their authentication story was perfect, they really messed up with their authorization implementation or lack thereof. By that i mean even though they were checking the user is who he says he is in the form of a username and password, once logged in the users could access anyones data. Once again, ASP.Net has built in ways to implement this. For some reason, the eServices team was passing the customer identifier in the url, which is crazy considering they actually had that information in the user tokens and didnt need it passed up from the client. In ASP.Net you can easily get the UserId for the logged in user.
This alone would have prevented the data leak.
You were also able to enumerate accounts by using the Forgot Password functionality. This is something i see alarmingly often. The idea is that you can guess if an email or account is on the system by brute forcing the forgot password feature, in this case, the system gave you clear message if the account didnt exist.
The email address does not exist
In this situation the solution is usually two fold. Firstly you need to implement rate limiting so that someone cant use a brute force attack, and secondly you should always return a vague response so that the attacker doesn't know if the account exists or not. Something like the following would have been perfect.
Please check your email to reset your password
Once again, this is something that needs to be addressed to prevent further data leaks.
How in the 21st century we have a government system that doesnt implement TLS encryption is what boggles my mind the most. Most of the readers here will know about SSL and the different variations so i am not going to go into any detail, suffice to say, that when they go live again they really should have SSL enabled. Failing to do so, is putting all your users at risk.
Regardless, whats done is done. The eThekwini Municipality now needs to reset everyone's passwords and make sure that once we choose a new one, it is stored encrypted. They also need to send out an email informing users to change their password on any other website that shares the same password. Of course, that will probably never happen, but we can only hope.
- [9/13/2016] - adding the Forgot Password and HTTPS sections after a chat with Werner van Deventer