T09 · Insecure Skill Coding Practices
- Location
SKILL.md:14- Finding
SQL Injection Through Unsafe Interpolation of Meeting Data
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 14–27
Vulnerability Type: SQL injection caused by direct interpolation of user-controlled data
Risk Level: HighVulnerable Code
bash psql "$DATABASE_URL" -c " INSERT INTO team_meetings (title, summary, attendees, meeting_date, created_at) VALUES ('TOPIC', 'SUMMARY', ARRAY['ATTENDEE1','ATTENDEE2'], NOW(), NOW()) RETURNING id;"bash psql "$DATABASE_URL" -c " INSERT INTO meeting_action_items (meeting_id, assignee, description, due_date, status, created_at) VALUES (MEETING_ID, 'ASSIGNEE', 'TASK DESCRIPTION', 'DUE_DATE', 'pending', NOW());"Technical Analysis
The skill instructs the agent to extract the meeting topic, summary, attendees, action-item assignees, descriptions, and due dates from user-supplied text and place them directly into SQL statements passed to
psql -c.No parameter binding, type enforcement, or SQL-literal escaping is specified. A malicious value containing a single quote and additional SQL syntax could terminate its intended literal and alter the command. The same weakness affects several fields, including
TOPIC,SUMMARY, attendees,ASSIGNEE,TASK DESCRIPTION, andDUE_DATE. Improper handling ofMEETING_IDcould also permit SQL manipulation because it is inserted as an unquoted expression.Although the SQL is enclosed in a shell string, the primary confirmed issue is SQL injection into PostgreSQL rather than shell command injection. The achievable result depends on the privileges of the database role referenced by
DATABASE_URL.Attack Path
- An attacker submits meeting content containing a crafted value in a parsed field, such as the title, summary, attendee name, assignee, task description, or due date.
- The agent extracts the malicious content and substitutes it into one of the documented SQL templates.
- The agent invokes
psql "$DATABASE_URL" -cwith the resulting SQL text. - PostgreSQL interprets the injected syntax ...[truncated 1102 chars]
- Remediation
View remediation
Remediation Suggestions
- Replace generated SQL strings with a trusted PostgreSQL client that supports prepared statements and bound parameters.
- Bind every user-derived value, including titles, summaries, attendee names, assignees, descriptions, and due dates.
- Treat
meeting_idas a typed integer obtained directly from the preceding insert result; do not accept or interpolate it from user input. - Parse and validate due dates against an explicit date format before database insertion.
- Pass attendees as a properly typed PostgreSQL array parameter rather than constructing an array literal manually.
- If
psqlis unavoidable, use PostgreSQL-safe variable mechanisms with explicit literal handling instead of concatenating content into SQL. Prepared statements in an application client remain preferable. - Execute the skill under a dedicated least-privilege database role restricted to the required
INSERTand necessarySELECToperations onteam_meetingsandmeeting_action_items. - Deny schema modification, role administration, extension installation, and access to unrelated tables.
- Add adversarial tests covering quotes, semicolons, SQL comments, Unicode edge cases, malformed dates, and oversized input.
- Use transactions so that meeting and action-item creation succeeds or fails atomically, reducing inconsistent records when validation or insertion fails.
