The talk is divided in following four sections.
(1 )We shall refresh our memory with the basics. Types of database users and privileges basics in MySQL.
(2) We shall divide the DB users in the logical categories,
(3)identify the vulnerability with a certain category of users.
(4) We shall learn to prevent such case with better separation of control.
In the end we shall bring the pieces together to define an access level policy for such users.
without further ado, lets refresh with the basics
MySQL access control involves two stages when a user connects to the server:
Stage 1: The server accepts or rejects the user connection based on user's identity. For instance : user name, host from which the user is connected, password etc. This is authentication.
Stage 2: Once the user connection is established, the server checks each statement user issues to determine whether you have sufficient permissions to perform it. For example, if you try to select rows from a table in a database or drop a table from the database, the server verifies that you have the SELECT permission to for the table. This stage is known authorization and permission checks as authorization.
There are two types of privileges
Static and Dynamic.
Static privileges are built in to the server. They consists types of permission to do database privileges such as SELECT, INSERT, UPDATE etc.
Database privileges apply to a database and to all objects within it. These privileges can be granted for specific schemas, or globally so that they apply to all schemas.
There are static administrative privileges as well such as PROCESS, CREATE USER.
Dynamic privileges can be registered and unregistered at runtime. That means server, components or plugins can define their own dynamic privileges. These privileges are global because they are not specific to a particular database.
How do we assign these privileges to the user account. Use the grant statement. Grant statement is also used to assign the roles.
Revoke statement does the opposite of the grant statement. It removes the privileges from the user account.
A quiz. Which privilege do you need to create users in MySQL ? If were paying attention it was mentioned on the previous slide.
As you guessed it right, CREATE USER. It is static privilege. Create user privilege enables the user to do ALTER USER, CREATE ROLE, CREATE USER, DROP ROLE, RENAME USER AND REVOKE ALL.
That's quite a few .
Besides that if you also have INSERT privilege on mysql schema then also you get the same capabilities.
Now for the rest of the talk lets us call the users who have at least either one of the privilege as privileged users and other users as non-privileged users.
We previously learnt about the DB users. Another quiz. Now, try to guess in which category those users will fall.
Ideally administrators should be able to create other users. So they will be privileges users.
The role of applications talking to DB is usually restricted to the specific tables or schema.
Application admins may also need to manage the DB users. So they could be privileged user.
Advanced or sophisticated users interact with the Database. They need not to create the DB.
Not to mention these users might be connected the database directly or through some other applications which could be internal.
But question arise, how does these applications connect to the database ? Lets find out..
Lets say there is an application. The app users data is stored in the mysql.
Now, the question arise how does the application users talk to database?
Does application open as many DB connections as many app users ? Does it create only one DB connection or a bunch of DB connections ?
There is no one size fit all answer to these questions. It depends upon the use case. The most commonly used strategy is to have a connection pool and reuse the DB connections to fulfil the app user's requirement.
Another question arises. What DB accounts are used by these DB connections ?
Usually the app users need access to a specific schema or table. So they need limited access to the database.
That means non-privileged DB users. Application may use bunch of non privileged users.
In this case DB is not aware of application specific users hence it onus of access control of app users lies on the application. Application may create a user table in the application schema to store the user name, host and password hashes in it
But you need someone to manage these non-privileged users and their data. Usually there is an application admin for that.
https://stackoverflow.com/questions/17475805/application-user-database-user
https://stackoverflow.com/questions/24397002/mysql-application-users-vs-database-users
https://stackoverflow.com/questions/24397002/mysql-application-users-vs-database-users
Do database really interact with only one application ? Usually an application consists of multiple services. each service may have it's own non-privileged users to serve.
If we zoom in further, there could be multiple applications interacting with the database and each application could have it's own services.
This model works well but do you see any problem ?
Do you see the problem now ?
There is privileged user who can create new user, alter or drop existing users. Why ? Because it has CREATE USER privilege. It means privileged user can promote himself to be root user by altering the root user
If a malicious user gets access to the privileged user he can gain control over the instance.
Even not malicious user, a normal app_admin has no business of knowing the information about the instance. So it should be protected. What do we do ?
Enter the system_user privilege in 8.0. release. It allows maintaining the separation of duty better. How ?
User with SYSTEM_USER privilege cannot be modified by user that does not have SYSTEM_USER, even if the latter has CREATE USER.
We can isolate the users that manage the instance from the users that do not manage the data.
We already have learnt about the privileged and non-privileged users. Now suppose you created a new user foo and granted SYSTEM_USER privilege to it. So what ? What good is this foo user for ? It is as good as a member of royal family that inherits the kingdom but doesn't know how to rule. It needs other privileges to be assigned. Now it you grant the foo user CREATE USER privilege then it become equivalent of root user. We name such user as power user since It can modify any user present in the instance. While privileged user could modify other privileged users/non-privileged user.
We categorize the users as privileged and non-privileged before. Lets call them both as regular users.
Since there were user who existed before SYSTEM_USER privilege was introduced. The users granted only system user privileges, lets call them system_user. They are no use unless they are granted other privileges.
If you grant the privileges in addition to system_user then we can imagine them as power users.
For instance - Instance admins.
Is this isolation through SYSTEM_USER privilege sufficient ?
We have protected the administrators that manages the instances by making them as power user. The regular users cannot modify power users using the DDLs.
But what if a regular user has global INSERT or UPDATE privilege ? It can still modify the mysql.user table. Lets see how to plug this loophole.
Partial revokes allows creating exception to global grants. If a user has been granted a global privilege then we can revoke the access of that user at schema levels.
For example - There is developer who can query the entire database. The database has a sensitive schema hrdb, we don't want developer to access. We can revoke the access from developer to this schema despite having the global select access.
We can restrict the regular users modifying the power user through DMLs using the partial revokes.
We identified the possibility of privilege escalation. It is good to keep the instance admins behind the system_user privilege wall to protect them getting modified by other users using DDL statements.
The Good old principle of least privileges still holds true. Don't over grant privilges to the users.
If you have to grant global DML to some users then use the partial revokes to restrict the access on mysql schema.
A good strategy will be to have a role that has access to global access but restrict access to mysql schema.
Since there is mechanism to draw clear boundary between the app_Admins and instance admin. You can manage the DB users in a better manner. You can have multiple app_admins without risking them high jacking the root account.