From afa5651e9fcd082ebdc6e8e21189ab491bed7234 Mon Sep 17 00:00:00 2001 From: Cedrick Cantero Date: Sun, 13 Sep 2026 03:15:37 +0800 Subject: [PATCH] fix(skills): avoid a literal $1 placeholder in the security-review sql example Invoking this skill with arguments substitutes a literal $1 away, so the "ALWAYS Use Parameterized Queries" example renders as 'SELECT * FROM users WHERE email = attacks' for `/security-review also attacks` -- concatenated SQL, which is exactly the anti-pattern the section above it warns against. The one place the skill must be unambiguous is the one place argument substitution rewrites. Switches the raw-SQL example to "?" and names the Postgres numbered form in prose, so the lesson is unchanged and no substitutable token is left. Adds a comment so the placeholder is not reintroduced. --- skills/security-review/SKILL.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/skills/security-review/SKILL.md b/skills/security-review/SKILL.md index 0846d70a1..3f26b0df6 100644 --- a/skills/security-review/SKILL.md +++ b/skills/security-review/SKILL.md @@ -124,13 +124,20 @@ const { data } = await supabase .select('*') .eq('email', userEmail) -// Or with raw SQL +// Or with raw SQL -- the value goes in the params array, never in the +// string. Use your driver's placeholder syntax (Postgres numbers its +// placeholders, MySQL uses "?"). await db.query( - 'SELECT * FROM users WHERE email = $1', + 'SELECT * FROM users WHERE email = ?', [userEmail] ) ``` + + #### Verification Steps - [ ] All database queries use parameterized queries - [ ] No string concatenation in SQL