Search code examples
mysqldatabasesql-injectionsleep

dash ( - ) in where clause with sleep function


In MySQL you can pause a result for x seconds with the SLEEP function.

I understand when you use it like this:

SELECT SLEEP(1000);

But I recently saw that you can enhance a query in this form:

mysql> select * from docs where rev = 1-sleep(4);

and it will wait 4 seconds before it returns the results in comparison to

mysql> select * from docs where rev = 1;

Why is this so? Is the dash a form of concatenating functions or something like this? I couldn't find any explanation for this syntax.


I reproduced this query using docker

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest
docker exec -ti some-mysql mysql -uroot -pmy-secret-pw

and the following code to create the table (using code from sql fiddle) and verify the behavior.

CREATE test;
USE test;
CREATE TABLE IF NOT EXISTS `docs` (
  `id` int(6) unsigned NOT NULL,
  `rev` int(3) unsigned NOT NULL,
  `content` varchar(200) NOT NULL,
  PRIMARY KEY (`id`,`rev`)
) DEFAULT CHARSET=utf8;
INSERT INTO `docs` (`id`, `rev`, `content`) VALUES
  ('1', '1', 'The earth is flat'),
  ('2', '1', 'One hundred angels can dance on the head of a pin'),
  ('1', '2', 'The earth is flat and rests on a bull\'s horn'),
  ('1', '3', 'The earth is like a ball.');
select * from docs where rev = 1;
select * from docs where rev = 1-sleep(4);

Solution

  • As you can read in the manual you've linked, SLEEP returns 0. So using it in some kind of calculation like where rev = 1-sleep(4); triggers the execution of SLEEP (as in: waits four seconds). Afterwards, the query is resumed with where rev = 1-0, making it equal to where rev = 1