COMMAND

    MySQL

SYSTEMS AFFECTED

    All MySQL affecting versions 3.22.29 and earlier,3.23.8 and earlier

PROBLEM

    Viktor Fougstedt found following.  While installing MySQL  3.22.29
    and  testing  it  out,  he  discovered  a very serious bug in it's
    handling  of  the  GRANT  statement.   This  was  tested  on MySQL
    3.22.27, 3.22.29, 3.23.8.  Anyone  with access to a running  MySQL
    and GRANT privilege  for any database  or table in  it, can change
    any MySQL-password he wishes, including the MySQL superuser's.

    If the malicious user has  access to run processes on  the machine
    where MySQL is running, he can hijack the entire database.  If  he
    does not have such  access, he can DOS  the server by setting  the
    MySQL superuser's password to  a random string.   The 'test'-users
    installed by  MySQL's install  scripts have  GRANT privileges  for
    any database whose name begins  with 'test', and can therefore  be
    used to exploit this bug.  The 'test' accounts by default  have no
    passwords  set,  and  no  restrictions  on where connects can come
    from.

    This makes  all default-configured  MySQL very  vulnerable (anyone
    on the net can change  your MySQL superuser password).   Be aware,
    however, that  _any_ user  with a  GRANT privilege  (no matter  on
    which database) in your  MySQL installation can exploit  this bug.
    You may be vulnerable even if you've removed the 'test' users.

    The  bug  is  that  the  GRANT  statement  does not properly check
    privileges when  you give  it an  IDENTIFIED BY-clause.   You  can
    therefore  GRANT  someone  (including   the  MySQL  superuser)   a
    privilege you yourself  possess, and set  her/his password at  the
    same time using IDENTIFIED BY.   Which privilege you pass on  does
    not matter.  It is the side-effect of the IDENTIFIED BY that  does
    the  magic.   This  can  be  exploited  regardless  of  your other
    permissions.  You only need the GRANT privilege for _any_ table or
    database to exploit this bug.

    For  someone  having  login  access  to the machine running MySQL,
    hijacking  the  database  is  trivial  once  the  MySQL  superuser
    password has  been changed  using the  above method.   For someone
    without login  access, changing  the superuser  password can  be a
    simple way  of DOS:ing,  or of  extortion.   In the default setup,
    MySQL prohibits  access to  the superuser  account from  any other
    hosts than localhost.  Sites that allow superusers to connect from
    the  net  may  be  vulnerable  to  hijacking  from malicious users
    without local access.

    Since  the   password-less  'test'-accounts   created  by    MySQL
    installation scripts have GRANT privileges for any database  whose
    name begins  with 'test',  they can  be used  to exploit this bug.
    Very nasty.

    Exploit: Connect to  mysql as any  user with grant  privileges for
    any  table.   The  default  test  users  will  do  nicely.   If no
    databases has been created for the  test user, do so.  Then  alter
    roots (MySQL's roots, not the real roots!) password with a  GRANT.
    After the code below has been executed, the password of the  MySQL
    superuser 'root' will be 'newpassword'.

        > mysql -utest -p
        Password:

        mysql> CREATE DATABASE test_expl;
        Query OK, 1 row affected (0.04 sec)

        mysql> GRANT select ON test_expl.* TO root@localhost IDENTIFIED BY 'newpassword';
        Query OK, 0 rows affected (0.01 sec)

        mysql> exit
        Bye

SOLUTION

    MySQL 3.22.30 has been released  for all available platforms.   To
    quote the CHANGELOG, "Fixed  critical problem with the  WITH GRANT
    OPTION option."  While waiting for opportunity to install them:

        1) Revoke  _all_  GRANT  privileges  from _all_ users in  your
           MySQL system except  root@localhost.  This  includes GRANTs
           in the mysql.db table.

        2) Confirm  that  your  root@localhost  password has not  been
           altered.

    For those of you using source distributions here's a patch for the
    problem from TCX:

    *** /my/monty/master/mysql-3.23.8-alpha/sql/sql_parse.cc        Fri Dec 31 13:53:03 1999
    --- ./sql_parse.cc      Mon Jan 10 21:53:59 2000
    ***************
    *** 1222,1227 ****
    --- 1222,1246 ----
                          tables ? &tables->grant.privilege : 0,
                          tables ? 0 : 1))
             goto error;
    +
    +      /* Check that the user isn't trying to change a password for
        another
    +       user if he doesn't have UPDATE privilege to the MySQL database
        */
    +
    +      List_iterator <LEX_USER> user_list(lex->users_list);
    +      LEX_USER *user;
    +      while ((user=user_list++))
    +      {
    +        if (user->password.str &&
    +          (strcmp(thd->user,user->user.str) ||
    +           user->host.str && my_strcasecmp(user->host.str,
    +                                           thd->host ? thd->host :
    thd->ip)))
    +        {
    +        if (check_access(thd, UPDATE_ACL, "mysql",0,1))
    +          goto error;
    +        break;                                 // We are allowed to
    do changes
    +        }
    +      }
    +
           if (tables)
           {
             if (grant_option && check_grant(thd,

    MySQL 3.22.32 fixes a couple  of possible security holes in  MySQL
    3.22 including this one.  3.23.x is also out.