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

Vulnerable
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);
});
Fixed
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

Updated 2026-10-11