Bug #20901 CREATE privilege is enough to insert into a table
Submitted: 7 Jul 2006 12:26 Modified: 21 Dec 2007 17:04
Reporter: Tomash Brechko Email Updates:
Status: Closed
Category:Server: General Severity:S2 (Serious)
Version:4.1.21-BK, 5.0.23-BK, 5.1.12-BK OS:Any (any)
Assigned to: Tatiana Azundris Nuernberg Target Version:
Triage: D2 (Serious)

[7 Jul 2006 12:26] Tomash Brechko
Description:
Having CREATE privilege on a table is enough to insert data into it from another table if
one also have SELECT privilege on source table.

How to repeat:
CREATE USER bug@localhost;
GRANT CREATE ON test.* TO bug@localhost;
GRANT SELECT, INSERT ON test.t2 TO bug@localhost;
CREATE TABLE t1 (i INT);

As bug@localhost:

INSERT INTO t1 VALUES (1);
ERROR 1142 (42000): INSERT command denied to user 'bug'@'localhost' for table 't1'
-- The error is correct, but:
CREATE TABLE t2 (i INT);
INSERT INTO t2 VALUES (1);
CREATE TABLE IF NOT EXISTS t1 SELECT * FROM t2;
SELECT * FROM t1;
+------+
| i    |
+------+
|    1 |
+------+

Suggested fix:
Check INSERT privilege for CREATE TABLE .. SELECT (at least in IF NOT EXISTS case when
table already exists).
[7 Jul 2006 15:10] Hartmut Holzgraefe
Verified, using a different sequence of commands though as
table t2 needs to exist before bug can be granted SELECT
and INSERT on it
[17 Sep 2007 5:16] Tatiana Azundris Nuernberg
If we wanted to block CREATE ... SELECT unless someone actually has INSERT, the code would
be the following; this would however prevent all CREATE ... SELECT (as the table has to be
created first before we can grant the user INSERT on that specific table) unless someone
has INSERT on the entire DB.

sql_parse.cc:~2586:
SQLCOM_CREATE_TABLE:

    if (select_lex->item_list.elements)		// With select
    {
...
+     if (!check_table_access(thd, INSERT_ACL, create_table,0) &&
          !(res=open_and_lock_tables(thd,tables)))
      {
	res= -1;				// If error
        /*
          select_create is currently not re-execution friendly and
          needs to be created for every execution of a PS/SP.
        */
[17 Sep 2007 5:48] 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/34326

ChangeSet@1.2675, 2007-09-17 07:54:49+02:00, tnurnberg@mysql.com +5 -0
  Bug #20901: CREATE privilege is enough to insert into a table
  
  CREATE privilege let you CREATE...SELECT into an existing table,
  and one you didn't had INSERT on to boot. On existing table,
  CREATE...SELECT will now fail with an error, CREATE TABLE IF
  NOT EXISTS...SELECT with a warning; in either case, no rows will
  be inserted.
[3 Oct 2007 17:48] Timothy Smith
I believe the old behavior must be preserved as much as possible here.  It must be
possible, assuming that permissions allow, to do "CREATE TABLE IF NOT EXISTS t SELECT
..." on an existing table t, and insert the rows from the select.  It must not fail to
insert the rows with a warning in this case.  The documentation is explicit about this
behavior:

http://dev.mysql.com/doc/refman/5.0/en/create-table.html

"If you use IF NOT EXISTS in a CREATE TABLE ... SELECT statement, any rows selected by
the SELECT part are inserted regardless of whether the table already exists."

I believe the only behavior change should be that INSERT privileges are required on table
t, for this to succeed.

One final question remains:  what to do in the case where table t does not exist, and the
user has CREATE but not INSERT privileges on table t.  How should "CREATE TABLE [IF NOT
EXISTS] t SELECT ..." behave?  My preference is that it fail with a permissions error. 
That is, INSERT permissions are required, whether or not the table exists.
[18 Oct 2007 18:25] 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/35863

ChangeSet@1.2675, 2007-10-18 19:46:53+02:00, tnurnberg@sin.intern.azundris.com +5 -0
  Bug #20901: CREATE privilege is enough to insert into a table
  
  CREATE TABLE IF NOT EXISTS ... SELECT let you insert into an existing
  table as long as you had the CREATE privilege.
  CREATE ... SELECT variants now always require INSERT privilege on target table.
[23 Oct 2007 15:38] Tatiana Azundris Nuernberg
pushed 5.1.23-maint
[6 Dec 2007 23:23] 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/39477

ChangeSet@1.2670, 2007-12-06 16:23:03-07:00, tsmith@ramayana.hindu.god +4 -0
  Move the test case for bug #20901 from create.test to grant.test, so
  testing embedded server works correctly.
[7 Dec 2007 7:54] 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/39494

ChangeSet@1.2670, 2007-12-07 00:54:32-07:00, tsmith@ramayana.hindu.god +4 -0
  Move the test case for bug #20901 from create.test to grant.test, so
  testing embedded server works correctly.
[7 Dec 2007 23:08] Bugs System
Pushed into 6.0.5-alpha
[7 Dec 2007 23:09] Bugs System
Pushed into 5.1.23-rc
[21 Dec 2007 17:04] Paul DuBois
Noted in 5.1.23, 6.0.5 changelogs.

It was possible to execute CREATE TABLE t1 ... SELECT ... FROM t2
with the CREATE privilege for t1 and SELECT privilege for t2, even in
the absence of the INSERT privilege for t1.