SQL injection is a web application flaw where untrusted input is treated as part of a database query. A small string typed into a search box, login form, URL parameter, or API request can change what the database executes if the application builds SQL by joining raw text together. The result can be login bypass, leaked records, changed data, deleted tables, or, in severe cases, a foothold for wider compromise.
This guide explains the main SQL injection types, shows safe simplified examples, and focuses on prevention steps that actually reduce risk: parameterized queries, allow-list validation, least-privilege database accounts, safe error handling, and regular testing. Do not test SQL injection payloads on websites you do not own or have explicit permission to assess.
How SQL Injection Works
Most SQL injection flaws start with a query that mixes application code and user input. A vulnerable login check, for example, may place the submitted username and password directly into a SQL statement. If an attacker adds SQL control characters instead of ordinary text, the database may read that input as instructions, not as data.
A safer application keeps code and data separate. It sends the database a query template first, then passes user values as parameters. The database treats those values as values even if they contain quotes, spaces, SQL keywords, or unusual characters.
Unsafe pattern
SELECT * FROM users
WHERE username = '$username'
AND password = '$password';
Safer pattern
SELECT * FROM users
WHERE username = ?
AND password = ?;
The second pattern is not secure because the question marks look special. It is secure when the application uses a prepared statement or parameterized query API so the database receives the SQL structure and the submitted values separately.
Main Types of SQL Injection
SQL injection is usually grouped by how the attacker sends the input and receives feedback. The categories below are useful for understanding risk, testing coverage, and log evidence.
| Type | What happens | Common sign |
|---|---|---|
| Union-based SQLi | The attacker tries to combine a malicious query with the page’s normal query output. | Unexpected rows, extra columns, or data from another table appears in the response. |
| Error-based SQLi | The attacker uses database error messages to learn table names, column counts, or query structure. | Detailed SQL errors appear in the browser, API response, or logs. |
| Boolean-based blind SQLi | The page does not show database output, but true and false conditions change the response. | One crafted request returns normal content while another returns an empty, different, or blocked page. |
| Time-based blind SQLi | The attacker makes the database delay a response and infers answers from timing. | Specific parameters cause repeated, unnatural response delays. |
| Out-of-band SQLi | The database is tricked into making a network request to a server controlled by the attacker. | Unexpected DNS or HTTP callbacks leave the database environment. |
| Second-order SQLi | Malicious input is stored first and becomes dangerous later when another feature uses it in a query. | The original form looks harmless, but a profile page, admin panel, report, or export breaks later. |
SQL Injection Examples
The examples below are intentionally simplified. Their purpose is to show the mistake, not to provide a testing script.
Login bypass example
A login form is vulnerable when it checks credentials by inserting raw form values into the query. If input can change the condition after WHERE, the database may return a user row even when the password is wrong. The fix is not to block a few suspicious words; the fix is to use prepared statements and normal password hashing checks.
Search box example
A product search may use a query like WHERE name LIKE '%input%'. If the application builds that query as plain text, a crafted search term may alter the filter or reveal query errors. A parameterized query can still support search, but the wildcard pattern should be passed as a value rather than pasted into SQL.
URL parameter example
Pages such as /article?id=42 are common SQLi targets because the parameter looks numeric and simple. If the application assumes every id is safe and builds a query directly, attackers can probe that parameter for errors, timing changes, or content differences. Treat URL parameters, cookies, headers, and API JSON fields as untrusted input.
Second-order example
Second-order SQL injection is easy to miss during quick tests. A malicious value may be saved into a harmless-looking account field, then later used by an admin dashboard, email export, analytics job, or support tool. The stored value becomes dangerous only when that second feature builds a query unsafely.
Why SQL Injection Is Still Dangerous
SQL injection is old, but it still appears because applications change faster than their security assumptions. New API endpoints, plugin updates, legacy admin tools, report builders, and quick custom filters can reintroduce string-built queries even when the main application framework is secure.
The damage can be severe. Depending on database permissions and architecture, SQL injection may allow attackers to read customer records, reset accounts, modify prices, plant malicious content, create administrator users, delete data, or pivot toward the server environment. A web application firewall can reduce noise, but it is not a replacement for fixing the query.
How to Prevent SQL Injection
The strongest SQL injection defense is boring in the best way: make unsafe query construction difficult or impossible in the codebase.
- Use parameterized queries everywhere. Prepared statements keep SQL code separate from user-controlled values. This should be the default for logins, search, filters, sorting, imports, API handlers, background jobs, and admin tools.
- Use safe ORM/query builder patterns. Frameworks help only when developers stay inside the safe API. Raw query escape hatches need review, tests, and clear ownership.
- Allow-list dynamic identifiers. Parameters protect values, not table names, column names, or sort directions. If users can choose a sort field, map the choice to a fixed allow-list such as
date,name, orprice. - Validate input by context. Numeric IDs should be numeric. Dates should be dates. Email fields should not accept arbitrary control characters. Validation reduces attack surface, but it should support parameterization, not replace it.
- Hide detailed database errors from users. Show a generic error message in production and send detailed diagnostics to protected logs.
- Use least-privilege database accounts. A public website feature rarely needs permissions to drop tables, create users, or read unrelated databases.
- Test risky paths after every change. Include authentication, search, filters, exports, profile fields, plugin endpoints, and old admin panels in security testing.
How to Spot a Possible SQL Injection Problem
Site owners and developers should investigate when a single field repeatedly triggers database errors, unusual response delays, strange quote-handling behavior, or WAF alerts that mention SQL keywords. Logs may show repeated requests to the same parameter with quotes, comments, encoded characters, or timing probes.
If you suspect an active attack, preserve web server logs, application logs, database logs, and WAF events before cleaning them up. Rotate exposed credentials, review recently changed administrator accounts, check for unexpected content changes, and verify that backups are clean before restoring. If the site also served suspicious downloads or redirects, scan affected endpoints and files with security tools before sending users back to them.
For broader context on injection risks, see our overview of dangerous injection attacks. If a suspicious site, redirect, or download was involved, Gridinsoft’s SQL injection check and website reputation tools can help with a first safety review, but code-level SQLi fixes must happen inside the application.
FAQ
What is the most common SQL injection type?
Classic in-band SQL injection is often the easiest to notice because the attacker may receive errors or database output in the same web response. Blind SQL injection can be harder to detect because the attacker infers results from content differences or timing.
Does input validation stop SQL injection?
Input validation helps, but it is not enough by itself. Parameterized queries are the core defense because they stop user input from becoming SQL code. Validation should add context checks around that safer query design.
Can a firewall fix SQL injection?
A web application firewall can block many common probes and reduce automated noise, but it does not fix vulnerable code. Treat WAF alerts as evidence that a route needs review, not as proof that the application is safe.
References
- OWASP Foundation. SQL Injection Prevention Cheat Sheet. OWASP Cheat Sheet Series. Accessed June 7, 2026.
- MITRE. CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’). Common Weakness Enumeration. Accessed June 7, 2026.
- OWASP Foundation. A03:2021 Injection. OWASP Top 10. Accessed June 7, 2026.


What is the most important lesson you can take away from this article?