Bug #17279 user with no global privs and with create priv in db can create databases
Submitted: 9 Feb 2006 15:55 Modified: 14 Mar 2006 16:43
Reporter: Andy Lear Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:5.0.18 OS:Linux (Redhat ES 4)
Assigned to: Magnus Blåudd CPU Architecture:Any

[9 Feb 2006 15:55] Andy Lear
Description:
We have created a user with no global privileges and then added an entry to db with select, insert, update, delete, create, drop, index, alter, create_tmp_table, create_view, show_view, create_routine, alter_routine, and execute.  The user can create a database and insert data into it if the database name is the same as the db entry in the db table, but of mixed case (eg database with priv='DATABASE' can create 'DataBase'), he can not however view it.

How to repeat:
create database ANDY;
INSERT INTO `user` VALUES ('%','andy','*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','','','','',0,0,0,0);
INSERT INTO `db` VALUES ('%','ANDY','andy','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','N','Y','Y','Y','Y','N');
FLUSH PRIVILEGES;

now login as andy password=password from another machine,

create database ANdy;

creates the db!

Suggested fix:
no idea,  getting alot of superflous databases created
[9 Feb 2006 18:18] Hartmut Holzgraefe
Verified, this contradicts http://dev.mysql.com/doc/refman/5.0/en/privileges.html

"For access-checking purposes, comparisons of Host values are case-insensitive. User, Password, Db, and Table_name values are case sensitive. Column_name and Routine_name values are case insensitive."
[23 Feb 2006 10:51] Magnus Blåudd
During the execution of "CREATE DATABASE ANdy" a the function 'acl_get' is called to see if the user has the the privs to perform the operation.

A key is formatted and used to search in the acl_cache. Unfortunately that hash search is not case sensitive, so the key "\0andy\0ANdy\0" matches the key "\0andy\0ANDY\0".

Below is the tracefile from the server when this happens.

T@10892066: | | >mysql_execute_command
T@10892066: | | | >end_active_trans
T@10892066: | | | <end_active_trans
T@10892066: | | | >alloc_root
T@10892066: | | | | enter: root: 0x15193a0
T@10892066: | | | | exit: ptr: 0x153b720
T@10892066: | | | <alloc_root
T@10892066: | | | >check_access
T@10892066: | | | | enter: db: ANdy  want_access: 16  master_access: 0
T@10892066: | | | | >acl_get
T@10892066: | | | | | >hash_first
T@10892066: | | | | | | exit: found key at 0
T@10892066: | | | | | <hash_first
T@10892066: | | | | | exit: access: 0xe1383f
T@10892066: | | | | <acl_get
T@10892066: | | | | info: db_access: 14759999
T@10892066: | | | | info: db_access: 14759999  want_access: 16
T@10892066: | | | <check_access
T@10892066: | | | >mysql_create_db
[23 Feb 2006 11:03] Magnus Blåudd
If I comment out the hash_search, the acl_db list will be searched for a matching record using wildcompare which is case sensitive, and thus the "CREATE DATABASE ANdy" will be rejected.

sql_acl.cc:991
 	  if (!acl_db->db || (db && !wild_compare(db, acl_db->db, 0)))
[24 Feb 2006 17:58] Magnus Blåudd
This little change does the trick.

===== sql_acl.cc 1.187 vs edited =====
--- 1.187/sql/sql_acl.cc        2006-01-26 13:29:42 +01:00
+++ edited/sql_acl.cc   2006-02-24 18:20:29 +01:00
@@ -148,7 +148,9 @@

   acl_cache= new hash_filo(ACL_CACHE_SIZE, 0, 0,
                            (hash_get_key) acl_entry_get_key,
-                           (hash_free_key) free, system_charset_info);
+                           (hash_free_key) free,
+                           /* utf8_bin for case sensitive search in acl_cache */
+                           &my_charset_utf8_bin);
   if (dont_read_acl_tables)
   {
[27 Feb 2006 10:03] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/3174
[27 Feb 2006 15:42] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/3197
[1 Mar 2006 19:24] Magnus Blåudd
"grant2" fails on windows after this bug has been fixed.
[1 Mar 2006 20:19] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/3349
[2 Mar 2006 10:02] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/3376
[6 Mar 2006 10:43] Magnus Blåudd
Pushed a fix to 5.0.20 and 5.1.8 that uses the "binary" charset in the "acl_cache". This makes lookup in the "acel_cache" case sensitive and thus user with access to database "DATABASE" should not be able to access "DataBASE"
[14 Mar 2006 16:43] Mike Hillyer
Documented in 5.0.20 and 5.1.8 changelogs:

      
      <listitem>
        <para>
          Security Improvement: Checks for permissions on database operations were performed
          in a case-insensitive manner, meaning that a user with permissions
          on database <literal>MYDATABASE</literal> also had permissions
          on database <literal>myDataBase</literal>. (Bug #17279)
        </para>
      </listitem>