One of the more serious vulnerabilities in web applications is when someone gains privileges or permissions that they should not have. The most common cause is when someone accidentally or deliberately manages to turn their "regular" account into an administrator account. Because this is the most common scenario, I think we end up thinking the two things are the same, that elevation of privileges = swap regular account for admin account. I learned today that this isn't true.
We saw a very strange problem on an internally used system (but which is hosted on a public web site) where a new employee who should not have had access to it was able to login and be given someone else's account - the worst of both worlds! It would have been bad for an employee to be given another employees account but for an un-registered user (who to all intents and purposes is a stranger) to be given an employee's account is very bad.
It seemed weird and I saw various internet posts about people with a similar problem caused by certain things related to ASP.Net forms authentication. I tried decrypting cookies etc. to try and find out what was happening (were they really logged in as someone else or was it just a display problem) but this failed.
Ultimately, I was able to run the site in the debugger and was surprised to see that it was not the site itself at fault but the OAuth2 sign-in process which was returning the wrong email address and therefore making the site login as the incorrect user. In fact, I maintain the OAuth2 system so somehow it was my fault.
I had to access the database and step through the process to find out what was wrong and eventually tracked it down to a stored procedure that had a slight flaw and caused a potential timing attack. This affected all site we were securing but would only occur if multiple logins occurred within a short period - before the OAuth2 tokens expired.
The problem was that I was updating a table and changing the access code to an access token and then selecting details from the affected row (in theory) but since I had already updated the code column and set it to null, it couldn't be used to select the affected row and using the remainder of the where clause could return multiple entries - and as it happened, the web service would choose the first of these, which would always be the wrong one.
So I had managed to create an elevation of privileges vulnerability by a simple oversight in the design of the system. The moral? Test, test and test some more. Also, have a system which is designed to update or fix quickly so these bugs won't lie around for weeks or months until another "update" can be made.