Break It Yourself
A real, running staff directory with the bug in it. You will make it hand over a record it is trying to keep from you — and then read the one line of code that let you.
Enough description. There is a lab attached to this chapter — an internal staff directory with exactly the bug we just drew. Open it, and make it show you the account it is hiding.
Hiding an account? How do I even know it is there?
You do not, yet. That is the point of OR 1=1: you do not ask for the hidden row, you ask for *everything*, and the hidden row comes with it.
Legal
This lab is ours and is meant to be broken. The same three keystrokes against a system you do not own or have written permission to test is a criminal offence in most countries. The technique is legal to learn; using it without authorisation is not.
The three moves
Every classic injection is the same three moves, and you can see all three in ' OR 1=1 --. Get these into your fingers and you can rediscover the attack anywhere you meet it.
' close the quote the application opened for you
OR 1=1 add a condition of your own that is always true
-- comment out whatever the application wrote next
- Line 1The application wrote
name = 'and expects you to fill in a value and for it to add the closing quote. Supply the closing quote yourself and you are now writing SQL, not a value. - Line 2
ORjoined to an always-true condition makes the whole filter true for every row. This is the move that turns "find my record" into "find every record". - Line 3Two dashes begin a comment. Everything the application added after your input — including the part that hides unlisted accounts — is now ignored.
Now do it
Open the lab. Search for a surname you can see first, so you know the box works. Then put in ' OR 1=1 -- and read what comes back. The flag is sitting in a record the directory never meant to show you.
You ran the injection and every row came back — including one whose role is "break-glass administrator". Why was that one hidden before, and why is it not hidden now?
and listed = 1, which filters out unlisted accounts. Your -- commented that clause out entirely, so the filter never ran. The row was never protected — it was merely *not asked for*, and you asked for everything.What actually went wrong
The lab shows you the query it builds, on every search. Look at it after a normal search and after your injection. The application did not have a security hole bolted to the side of it — the hole is the way it builds the string. There is nothing to patch except that.