Catching a SQL injection a single-agent missed
A pull request adds a search endpoint. The author tested manually with safe inputs. A single-agent reviewer flagged style. Warden flagged the actual vulnerability.
// src/api/search.ts
+ app.get("/search", async (req, res) => {
+ const term = req.query.q as string
+ const sql = `SELECT id, title FROM docs WHERE title LIKE '%${term}%'`
+ const { rows } = await pg.query(sql)
+ res.json(rows)
+ })req.query.q is concatenated directly into the SQL string on line 3. Any client can pass '%' OR 1=1; -- and dump the table. Use the parameterized form already established in authService.ts:pg.query(`SELECT id, title FROM docs WHERE title LIKE $1`, [`%${term}%`])LIKE '%term%' with a leading wildcard can't use a B-tree index. For the docs table's ~120K rows this is fine; if it grows past 1M, switch to a pg_trgm GIN index or a dedicated FTS column.Takeaway
A single-agent reviewer caught nothing critical here. Warden owns security; the bug surfaces in the first pass — not the third revision.