Is it possible to grant only metadata privileges in MySQL - mysql

TLDR;
Target:
Is it possible to grant privileges to a certain "audit" user to access to MySQL metadata only (schema,table,column at least) without access to exact data in tables?
Version
MySQL 8+
Try:
Before this issues,
I've been already tried or known:
review MySQL official docs on privileges (notice me if I missed the answer in it)
search keywords on SOF: mysql, privilege, metadata, etc.
find solutions with my DBA friends
grant show databases to users, but it could get the schema lists only
all grants to infomatica_schema was in vain, as known to all
SELECT ON *.* is another answer, but my leader dont wanna data leak through it
Background:
My company ordered devops to collect MySQL metadata for some issues of audits or security monitoring or else (I don't know the details of whole story). Unnecessary data leak would not be expected to my leader.
BTW, I dont know the specific method where they, audit depts maybe, are going to collect metadata. All I've been required to do is to create a granted user for them.

I think I found a workaround for this, but it's kind of a hack, not a true solution.
https://dev.mysql.com/doc/refman/8.0/en/show-tables.html says:
If you have no privileges for a base table or view, it does not show up in the output from SHOW TABLES or mysqlshow db_name.
That is, you can't use SHOW TABLES, or see the tables in queries against INFORMATION_SCHEMA (because SHOW TABLES is really just a query against those system views).
But the language of "no privileges" got me thinking. Is there a privilege that the user could have, but which does not allow reading or writing data?
https://dev.mysql.com/doc/refman/8.0/en/grant.html says:
The permissible priv_type values at the table level are ALTER, CREATE VIEW, CREATE, DELETE, DROP, GRANT OPTION, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, and UPDATE.
How about SHOW VIEW? This would only allow viewing metadata, not querying a table or a view.
So I tried it:
mysql> create user 'auditor'#'%';
mysql> grant show view on test.* to 'auditor'#'%';
Then I logged in as that user, and tried it:
mysql> show grants;
+----------------------------------------------+
| Grants for auditor#% |
+----------------------------------------------+
| GRANT USAGE ON *.* TO `auditor`#`%` |
| GRANT SHOW VIEW ON `test`.* TO `auditor`#`%` |
+----------------------------------------------+
mysql> use test
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| Accounts |
| Bugs |
| BugsProducts |
| BugStatus |
...
I could also view columns, etc.
To be clear, those are concrete tables, not views. But since my auditor user has more than no privileges on the tables (even an irrelevant privilege), it qualifies for purposes of letting them view metadata about the tables.
In MySQL 8.0.20, they added the SHOW ROUTINES privilege. Prior to that, you needed SELECT privilege to view the body of stored procedure or functions. But you didn't mention auditors viewing routines in your question.

Related

Automative way to check mysql grants

we have many users in our mysql server with alot of grants. Is there exists some automated way to check that all grants are really required for these users base on query set which these users use?
For example:
you have user1 and user2 and known that user1 do query1, query2, query3. user2 do others query4, query5, query6. Could I predict in automatic way, which grants are required for these users, base on these queries, to compare these autogenerated grants set with grants which already exists in our db server to remove excesive grants?

How to set table level privileges in MySQL

I am trying to revoke select privilege from a particular table from a MySQL DB.
Database level restriction is working but table level is not.
When I write "show grants"
This is what I get :
| GRANT USAGE ON *.* TO 'rachit'#'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' |
| GRANT ALL PRIVILEGES ON `test123`.* TO 'rachit'#'localhost' |
| GRANT INSERT, UPDATE, DELETE ON `test123`.`names123` TO 'rachit'#'localhost'
As you can see above I want to
revoke select privilege from rachit user on 'names123' table of 'test123' database, but SELECT is working.
I have attached a screenshot below for better understanding.
https://ibb.co/GRtjXX7
If you GRANT ALL ON test123.* TO 'rachit'#'localhost' you cannot remove one table by running REVOKE ALL ON test123.* TO 'rachit'#'localhost'.
some DBMS systems specifically DENY option for specifically denying access to specific table but this is not the case for mysql.
you may consider to write script and give access to each table one by one
Discussion:
If it wasn't specifically GRANTed, it can't be REVOKEd. This is an unfortunate side effect of the not-so-user-friendly Grant/Revoke syntax and implementation.
You can use a SELECT against information_schema.TABLES to automate the discovery of all the other tables. And have the SELECT build the desired GRANTs.
Possible workaround:
Another approach to your particular problem is to move that one table to a different database. Then GRANT different permissions to that db.

MYSQL Update permission need to select permission also?

In MYSQL Database, I want to give update permission to the user without select, is it possible?
It is possible but your problem is, that your UPDATE-Query contains a WHERE-clause which needs to query the fields at least internally. So it is intended that you need SELECT permission here.
Otherwise, one could try to use brute force techniques to get the actual contents of the table by using a UPDATE-Query and checking wether it has affected rows.
Example:
UPDATE customers SET some_irrellevant_field=1 WHERE user = 'jimmy' AND sexual_orientation = '2'
As soon as you have a affected rows count > 0, you would have the information. So it would possibly be to dangerous to allow that.
But you can explicitly give permissions for single columns. Lets say you want to update the password hash of a user with a certain id, you give select permission on the id-column to the database user and update permission to hash column.
PHPMyAdmin table specific permission dialog (sorry, some parts of the screenshots are in german):
Then this should work fine:
UPDATE users SET hash='0123456789abcdef' WHERE id = 1234
Alternatively, if column level permission should not be available in you DBMS or storage engine you could still use a separate table or database and join it when it is needed.
Yes, you can do it.
These steps are example.
Step1 : create the user (if not already done)
CREATE USER 'username'#'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
Step 2 : grant only the update privilege
GRANT UPDATE ON *.* TO 'username'#'%' ;
NB : You have to connect with an user who has the grant privilege to execute these command. (E.g : root user)
The grant syntax is
GRANT
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type] priv_level
TO user_specification [, user_specification] ...
[REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}]
[WITH with_option ...]
object_type:
TABLE
| FUNCTION
| PROCEDURE
priv_level:
*
| *.*
| db_name.*
| db_name.tbl_name
| tbl_name
| db_name.routine_name
Thanks All on your replies, but i Don't think you try this case before, so as the error which i got, you can't execute the update query without Select and Update Permission.
Thanks All.

Permissions error running EXPLAIN on MySQL VIEW

I have a view defined in a MySQL 5.0 database as:
CREATE OR REPLACE ALGORITHM=MERGE
DEFINER=db1_user#'%' SQL SECURITY DEFINER
VIEW db2.data_view AS SELECT * FROM db1.data_table;
This is done to give users of db2 access to this single table in db1, and works for SELECT queries:
[db2_user#db2]> select name from data_view limit 1;
+----------------+
| name |
+----------------+
| slartibartfast |
+----------------+
1 row in set (0.00 sec)
However, when I try and explain the same query, I get:
[db2_user#db2]> explain select name from data_view limit 1;
ERROR 1345 (HY000): EXPLAIN/SHOW can not be issued; lacking privileges for
underlying table
I granted the db2 user the SHOW VIEW privilege for the view, but I get the same error for EXPLAIN.
GRANT SHOW VIEW ON `db2`.`data_view` TO 'db2_user'#'%';
What is required to allow users with access to the view to run EXPLAIN on it?
You are trying to explain the query which is different than show create view. Explaining a query is same as selecting it (talking from privilege point of view), hence a select privilege shall be enough for it
GRANT select, SHOW VIEW ON `db2`.`data_view` TO 'db2_user'#'%';
explain select name from data_view limit 1;
Note that the behavior here appears to have changed between MySQL 5.0 and 5.5, as described in MySQL bug 64198.
I ran into a failure to run an EXPLAIN on a query and found the reason in the MySQL 5.7 documentation:
"The SELECT privilege is needed for tables or views used with EXPLAIN, including any underlying tables in view definitions. "
The needing SELECT permission on the underlying tables of the views was the problem for me. We wall our data off from our lower level analysts by exposing views that they have SELECT rights for but giving the analysts no rights to the underlying tables. This works well for us but makes it impossible for our analysts to use EXPLAIN to optimize their queries. Maybe some of you are running into the same problem.

Is there a database tool which shows a list of sql commands I have permission for?

I talked to the developer of HeidiSQL about it and he told me I can query it by "show grants" command of sql, but i don't understand the result set coming from it.
show grants // I execute query here
GRANT USAGE ON . TO 'fsdb1user1'#'%' IDENTIFIED BY PASSWORD
'something'
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP,
REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON
fsdb1.* TO 'fsdb1user1'#'%'
mysql documentation says
SHOW GRANTS displays only the privileges granted explicitly to the
named account. Other privileges might be available to the account, but
they are not displayed. For example, if an anonymous account exists,
the named account might be able to use its privileges, but SHOW GRANTS
will not display them.
I think there might be some software somewhere trying some queries and checks grants that way.
It appears that this user is allowed to do a lot. Here is actually a good reference on all of these http://dev.mysql.com/doc/refman/5.1/en/grant.html#grant-privileges.
The user in question can run SELECT, UPDATE, and DELETE queries. They can CREATE tables and databases. They can DROP tables, databases, and views. They can create and alter INDEXes. They can ALTER table structures. They can use CREATE TEMPORARY TABLE. And finally, they can LOCK TABLES that they have SELECT privileges on. In this case, the user can do this on any table in this database (fsdb1) and from any host.