Bug #28565 Information disclosure during SELECT
Submitted: 21 May 2007 15:39 Modified: 8 Jun 2007 11:14
Reporter: Andrey Hristov Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Security: Privileges Severity:S3 (Non-critical)
Version:5.1, 5.0 OS:Any
Assigned to: Assigned Account CPU Architecture:Any

[21 May 2007 15:39] Andrey Hristov
Description:
If an user doesn't have access to specific column of a table and doing SELECT * on that table, he can find out the name of one of the columns he doesn't have access to. Compared to the situation when an user doesn't have the right to access a table, the MySQL server shows the same message no matter whether actually the table exists or not. This is to prevent information disclosure (imagine table to_be_fired). However, if there is column in the employees table named to_be_fired, the user can see its existence.

How to repeat:
andrey@whirlpool:~> mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.1.19-beta-valgrind-max-debug Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create user inf_disc@localhost;
Query OK, 0 rows affected (0.02 sec)

mysql> create database inf_disc;
Query OK, 1 row affected (0.04 sec)

mysql> create table inf_disc.t1(name varchar(20), salary decimal(5,2));
Query OK, 0 rows affected (0.03 sec)

mysql> insert into inf_disc.t1 values ("fubar", "999.99");
Query OK, 1 row affected (0.00 sec)

mysql> select * from inf_disc.t1;
+-------+--------+
| name  | salary |
+-------+--------+
| fubar | 999.99 |
+-------+--------+
1 row in set (0.00 sec)

mysql> grant select(name) on inf_disc.t1 to inf_disc@localhost;
Query OK, 0 rows affected (0.00 sec)

mysql> Bye
andrey@whirlpool:~> mysql -u inf_disc
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.1.19-beta-valgrind-max-debug Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> select user(), current_user();
+--------------------+--------------------+
| user()             | current_user()     |
+--------------------+--------------------+
| inf_disc@localhost | inf_disc@localhost |
+--------------------+--------------------+
1 row in set (0.00 sec)

mysql> select * from inf_disc.t1;
ERROR 1143 (42000): SELECT command denied to user 'inf_disc'@'localhost' for column 'salary' in table 't1'
[8 Jun 2007 11:14] Sveta Smirnova
Thank you for the report.

Verified as described.
[27 Jun 2007 20:29] Mr Wakazula
I too came across the same problem.  Currently an error is thrown.  It would be great if "SELECT * FROM SampleTable" would return only the fields for which you have access.  For example:

CREATE TABLE `test`.`SampleTable` (
  `VisibleField1` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `HiddenField2` VARCHAR(45) NOT NULL,
  `VisibleField3` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`VisibleField1`)
)
ENGINE = InnoDB;

If the current user only had sufficient privileges to `VisibleField1` and `VisibleField3`, then "SELECT * FROM SampleTable" should return:

+---------------+---------------+
| VisibleField1 | VisibleField3 |
+---------------+---------------+
|             1 | sample data   |
|             2 | sample data   |
|             3 | sample data   |
+---------------+---------------+

and not

+---------------+--------------+---------------+
| VisibleField1 | HiddenField2 | VisibleField3 |
+---------------+--------------+---------------+
|             1 | hidden data  | sample data   |
|             2 | hidden data  | sample data   |
|             3 | hidden data  | sample data   |
+---------------+--------------+---------------+
[24 Jul 2007 12:55] Mr Wakazula
Good morning.

Does anyone know if there plans to roll a fix into MySql server for this issue?