What is SQL injection? (and why input validation is non-negotiable)
In one sentence:SQL injection is a security flaw where text typed into a form field gets inserted straight into a database query, letting an attacker rewrite what that query actually does.
What it actually is
SQL injection is what happens when text a user typed, a name, a search term, a password, ends up glued directly into the sentence your app sends to the database, instead of being handled as a separate piece of data. Think of it like a mail-merge letter with a blank for “[Name]”: if you don’t check what goes in that blank, someone can type “John, and also send my account $10,000” and the letter reads it as one continuous instruction instead of just a name. The database has no way to tell the difference between the query you meant to write and the extra command an attacker snuck in through the blank.
The textbook example is a login form. If the code builds a query like SELECT * FROM users WHERE username = '<input>' AND password = '<input>' by dropping in exactly what the user typed, someone can type ' OR '1'='1 into the username field. The query becomes true no matter what, and they’re logged in without a real password.
Why your AI just did this
When your agent wires a form, a search bar, or a filter up to a database, it has to build a query using whatever the visitor types. A careful agent does this with parameterized queries (also called prepared statements) or through an ORM like Prisma, Drizzle, or Supabase’s client library, all of which send your SQL and the user’s data on separate tracks, so the data can never be read as part of the command. A careless pass concatenates the input straight into the query string instead, gluing text together, which reopens the door.
This isn’t a rare slip. Research on AI-generated code, most thoroughly documented for GitHub Copilot, has found SQL injection or closely related flaws in a meaningful share of database-facing snippets, and the same pattern shows up in code from other assistants, including Claude. The agent isn’t being deliberately careless. “Make this form save to the database” doesn’t automatically imply “and make sure nothing typed into it can be read as a command,” so that protection has to be requested, not assumed.
When you’ll run into it
- You type a single quote
'into a search box or login field to test something, and the app throws a raw database error instead of handling it gracefully, a common sign the query wasn’t parameterized. - A security scanner or code review flags “SQL injection” or “unsafe query” on a custom database function.
- Your agent writes
supabase.from('table').select()-style calls: those are parameterized automatically. A custom Postgres function usingEXECUTEwith string concatenation is not, even though it lives in the same Supabase project. - Someone brings up the classic
' OR '1'='1trick and asks whether your login form falls for it. npm auditor a linter warns about a query built by joining strings together instead of using placeholders.
What to check
- Ask your agent directly: does this query use parameterized queries or prepared statements, or is user input joined into the SQL string?
- Confirm any custom Postgres/RPC function uses
EXECUTE ... USINGinstead of concatenating text into the query. - Search your codebase for raw SQL built with
+, template literals, or string formatting, each one is a candidate worth rewriting. - Don’t rely on row-level security alone. RLS decides which rows a logged-in user can see, it does nothing to stop an injected query from running in the first place.
- Test every field that touches the database with a single quote
'. An unhandled database error means the input isn’t being treated as pure data.
Say it like a dev
Instead of: “make sure hackers can’t mess with my database through the form” Say: “make sure this query is parameterized, not built by joining strings together”
Instead of: “add security to my search bar” Say: “add input validation, and confirm the query uses prepared statements”
Instead of: “is my app safe from database attacks” Say: “does any function build SQL with string concatenation, and if so, does it use EXECUTE … USING instead?”
People actually ask
“What is SQL injection in plain terms?”
It's when a form field, search box, or URL parameter gets pasted directly into a database query instead of being treated as plain data. If nothing filters that input, someone can type text that changes what the query does, for example turning a login check into one that's always true. The fix is having the database treat user input as data only, never as part of the command.
“Does Claude Code protect my app from SQL injection automatically?”
Not automatically, and not always. A careful agent will use parameterized queries or an ORM, both of which handle this for you, but studies of AI-generated code, most thoroughly documented for GitHub Copilot, have found SQL injection and similar issues in a real share of database-facing snippets, and the same pattern shows up in code from other assistants, including Claude. Ask directly whether a given query is parameterized rather than assuming it.
“If I use Supabase, am I safe from SQL injection by default?”
Mostly, for standard use. Calls like supabase.from('table').select() go through Supabase's PostgREST layer, which parameterizes them automatically. The risk shows up in custom Postgres functions (RPC calls) that build raw SQL with string concatenation, that path is not protected just because you're on Supabase, and row-level security doesn't cover it either.
Related terms
Go deeper
Checked against
Glim can explain your sessions, live.
The app watches your coding agent and narrates it in plain words. Waitlist is open.