SQL injection prevention via parameterized queries or ORM
Why it matters
SQL injection (CWE-89) is the canonical database attack and remains OWASP A03 (Injection) for good reason. String-concatenating user input into SQL queries lets attackers read or delete every table in the database, bypass authentication by injecting OR 1=1, and in some configurations execute OS commands. NIST 800-53 SI-10 requires input validation as a system security measure. A single unparameterized query in a public-facing endpoint is sufficient to exfiltrate an entire user table. ORM raw query methods like Prisma's $queryRaw with template literal interpolation carry exactly the same risk as hand-rolled string concatenation.
Severity rationale
High because a single injectable query gives an attacker full read and often write access to the database, compromising every user's data in one request.
Remediation
Use ORM builder methods for all queries. When raw SQL is unavoidable, use Prisma's tagged template — not a plain string:
import { Prisma } from '@prisma/client'
// Safe: ORM builder
const user = await prisma.user.findUnique({ where: { email } })
// Safe: Prisma.sql tagged template (parameterized)
const rows = await prisma.$queryRaw(
Prisma.sql`SELECT * FROM users WHERE email = ${email}`
)
// UNSAFE — never do this:
// prisma.$queryRaw(`SELECT * FROM users WHERE email = '${email}'`)
For node-postgres, always pass values as the second array argument: db.query('SELECT * FROM users WHERE email = $1', [email]).
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Security Hardening Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-89 — SQL Injection
- owasp:2021 · A03 — Injection
- nist:rev5 · SI-10 — Information Input Validation
Taxons
History
- 2026-04-18·v1.0.0·Initial import from security-hardening·automated