T09 · Insecure Skill Coding Practices
- Location
scripts/pgsql_skill.py:162- Finding
SQL Safety Validation Can Be Bypassed with Multiple Statements and Comment Tokens
- Content
View full analysis
Optional[str]: """Validate SQL for safety""" import re upper = sql.strip().upper() first_word = upper.split()[0] if upper.split() else "" # Forbidden operations for forbidden in ("DROP", "TRUNCATE", "ALTER"): if re.match(rf"^{forbidden}\b", upper): return f"Forbidden operation: {forbidden}" # Only allow SELECT/INSERT/UPDATE/DELETE if first_word not in ("SELECT", "INSERT", "UPDATE", "DELETE"): return f"Unsupported operation: {first_word} (only SELECT/INSERT/UPDATE/DELETE allowed)" # INSERT: single row only if first_word == "INSERT": values_count = len(re.findall(r"\bVALUES\b", upper)) if values_count != 1: return "INSERT must contain exactly one VALUES clause" # Check for multiple value groups values_pos = upper.index("VALUES") after_values = upper[values_pos + 6:] paren_groups = re.findall(r"\([^)]+\)", after_values) if len(paren_groups) > 1: return "INSERT allows only single row insertion" # UPDATE/DELETE: must have WHERE if first_word in ("UPDATE", "DELETE"): if not re.search(r"\bWHERE\b", upper): return f"{first_word} must include WHERE clause to prevent full table operation" return None ``` ### Technical Analysis The validator treats untrusted SQL as plain text rather than parsing its statement structure. It only checks the first keyword for forbidden operations and does not establish that the input contains exactly one statement. The accepted string is subsequently passed directly to `cursor.execute()`. Consequently, a str ...[truncated 2068 chars]- Remediation
View remediation
