T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:532- Finding
Unescaped SQL Export Enables SQL Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/script.sh, lines 532–534
Vulnerability Type: SQL injection through unsafe SQL statement generation
Risk Level: HighVulnerable Code
python cols = ", ".join(fields.keys()) vals = ", ".join(f"'{v}'" if isinstance(v, str) else str(v) for v in fields.values()) f.write(f"INSERT INTO {table} ({cols}) VALUES ({vals});\n")Technical Analysis
The SQL export feature constructs executable
INSERTstatements by directly concatenating untrusted table names, field names, and fixture values.String values are enclosed in single quotes without escaping embedded quotes. Column names are joined without identifier validation or quoting, while the user-controlled
--tablevalue is interpolated directly into each statement. Fixture content can originate from thecreate,load, orimportcommands, including external JSON, JSONL, and CSV files.For example, a field value such as:
text x'); DROP TABLE users; --can terminate the intended string and append an attacker-controlled SQL statement. Malicious table or column names may provide additional injection vectors. The generated SQL file therefore cannot safely be treated as executable database input.
Attack Path
- An attacker prepares a JSON, JSONL, or CSV fixture containing a malicious field name or value.
- A victim loads or imports that fixture using the documented CLI functionality.
- The victim exports the stored fixtures with
export --format sql. - Lines 532–534 place the attacker-controlled content into the SQL output without escaping or validation.
- The victim executes the generated SQL file against a database.
- The injected SQL runs with the privileges of the database account used for the import.
The same issue can be triggered directly through attacker-controlled arguments, particularly the
--tableoption.Impact Assessment
Successful exploitation can execute arbitrary SQL with the permissions of the ...[truncated 457 chars]
- Remediation
View remediation
Remediation Suggestions
- Do not generate SQL through direct string concatenation of identifiers or values.
- Validate table and column names against a strict allowlist or identifier pattern, such as
^[A-Za-z_][A-Za-z0-9_]*$. - Quote identifiers using rules appropriate to the selected database dialect.
- Escape string literals correctly for the target database, including embedded quote characters.
- Serialize
NULL, boolean, numeric, date, and binary values explicitly rather than relying on Python's genericstr()conversion. - Prefer generating parameterized import code or using a database driver with bound parameters when statements can be executed directly.
- If standalone SQL output is required, require an explicit database dialect and use a trusted dialect-aware SQL generation library.
- Add regression tests covering apostrophes, statement delimiters, SQL comments, malicious table and column names, Unicode, null values, and database-specific escaping behavior.
- Clearly warn users not to execute generated SQL from untrusted fixture data until it has been reviewed.
