Glossary/Detection Engineering/SQL Injection

What Is SQL Injection? Types and Defense

SQL injection is a web vulnerability in which an attacker supplies input that an application splices into a database query as code, letting the attacker read, change, or delete data and sometimes run commands on the database host.

A login form asks for a username and password. An attacker types ' OR '1'='1 into the username field and leaves the password blank. The application drops that text straight into a SQL query: SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''. The injected OR '1'='1' is always true, so the WHERE clause matches every row, and the query returns the first user in the table, often an administrator. No password was guessed. The application did exactly what its code said: it treated attacker input as part of the query.

That is SQL injection in one line. SQL injection (SQLi) is a flaw where an application builds a database query out of untrusted input, letting an attacker change what the query does. The database cannot tell the developer's SQL apart from the attacker's, so it runs both. With a working SQLi an attacker can read data they should never see, bypass a login, modify or delete records, and in some configurations run commands on the database host.

This guide covers what SQL injection is, the types a defender should be able to name, how the attack works under the hood, what it costs, the parameterized-query discipline that fixes it at the source, and the telemetry that exposes a probe. SQLi is one member of the broader injection family; this article stays on the SQL case.

What is SQL injection?

SQL injection is a web vulnerability in which an attacker interferes with the SQL queries an application sends to its database by supplying input that the application splices into a query as code rather than treating it as data. The classic shape is a string-concatenated query: the application glues a user-supplied value into a SQL statement, and a value crafted with quotes and SQL keywords breaks out of the data slot and rewrites the statement.

The root cause is the absence of separation between code and data. When an application assembles a query by joining trusted SQL text with untrusted input as one string, an attacker who controls part of that string controls the whole statement. A single quote closes the string literal the developer opened; everything after it is parsed as SQL. This is the same data-versus-code failure behind every injection flaw, applied to a SQL database.

SQL injection has been near the top of the industry's risk lists for two decades. In the OWASP Top 10:2025, the current edition, Injection (the category that includes SQLi) is ranked A05:2025. It sat at A03 in the 2021 list and at A01, the single highest web application risk, in 2017. The drop in rank tracks better framework defaults and wider use of safe APIs, not the disappearance of the bug. SQLi remains one of the most tested and most exploited weaknesses in web applications, and it maps to CWE-89 (Improper Neutralization of Special Elements used in an SQL Command).

The main types of SQL injection

SQL injection is classified by how the attacker gets the answer back. The injection mechanism is the same in every case: untrusted input crosses into the query. What differs is whether the data comes straight back, has to be smuggled out, or has to be inferred one bit at a time.

TypeHow results come backSpeedClassic shape
In-band: error-basedDatabase error messages leak data into the responseFastForce a type-cast or syntax error that prints a value
In-band: UNION-basedResults appended to the application's own outputFast' UNION SELECT username, password FROM users--
Blind: boolean-basedNo data shown; inferred from true/false page differencesSlow' AND 1=1-- versus ' AND 1=2--
Blind: time-basedInferred from how long the response takesSlow' AND SLEEP(5)--
Out-of-band (OAST)Data exfiltrated over a separate channel like DNSVariesTrigger an outbound DNS or HTTP lookup carrying data
Second-orderStored input fires later when reused in a queryDelayedInject on save; payload runs when the value is read back

A few of these carry most of the real-world weight.

In-band SQLi is the loud, fast case: the attacker reads the answer in the same response. Error-based injection coaxes the database into printing data inside an error message. UNION-based injection appends a second SELECT to the original query so the results of an attacker-chosen query ride back in the application's normal output. A payload like ' UNION SELECT username, password FROM users-- dumps a credentials table into a page that was meant to show a product list.

Blind SQLi applies when the application does not return query results or errors, but its behavior still changes with the query outcome. In boolean-based blind injection the attacker submits a condition and watches whether the page renders the true state or the false state, extracting data one character at a time. In time-based blind injection the attacker makes the database pause when a condition is true (SLEEP(5)), so a slow response confirms the guess. Blind techniques are slower but just as complete, which is why a quiet application is not a safe one.

Out-of-band SQLi forces the database to make an external request, such as a DNS lookup, that carries stolen data to a server the attacker controls. It is the fallback when in-band and blind channels are closed. Second-order SQLi is the subtle one: the payload is stored on first submission and only executes later, when some other code path reads that stored value back into a query. The injection point and the trigger are in different requests, which is why input validation that only checks the entry point misses it.

How a SQL injection attack works

How SQL injection works · CWE-89
Untrusted input crosses from data into SQL.
Four beats turn a username field into a rewritten query the database runs as written.
01 FIND
Input reaches a query
Probe form fields, URL params, headers, cookies, API bodies. A stray quote that errors is the tell.
02 CRAFT
Break out of the string
A quote closes the literal, -- truncates the rest, OR '1'='1' forces the clause true.
03 EXECUTE
Database runs the rewritten query
Handed developer SQL plus attacker input as one string, it parses and runs the whole statement.
04 READ OR PIVOT
Dump data or move deeper
Returned rows, an error, a true/false page difference, or a timing delay confirms what worked.
The root cause is beat three The database cannot tell which characters came from the developer and which came from the attacker, so it runs both. The flaw is never in the database engine. It is in the application that built a query out of untrusted parts. Parameterized queries fix it by sending structure and data on separate channels.

Every SQL injection follows the same four-beat sequence. Seeing it once makes every variant recognizable.

  1. Find an input that reaches a query. The attacker probes form fields, URL parameters, HTTP headers, cookies, and API bodies for any value the application forwards into SQL. A single quote that produces a database error or a changed response is the tell that input is reaching the query unescaped.
  2. Craft a payload that breaks out of the data context. The input is shaped so part of it is parsed as SQL: a quote that closes the string literal, a comment marker (--) that truncates the rest of the original query, a UNION that appends a new SELECT, an OR '1'='1' that forces the WHERE clause true.
  3. The database executes the rewritten query. Because the application handed it one string of developer SQL plus attacker input, the database parses and runs the whole statement. It has no way to know which characters came from the developer and which came from the attacker.
  4. The attacker reads the result or pivots. Returned rows, an error message, a true/false page difference, or a timing delay tells the attacker what worked. From there they dump tables, bypass the login, modify data, or, against a permissive database account, run commands on the host.

The reason the whole class exists is beat three. A database executes whatever syntactically valid SQL it receives. The vulnerability is never in the database engine; it is in the application that built a query out of untrusted parts and trusted the result.

What SQL injection attacks cost

When SQLi succeeds, the impact tracks what the query can reach and what the database account is allowed to do. The same flaw can mean a minor information leak or a full compromise.

  • Mass data theft. SQL injection is a leading route to bulk data exfiltration. A UNION or blind attack can dump entire tables of customer records, credentials, and payment data, the raw material of a data breach and the extortion or resale that follows.
  • Authentication bypass. Injection that rewrites a login query lets an attacker log in as another user, often an administrator, without a valid password.
  • Data integrity loss. Beyond reading, an attacker can modify or delete records. A single UPDATE or DROP payload can corrupt or destroy data.
  • Remote code execution. Against a database account with high privileges or features like xp_cmdshell, SQLi can run operating-system commands, turning a web flaw into a foothold on the server and the network behind it.
  • Lateral movement. Credentials and connection strings pulled from the database often unlock other systems, so a SQLi at the edge becomes initial access for a larger intrusion.
  • Downstream cost. A successful SQLi drives the familiar tail of any serious incident: downtime, investigation and remediation, regulatory fines, legal exposure, and reputational damage.

The through-line is that SQLi sits at the front of an attack, not the end. It is frequently the initial access a larger cyberattack is built on, which is why one unvalidated parameter can lead to a breach that takes months to clean up.

How to prevent SQL injection

The fix for SQLi is structural, not cosmetic. The root cause is mixing code and data in one query string, so the durable defenses keep them separate. Treat the controls as layers; the first one does most of the work.

  • Use parameterized queries and prepared statements. This is the single most effective control. Instead of building a query by concatenating strings, the application sends the query structure and the user data to the database separately, with placeholders for the data. The database treats the supplied values strictly as data, so they can never be parsed as SQL, no matter what characters they contain. Use the parameterized API of the database driver or ORM rather than assembling raw SQL.
  • Validate input on an allowlist. Treat every input as untrusted. Accept only the characters and formats a field legitimately needs rather than trying to blocklist bad ones. Validation does not replace parameterization; it is a second layer, and it is the only practical guard for the few places parameters cannot cover, such as a table or column name supplied at runtime.
  • Escape only as a last resort. Where a parameterized API genuinely cannot be used, escape user input with the database's own escaping function for the exact context. This is weaker than parameterization and easy to get wrong, so it is a fallback, not a primary control.
  • Enforce least privilege on the database account. Run the application's database account with the minimum rights it needs. A read-only account cannot drop a table even if injection succeeds, and an account without xp_cmdshell rights cannot reach the OS. Least privilege caps the blast radius when something slips through.
  • Keep a WAF as a backstop, not a fix. A web application firewall can block common SQLi payload patterns and buy time, but attackers obfuscate around signatures, so a WAF never substitutes for safe queries.

The order matters. Parameterized queries remove the vulnerability at its source. Input validation, least privilege, and a WAF reduce what an attacker can do if something slips through. A team that parameterizes every query consistently has solved most of the problem. This discipline is part of broader application security: build the safe query API in during development and test for the flaw before release.

How to detect SQL injection attempts

Because SQLi rides in over normal application traffic, detection watches the inputs and the database behavior rather than looking for malware. Useful signals include application and web server logs showing payload-like characters in parameters (stray single quotes, --, UNION, OR 1=1, SLEEP), database error messages surfacing to users, and unusual query patterns: a sudden large result set, a spike in failed queries, or repeated requests that differ only by a timing-control payload, the signature of a blind extraction.

Tying this together at scale means centralizing application, web server, and database logs and alerting on the patterns above, ideally correlated so a probe in the web logs and an anomaly at the database surface as one event. Database activity monitoring helps here: query-level logging catches the rewritten statements that a request log alone would miss. Detection does not replace prevention, but it shortens the time between a first probe and a response, which is the difference between a blocked attempt and a breach.

Frequently Asked Questions

What is SQL injection in simple terms?

SQL injection is a web vulnerability where an attacker types special input into a form or URL that the application mistakenly runs as part of a database query. Because the database cannot tell the attacker's input from the developer's SQL, it executes both. This lets the attacker read data, bypass logins, or change records they should never have access to.

What is an example of a SQL injection attack?

The classic example is a login bypass. An attacker enters ' OR '1'='1 as the username, which turns the login query into one whose condition is always true, so it returns a valid user without a correct password. Another common example is a UNION attack like ' UNION SELECT username, password FROM users-- , which appends a second query to dump a credentials table into the page's normal output.

What are the types of SQL injection?

The main types are in-band (error-based and UNION-based, where results come straight back), blind (boolean-based and time-based, where the attacker infers data from page behavior or response timing), out-of-band (data exfiltrated over a separate channel like DNS), and second-order (a stored payload that fires when the value is later reused in a query). They differ in how the answer is retrieved, not in the underlying flaw.

What is blind SQL injection?

Blind SQL injection is used when the application does not display query results or errors, but its behavior still changes with the query outcome. The attacker submits true/false conditions and reads the answer from a page difference (boolean-based) or from how long the response takes (time-based, using a command like SLEEP). It extracts data one piece at a time, so it is slower but just as effective.

How do you prevent SQL injection?

The primary defense is parameterized queries (prepared statements): the application sends the query structure and the user data to the database separately, so input can never be parsed as SQL. Layer that with allowlist input validation, least-privilege database accounts so a successful injection cannot drop tables or reach the OS, and a web application firewall as a backstop. Parameterization fixes the flaw at the source; the rest limit the damage if something slips through.

Is SQL injection still a threat in 2026?

Yes. SQL injection remains a common and high-impact web vulnerability and sits inside the Injection category at A05 in the current OWASP Top 10:2025. Its rank fell from A01 in 2017 because modern frameworks parameterize by default, not because the bug disappeared. Legacy code, hand-built queries, and second-order cases keep SQLi a live threat, and it is still a leading route to mass data breaches.

The bottom line

SQL injection is what happens when an application lets untrusted input cross from data into the SQL it sends to its database. The database runs whatever syntactically valid query it receives, so an attacker who controls part of that query controls the outcome: read any table, bypass the login, modify data, or run commands on the host. The variants, in-band, blind, out-of-band, and second-order, differ only in how the answer comes back, never in the root cause. The defense is narrow and well understood. Parameterize every query so data can never be parsed as code, validate input as a second layer, run the database account with least privilege, and watch your logs for the quote-and-keyword patterns that signal a probe. SQLi has fallen down the OWASP list because those defenses work, not because attackers stopped trying.

Frequently asked questions

What is SQL injection in simple terms?

<p>SQL injection is a web vulnerability where an attacker types special input into a form or URL that the application mistakenly runs as part of a database query. Because the database cannot tell the attacker's input from the developer's SQL, it executes both. This lets the attacker read data, bypass logins, or change records they should never have access to.</p>

What is an example of a SQL injection attack?

<p>The classic example is a login bypass. An attacker enters <code>' OR '1'='1</code> as the username, which turns the login query into one whose condition is always true, so it returns a valid user without a correct password. Another common example is a UNION attack like <code>' UNION SELECT username, password FROM users-- </code>, which appends a second query to dump a credentials table into the page's normal output.</p>

What are the types of SQL injection?

<p>The main types are in-band (error-based and UNION-based, where results come straight back), blind (boolean-based and time-based, where the attacker infers data from page behavior or response timing), out-of-band (data exfiltrated over a separate channel like DNS), and second-order (a stored payload that fires when the value is later reused in a query). They differ in how the answer is retrieved, not in the underlying flaw.</p>

What is blind SQL injection?

<p>Blind SQL injection is used when the application does not display query results or errors, but its behavior still changes with the query outcome. The attacker submits true/false conditions and reads the answer from a page difference (boolean-based) or from how long the response takes (time-based, using a command like <code>SLEEP</code>). It extracts data one piece at a time, so it is slower but just as effective.</p>

How do you prevent SQL injection?

<p>The primary defense is parameterized queries (prepared statements): the application sends the query structure and the user data to the database separately, so input can never be parsed as SQL. Layer that with allowlist input validation, least-privilege database accounts so a successful injection cannot drop tables or reach the OS, and a web application firewall as a backstop. Parameterization fixes the flaw at the source; the rest limit the damage if something slips through.</p>

Is SQL injection still a threat in 2026?

<p>Yes. SQL injection remains a common and high-impact web vulnerability and sits inside the Injection category at A05 in the current OWASP Top 10:2025. Its rank fell from A01 in 2017 because modern frameworks parameterize by default, not because the bug disappeared. Legacy code, hand-built queries, and second-order cases keep SQLi a live threat, and it is still a leading route to mass data breaches.</p>

Practice track
Network Forensics
Investigate security incidents by analyzing packet captures, identifying malicious traffic patterns, and reconstructing cyber attacks from network communications.
Browse Network Forensics Labs โ†’