skip to Main Content

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


  1. — is obviously true, because it exists. Otherwise it would be false.

    Login or Signup to reply.
  2. 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 query

    SELECT '10'--'9'
    

    You will get the following result:

    +-----------+
    | '10'--'9' |
    +-----------+
    |        19 |
    +-----------+
    

    So when you run the query

    SELECT ''--''
    

    You get the result of the first number (0) minus the negative second number (-0), which results in 0.

    +--------+
    | ''--'' |
    +--------+
    |      0 |
    +--------+
    

    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:

    SELECT 'some value', '42 apples';
    

    This results in nothing special:

    +------------+-----------+
    | some value | 42 apples |
    +------------+-----------+
    | some value | 42 apples |
    +------------+-----------+
    

    but when you do arithmetic like this

    SELECT 'some value'+0, '42 apples'+0;
    

    you get this:

    +----------------+---------------+
    | 'some value'+0 | '42 apples'+0 |
    +----------------+---------------+
    |              0 |            42 |
    +----------------+---------------+
    

    This can be used against you with the arithmetic above with a value that results in 0. The query

    SELECT password, ''--'', password+0, password=0, password=''--'' FROM users;
    

    will show the following results (I added a new user with a number at the beginning of the password):

    +-----------------+--------+------------+------------+-----------------+
    | password        | ''--'' | password+0 | password=0 | password=''--'' |
    +-----------------+--------+------------+------------+-----------------+
    | S3cur3P4ssw0rd! |      0 |          0 |          1 |               1 |
    | Password        |      0 |          0 |          1 |               1 |
    | 42 apples       |      0 |         42 |          0 |               0 |
    +-----------------+--------+------------+------------+-----------------+
    

    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search