[MDEV-32500] Information schema leaks table names and structure to unauthorized users Created: 2023-10-17  Updated: 2023-10-23  Resolved: 2023-10-23

Status: Closed
Project: MariaDB Server
Component/s: Authentication and Privilege System, Information Schema
Affects Version/s: 10.4, 10.5, 10.6, 10.10, 10.11, 11.0, 11.1, 11.2
Fix Version/s: 10.4.32, 10.5.23, 10.6.16, 10.10.7, 10.11.6, 11.0.4, 11.1.3, 11.2.2

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Sergei Golubchik
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-32501 INFORMATION_SCHEMA.KEY_PERIOD_USAGE r... In Testing

 Description   

InnoDB is used to get a foreign key, otherwise it is not specific to InnoDB.

--source include/have_innodb.inc
 
create database db;
create table db.t1 (x int, key(x)) engine=InnoDB;
create table db.t2 (a int, b int, c int, unique(b), check(c>b), foreign key(c) references db.t1(x)) engine=InnoDB;
 
create user u@localhost;
grant select (a) on db.t2 to u@localhost;
 
--connect (con1,localhost,u,,db)
--echo #
--echo # This is OK:
select table_name, column_name from information_schema.columns where table_name in ('t1','t2');
--echo #
--echo # This is not:
select table_name, column_name from information_schema.key_column_usage where table_name in ('t1','t2');
select table_name, unique_constraint_name, referenced_table_name from information_schema.referential_constraints where table_name in ('t1','t2');
--echo #
--echo # This is possibly not OK either:
select table_name, constraint_name from information_schema.table_constraints where table_name in ('t1','t2');
select table_name, constraint_name, constraint_type from information_schema.table_constraints where table_name in ('t1','t2');
show index in t2;
 
# Cleanup
--disconnect con1
--connection default
drop user u@localhost;
drop database db;

Actual result, 10.4 b1c8ea83

# This is OK:
select table_name, column_name from information_schema.columns where table_name in ('t1','t2');
table_name	column_name
t2	a
#
# This is not:
select table_name, column_name from information_schema.key_column_usage where table_name in ('t1','t2');
table_name	column_name
t2	b
t2	c
select table_name, unique_constraint_name, referenced_table_name from information_schema.referential_constraints where table_name in ('t1','t2');
table_name	unique_constraint_name	referenced_table_name
t2	x	t1
#
# This is possibly not OK either:
select table_name, constraint_name from information_schema.table_constraints where table_name in ('t1','t2');
table_name	constraint_name
t2	b
t2	CONSTRAINT_1
t2	t2_ibfk_1
select table_name, constraint_name, constraint_type from information_schema.table_constraints where table_name in ('t1','t2');
table_name	constraint_name	constraint_type
t2	b	UNIQUE
t2	CONSTRAINT_1	CHECK
t2	t2_ibfk_1	FOREIGN KEY
show index in t2;
Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
t2	0	b	1	b	A	0	NULL	NULL	YES	BTREE		
t2	1	c	1	c	A	0	NULL	NULL	YES	BTREE	

The expected result is probably only to return one row to the first query and nothing else, but maybe it's trickier than that.



 Comments   
Comment by Sergei Golubchik [ 2023-10-18 ]
  • second case (key_column_usage) is not OK, one needs to have some privileges on all columns that are part of the key
  • third case (table_constraints) in not OK but barely, one needs any non-select privilege on a table or on any columns of the table, so having update (a) on db.t2 would be enough
  • fourth case (show index) is non-standard, we can do whatever we want. may be doing what key_column_usage does would be reasonable?
Comment by Elena Stepanova [ 2023-10-18 ]

fourth case (show index) is non-standard, we can do whatever we want. may be doing what key_column_usage does would be reasonable?

Yes, I would expect SHOW commands behave consistently with I_S views with similar semantics (key_column_usage seems a good candidate at the first glance), but since I_S itself is all over the place, I couldn't even formulate it this way.

Note that there is also case 2a (not to break your numeration completely), referential_constraints. Its specifics is that shows the referenced table, to which the user has no privileges at all.

Comment by Sergei Golubchik [ 2023-10-18 ]

Right, sorry. Missed that.

  • second "a" case (referential_constraints) is defined via table_constraints. A row is shown if the TABLE_NAME is present in table_constraints. If REFERENCED_TABLE_NAME is not present in table_constraints, the column value will be NULL (the standard uses LEFT JOIN there).
Comment by Elena Stepanova [ 2023-10-18 ]

Yes, in case of referential constraints the doubt is not about the column name, but about the table t1 itself. A user without any grants for a table normally isn't allowed to know about its existence at all.

Generated at Thu Feb 08 10:31:50 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.