SQL injection (SQLi) happens when user input is concatenated into SQL strings instead of passed as bound parameters. An attacker submits input that closes the original query and adds their own: '; DROP TABLE users; --. The database executes both. SQLi can leak data (read tables the user should not see), modify data (update prices, escalate roles), or destroy data. It is one of the oldest and best-known web vulnerabilities, and it still happens regularly.
The fix is parameterized queries (also called prepared statements). Instead of "SELECT * FROM users WHERE id = " + userId, write "SELECT * FROM users WHERE id = ?" and pass userId as a separate argument. The database driver handles escaping, and there is no string concatenation that could be exploited.
Modern ORMs (Sequelize, Prisma, SQLAlchemy, Django ORM) use parameterized queries by default. SQLi in 2026 mostly happens in: legacy code with hand-built queries, raw SQL escapes inside ORMs, dynamic schema (table or column names that can not be parameterized), and stored procedures called with concatenated arguments.
SQL injection has been on the OWASP Top 10 for two decades and continues to cause data breaches every year. The fix is well-known and easy; the failure mode is "I forgot just this once".
Parameterized queries are part of the broader topic in the API security article.