What is SQL injection, and how do you prevent it?
Quick Answer
SQL injection is when attacker-controlled input is concatenated into a SQL string and changes the query's meaning — e.g. ' OR 1=1 -- to bypass a filter, or a stacked ; DROP TABLE. Prevent it with parameterised queries (the data is sent separately from the SQL), which every ORM and SqlCommand supports. Least-privilege DB accounts and input validation are defence in depth, not the primary fix.
SQL injection is when user input gets concatenated into a query and changes what the query does — the textbook example is entering ' OR '1'='1 into a login form to make the WHERE clause always true. The fix is parameterised queries: you send the SQL and the values separately, so the database treats the input purely as data and never as part of the command. Every ORM and SqlCommand does this. On top of that I'd run the app under a database account with minimal permissions and not leak raw errors, but parameterisation is the actual defence. Stored procedures aren't a magic shield — one that builds dynamic SQL from its inputs is still vulnerable.
- Primary fix: never build SQL by string concatenation with user input. Use
SqlParameter, Dapper parameters, EF (which parameterises), orsp_executesql. - Parameterisation works because the value is bound as data —
' OR 1=1becomes a literal string to search for, not code. - Dynamic identifiers (column/table from input) can't be parameterised — whitelist them.
- Defence in depth: app connects with a low-privilege account (no DDL, no
xp_cmdshell); validate input length/format; don't expose raw DB errors. - Stored procedures are not automatically safe — a proc that builds dynamic SQL from its parameters is still injectable.