Behind the Breach: SQL Injections


In the first post of my Behind the Breach series, I’m sharing what I’ve learned about some of the most common malicious attacks targeting web applications. Today, let’s dive into SQL injection. I’ll start by explaining what it is, then go over some example SQL injection payloads (for educational purposes only — don’t go testing these on random websites; it’s illegal!). Finally, we’ll look at how to detect potential SQL injection attempts and what we can do to prevent them.
WHAT IS SQL INJECTION?
Put simply, SQL injection is one of the most common web hacking techniques – it allows attackers to insert malicious SQL code that can potentially manipulate, exfiltrate data from, or even destroy your database.
Where can this malicious code be injected? In multiple places – for example, in UPDATE statements (inside the updated values) or in WHERE clauses. It can be injected anywhere user input is passed unsanitised to a database – including login fields, search bars, or even cookies.
To illustrate the basic idea, here’s a little scene I’ve prepared:
A website sends a request to the database:
"Hey database, get me the user info where the name is 'Alice'."
But if user input isn’t properly secured, a hacker can inject extra code:
"Hey database, get me the user info where the name is 'Alice' OR 1=1."
Now the query returns everyone, not just Alice!
WEB LOGS — A GOOD PLACE TO START
To detect SQL injection, the first step is collecting the right data. But where can we find information crucial to understanding a web application's network behavior? In the web logs, of course!
Web logs contain a wealth of information — often enough to trace malicious activity and understand the attacker’s behaviour. The exact content of a web log depends on many factors: the source, destination, environment, and more. These logs are usually parsed, enriched, and collected by tools like SIEM platforms or custom parsers. These tools focus only on the most relevant logs for cybersecurity purposes (if properly configured, of course).
Logs processing and preparation is a complex process that deserves its own post (coming soon!). For now, just know this: as cybersecurity analysts, we can’t look through every single web log manually – there are simply too many. So instead, we work with filtered subsets, extracted by dedicated tools, or we respond to alerts that point us to logs related to specific events.
SQL INJECTION DETECTION
Now that we’ve got our filtered log set — or if we’re combing through logs from a specific time window — we need to know what to look for. In other words, we want to identify the footprints that attackers might leave behind.
USER-AGENT: SPOTTING MALICIOUS TOOLS
One helpful log field is the User-Agent in the HTTP request header. This can reveal whether an attacker is using an automated tool to carry out SQL injection. Many such tools allow attackers to spoof or customize the User-Agent value — but it’s still worth checking, because sometimes attackers overlook this. Here are a few common tools used for SQL injection, and what they might look like in your logs:
sqlmap/1.7.10.17#dev
Or depending on the version:
sqlmap/1.6.5.11#dev
Another tool worth mentioning is the Netsparker:
Netsparker/1.0
Or Acunetix:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) Acunetix Web Vulnerability Scanner
A hacker could also use a different, older tool, like Havij, that generates a basic browser User-Agent (UA) as a cover:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)
At first glance, that last one might seem legitimate. But let’s break it down:
MSIE 8.0 means it claims to be Internet Explorer 8
Windows NT 6.0 means it’s supposedly running on Windows Vista.
Both are seriously outdated — and very few legitimate users are still running them. Does that mean it’s definitely an SQL injection attempt? Not necessarily. But for me, that’s a red flag worth investigating further.
If I spotted that kind of User-Agent, I’d:
Look for repeated requests using the same UA but from different IP addresses.
Check whether those requests contain SQL injection payloads.
Make sure the other headers or behaviors match a real browser — or don’t.
COOKIE: AN EASY WAY TO ACCESS LOGIN DATA
Another part of the HTTP header that can be targeted is the Cookie section, as this often contains a user's login information. As a result, it's not unusual to find suspicious entries like this:
Cookie: sessionid=123' OR '1'='1
This could correspond to a query such as:
SELECT * FROM sessions WHERE sessionid = '$cookie_value'
If the injection succeeds, the attacker may bypass authentication and potentially gain access to any active session data, depending on how the back-end handles the session lookup.
But how can a hacker actually access and modify the cookie section? It’s surprisingly easy with the right tools. They can use custom tools like cURL, Burp Suite, or simply open DevTools → Application → Cookies and manually edit a cookie. And that’s not even considering what’s possible with JavaScript – but I’ll save that for another post!
ALARMING REQUESTS: TOO MANY, TOO OFTEN
A typical user might send about one request per second. However, automated tools used by attackers can send many more, allowing them to test a large number of SQL payloads in a short time. That’s why I always monitor the volume of requests – if it’s unusually high, it’s a clear red flag.
KEYWORDS THAT UNCOVER A HACKER
The content of the payload is critical! Look out for SQL-related keywords that are rarely used by regular users, such as "WHERE", "SELECT", and "INSERT".
In addition, some tools include their own names in the payload—for example: "sqlmap OR 1=1". Certain special characters can also raise suspicion, such as apostrophes ('), dashes (-), or parentheses (()), which are often used in SQL syntax. While they could be the result of a user mistyping, they might also indicate an attempt to manipulate the logic of a query.
COMPLEX = SUSPICIOUS
Watch out for overly complex payloads. While complexity alone isn’t definitive proof of malicious intent, automated tools often generate more intricate queries. Take this example, which attempts to test for SQL injection using a time delay (let’s call it the “Steve payload”):
In addition to keywords like FROM and SELECT, this query uses advanced functions such as ASCII(), VERSION(), and DATABASE(). Seeing something like this in the wild would definitely set off alarm bells.
PERCENT ENCODING – STEVE PAYLOAD EXAMPLE
It's important to examine web server logs for suspicious percentage symbols (%). Why? Because of a mechanism called Percent Encoding (also known as URL Encoding). This process replaces certain characters in a URL with a % followed by two hexadecimal digits representing the character’s ASCII code. Instead of looking for all single % signs, focus on patterns like %27 (apostrophe), %3D (equals), or known encoded payload signatures. Otherwise, the number of matching logs would be too big.
Originally, percent encoding was intended to ensure that URLs could be safely transmitted over the Internet—since some characters have special meanings in URLs or aren’t allowed at all (like spaces). Unfortunately, encoding method can also be used to hide malicious SQL payloads. If we only search for special characters like = or -, we might completely miss an encoded version of the previously mentioned Steve payload.
Here's what it would look like in percent-encoded form:
This is essentially the same logic, just obfuscated through encoding.
LOOK FOR THE ERRORS
Certain error messages can indicate that SQL injection is leaking through – a clear sign of poor input sanitization. Watch for error messages like:
"SQL syntax error"
"Unclosed quotation mark"
"ORA-01756"
"MySQL error"
"ODBC Drivers"
These messages suggest that the backend is exposing internal database behavior, which should never happen in a secure application.
WE'VE FOUND THE ATTACK! BUT… DID IT WORK?
You've identified signs of SQL injection – malicious payloads in requests, abnormal request volumes, and automated patterns. But how do you know if the attack actually succeeded?
The answer lies in the web responses.
By analyzing the server’s response content and size, you can determine whether an injection was effective. To evaluate responses, use full traffic logs, reverse proxy logs, or packet captures that include response bodies and sizes. Then establish a baseline by looking at the typical response sizes for normal requests. If you notice a significant deviation from that baseline, it's a strong indicator that something unusual occurred. For example:
Normal response size: 850–1000 bytes
Response after SQL injection: 6000–8000 bytes
Such a jump could mean the attacker successfully retrieved data - perhaps from the database itself.
WHAT A HACKER NEEDS TO KNOW: THE SINGLE APOSTROPHE CASE
Recently I wondered why one of the most common SQL injection examples looks like this:
' OR '1'='1
Why does it start with a single apostrophe? And why doesn’t the 1 at the end have one? To understand this, let’s look at what’s happening on the backend. A vulnerable SQL query might look like this:
query = "SELECT * FROM users WHERE username = '" + input + "';”
Now, if a regular user enters a clean input like Alice, the resulting SQL query would be:
SELECT * FROM users WHERE username = 'Alice';
The input is neatly wrapped in single quotes, and everything works as expected. But a hacker wants to inject code into this query. To do that, they must understand – or guess – how the backend query is structured. Knowing that the input is enclosed in single quotes, they can exploit this by injecting a starting apostrophe to break out of the string and append malicious logic. By submitting the following: ' OR '1'='1
The resulting query becomes:
SELECT * FROM users WHERE username = '' OR '1'='1';
But then, if the username is an empty string, it may not return any results - assuming the application or database enforces constraints against blank usernames. So why does this injection still work? The answer lies in the syntax. In SQL, the WHERE clause evaluates expressions using logical operators. In this case, the condition becomes: username = '' OR '1'='1'.
SQL checks:
Is there a user with an empty username? → False
Is '1'='1'? → True
Since False OR True evaluates to True, the query returns all rows in the table. And just like that, the hacker gets access to everything.
This simple analysis reveals the core concept behind a common malicious technique known as SQL injection. To carry out a successful injection, a hacker needs to understand how the SQL query is structured on the backend. They often rely on error messages to uncover details about the syntax, then craft their injection to match that specific structure.
PREVENTION BEFORE DETECTION: HOW TO SECURE APPLICATIONS
To prevent SQL injection (SQLi), the first step is to identify all potential input vectors in your web application. These commonly include:
URL query strings
Form data (POST body)
Cookies
Headers (like User-Agent)
Once identified, the golden rule is: never trust user input. That means all input from external sources must be treated as not-trusted and handled appropriately.
The most effective prevention techniques include:
Using parameterized queries (prepared statements) – this ensures that input is treated strictly as data, not executable code.
Validating input formats – for example, ensuring session IDs follow a strict pattern.
Sanitizing inputs – while important, sanitization alone is not enough without parameterization. In fact, parameterized queries eliminate the need for manual sanitization in most cases, because they keep code and data strictly separated.
Monitoring logs continuously – logging and alerting on suspicious activity is an essential, ongoing responsibility for cybersecurity teams.
There are many additional techniques and best practices, but we’ll cover those in a separate post. For now, just remember: prevention is far more effective (and cheaper) than trying to detect and contain an attack after it happens.
CONCLUSION
From empty strings to encoded payloads, error messages, and logic manipulation, SQL injection relies on small openings in input handling that lead to big consequences.
The good news? These patterns are detectable and preventable. Use parameterized queries, validate every input (especially those hidden in cookies or headers), and monitor responses for unusual behavior. Prevention doesn’t start with firewalls – it starts with knowing your code.
Subscribe to my newsletter
Read articles from Emilia Vemaraju directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Emilia Vemaraju
Emilia Vemaraju
I was supposed to become a pianist but I chose not to. Instead, I’m a self-driven cybersecurity learner, preparing for a career in Detection & Response or Red Teaming. I'm currently building hands-on experience through platforms like TryHackMe and Hack The Box, focusing on practical skills in threat detection, incident response, and ethical hacking. My goal is to enter the cybersecurity field in 2026 with a strong portfolio, real-world lab experience, and relevant certifications.