vuln-class-sqli
SQL Injection, in plain English
SQL injection lets an attacker rewrite the questions your application asks its database. Done well, it gives them every record in every table — and sometimes the operating system underneath.
What this is
A database query is the question your application asks its database — for example “give me the user named Alice”. The application typically builds the query at runtime by combining a fixed template with user input.
SQL injection happens when the user input ends up glued straight into the query template, so that input which contains query syntax becomes part of the question instead of being treated as data. Concretely, what the application meant as “give me the user named Alice” the attacker turns into “give me every user”.
The classic minimal example. The application does:
"SELECT * FROM users WHERE name = '" + name + "'"
The attacker types ' OR '1'='1 as the name. The query becomes:
SELECT * FROM users WHERE name = '' OR '1'='1'
— which returns every user in the table.
Why it matters
What an attacker gets from a successful SQL injection:
- Read every row of every table. Customer lists, password hashes, payment details, internal notes. Almost every “X million credentials leaked” headline comes from either a SQL injection or a stolen backup.
- Log in as anyone. With a known username, the attacker can craft input that makes the password check pass regardless of the actual password.
- Wipe or corrupt the database. A crafted input can issue a
DROP TABLEor anUPDATEwithout conditions. - Get to the operating system. Some databases (older Microsoft
SQL Server with
xp_cmdshellenabled, PostgreSQL with file-write rights) allow SQL to run shell commands. Crossing from a SQL injection into a full server takeover is not unusual.
The fix is well-known and has been shipped with every modern database driver since the early 2000s. The reason SQL injection is still in the top three causes of web breaches is mostly legacy code that never got migrated, plus a few common shortcuts developers take under deadline pressure.
How it gets fixed (in your own application)
The single answer is parameterised queries (also called prepared statements) — a way of writing the query in which the template and the data are kept strictly separate, so user input can never become part of the query syntax.
# Wrong — input mixed into the query string
db.execute("SELECT * FROM users WHERE name = '" + name + "'")
# Right — input passed separately as a parameter
db.execute("SELECT * FROM users WHERE name = %s", (name,))
// Wrong
db.query(`SELECT * FROM users WHERE name = '${name}'`)
// Right
db.query('SELECT * FROM users WHERE name = $1', [name])
Specific things for your developer to check:
- Search filters and LIKE patterns. Still parameterise; wrap
the value in
%before it goes into the parameter, never glue it into the template. - Dynamic column or table names. Parameterisation doesn’t apply here. Use an allowlist (only certain known column names are accepted) and insert the validated value into the template directly.
- Raw-SQL escape hatches in ORMs. Most frameworks have a “raw query” mode for edge cases. Search the codebase for those and audit each one.
- Stored procedures with
EXECorEXECUTE. These often bypass the framework’s parameterisation. Review separately.
Layered defences for when something slips through anyway:
- Least-privilege database accounts. The application connects
with a database user that can only do what the application needs
—
SELECTandINSERTon its own tables, nothing more. NoDROP, no shell-command features, no read access to tables it doesn’t use. - Web application firewall (WAF) rules as a backstop — Cloudflare, AWS WAF, ModSecurity. They don’t replace parameterisation but they buy time when a 0-day shows up in a third-party component.
How blueredix surfaces SQL injection
The scanner doesn’t actively try to inject SQL into your live application — that’s an actively dangerous operation that risks corrupting data and is reserved for authorised penetration tests.
What we do flag:
- CVEs in third-party software (CMS, e-commerce platforms, plugins, admin panels) whose description mentions SQL injection. These get the standard severity treatment and link back to How to read a CVE.
- Patterns in detected JavaScript libraries with a documented history of SQL-injection bugs and a fixed version available.
For a real test of your own code’s SQL-injection resistance, a manual penetration test or a tool like sqlmap (in a non-production environment, with permission) is the right next step.