[MDEV-27541] Nonsense error "alter routine command denied" Created: 2022-01-18  Updated: 2022-02-14

Status: Stalled
Project: MariaDB Server
Component/s: Authentication and Privilege System
Affects Version/s: None
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: Christopher Yeleighton Assignee: Sergei Golubchik
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The server reports an access error when it is expected to do nothing.

Server version: 10.6.5-MariaDB

\utest
DROP PROCEDURE IF EXISTS THIS_PROCEDURE_DOES_NOT_EXIST;

ERROR 1370 (42000): alter routine command denied to user ''@'localhost' for routine 'test.THIS_PROCEDURE_DOES_NOT_EXIST'



 Comments   
Comment by Daniel Black [ 2022-01-18 ]

The server in all SQL aspects is implemented to check access before running the SQL.

Without a denied error, it could lead users to believe it could DROP PROCEDURE. If we extended the pattern would there be no access denied for SELECT * FROM protected_table WHERE id=MISSING_ID?

Is removal of access denied errors what you are asking for? This behaviour is probably defined in the SQL standard.

Or is "alter routine" inaccurate for a "drop routine" SQL? There are only ALTER PROCEDURE and EXECUTE grants on procedures - https://mariadb.com/kb/en/grant/#procedure-privileges.

Comment by Christopher Yeleighton [ 2022-01-18 ]

If we extended the pattern would there be no access denied for SELECT * FROM protected_table WHERE id=MISSING_ID?

SELECT WHERE FALSE is not a no-op, so no. DROP IF EXISTS is, by definition, a no-op.

I am not asking for removal of ACCESS DENIED checks.

ALTER ROUTINE is accurate for DROP PROCEDURE. It is accurate for DROP PROCEDURE IF EXISTS if the procedure exists. Please observe that I get no error if it exists.

Thank you for your consideration.

Comment by Daniel Black [ 2022-01-19 ]

To return a non-error result on DROP PROCEDURE IF EXISTS THIS_PROCEDURE_DOES_NOT_EXIST; where the procedure doesn't exist is an information disclosure vulnerability.

The user may not have even the permissions EXECUTE let alone ALTER PROCEDURE so disclosing the existence of the procedure where they don't have access is an information disclosure vulnerability. Keeping the Access denied, even though its a no-op, removes the vulnerability. Even a basic attempt at checking if the procedure exists before access control checks introduces potential timing based disclosure of the procedure's existence.

CC serg just in case am I missing something, or as the security responder you have anything to add.

Comment by Christopher Yeleighton [ 2022-02-14 ]

There can be no security vulnerabilities related to the test database. It is there for everyone to see and use as they wish. It offers no integrity guarantees whatsoever.

Comment by Daniel Black [ 2022-02-14 ]

MariaDB [(none)]> \s
--------------
client/mysql  Ver 15.1 Distrib 10.6.7-MariaDB, for Linux (x86_64) using  EditLine wrapper
 
Connection id:		3
Current database:	
Current user:		noboidy@localhost
SSL:			Not in use
Current pager:		stdout
Using outfile:		''
Using delimiter:	;
Server:			MariaDB
Server version:		10.6.7-MariaDB MariaDB Server
Protocol version:	10
Connection:		Localhost via UNIX socket
Server characterset:	latin1
Db     characterset:	latin1
Client characterset:	utf8mb3
Conn.  characterset:	utf8mb3
UNIX socket:		/tmp/build-mariadb-server-10.6.sock
Uptime:			10 sec
 
Threads: 1  Questions: 4  Slow queries: 0  Opens: 17  Open tables: 10  Queries per second avg: 0.400
 
MariaDB [(none)]> \utest
Database changed
 
MariaDB [test]> show grants;
+--------------------------------------+
| Grants for @localhost                |
+--------------------------------------+
| GRANT USAGE ON *.* TO ``@`localhost` |
+--------------------------------------+
1 row in set (0.000 sec)
 
MariaDB [test]> DELIMITER //
MariaDB [test]> 
MariaDB [test]> CREATE PROCEDURE simpleproc (OUT param1 INT)
    ->  BEGIN
    ->   SELECT COUNT(*) INTO param1 FROM t;
    ->  END;
    -> //
Query OK, 0 rows affected (0.001 sec)
 
MariaDB [test]> show create procedure simpleproc\G
*************************** 1. row ***************************
           Procedure: simpleproc
            sql_mode: STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    Create Procedure: CREATE DEFINER=``@`localhost` PROCEDURE `simpleproc`(OUT param1 INT)
BEGIN
  SELECT COUNT(*) INTO param1 FROM t;
 END
character_set_client: utf8mb3
collation_connection: utf8mb3_general_ci
  Database Collation: latin1_swedish_ci
1 row in set (0.000 sec)
 
MariaDB [test]> drop procedure if exists simpleproc//
Query OK, 0 rows affected (0.009 sec)
 
MariaDB [test]> drop procedure if exists simpleproc//
ERROR 1370 (42000): alter routine command denied to user ''@'localhost' for routine 'test.simpleproc'

Apologizes, I see what you are saying now. An anon user can remove procs on test, but gets denied because of the if exist, when it doesn't.

Generated at Thu Feb 08 09:53:42 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.