Security Stories Part 1
I have a knack for finding security flaws in software applications. When I read about breaches in the news, I am not surprised, merely dismayed. Perhaps contributing to a more honest culture that shares openly about security flaws could help.
In that vein, let me share some of the security flaws that I've discovered at companies throughout my career. I've found quite a few, so this will be a series of posts.
The query endpoint
At one company I worked for, we built custom websites for small businesses. Some were storefronts for pizza parlors, others more involved applications. The founder of the company was a self taught programmer, better at business than programming. This was demonstrated in his code: get the job done and get paid.
I introduced source code management at this company. I also introduced a ticketing system. I tried to mature the company's engineering practices. It was an uphill battle.
Engineers understand the need to debug production systems. The bug can't be reproduced locally, despite trying every imaginable configuration of data states. So we add the functionality to impersonate a user's account, or hook up our local server with a readonly connection to the production database. Tools of the trade.
My boss, clever little devil, considered these approaches too complex, too much effort. He added a web endpoint for querying the production database. It looked like this:
<?php
// Execute query directly (INSECURE!)
$result = $conn->query( $_GET['query'] );
while($row = $result->fetch_assoc()) {
print_r($row);
echo "<br>";
}
Behind a VPN, you ask? Protected with HTTP Basic Auth, you wonder as you start to sweat? Nope. What you see is what was live in production.
Can't beat the convenience when debugging in production.
The password-less login
At another company, I worked a lot on the signup funnel. It was comprised of multiple steps, and we were always attempting to optimize conversion by making tweaks to such and such page, or rearranging the order of the steps. At a certain step in the funnel, the user enters their email address.
My usual approach to test accounts is the gmail +
trick. For those not in the know, gmail will accept emails with additional alphanumeric characters after a +
sign, for example if the base address is [email protected]
, then [email protected]
and [email protected]
will correctly forward. I am in the habit of incrementing +001
, +002
, and so on.
I so frequently made new accounts in the signup funnel that it became almost second-nature. Almost. One day, when testing some change in the funnel, I entered [email protected]
. Hmm. I had the sudden suspicion that I had made a mistake and re-used an existing test account. I had forgotten to increment.
Then I noticed that I was logged in as [email protected]
. As in, fully authenticated.. without entering a password.. the hair on my neck started to rise!
I quickly confirmed this by logging in as my boss in production. All I had to do was enter his email address in the signup funnel: [email protected]
. I was so excited when I shared this with my boss, his reply, calm and collected:
nice find, when can you fix it?
I learned an important lesson that day. Reporting an issue means that I'm likely to be the one to fix it. I'm such a professional that this doesn't prevent me from reporting, of course 🫠
More to come
I hope to write more about security. I think sharing some war stories is helpful for others to feel comfortable sharing. I hope it also dissolves the myth that security can be taken for granted.