Skip to content

SQL Injection in modern ORMs and databases: second-order, blind, and time-based SQLi prevention

Why SQL injection persists despite modern ORMs like Prisma, TypeORM, and SQLAlchemy, and how to identify and remediate second-order and blind SQLi vectors.

By BugSnaps Security Research · · 8 min read

Many developers believe SQL Injection (SQLi) is an obsolete vulnerability solved by modern Object-Relational Mappers (ORMs). Yet SQL injection consistently appears in real-world penetration tests. While ORMs parameterize standard CRUD operations, developers frequently introduce SQLi through raw query fragments, dynamic ORDER BY clauses, and second-order storage.

Where ORMs fail: raw SQL and dynamic clauses

ORMs protect you only when you use their built-in query builders. When performance optimization or complex joins require raw SQL, parameterization is often bypassed:

  • Dynamic sorting: `ORDER BY` and `GROUP BY` clauses cannot typically use parameterized query placeholders in SQL syntax, leading developers to concatenate unsanitized user strings.
  • Raw queries: using methods like Prisma's `$queryRawUnsafe()` or Sequelize's `sequelize.query()` with string interpolation instead of tagged template literals.
  • Second-order SQLi: storing user input safely during registration, but subsequently retrieving that unescaped string and concatenating it into an administrative background job.

Detecting blind and time-based SQLi

Modern SQLi rarely returns explicit database error messages. Attackers detect blind SQLi by injecting conditional boolean expressions (`AND 1=1` vs `AND 1=2`) or injecting sleep functions (`pg_sleep(5)`, `WAITFOR DELAY '0:0:5'`) to measure server response delay deltas.

BugSnaps MyPentest tests input parameters with differential time and boolean probes, verifying SQL injection vulnerabilities with mathematical certainty without corrupting production data.

Run a real pentest on your app - free.

Sign in, prove you own the domain, and MyPentest maps and tests it. No credit card.