DEV Community

CopperSunDev
CopperSunDev

Posted on • Originally published at coppersun.dev

What's the Cost of a SQL Injection in AI-Generated Code?

SQL injection caught at commit time costs seconds. The same finding caught in production — or after active exploitation — costs engineering weeks.

The gap is structural. Without a scanning gate at commit time, a SQL injection bug lives in your codebase until a penetration test, a security audit, or an incident surfaces it. That window is typically weeks to months. During that window, the code runs against a real database with real credentials.

When the vulnerability surfaces (or is suspected after an incident), the repair scope expands well past the code fix itself. The parameterized-query patch takes minutes. What follows doesn't:

  • Log audit: Query logs must be reviewed to determine whether the injection path was ever triggered, and by what inputs.
  • Credential rotation: If the database was reachable during the exposure window, you cannot determine without forensic analysis whether credentials were exfiltrated — so rotation is the default safe action.
  • Compliance notification: If the database held regulated data (PII, health records, or payment data), most jurisdictions require breach notification within a defined window. The notification cycle spans person-weeks across legal, engineering, and communications.

BrassCoders catches the Bandit B608 rule at commit time, in the OSS core. The scan makes zero outbound network calls and completes in under a second. B608 fires on string-formatting operations interpolated directly into SQL query strings. The pattern that triggers it:

# B608 fires here — caller-supplied value interpolated into the query string
query = f"SELECT * FROM users WHERE name = '{name}'"
Enter fullscreen mode Exit fullscreen mode

The parameterized fix eliminates the interpolation entirely:

cursor.execute("SELECT * FROM users WHERE name = ?", (name,))
Enter fullscreen mode Exit fullscreen mode

The database driver sends the query structure and the value as separate arguments. No input can alter the query's structure, because the structure is fixed before the value arrives.

BrassCoders emits the B608 finding with severity HIGH, the file path, and the line number in .brass/ai_instructions.yaml. Claude Code or Cursor reads that file and generates the parameterized version from the flagged line. The finding is deterministic — same commit, same output, every scan — which makes a CI gate on it reliable: the finding either appears or it doesn't.

Adding brasscoders scan to a GitHub Actions or GitLab CI step catches B608 before any branch merges. The OSS core is free. The full ready-made workflow is in the BrassCoders open-source repository at github.com/CopperSunDev/brasscoders. The cost of running it is a few seconds per commit. The cost of not running it is measured in the engineering hours described above.

Top comments (0)