PrimLagicPrimLagic

What is SQL injection and how do you prevent it?

By Ali Abdollahi · · 2 min read

SQL injection is one of the oldest web vulnerabilities and still shows up on every list of common security problems. The good news: if you know the right technique, preventing it is simple. This is an educational note for developers who want to write safe code.

The problem

To read data, the app builds an SQL command. If user input is concatenated straight into that command string, the user can change the command's structure itself. Wrong example (pseudocode):

// dangerous: input concatenated into the string
const q = "SELECT * FROM users WHERE username = '" + username + "'";

If a user types something containing a quote and SQL keywords instead of a name, the database treats it as part of the command — and may return data that should be off-limits.

What's the damage?

Depending on configuration: reading unauthorized data (users and password hashes, for example), bypassing login, modifying or deleting data. That's why it's taken seriously.

The main fix: parameterized queries

Send the command and the data separately. The database never interprets the value as part of the command:

// safe: placeholder and parameter sent apart
const q = "SELECT * FROM users WHERE username = ?";
db.query(q, [username]);

If you use an ORM like Prisma, Sequelize or SQLAlchemy, their regular methods are parameterized by default. The danger returns when you write a raw query for one special case and concatenate input into it — for example Prisma's $queryRawUnsafe fed with user input.

The other layers of defense

  • Server-side input validation (type, length, format). Helps, but does not replace parameterizing.
  • Least privilege: the app's database user gets only the permissions it needs — not ownership of the whole database.
  • Generic error messages: don't show database error details to users.
  • Hashing passwords: even if data leaks, passwords aren't plain text (bcrypt or Argon2).
  • Security testing: scanners find problem files and configurations; see how a recon scanner works. Only ever test systems you own.

Common questions

Doesn't escaping input solve it? Escaping is fragile — one missed path and you're open. Parameterized queries are correct by construction.

Do ORMs make it impossible? No. The same bug reappears in raw queries. The rule travels with you: data never joins the command string.

SecuritySQLWeb