I inadvertently changed the passwords of 17,000 users once.
We all have our favorite horror stories testing live applications. Mine was executing a SQL Injection test-case 'OR 1=1;-- on a Change Password page. To my utter dismay, I realized the test case worked and all users had their password reset. Thankfully, the usertable could be restored from backup quickly.
That was two years ago. I've since chuckled when I hear similar tales of horror; now I expect little to shock me. So imagine my surprise last week when the same test case wreaked havoc again.
We were testing the beta version of an online trading site. We routinely use the SQL Injection test case 'OR 1=1;-- in the login page to see if login can be bypassed.
The test case worked, we were authenticated and able to log in. So far so good.
Trouble began 10 minutes later when we got a call complaining that no one could log in. Did we know anything about it? Hmmm, no... we had just bypassed the login page. Why should others be affected? 15 mins later, it was clear that no one could log in to the beta application- not even the administrator. We compared notes and decided that it had to be the 'OR 1=1;-- test case.
In the next 30 minutes, we figured out what was happening: To prevent concurrent logins by the same user, the application set a field called isLoggedIn in the user database to true when a user logged in. When the user logged out it would set isLoggedIn to false. Alternately, when a session expired, it would set isLoggedIn to false. By tracking this field, the application ensured a user could not have concurrent sessions.
And our 'OR 1=1;-- upset the scheme!
The 'OR 1=1;-- set isLoggedIn to true for all rows in the user table. The database believed that every user was logged in. And until each person was logged out, he couldn't log in again!
Recovery took 20 minutes more: a SQL script was written to directly set isLoggedIn to false for all users. That worked and the site was back online.
I shudder to think of the consequences had the site been already launched. An adversary could have denied service to users for several days - the time it takes to get a bug fixed, tested and released to production.