Bug #116857 Users without any permissions could retrieve table names via the error message of DROP TRIGGER
Submitted: 3 Dec 2024 16:00 Modified: 3 Dec 2024 16:19
Reporter: Jingzhou Fu Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: Security: Privileges Severity:S3 (Non-critical)
Version:8.0 OS:Linux (20.04)
Assigned to: CPU Architecture:x86 (x86-64)

[3 Dec 2024 16:00] Jingzhou Fu
Description:
Users without any permissions can retrieve table names via the error message of the DROP TRIGGER statement.

For example, if the table `test.tbl` has a trigger named `before_insert_tbl`, a user without any permissions can retrieve the table name by executing the statement `DROP TRIGGER test.before_insert_tbl`. The error message displayed is "ERROR 1142 (42000): TRIGGER command denied to user 'foo'@'localhost' for table 'tbl'", which reveals the table name `tbl` to the user.

How to repeat:
The Proof of Concept (PoC):

```sql
# Use the root user to connect to MySQL and create a trigger and an empty user
# Example:
#   docker run -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -p 3306:3306 -itd --name some-mysql mysql:9.1.0
#   docker exec -it some-mysql mysql -uroot

CREATE DATABASE test;
CREATE TABLE test.tbl (x INT);
CREATE TRIGGER test.before_insert_tbl -- Create a trigger
BEFORE INSERT ON test.tbl FOR EACH ROW
INSERT INTO test SELECT 1;

CREATE USER foo; -- Create a empty user
QUIT; -- Exit

# Login with the user `foo` and try to drop trigger
# Example:
#   docker exec -it some-mysql mysql -ufoo

DROP TRIGGER test.test; -- Drop a non-existing trigger
-- Error message: ERROR 1360 (HY000): Trigger does not exist

DROP TRIGGER test.before_insert_tbl; -- Drop an existing trigger
-- Error message: ERROR 1142 (42000): TRIGGER command denied to user 'foo'@'localhost' for table 'tbl'
```

From the error message when dropping an existing trigger, the user `foo` (who has no permissions) can infer the existence of the database `test`, the table `test.tbl`, and the trigger `test.before_insert_tbl`.  

If the user can "guess" a trigger name (e.g., via brute-force enumeration or by attempting commonly-used names) and the trigger name exists, the user can infer the existence of the trigger and retrieve the corresponding table name via the `DROP TRIGGER` statement.

Since the user has no permissions, it seems unreasonable that they can obtain information about databases, tables, and triggers. Maybe it is a bug or issue?

Suggested fix:
Instead, other statements like the DROP INDEX statment can protect such information:

```
# Create index with the root user
CREATE INDEX w ON test.tbl(x);
QUIT; -- Exit

# Connect with the empty user
# Example:
#   docker exec -it some-mysql mysql -ufoo
# Attempting DROP INDEX
DROP INDEX w ON test.tbl;
-- ERROR 1142 (42000): INDEX command denied to user 'foo'@'localhost' for table 'tbl'
DROP INDEX w ON testx.tbl;
-- ERROR 1142 (42000): INDEX command denied to user 'foo'@'localhost' for table 'tbl'
DROP INDEX w ON `???`.tbl;
-- ERROR 1142 (42000): INDEX command denied to user 'foo'@'localhost' for table 'tbl'
DROP INDEX w ON `???`.`???`;
-- ERROR 1142 (42000): INDEX command denied to user 'foo'@'localhost' for table '???'
DROP INDEX w ON `test`.`???`;
-- ERROR 1142 (42000): INDEX command denied to user 'foo'@'localhost' for table '???'
DROP INDEX `???` ON testx.tbl;
-- ERROR 1142 (42000): INDEX command denied to user 'foo'@'localhost' for table 'tbl'
```

For the `DROP INDEX` statement, the user without permissions cannot retrieve any information about the database, table, or index because the error messages are always generic. This seems to be the correct behavior for `DROP` statements.

So, maybe current error message of DROP TRIGGER need to be improved?
[3 Dec 2024 16:19] MySQL Verification Team
Hi Mr. Fu,

Thank you for your bug report.

However, we do not think that this is a bug.

This is not a security threat in any way ......

First of all, user with no privileges would not know what schemas exist on the server. Next, that user would not know what triggers exist, at all. 

Third, if that user acquired schema and trigger names, he would already have more info then table names. 

Fourth, knowing a table name is NOT any security risk, since such a user could not represent any security risk, at all ......

Last, this kind of behaviour exists since version 5.5 and nobody experienced any problems with it.

Not a bug.