MySQL Stored Object Access Control

Summary: in this tutorial, you will learn about the stored object access control in MySQL.

In MySQL, stored programs including stored procedures stored functions, triggers, and events execute within a security context which determines their privileges.

MySQL uses DEFINER and SQL SECURITY characteristics to control these privileges.

The DEFINER attribute

When you define a stored routine such as a stored procedure or function, you can optionally specify the DEFINER attribute, which is the name of a MySQL account:

CREATE [DEFINER=user] PROCEDURE spName(parameter_list)
...

CREATE [DEFINER=user] FUNCTION sfName()
...
Code language: SQL (Structured Query Language) (sql)

If you skip the DEFINER attribute, the default is the current user account.

You can specify any account in the DEFINER attribute if you have the SUPER or SET_USER_ID privilege. If you specify a user account that does not exist, MySQL will issue a warning.

As of MySQL 8.0.16, you must have the SYSTEM_USER privilege to set the DEFINER attribute for a stored object to a user account that has the SYSTEM_USER privilege.

The SQL SECURITY characteristic

Stored routines (stored procedures and functions) and views can include an SQL SECURITY clause with a value of DEFINER or INVOKER:

CREATE [DEFINER=user] PROCEDURE spName(parameter_list)
SQL SECURITY [DEFINER | INVOKER]
...

CREATE [DEFINER=user] FUNCTION sfName(parameter_list)
SQL SECURITY [DEFINER | INVOKER]
...
Code language: SQL (Structured Query Language) (sql)

SQL SECURITY DEFINER

When you use the SQL SECURITY DEFINER for a stored object, it will execute in a definer security context with the privilege of the user specified by the DEFINER attribute.

Note that the user that invokes the stored object (or invoker) may not have the same privilege as the definer.

In case the invoker has the least privilege and the definer has the most privileges, the invoker can perform operations above its privilege within the stored object.

SQL SECURITY INVOKER

If you use the SQL SECURITY INVOKER for a stored routine or view, it will operate within the privileges of the invoker.

The DEFINER attribute has no effect during object execution.

Stored object access control example

First, create a new database called testdb:

CREATE DATABASE testdb;Code language: SQL (Structured Query Language) (sql)

Second, select the database testdb to work with:

USE testdb;Code language: SQL (Structured Query Language) (sql)

Third, create a new table called messages:

CREATE TABLE messages (
    id INT AUTO_INCREMENT,
    message VARCHAR(100) NOT NULL,
    PRIMARY KEY (id)
);Code language: SQL (Structured Query Language) (sql)

Fourth, create a stored procedure that inserts a new row into the messages table:

DELIMITER $$

CREATE DEFINER = root@localhost PROCEDURE InsertMessage( 
    msg VARCHAR(100)
)
SQL SECURITY DEFINER
BEGIN
    INSERT INTO messages(message)
    VALUES(msg);
END$$

DELIMITER ;Code language: SQL (Structured Query Language) (sql)

In this stored procedure, the definer is root@localhost that is the superuser which has all privileges.

The SQL Security is set to the definer. It means that any user account that calls this stored procedure will execute with all privileges of the definer i.e., root@localhost user account.

Fifth, create a new user named dev@localhost:

CREATE USER dev@localhost 
IDENTIFIED BY 'Abcd1234';Code language: SQL (Structured Query Language) (sql)

Sixth, grant the EXECUTE privilege to dev@localhost so that it can execute any stored procedure in the testdb database:

GRANT EXECUTE ON testdb.* 
TO dev@localhost;Code language: SQL (Structured Query Language) (sql)

Seventh, use the dev@localhost to log in to the MySQL Server:

mysql -u dev@localhost -pCode language: SQL (Structured Query Language) (sql)

Eight, use the SHOW DATABASES to display the database that dev@localhost can access:

mysql> show databases;Code language: SQL (Structured Query Language) (sql)

Here is the list:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| testdb             |
+--------------------+
2 rows in set (0.00 sec)
Code language: SQL (Structured Query Language) (sql)

Ninth, select the testdb database:

mysql> use testdb;Code language: SQL (Structured Query Language) (sql)

Tenth, call the InsertMessage procedure to insert a row into the messages table:

mysql> call InsertMessage('Hello World');Code language: SQL (Structured Query Language) (sql)

This is the output:

Query OK, 1 row affected (0.01 sec)Code language: SQL (Structured Query Language) (sql)

Even though dev@localhost does not have any privilege on the messages table, it can insert a new row into that table successfully via the stored procedure because the stored procedure executes in the security context of the root@localhost user account.

Eleventh, go to the root’s session and create a stored procedure that updates the messages table:

DELIMITER $$

CREATE DEFINER=root@localhost 
PROCEDURE UpdateMessage( 
    msgId INT,
    msg VARCHAR(100)
)
SQL SECURITY INVOKER
BEGIN
    UPDATE messages
    SET message = msg
    WHERE id = msgId;
END$$

DELIMITER ;
Code language: SQL (Structured Query Language) (sql)

The UpdateMessage has the security context of INVOKER who calls this stored procedure.

Twelfth, go to the dev@localhost‘s session and call the UpdateMessage() stored procedure:

mysql> call UpdateMessage(1,'Good Bye');
Code language: SQL (Structured Query Language) (sql)

This time the UpdateMessage() stored procedure executes with the privileges of the caller which is dev@localhost.

Because dev@localhost does not have any privileges on the messages table, MySQL issues an error and rejects the update:

ERROR 1142 (42000): UPDATE command denied to user 'dev'@'localhost' for table 'messages'
Code language: SQL (Structured Query Language) (sql)

In this tutorial, you have learned about the MySQL stored object access control.

Was this tutorial helpful?