May 28, 2026
BlogSystem

Sometimes the Most Dangerous Security Bugs Are the Simplest Ones

Some security vulnerabilities are surprisingly simple. In fact, the most dangerous ones are often the things we least expect. That’s true not only in programming, but sometimes in life as well. Problems can sit right in front of us for years simply because they’ve become too familiar to question.

As some of you may already know from the About page on my blog, I recently joined a new company. New to me, at least, the company itself has been running for more than 20 years. And like many long-running systems, the codebase has evolved through multiple generations of technologies, developers, and architectural decisions. Some solutions that once made sense are no longer suitable today, especially from a security perspective.

When the Twilio Account Got Suspended

One day, we received a notification that the Twilio account had been suspended because attackers were using the API keys to send spam. The first thing we did was investigate how the credentials had been exposed.

Initially, several possibilities came to mind. Maybe the keys were hardcoded directly in the source code. Maybe the repository had leaked at some point because many developers had worked on the project over the years. It was also possible that the infrastructure itself was outdated and vulnerable, especially since the system still had to support multiple older PHP versions.

All of those assumptions sounded reasonable.

But after spending time digging deeper, the real issue turned out to be much simpler than expected.

The .env File Was Publicly Accessible

At some point during the investigation, I discovered that the .env file could be accessed directly from the internet.

That meant every API key, token, credential, and sensitive configuration stored inside it was potentially exposed. Most likely, this was the actual reason the Twilio account had already been suspended twice.

At first, the team suspected source code leakage because many developers had joined and left the company over the years. But the problem wasn’t that someone had access to the source code. The problem was that a sensitive configuration file was accidentally exposed publicly.

What’s funny is that I didn’t use any advanced security tools to discover this. I simply followed the code, checked how the credentials were being used, reviewed the configuration, and eventually tested direct access to the .env file.

And yes… it was accessible.

How I Fixed It

The first thing I did was move all hardcoded credentials out of the source code and into .env files. That alone was already an improvement because secrets should never live directly inside application code.

But of course, if .env itself is publicly accessible, moving secrets there changes nothing. It only relocates the problem.

Since the system was running on a LAMP stack, I decided to secure the issue at the Apache level. One option was updating .htaccess files individually for each customer environment, but the infrastructure hosted many clients across multiple servers. Updating every single .htaccess manually would have taken a huge amount of time and increased the risk of inconsistencies.

Instead, I added a global Apache rule directly inside /etc/httpd/conf.d/:

<FilesMatch "(^\.ht|^\.env|\.env$|\.env\.|^\.git|^\.svn|^\.DS_Store)">
    Order allow,deny
    Deny from all
</FilesMatch>

<FilesMatch "\.(bak|backup|swp|old|orig|save|sql|sql\.gz|tar|tar\.gz|zip|log|ini|conf|sh)$">
    Order allow,deny
    Deny from all
</FilesMatch>

This configuration blocks direct public access to sensitive files such as .env, .git, backups, logs, SQL dumps, and configuration files that should never be exposed through the web server.

After that, I rolled the update across more than 10 servers. Once everything was deployed and verified, the exposed files were no longer accessible from the internet, and the systems returned to stable operation.

What This Taught Me

The thing that stayed in my mind the most is how simple the vulnerability actually was.

It wasn’t an advanced exploit.
It wasn’t some zero-day vulnerability.
It wasn’t an obscure framework bug.

It was just a public .env file.

But the consequences were very real.

A single configuration file can contain the entire identity of a system: API keys, database passwords, tokens, credentials, and secrets. Once exposed, attackers don’t even need sophisticated hacking techniques. Sometimes all they need is a browser.

This experience also reminded me that when working with long-running systems, security problems are often inherited quietly over time. Old assumptions survive upgrades. Temporary solutions become permanent. And configurations that once seemed harmless eventually turn into critical vulnerabilities.

I’m pretty sure there are still more security issues hidden somewhere inside a 20-year-old codebase. That’s simply reality. But at the very least, every issue we discover is one less problem waiting silently in production.

Fix what you find.
Improve what you can.
Keep moving forward.

Because sometimes the most basic vulnerabilities are also the most dangerous ones.

Thanks for reading!