SQL Injection Is Still the #1 Database Threat

SQL injection has been around for 25 years. It still works because developers still concatenate strings into queries.

··5 min read·By ismycodesafe.com Security Team
Comparison of vulnerable SQL string concatenation versus safe parameterized query with database icon

Key Takeaway

SQL injection happens when user input is concatenated directly into SQL queries. The fix is simple and absolute: use parameterized queries or prepared statements. Every modern database driver and ORM supports them.

How SQL Injection Works

Your application builds a SQL query by pasting user input directly into the query string. The attacker provides input that changes the query's structure. Adding conditions, unions, or entirely new statements.

Vulnerable code (Python):

# NEVER DO THIS
query = f"SELECT * FROM users WHERE email = '{email}'"
cursor.execute(query)

If the attacker enters ' OR '1'='1' -- as the email, the query becomes:

SELECT * FROM users WHERE email = '' OR '1'='1' --'

This returns every row in the users table. The -- comments out the rest of the query.

Attack Types

  • Classic (in-band). The attacker sees the query results directly in the response. Fastest to exploit.
  • Blind (boolean-based). The response changes based on whether the injected condition is true or false. Slower, but works when results aren't displayed.
  • Time-based blind. The attacker injects SLEEP(5) and measures response time. Works when there's no visible difference in output.
  • Union-based. The attacker appends a UNION SELECT to extract data from other tables. Can dump the entire database schema.
  • Stacked queries. Some database drivers allow semicolons to execute multiple statements. The attacker can DROP TABLE or INSERT admin accounts.

Real-World Damage

SQL injection has caused some of the largest data breaches in history. The OWASP SQL Injection page documents the attack vector. Some notable cases:

  • 2008: Heartland Payment Systems. 130 million credit card numbers stolen via SQLi
  • 2011: Sony PlayStation Network. 77 million accounts compromised
  • 2015: TalkTalk. 157,000 customer records, £400,000 fine

Parameterized Queries

The fix is straightforward. Parameterized queries (also called prepared statements) separate the SQL structure from the data. The database treats user input as a value, never as SQL code.

Python (psycopg2):

cursor.execute("SELECT * FROM users WHERE email = %s", (email,))

Node.js (pg):

await pool.query('SELECT * FROM users WHERE email = $1', [email]);

Python (SQLAlchemy):

result = session.execute(text("SELECT * FROM users WHERE email = :email"), {"email": email})

Every language and database driver supports parameterized queries. There is no valid reason to concatenate user input into SQL strings. See bobby-tables.com for examples in every language.

ORM Protection

Object-Relational Mappers (ORMs) like SQLAlchemy, Django ORM, Prisma, and TypeORM use parameterized queries internally. As long as you use the ORM's query builder, you're protected by default.

# Django. Safe by default
User.objects.filter(email=email)

# Prisma. Safe by default
await prisma.user.findMany({ where: { email } })

The danger comes when you bypass the ORM and write raw SQL. If you must use raw queries, use the ORM's parameterized raw query method. Never string concatenation.

Additional Defense Layers

  • Input validation. Reject unexpected characters. An email field should not contain single quotes or semicolons.
  • Least privilege. Your application's database user should only have the permissions it needs. A read-only endpoint should use a read-only database role.
  • WAF rules. A Web Application Firewall can catch common SQLi patterns. This is a defense-in-depth measure, not a replacement for parameterized queries.
  • Error handling. Never show database error messages to users. Stack traces expose table names, column names, and query structure.

The OWASP SQL Injection Prevention Cheat Sheet is the definitive reference.

Check your website right now

110 security checks in 60 seconds. Free, no signup required.

Scan My Website (Free)

ismycodesafe.com Security Team

We run automated security scans on thousands of websites daily, combining static analysis, SSL/TLS inspection, header auditing, and CVE lookups. Our team tracks OWASP, NIST, and evolving compliance requirements (GDPR, NIS2, PCI DSS) to keep these guides accurate and practical.