Blind SQL Injection in a Login Form: How One Request Leaked a Database

I sent one login request to a news website and got a ten-second delay back. That delay was enough to read an entire database, one bit at a time. Here is how time-based blind SQL injection really works, and the one fix that kills it.

I sent one login request. I didn't get a username wrong. I didn't get a password wrong. I got a ten-second delay. And that delay told me everything.

This is a real bug I found on a news website, in its login form. The organisation is not named. Before I show you what I sent, let's talk about what a login form actually does behind the scenes, because the bug lives in that gap.

Blind SQL Injection Explained: How One Login Request Leaked a Database | Bug Bounty

What the login form really does

When you submit a username and password, the server usually builds a database query to check whether that user exists. Something like:

sql
SELECT * FROM users WHERE username = '<your input>'

In plain, unsafe code, your input is glued directly into that query as text. That is the entire problem. If the server trusts your input completely and just pastes it into the query, then you are not only providing a username. You are providing a piece of the query itself.

Turning input into logic

So instead of a normal username, I sent something built like this:

  • close the username's quote early,
  • add my own condition with AND,
  • inside that condition, ask the database to sleep for ten seconds if a certain condition is true,
  • then reopen a quote at the end so the syntax still matches and the query doesn't just error out.

The shape of the resulting query looked like this:

sql
SELECT * FROM users WHERE username = 'x' AND SLEEP(10) -- '

If the input were handled properly, none of that extra logic would ever reach the database as code. It would be treated as a weird username that doesn't exist: instant response, no delay.

But here, the server pasted my input straight into the query. The database read my AND SLEEP condition as real logic, not as text. It evaluated it. And since the condition was true, it waited ten seconds before responding.

The delay is the whole signal

That ten-second wait is the entire signal. I can't see the database's data directly. There's no error message, nothing printed on screen. But I can ask it yes-or-no questions and read the answer in time:

  • a fast response means false,
  • a ten-second delay means true.

That is called blind SQL injection, specifically the time-based kind. "Blind" because there's no visible output. "Time-based" because the clock is the only channel I have.

From one bit to the whole database

Once that one true-or-false channel exists, it scales. Instead of one guess, you ask thousands of tiny yes-or-no questions automatically:

Is the first letter of the admin's password an "a"? No — fast.
A "b"? No — fast.
Eventually, yes — slow.

Letter by letter, table by table, the entire database can be reconstructed one bit at a time, without ever logging in.

In practice, nobody does that by hand. Tools like sqlmap automate exactly this process: feed it the request, and it finds the injectable parameter, confirms the technique, and extracts table names, columns and credentials, all pre-authentication. No account is needed, because this lives in the login form itself, before any login check happens.

Why it is rated critical

This is why it scores 9.1 out of 10 (critical). An attacker needs no credentials and no user interaction, and the technique is completely reliable, because a clock doesn't lie.

The fix: never let input become code

The fix isn't about "cleaning" input harder. It's about never letting input become code in the first place. Parameterized queries, also called prepared statements, separate the query's structure from the data:

sql
SELECT * FROM users WHERE username = ?

The database is told, in advance, "this slot is always a value, never logic," no matter what text lands inside it. The same input that broke this login form becomes just a very strange, harmless username.


For educational purposes only. The organisation is not named. Only test systems you own or have written permission to test.

Follow Devsecknight for more real bug reports, explained properly.

Related posts

Bug Reports

Reflected XSS on a News Site: How One URL Ran My JavaScript

I changed one thing in the address bar of a news website, and the site ran my JavaScript. This is a real reflected XSS, explained step by step: how input is reflected into an HTML attribute, how an autofocus/onfocus breakout fires code on page load, why a slash filter completely missed it, and the fix that actually works.