Chapter 3 of 8 · 4 checks · 2 min
Injection (A05)
Injection happens when user input is treated as part of a query or command. These checks keep data and code apart.
Use parameterized queries for every SQL statementMust
Why it matters and how to check
String concatenation in SQL is still the classic injection bug. Use your driver's placeholders or an ORM query builder so values are sent separately from the query text. Where you must build dynamic parts, such as a sort column, map user input to a fixed allowlist of column names.
To verify, search the codebase for template strings or
+nearSELECT,INSERT,UPDATEandORDER BY, and for raw query helpers. Then send a single quote and' OR '1'='1in every search box and filter. You should see normal "no results" behaviour, never a database error or extra rows.Example
TypeScript // Values travel separately from the SQL text const { rows } = await pool.query( 'SELECT id, title FROM posts WHERE author_id = $1 AND status = $2', [userId, status] );Reject objects where you expect strings in NoSQL queriesMust
Why it matters and how to check
With MongoDB and similar stores, the risk is operator injection: a JSON body like
{"email": {"$ne": null}}turns an equality check into "match anything". This bypasses login forms and filters when request fields go straight into a query.Validate the type of every field before it reaches the database, and cast ids and strings explicitly. To verify, send a login request whose email or password is an object containing
$neor$gt. It must fail validation with a 400, not sign you in or return a list.Never pass user input to a shellMust
Why it matters and how to check
Functions that run a command through a shell, like
execin Node oros.systemin Python, will run anything after a;or&&. If you need to call a program, use the form that takes the program and an argument array with no shell, and validate the arguments against an allowlist.To verify, search for
exec(,execSync,shell=True,system(and backtick command strings in server code. For each hit, confirm no request data reaches it, or that it usesexecFileorspawnwith an argument array.Validate every request body against a schema on the serverShould
Why it matters and how to check
Schema validation is not a replacement for parameterized queries or output encoding, but it removes whole classes of surprises: wrong types, unexpected fields, huge strings and mass assignment of fields like
role. Define a schema per endpoint, reject unknown keys, and set maximum lengths.To verify, pick five write endpoints and send a body with an extra field, a number where a string belongs and a 1 MB string. Each should return a 400 with a short message, and none of the extra data should appear in the database afterwards.