Bug #44311 | privilege escalation | ||
---|---|---|---|
Submitted: | 16 Apr 2009 9:41 | Modified: | 29 Jul 2009 21:27 |
Reporter: | Peter Laursen (Basic Quality Contributor) | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: Security: Privileges | Severity: | S2 (Serious) |
Version: | 5.1.33 | OS: | Windows (Vista 32 bit) |
Assigned to: | CPU Architecture: | Any | |
Tags: | qc |
[16 Apr 2009 9:41]
Peter Laursen
[16 Apr 2009 9:44]
Peter Laursen
oops .. my mistake when posting! "SELECT .. FROM booltest" is OK of course, but SELECT * FROM chsettest; /* returns id txt ------ ------ 1 (NULL) 2 b 3 a 4 a 5 (NULL) */ There is no SELECT privilege to 'chsettest' table for this user.
[16 Apr 2009 9:47]
Peter Laursen
However trying FROM another DATABASE ON same SERVER SELECT * FROM test2.bittest /* Error Code : 1142 SELECT command denied to user 'testuser'@'localhost' for table 'bittest' */
[16 Apr 2009 10:49]
Valeriy Kravchuk
So, had you tried the same trick with another database besides test? Do you have privileges escalation outside of test?
[16 Apr 2009 10:56]
Peter Laursen
I do not see any escalation outside 'test' database, but have not checked all possible combinations of statements and tables of course! btw: SHOW CREATE TABLE shows same pattern SHOW CREATE TABLE test.chsettest; -- success SHOW CREATE TABLE test1.bittest; -- SELECT command denied to user 'testuser'@'localhost' for table 'bittest'
[16 Apr 2009 11:17]
Valeriy Kravchuk
Please, check the results of: select user, db from mysql.db; Do you have test database mentioned there?
[16 Apr 2009 11:29]
Peter Laursen
I do not see any escalation outside 'test' database, but have not checked all possible combinations of statements and tables of course! btw: SHOW CREATE TABLE shows same pattern SHOW CREATE TABLE test.chsettest; -- success SHOW CREATE TABLE test1.bittest; -- SELECT command denied to user 'testuser'@'localhost' for table 'bittest'
[16 Apr 2009 11:32]
Peter Laursen
-- as root SELECT USER, db FROM mysql.db; /* USER db ------ ------- test test\_% */
[16 Apr 2009 11:37]
Peter Laursen
Additionally I can tell I dropped an anonymous user yesterday (I would normally not have such, but as usual the config wizard failed to 'apply security settings' when I originally installed the server. I believe this server was originally installed as 5.1.31 or 5.1.32 and later upgraded)
[16 Apr 2009 11:51]
Peter Laursen
full details from mysql.db table: Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv ------ ------- ------ ----------- ----------- ----------- ----------- ----------- --------- ---------- --------------- ---------- ---------- --------------------- ---------------- ---------------- -------------- ------------------- ------------------ ------------ ---------- ------------ % test Y Y Y Y Y Y N Y Y Y Y Y Y Y Y N N Y Y % test\_% Y Y Y Y Y Y N Y Y Y Y Y Y Y Y N N Y Y
[16 Apr 2009 12:36]
Peter Laursen
I hav e exactly same situation wiht 5.0.77 -- as root GRANT USAGE ON *.* TO 'testuser'@'localhost' ; GRANT SELECT ON `test`.`uctf8test` TO 'testuser'@'localhost'; SELECT USER, db FROM mysql.db /* returns user db ------ ------- test test\_% */ -- as testuser SELECT * FROM utf8test; -- success! This machine is 6-8 weeks only only. 5.0, 5.1 and 6.0 servers were installed after a few days. I upgrade regularly when I see upgrades at the server - so those where upgrades were released later have been upgraded. If this is caused by the Windows config wizard failure to 'apply security settings', then the related bug(s) with the wizard should be 'promoted' to 5.0 and 5.1 and given priority (I think they are currently set to be fixed in 6.0 only)
[16 Apr 2009 13:16]
Peter Laursen
OK .. maybe only now I understand Valeriy's rist question to me. It is only reproducable inside 'test' database! -- as root CREATE DATABASE newthing; USE newthing; CREATE TABLE t1(id INTEGER); CREATE TABLE t2(id INTEGER); GRANT USAGE ON *.* TO 'newuser'@'localhost'; GRANT SELECT ON `newthing`.`t1` TO 'newuser'@'localhost'; -- as newuser USE newthing; SELECT * FROM t1; -- success SELECT * FROM t2; -- SELECT command denied to user 'newuser'@'localhost' for table 't2' SELECT * FROM test.booltest; -- success .. so any user seems to have privilege to all tables in `test` database. This is not how I understand it should be! "SELECT user, db .." returned an empty string and not a wildcard (%) for both 'user's. And GRANT informed nothing about it either! Also databases of the pattern test_% (like `test_100`) are affected (what is expected from the output of "SELECT .. FROM db, user"). If I delete from mysql.db, flush privileges and connect again as newuser I get expected results. Issues as I understand this: 1) an empty string for user in mysql.db table is treated like a wildcard (%) 2) SHOW GRANTs and what user really can do are in conflict 3) possibly it all started with config wizard failure. But even if that is the case this is not the primary issue!
[16 Apr 2009 13:18]
Peter Laursen
typo! .. maybe only now I understand Valeriy's FIRST question to me. It is only reproducable inside 'test' and 'test_%' databases!
[16 Apr 2009 16:18]
Valeriy Kravchuk
Item 3 is irrelevant as I've got the same rows for test and test_% in mysql.db on Linux (no wizard at all, but mysql_install_db script used). Actually, this is known and, I assume, intended behavior of test database. Check http://dev.mysql.com/doc/refman/5.0/en/default-privileges.html. Are you sure you had removed both anonimous accounts mentioned there?
[16 Apr 2009 16:33]
Peter Laursen
There was only one anonymous account in both 5.0.77 and 5.1.33! I do not remember it it was <empty>@localhost or <empty>@%. It has been removed by deleting from mysql.users. users now in 5.1.33: SELECT user, host FROM mysql.user /* user host -------- --------- root 127.0.0.1 newuser localhost root localhost testuser localhost */ I do not quite understand what passage from docs you refer to. I see this "The other is for connections from any host and has all privileges for the test database and for other databases with names that start with test." .. yes BUT 'testuser' is not a user created during installation. I created. And she not only have privileges to specific tables.
[16 Apr 2009 16:48]
Peter Laursen
I tried (as root) INSERT INTO `db`(`Host`,`Db`,`User`,`Select_priv`,`Insert_priv`,`Update_priv`,`Delete_priv`,`Create_priv`,`Drop_priv`,`Grant_priv`,`References_priv`,`Index_priv`,`Alter_priv`,`Create_tmp_table_priv`,`Lock_tables_priv`,`Create_view_priv`,`Show_view_priv`,`Create_routine_priv`,`Alter_routine_priv`,`Execute_priv`,`Event_priv`,`Trigger_priv`) VALUES ( '','test2','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N'); FLUSH PRIVILEGES; and as testuser SELECT * FROM test2.bittest -- SELECT command denied to user 'testuser'@'localhost' for table 'bittest' .. so seems that it is only affecting databases starting wiht 'test..'. 1) I do not find that the behavior here is as what is documented. Not for 'test' user and not for 'test_77' and 'test_99' etc databases (undocumented full access for all users to all 'test_%' databases is a very serious flaw in my opinion. 2) I find it wrong that <empty> fields in the db database are used like that. If 'test' user has access then put the value 'test' in the user field. 3) SHOW GRANTS does not tell that any user can read everything from 'test', 'test_77' etc. databases
[29 Jul 2009 5:28]
Sveta Smirnova
Thank you for the report. Really this behavior is documented at http://dev.mysql.com/doc/refman/5.1/en/default-privileges.html: ----<q>---- Two anonymous-user accounts are created, each with an empty user name. The anonymous accounts have no password, so anyone can use them to connect to the MySQL server. * On Windows, one anonymous account is for connections from the local host. It has no global privileges. (Before MySQL 5.1.16, it has all global privileges, just like the root accounts.) The other is for connections from any host and has all privileges for the test database and for other databases with names that start with test. * On Unix, both anonymous accounts are for connections from the local host. Connections must be made from the local host by specifying a host name of localhost for one of the accounts, or the actual host name or IP number for the other. These accounts have all privileges for the test database and for other databases with names that start with test_. ----</q>---- See also http://dev.mysql.com/doc/refman/5.1/en/mysql-secure-installation.html
[29 Jul 2009 14:11]
Peter Laursen
I think the reply misses the point. I am not an anonymous user and not a 'test' user either. I am 'testuser'@'localhost'. 1) I find it both undocumented and wrong that 'testuser'@'localhost' can access `test` database. Am I missing something here? 2) And additionally I think that SHOW GRANTS should tell *effective privileges* to all objects. Not only the privileges that were explcitly granted. I am opning again. Not to be pedantic. But the reply does not take my test case into consideration (or I fail to understand the point).
[29 Jul 2009 21:27]
Sveta Smirnova
Thank you for the feedback. > I find it both undocumented and wrong that 'testuser'@'localhost' can access `test` > database. Am I missing something here? Please see http://dev.mysql.com/doc/refman/5.1/en/request-access.html and following output right after installing: mysql> select user, host, db from mysql.db; +------+-----------+---------+ | user | host | db | +------+-----------+---------+ | | % | test | | | % | test\_% | +------+-----------+---------+ 2 rows in set (0.40 sec) Probably "A blank User value in the db table matches the anonymous user. " should be changed to "A blank User value in the db table matches the any user.", but this is documented. Regarding to second option: > And additionally I think that SHOW GRANTS should tell *effective privileges* to all > objects. Not only the privileges that were explcitly granted. I think this can be good addition. Set to verified feature request.