warming up your workspace

SQL injection explained safely with a toy login

SQL injection has been at or near the top of web vulnerability lists for two decades, and yet it is genuinely easy to understand once you see it happen. The safe, legal way to learn it is on a toy login you build yourself: watch it break, then fix it properly. This article is about defense, not attacking anyone's system.

How the bug happens

Imagine a login that builds its query by gluing user input into a string:

# VULNERABLE, do not do this
query = f"SELECT * FROM users WHERE name = '{username}' AND pw = '{password}'"

The problem is that the input is treated as part of the SQL, not as data. If someone types this as the username:

admin' --

the query becomes:

SELECT * FROM users WHERE name = 'admin' --' AND pw = '...'

The -- comments out the password check, and they are logged in as admin without knowing the password. The input changed the structure of the query. That is injection.

Why string-building is the root cause

The vulnerability is not really about SQL; it is about mixing code and data in the same string. Whenever untrusted input can change the meaning of a command (SQL, shell, HTML), you have an injection class of bug. SQL injection is just the most famous member.

The fix: parameterized queries

The correct fix is to never build queries by concatenation. Use parameterized queries (also called prepared statements), where the database is told the query structure separately from the values:

# SAFE
cur.execute(
    "SELECT * FROM users WHERE name = ? AND pw = ?",
    (username, password),
)

Now admin' -- is treated as a literal username string, searched for, and not found. The input can never change the query's structure, because structure and data travel separately. This single habit eliminates the entire vulnerability class.

The other half: validation and least privilege

Parameterized queries are the core fix, but defense in depth helps: validate input (a username should not be 5,000 characters), hash passwords properly so a leaked table is not catastrophic, and give the database account only the permissions it needs so a breach is contained.

Learn it by building both sides

Understanding the attack from the inside is what makes the defense stick. The cybersecurity track covers web security, including building a vulnerable endpoint and then securing it, plus the crypto and forensics around it, all run safely in your browser. The first project is free.

See injection happen once on your own toy app, and parameterized queries stop being a rule you follow and become a thing you understand.