This article describes an interactive lab demonstrating SQL injection through a vulnerable login page that concatenates user input directly into SQL queries. The lab teaches how attackers can bypass authentication by injecting SQL syntax—specifically using quotes and comments—to alter query logic without knowing credentials. SQL injection remains prevalent in real-world applications and appears in major breaches, making this a foundational vulnerability that every security learner should understand.
- How the vulnerable login query worksMiniMail builds its login query through string concatenation: SELECT * FROM users WHERE username='[your input]' AND password='[your input]'. User input sits directly inside single quotes within the SQL code, meaning the database cannot distinguish between developer-written SQL and attacker-supplied input once the string is assembled.
- The injection attack mechanismAn attacker enters a single quote in the username field to close the developer's quote early, followed by a SQL comment marker (two dashes and a space). This transforms the query to match the admin user while the comment syntax causes the database to ignore the password check and remaining query text, allowing login without credentials.
- Why string concatenation causes the vulnerabilityThe core problem is that user input is joined into a single string with SQL code before the database processes it. Once combined, the database cannot tell which characters are intended as data versus SQL commands, allowing an attacker's quote to end strings and their comments to remove logic the developer wrote.
- Real-world impact and prevalenceSQL injection has driven some of the largest breaches on record and remains in the OWASP Top 10. A 2023 example involved SQL injection in MOVEit Transfer file-sharing product, which was exploited at mass scale and affected thousands of organizations, demonstrating the vulnerability's continued practical relevance.
- Parameterised queries as the primary defenseThe article identifies parameterised queries (prepared statements) as the real fix, sending user input as parameters separate from SQL code rather than concatenating strings. Using an ORM or query builder correctly, without raw string queries, also provides protection, whereas blocklists of quotes or keywords are unreliable because attackers can bypass them.
- Additional security measuresRunning the database account with least privilege provides secondary defense by limiting what an attacker can do even if injection succeeds. However, the article emphasizes this is not a replacement for proper input handling.
- Connection to other injection vulnerabilitiesThe article notes that understanding SQL injection transfers directly to prompt injection, suggesting the underlying principle—user input altering code logic—applies across different contexts and attack surfaces.
Bottom line: SQL injection remains a critical vulnerability because developers concatenate user input into SQL queries, allowing attackers to alter query logic using quotes and comments rather than knowing actual credentials. The definitive defense is using parameterised queries so input always stays data, never code—a principle that also applies to preventing prompt injection and other injection attacks.
📋 In this walkthrough
What this lab teaches
SQL injection happens when user input becomes part of a database query’s code instead of staying data. Once that happens, the attacker can change what the query means, not just what it searches for.
How MiniMail's login works
The login builds a query by string concatenation, roughly:
SELECT * FROM users WHERE username='[your input]' AND password='[your input]'If a row comes back, you are logged in as that user. The lab is solved when you are logged in as admin.
The attack approach
- Your input sits inside single quotes. A quote of your own closes that string early.
- After closing it, you are writing SQL. Your goal is to make the WHERE clause match the admin row without checking the password.
- SQL comments make the database ignore the rest of the line, including the password check.
Full walkthrough (spoiler)
Stuck after a few attempts? Open the steps below. Solving it yourself first is worth more XP, and more learning.
Show the step-by-step solution
- In the username field, type the admin username, then a single quote to close the string, then a SQL comment marker (two dashes and a space).
- Type anything as the password.
- The query becomes “find the user called admin”, and everything after the comment, including the password check, is ignored. You are logged in as admin.
Why it works
The database cannot tell which characters came from the developer and which came from you, because they were joined into one string before it ever saw them. Your quote ended their string; your comment deleted their password check.
Where this happens in the real world
SQL injection has driven some of the largest breaches on record, and injection still sits in the OWASP Top 10. In 2023 a SQL injection in the MOVEit Transfer file-sharing product was exploited at mass scale, affecting thousands of organisations.
How to defend against it
- Use parameterised queries (prepared statements) everywhere. This is the real fix.
- Use an ORM or query builder correctly, without raw string queries.
- Run the database account with least privilege.
- Do not rely on blocklists of quotes or keywords; they get bypassed.
Try it, then go further
Reading about it is the easy part. Open the lab, try your own phrasing before peeking at the spoiler, and see how many attempts it takes.
