Skip to content

The Story of Fixing an SQL Injection Vulnerability: A Slice from My Own Experiences

Hey friends, there’s a topic lately that has been bothering all of us, sometimes even keeping us awake at night: our security vulnerabilities. Especially that infamous ‘SQL Injection’ bug in our web applications. I remember back in the day, I would underestimate it in my early projects. I thought, “What’s the big deal, how important can my database be?” Oh how wrong I was… Truly, even the smallest vulnerability can disrupt your entire system. That’s exactly why today I want to share my story of how I fixed the SQL Injection vulnerability, along with lessons learned from my own mistakes. Maybe you won’t fall into the same traps I did, who knows? 🙂

Before diving into the details, let’s briefly explain what SQL Injection is. Simply put, it’s a type of attack where malicious actors send specially crafted SQL commands into a web site or application’s input fields, gaining access to the database. Think of it like entering through a door with a key, but this is the brute-force, deceptive version. They can directly access the database and retrieve desired information, or worse, delete or modify data. Isn’t it nice? Especially if you’ve got sensitive customer information, then you’re in trouble.

I first dealt seriously with these kinds of attacks about 5-6 years ago. At that time, I was working on a project where we collected some user information via a form and saved it to the database. Everything worked fine, tests were done, but security was always a bit neglected. Well, my own program failed that day.

Then one day, we noticed strange activity in the system. It looked like some of our users’ information was being entered by someone else. Initially, we thought it was just a bug. But upon detailed inspection, we realized the severity of the issue. Apparently, one of our simple input fields was actually an ‘open door’. Someone wrote a strange SQL command into the username field. Thanks to that command, all user names, addresses, and even passwords stored in plaintext (can you imagine?) could be queried.

That’s when I understood that this isn’t just ‘working well’. Whatever development we do, we need to look at it from a security perspective. By the way, we didn’t even know who the attacker was or how they found us. Maybe they targeted an amateur like me, who knows.

Ways to Protect Against SQL Injection: Practical Tips

After that incident, I did thorough research on how to prevent SQL Injection. The first thing that came to mind was using parameterized queries. Instead of concatenating SQL commands directly as strings, we should use the secure methods provided by the database driver. This allows the database to treat incoming data as a ‘value’ rather than part of the SQL command. For example, if you type a username like ‘Ali’, the system will see it as ‘Ali’ and not as part of the command like ‘SELECT * FROM Users WHERE Username = ‘Ali”. This is one of the most basic and effective methods. As the saying goes, ‘the simplest solution is often the best.’

For example, using Dapper ORM with C# greatly helps us in this regard. Dapper prepares parameterized queries based on your database (PostgreSQL, MySQL, SQL Server, etc.), so you just provide the data, and Dapper takes care of the rest. Think of it like this:

// WRONG APPROACH (Vulnerable to SQL Injection!) var username = Console.ReadLine(); var query = $"SELECT * FROM Users WHERE Username = '{username}'"; // String concatenation, dangerous! // If someone enters ' OR '1'='1, it will return all users!

// CORRECT APPROACH (Using Dapper with Parameterized Query) var username = Console.ReadLine(); var query = "SELECT * FROM Users WHERE Username = @Username"; var user = connection.QueryFirstOrDefault(query, new { Username = username }); // Dapper safely handles @Username parameter.

As you see, in the first example, we directly embed the user input into the SQL query, which is a disaster! In the second example, we use parameters like ‘@Username’, and Dapper handles this securely, even if someone enters malicious code like ‘OR 1=1’. This feature is truly lifesaving.

Another key point is validating all inputs. We should check whether the incoming data matches the expected format, length, and doesn’t contain invalid characters. For instance, when you see a warning like ‘enter only letters,’ that’s a security barrier. If an input differs from what’s expected, it should be rejected without processing. While this doesn’t prevent SQL Injection entirely, it helps narrow the attack surface.

Recently, I came across a YouTube video discussing this topic from different perspectives. If you’re interested, you can find many resources on SQL Injection: What it is and how to prevent it. I learned quite a bit from those videos and articles.

In conclusion, fixing security vulnerabilities like SQL Injection is an integral part of software development. Instead of treating security as an afterthought, it’s better to adopt security principles from the start. As they say, ‘prevention is better than cure,’ and this applies to security as well. Remember, a small negligence can lead to big problems.

Let’s wrap up without prolonging this topic. Always think a step ahead when writing code, anticipate potential risks, and learn from mistakes. And of course, everyone makes mistakes from time to time. What matters is learning from them and building more secure systems.

By the way, I also remembered a recent camping trip planned with my wife to a village in Bursa. The weather was perfect, and we were about to decide when suddenly my laptop screen started flickering. No matter what I did, it didn’t stabilize. I thought, “Okay, this trip is canceled.” As I was handling the repair, I wondered if there was a motherboard issue. Turns out, it was just a loose cable causing a simple connection problem. A quick touch fixed it. Sometimes, the most complex-looking problems have the simplest solutions, just like fixing SQL Injection with parameterized queries. 🙂