As part of our introduction to computer security course, we have a short unit on SQL injections. One of the homework assignments is a basic unsanitized login page. The expected solution is something along the lines of the classic ' or 1=1; --
, but we always welcome students to find unconventional solutions.
One such solution was presented to me recently: inputting '--'
for the password seems to perform a successful SQL injection. This would cause the query to be evaluated as something like:
SELECT * FROM users WHERE name='admin' AND password=''--'';
Here, --'';
is not parsed as a comment, since MariaDB requires that comments are followed by spaces. In fact, if the double dash was parsed as a comment, this query wouldn’t return anything at all; equivalently we would have password=''
, which would evaluate to false, assuming a non-empty password.
The extra pair of quotes at the end appears to be necessary: leaving it as password=''--;
or inserting other data behind it (password=''--1;
) causes the conditional to be evaluated as false, as expected.
Some quick testing fails to reproduce this behavior in other databases — as far as I can tell, this is MariaDB-specific behavior. The documentation confirms that two dashes without a space are not parsed as a comment, but does not elaborate on what they are parsed as instead. EDIT: Somehow I managed to miss the fact that this happens in MySQL too. In fact, this behavior occurs in any MySQL fork (not just MariaDB).
What does --
do when it is not followed by a space, and why it causing comparisons to evaluate as true?
A toy example:
CREATE TABLE users (
userid INTEGER PRIMARY KEY,
username TEXT NOT NULL,
password TEXT NOT NULL
);
INSERT INTO users VALUES (0001, 'admin', 'S3cur3P4ssw0rd!');
INSERT INTO users VALUES (0002, 'generic_user', 'Password');
SELECT * FROM users WHERE username='admin' AND password=''; -- empty password, query returns no users
SELECT * FROM users WHERE username='admin' AND password=''-- ''; -- parsed as comment, equivalent to above query, returns no users
SELECT * FROM users WHERE username='admin' AND password=''--''; -- query returns admin user
SELECT * FROM users WHERE username='admin' AND password=''--; -- query returns zero users
SELECT * FROM users WHERE username='admin' AND password=''--1; -- query returns zero users
2
Answers
— is obviously true, because it exists. Otherwise it would be false.
This specific SQL injection uses two aspects:
First,
--
without the space, together with a value behind it, is parsed as a subtraction of a negative number. When you run the queryYou will get the following result:
So when you run the query
You get the result of the first number (
0
) minus the negative second number (-0
), which results in0
.The second part is that MariaDB (and MySQL) tries to convert a string to a number when the context required it to be a number. See the following query:
This results in nothing special:
but when you do arithmetic like this
you get this:
This can be used against you with the arithmetic above with a value that results in
0
. The querywill show the following results (I added a new user with a number at the beginning of the password):
Here you see, it will first convert the password to a number, most likely
0
, and then compare it against "your"0
value from''--''
, resulting in a successful SQL injection.