Login
ChallengesLearn
Scoreboard
Teams
Profile

Preferences

Truesapiens

LearnSQL InjectionSQL Injection: Authentication bypass
SQL Injection·Lesson 4 of 20

SQL Injection: Authentication bypass

Skip the login form entirely. How a single apostrophe turns "wrong password" into "welcome, admin" - and why the cascade is worse than the bypass itself.

Intermediate16 min
SQLiAuthBypass
Loading lesson…
PreviousSQL Injection: Why it's possibleNextSQL Injection: Comment injection

© 2026 Truesapiens.

Terms of ServicePrivacy PolicyCookie Policy

Login forms are the highest-value target on a web application. They sit at the one chokepoint that protects every account, and the logic that powers them is a single database query. If that query is vulnerable, the rest of the application is irrelevant - the attacker is already inside as the most privileged user in the table.

What you'll be able to do
  • Construct the canonical ' OR 1=1 LIMIT 1-- payload and explain each token.
  • Trace the cascade from a single SQLi to full application compromise.
  • Distinguish between string-concat password checks and application-code password checks.
  • Re-verify role on every page request, not just on login.
Key terms
CWE-287
Improper Authentication - when an application fails to verify, or incorrectly verifies, the identity of a user.
Hash in app code
Pattern where the database stores a password hash and the application retrieves it, then calls a constant-time verification function (argon2.verify, bcrypt.compare) to compare against the user-supplied password.
Role re-verification
The discipline of re-checking the user's role on every authorisation-sensitive page, rather than trusting a role flag stored in a session or in the login response.
What is it?

Skipping the door, walking through the wall

An authentication bypass is a SQL injection payload that turns a failed login into a successful one. The classic form appends a clause that always evaluates to true: ' OR 1=1 LIMIT 1-- . The single quote terminates the password string, the OR clause makes the WHERE true, LIMIT 1 returns a single row so the application does not crash on iterating the result set, and the double-dash comments out the trailing quote. The application reads the first row, looks up its role, and grants access - usually to admin.

What makes the bypass devastating is the cascade. Once the attacker is logged in as admin, every other security control in the application is downstream of the database role. They can list users, change passwords, view payment data, and read audit logs. A single SQLi in the login form escalates to full application compromise in one HTTP request.

Authentication bypass flow
Mini Map
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.
Try it

Walk through the full attack chain

The sandbox is a two-step flow. Step 1 is the login form - type the bypass payload to skip authentication. Step 2 is the admin dashboard that opens after a “successful” login. Notice that the dashboard has no additional access checks because it trusts the role flag set during login.

prodacme-portal.app/auth/login
acme-portal
Sign in to admin panel vulnerable
Bypass payload - any username + password ' OR 1=1 LIMIT 1--
Real-world relevance

The first move of every breach

Authentication bypasses are the opening move in a large fraction of the breaches that make the news. The attacker finds a SQLi in a login or password-reset form, gets logged in as admin, then uses the application's own admin tools to walk out with the data. The breach looks like legitimate use of the admin panel - the audit trail shows a successful login and a series of authorized reads, which is exactly what an attacker wants defenders to see.

The 2015 TalkTalk breach in the UK followed this pattern almost exactly: a 15-year-old attacker found a SQLi in a publicly accessible form, walked in as an admin user, and exfiltrated 156,959 customer records including bank details. The total cost of the incident, including regulatory fines, was around £77 million.

Mitigation

Parameterise, hash, and re-check

Parameterised queries are still the primary defense. For authentication specifically, password storage and verification should use a memory-hard hash function (argon2id or scrypt are the current recommendations; bcrypt is acceptable for legacy compatibility but is CPU-only) and the comparison should happen in code, not in SQL - you do not want a query that can be turned into WHERE password = '<hashed input>' because the database still has to evaluate the result. The role check on the next page should re-verify the session against the database or a signed token, not trust a flag stored in plain text.

javascriptparameterised
// VULNERABLE: password check inside SQL
const q = "SELECT id, role FROM users WHERE u = '" + u + "' AND p = '" + p + "' LIMIT 1";
// attacker injects: ' OR 1=1 LIMIT 1--

// SAFE: parameterised + password verified in app code
const row = await db.query(
  'SELECT id, role, password_hash FROM users WHERE username = $1',
  [u]
);
if (row && await argon2.verify(row.password_hash, p)) {
  startSession(row.id, row.role);
}

The second snippet removes the password from the SQL string entirely and compares the hash in application code. There is no SQL payload an attacker can use to bypass this check - even a fully tautological WHERE clause returns a row, but the row's stored hash will not match the supplied password.

Further reading
  • OWASP Password Storage Cheat Sheet(OWASP)
  • CWE-287: Improper Authentication(MITRE)
Key takeaways

What to remember

  • Auth bypass payloads end with -- to comment out the trailing quote.
  • LIMIT 1 prevents the application from crashing on a multi-row result set.
  • Once the bypass succeeds, the attacker is logged in as whoever happens to be at the top of the table - usually admin.
  • Hash and compare in application code, not in SQL. The role check on subsequent pages should re-verify, not trust.
  • The breach trail looks like a normal successful login. Detect by anomaly, not by failed-login counting.

Knowledge check

0/2 answered · 0 correct
  1. 1.Why is it wrong to verify a password inside the SQL query?

  2. 2.A user logs in and receives a session cookie with role=admin. The admin dashboard trusts the cookie without re-checking. What is the risk?