⬡
Enterprise Portal
Authorized personnel sign-in system
💡 Presenter Helper: Load SQLi payload
SQL Injection Lab Analysis
Vulnerable ModeIn Vulnerable mode the SQL query is built by raw string concatenation; in Secure mode it uses bound parameters (prepared statements). Compare both modes below to see how parameterization stops the attack.
Interactive Query Simulator
SQL query sent to database
query.sql
Run a login to see the constructed query…
Database response
No query run yet.
Vulnerability status
—
How the attack works (Attack Flow)
1. Input' OR '1'='1' --
→
2. ConcatenationGlued directly into SQL string
→
3. Always-trueWHERE matches every row
→
4. BypassLogged in as first record (Admin)
1. Input' OR '1'='1' --
→
2. Bound paramSent as literal data, not SQL code
→
3. Literal matchNo username equals the raw text
→
4. NeutralizedZero rows returned · login denied
Educational Deep-Dive
What is SQL Injection?
SQL Injection (SQLi) occurs when untrusted user input is concatenated directly into a database query string.
The database SQL parser cannot distinguish between the programmer's SQL commands and the attacker's input, allowing the input to alter the structure and logic of the SQL statement.
Step-by-step: How did the bypass happen?
The application constructs the query like this:
When the attacker enters
f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"
When the attacker enters
' OR '1'='1' --:
- The leading single quote (
') closes the string literal for the username. - The
OR '1'='1'condition evaluates to TRUE for every single row in the database. - The double-dash (
--) comments out the rest of the query, completely eliminating the password check. - The database returns the entire users table; the application takes the first row (the admin account) and establishes an authenticated session.
How Parameterized Queries prevent this completely
Parameterized queries (prepared statements) separate code from data:
The database pre-compiles the query template with placeholders (
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))
The database pre-compiles the query template with placeholders (
?). When the driver sends ' OR '1'='1' --, it treats it strictly as a literal text string. The database searches for a user whose literal username is ' OR '1'='1' --, finds none, and denies authentication.
Industry Best Practices & Prevention
- Always use Parameterized Queries or ORMs (e.g. SQLAlchemy, Prisma, Hibernate) for all database operations.
- Principle of Least Privilege: Database accounts should only have permissions required for their specific role.
- Input Validation & Type Checking: Reject unexpected characters before database queries are formed.
- Never build queries via string concatenation or f-strings.