T09 · Insecure Skill Coding Practices
- Location
SKILL.md:430- Finding
SQL Injection Through Direct String Interpolation
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 430–449
Vulnerability Type: SQL injection
Risk Level: MediumVulnerable Code
python # DAU query def get_dau(date): query = """ SELECT COUNT(DISTINCT user_id) FROM user_behavior WHERE event_date = '{date}' AND event_type IN ('view', 'search', 'add_cart', 'order') """ return execute_query(query) # GMV query def get_gmv(start_date, end_date): query = """ SELECT SUM(order_amount) FROM orders WHERE order_status IN ('paid', 'shipped', 'completed') AND payment_status = 'success' AND order_date BETWEEN '{start_date}' AND '{end_date}' """ return execute_query(query)Technical Analysis
The example constructs SQL statements by directly interpolating the
date,start_date, andend_datearguments into query text. No parameter binding, strict date parsing, or allowlist validation is shown.If an application copies this implementation and passes attacker-controlled values to these functions, crafted input can terminate the intended string literal and append SQL syntax. The resulting statement is then passed to
execute_query()under the application's database identity.The exact exploit syntax and whether stacked statements are possible depend on the database engine, driver, and
execute_query()implementation. Even where multiple statements are disabled, an attacker may still be able to modify predicates, bypass intended date constraints, or extract data through union-, error-, or time-based techniques.Attack Path
- An application adopts the documented query implementation.
- A date argument becomes controllable through an API parameter, form field, generated Agent input, or another untrusted source.
- An attacker supplies a value containing a quote and additional SQL syntax.
- Direct interpolation incorporates that syntax into the SQL statement.
execute_query()submits the modified query to the datab ...[truncated 798 chars]
- Remediation
View remediation
Remediation Suggestions
Use database-driver parameter binding instead of inserting values into SQL text:
python def get_dau(date): query = """ SELECT COUNT(DISTINCT user_id) FROM user_behavior WHERE event_date = %s AND event_type IN ('view', 'search', 'add_cart', 'order') """ return execute_query(query, (date,)) def get_gmv(start_date, end_date): query = """ SELECT SUM(order_amount) FROM orders WHERE order_status IN ('paid', 'shipped', 'completed') AND payment_status = 'success' AND order_date BETWEEN %s AND %s """ return execute_query(query, (start_date, end_date))The placeholder syntax must be adapted to the actual database driver, such as
?,%s,$1, or named placeholders.Additional hardening should include:
- Parse all incoming dates into strict date or datetime objects before database use.
- Reject malformed values rather than attempting to sanitize SQL fragments.
- Ensure
execute_query()accepts query parameters separately and never performs string formatting internally. - Run queries through a least-privileged, preferably read-only database account.
- Disable stacked statements and unnecessary database capabilities where supported.
- Add tests containing quotes, SQL metacharacters, comments, and malformed dates to verify that inputs remain data rather than executable SQL.
- Clearly label documentation snippets as secure production patterns so generated implementations do not reproduce unsafe interpolation.
