SQL injection: what it is and how to fix it
SQL injection happens when text from a request becomes part of the SQL statement itself instead of a value the statement uses. The attacker stops supplying data and starts writing the query.
Example
app.get("/users", async (req, res) => {
const name = req.query.name;
const rows = await db.query(
"SELECT * FROM users WHERE name = '" + name + "'"
);
res.json(rows);
});app.get("/users", async (req, res) => {
const rows = await db.query(
"SELECT * FROM users WHERE name = $1",
[String(req.query.name)]
);
res.json(rows);
});How it happens
The database cannot tell which part of a string-built query the developer wrote and which part came from the request. A name of ' OR '1'='1 turns a lookup into a dump of every row; a value ending in a comment removes the password check from a login query; stacked statements can modify or delete data. ORMs prevent most of this until someone reaches for a raw query or builds a WHERE clause with a template string.
How to fix it
Send values separately from the statement.
- Use placeholders ($1, ?, :name) and pass values as parameters
- Use the query builder or ORM methods instead of raw SQL with interpolation
- Convert numbers with Number or parseInt and check their range before use
- Never build table or column names from input; map allowed names explicitly
How RepoVerse finds it
- HighRequest input is built into a SQL statement
The caller can rewrite the query: read other users' rows, bypass a login check, or modify data.
data flow · CWE-89
- HighSQL built by string interpolation
A query is assembled out of variables instead of being parameterised.
pattern
- HighSQL assembled with format or concatenation
A SQL string is produced by `%`, `.format()`, f-string or `+` before being run.
pattern
Questions
- Does escaping quotes prevent SQL injection?
- Not reliably. Escaping depends on the database, the encoding and the context inside the query. Parameterised queries remove the problem rather than trying to neutralise it.
- How does RepoVerse find SQL injection?
- It follows request input through assignments and function calls — across files — to calls such as query, execute and raw, and reports a traced finding with the path when the input reaches the SQL text. Numeric conversions end the trail.
Related
- NoSQL injection: rewriting MongoDB queries from a requestHow MongoDB $where expressions and operator objects like {"$ne": null} let request data rewrite a query (CWE-943), with vulnerable and fixed examples.
- Command injection: when a parameter runs a shell commandHow OS command injection (CWE-78) turns a request parameter into a second shell command, the safe execFile pattern, and how to find exec calls fed by user input.
- GitHub security scanner for code, secrets and dependenciesScan a GitHub repository for injection flaws, leaked secrets and vulnerable dependencies. Data-flow traces from request to sink, lockfile-aware, with fixes.
Updated 2026-10-11