T09 · Insecure Skill Coding Practices
- Location
SKILL.md:33- Finding
SQL Injection Through Unvalidated Material Slug Substitution
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 33-46
Vulnerability Type: SQL injection
Risk Level: HighVulnerable Code
bash sqlite3 "$DB" \ "SELECT c.id, c.front, c.back, c.tags FROM cards c JOIN decks d ON d.id = c.deck_id JOIN materials m ON m.id = d.material_id WHERE m.slug = 'SLUG' ORDER BY CASE WHEN c.tags LIKE '%N3%' THEN 1 WHEN c.tags LIKE '%N2%' THEN 2 ELSE 3 END, RANDOM() LIMIT 5;"Technical Analysis
The Skill instructs the agent to replace
SLUGinside a quoted SQL statement. The material slug originates from the user's invocation, but the documented query does not use parameter binding or require validation of that value.If the agent performs direct textual substitution, a slug containing a single quote can terminate the intended SQL string. Additional SQL syntax may then alter the selection criteria or introduce additional statements supported by the SQLite command-line interface.
For example, a malicious value could close the string literal, append attacker-selected SQL, and comment out the remainder of the original query. The exact payload depends on how the agent constructs and submits the command, but the vulnerable trust boundary is the direct placement of user-controlled data into SQL source.
Attack Path
- An attacker invokes the Skill with a crafted material slug containing SQL metacharacters.
- The agent replaces the
SLUGplaceholder directly inWHERE m.slug = 'SLUG'. - The injected quote terminates the intended SQL literal.
- Attacker-provided SQL changes the query or adds another SQLite statement.
- The
sqlite3process executes the resulting SQL with the invoking user's access to the study database. - The attacker may disclose, modify, or delete records in
study.db, subject to database and filesystem permissions.
Impact Assessment
Successful exploitation coul ...[truncated 483 chars]
- Remediation
View remediation
Remediation Suggestions
- Store the requested slug in a separate value rather than substituting it into SQL source.
- Use SQLite parameter binding, such as a named
@slugparameter withWHERE m.slug = @slug. - Validate slugs against a strict allowlist before database access. If the intended slug format permits only letters, digits, underscores, and hyphens, enforce
^[A-Za-z0-9_-]+$. - Reject values containing quotes, SQL comments, statement separators, control characters, or characters outside the documented slug format.
- Open the database in read-only mode for this operation where feasible, limiting the impact of any query-construction error.
- Avoid asking an agent to construct executable SQL through placeholder replacement. Prefer a fixed helper script or structured database API that binds parameters automatically.
