T09 · Insecure Skill Coding Practices
- Location
scripts/db_core.py:648- Finding
SQL Policy Bypass Through Stacked Statements
- Content
View full analysis
str: """Return the SQL operation level: READ / DML / DDL / BLOCKED.""" s = stripped_sql.upper() for p in _BLOCKED_PREFIXES: if s.startswith(p): return "BLOCKED" for p in _DDL_PREFIXES: if s.startswith(p): return "DDL" for p in _DML_PREFIXES: if s.startswith(p): return "DML" for p in _READ_PREFIXES: if s.startswith(p): return "READ" return "BLOCKED" ``` ```python # scripts/query.py:395-399 op_type = validate_sql(args.sql, args.db_alias, env, args.config, dry_run=args.dry_run) sql = args.sql.strip() is_write = op_type in ("DML", "DDL") ``` ```python # scripts/db_core.py:153 cursor.execute(sql) ``` ### Technical Analysis The normal query path classifies the complete SQL string solely by its initial keyword. It does not parse the input into statements or require that the input contain exactly one statement. An input beginning with `SELECT` is therefore classified as `READ`, even if it contains a second DML or DDL statement after a semicolon. The original, unmodified string is subsequently passed to `cursor.execute()`. This bypasses controls that only run when `is_write` is true: - `readonly: false` authorization for DML - `allow_ddl: true` authorization for DDL - DELETE and UPDATE WHERE-clause validation - Dry-run handling - Production write confirmation - Write-operation log ...[truncated 1585 chars]- Remediation
View remediation
