SQL Injection Detection — ShipSafe
ShipSafe ships 127 SQL injection rules that understand Prisma, Drizzle, Knex, and raw pg/mysql2 drivers. It parses your code into an AST with Tree-sitter so it can tell the difference between a safe tagged-template query and a dangerous string-concatenated one — a distinction regex scanners consistently get wrong.
What is SQL Injection?
SQL injection occurs when untrusted user input is concatenated directly into SQL queries, allowing attackers to read, modify, or delete database data. It remains one of the most common and dangerous web vulnerabilities — consistently in the OWASP Top 10.
Why It Matters
A single SQL injection vulnerability can give an attacker full read access to your database — user emails, hashed passwords, payment records, everything. In the worst case, they can escalate to write access and modify or delete data, or use stacked queries and database-specific features (like xp_cmdshell on SQL Server or COPY TO PROGRAM on PostgreSQL) to execute operating system commands on the database server itself.
What ShipSafe Detects
- ✓Raw SQL queries with string concatenation or template literals containing user input
- ✓ORM bypass patterns where raw queries are used alongside an ORM (e.g., Prisma $queryRawUnsafe with concatenation)
- ✓Parameterized query misuse (e.g., wrapping interpolated values in quotes inside Prisma tagged templates, which disables parameterization)
- ✓Dynamic table and column names derived from user input — ORDER BY and table name injection
- ✓Stored procedure calls with unsanitized parameters
- ✓Second-order SQL injection where data stored from one request is later used unsafely in a query
- ✓NoSQL injection patterns in MongoDB queries ($where, $gt, $regex with user-controlled objects)
Example: Vulnerable Code
Vulnerable Express.js route with SQL injection
// Vulnerable: user input directly in SQL query
app.get("/users", async (req, res) => {
const { search } = req.query;
const result = await db.query(
`SELECT * FROM users WHERE name = '${search}'`
);
res.json(result.rows);
});
// An attacker sends: search=' OR '1'='1' --
// The query becomes: SELECT * FROM users WHERE name = '' OR '1'='1' --'
// This returns ALL users in the database.ShipSafe Catches It
$ shipsafe scan
CRITICAL sql-injection/template-literal-in-query
src/routes/users.ts:4
User input from req.query is interpolated directly into SQL query.
Fix: Use parameterized queries — db.query("SELECT * FROM users WHERE name = $1", [search])What to Do Instead
Safe alternatives: parameterized queries with pg, Prisma, and Drizzle
// SAFE: parameterized query with pg driver
app.get("/users", async (req, res) => {
const { search } = req.query;
const result = await db.query(
"SELECT * FROM users WHERE name = $1",
[search]
);
res.json(result.rows);
});
// SAFE: Prisma tagged template (auto-parameterizes)
const users = await prisma.$queryRaw`
SELECT * FROM users WHERE name = ${search}
`;
// Prisma converts this to: SELECT * FROM users WHERE name = $1
// SAFE: Drizzle query builder
const users = await db
.select()
.from(usersTable)
.where(eq(usersTable.name, search));Frequently Asked Questions
Does ShipSafe detect SQL injection in Prisma?
Yes. ShipSafe detects unsafe Prisma patterns like $queryRawUnsafe with string concatenation while correctly ignoring safe parameterized Prisma queries. Prisma-specific exceptions were added in v1.0.4.
Can ShipSafe find SQL injection in template literals?
Yes. ShipSafe has specific rules for detecting user input interpolated into SQL template literals, including cases where quotes around interpolation disable parameterization in Prisma and Drizzle.
How many SQL injection rules does ShipSafe have?
ShipSafe has 127 SQL injection detection rules covering raw SQL, ORM bypass, template literals, dynamic table names, stored procedures, second-order injection, and NoSQL injection.
Does ShipSafe detect NoSQL injection in MongoDB?
Yes. ShipSafe detects NoSQL injection patterns in MongoDB queries where user-controlled objects are passed directly to query operators like $where, $gt, and $regex.
Detect SQL Injection in Your Code
Install ShipSafe and scan your project in under 60 seconds.
npm install -g @shipsafe/cli