【问题标题】:How to allow insert through stored procedure only?如何只允许通过存储过程插入?
【发布时间】:2016-05-31 03:22:09
【问题描述】:

我有this question for SQL-Server的MySQL版本

我正在使用 readline 6.3 为 debian-linux-gnu (x86_64) 运行 mysql Ver 14.14 Distrib 5.5.49

我创建了一个只有这个权限的用户:

CREATE USER 'username'@'localhost' IDENTIFIED BY 'p@55w0rd';
GRANT EXECUTE ON dbname.* TO 'username'@'localhost';

我在dbname 上创建了这个程序:

DELIMITER $$
CREATE PROCEDURE seed_database()
this_procedure:BEGIN

  INSERT INTO `dbtable` VALUES (1,'data');

END $$
DELIMITER ;

但是当我使用该用户登录并尝试CALL seed_database(); 时,我得到:

ERROR 1142 (42000) at line 1: INSERT command denied to user 'username'@'localhost' for table 'dbtable'

我试图通过只允许用户执行存储过程来遵循the principle of least privilege。我不想授予用户权限直接在具有明显GRANT INSERT ON dbname.dbtable TO 'username'@'localhost'; 的表上插入,以防凭据被泄露,并且因为我在存储过程中有一些复杂的逻辑会产生要存储的输入(由硬表示-我不希望用户直接生成和插入的示例(1,'data') 中的编码数据。但我希望他们使用存储过程来实现相同的目标。

【问题讨论】:

    标签: mysql sql security stored-procedures insert


    【解决方案1】:

    我建议您阅读definer's rights procedures。您应该能够定义您的程序以特权用户身份运行,然后将GRANT EXECUTE 定义为非特权用户:

    GRANT INSERT ON TABLE dbtable
      TO 'privileged_user'@'localhost';
    
    CREATE
        DEFINER = 'privileged_user'@'localhost'
      PROCEDURE seed_database()
        BEGIN
    
          INSERT INTO `dbtable` VALUES (1,'data');
    
        END;
    
    GRANT EXECUTE ON PROCEDURE dbname.seed_database
      TO 'unprivileged_user'@'localhost';
    

    免责声明:我目前还没有准备好对此进行测试,但它应该可以工作。

    默认情况下,MySQL 以“定义者的权限”执行存储过程,即使用创建存储过程的人的权限。这意味着该用户必须对过程访问的所有数据对象具有特权。当DEFINER 子句在CREATE FUNCTION / PROCEDURE 中指定时,MySQL 将改为以DEFINER 子句中指定的用户的权限执行该过程。在这两种情况下,只要定义者拥有数据对象的权限,调用者只需要过程本身的权限。

    调用者或定义者的权限也可以明确指定,如

    CREATE PROCEDURE seed_database()
      SQL SECURITY DEFINER
      BEGIN
        ...
    

    在没有DEFINER = 子句的情况下指定SECURITY DEFINER 会导致定义者默认为实际执行CREATE 语句的人。这与不指定任一子句相同。

    指定SECURITY INVOKER 会使MySQL 以使用存储过程的人的权限执行。这意味着调用者必须对过程拥有过程访问的所有数据对象的权限。例如,这可以通过管理例程来完成,这样不允许在系统表中乱搞的用户也不能使用在系统表中乱搞的过程,即使意外授予对该过程的访问权限。

    【讨论】:

    • 谢谢!那是我需要的必读。在做了一些测试之后,我意识到它在以 root 身份创建过程时第一次确实有效。但是我试图创建一个用户可以更改、删除和创建过程的测试环境,从而混淆了一些事情。我天真地假设所有 SP 都以提升的权限运行。因此他们可以重新创建该过程,但显然允许插入权限将是一个安全漏洞。谢谢
    • 非常欢迎。为了未来读者的利益,我在我的答案中添加了一些关于调用者与定义者权利的信息。
    • 关于 默认情况下,MySQL 以“调用者的权限”执行存储过程,这在最近的版本中可能已经改变,但对于 5.5 SQL SECURITY 特性可以是 DEFINER 或 INVOKER ... 默认 值是 DEFINER ... 默认 DEFINER 值是执行 CREATE PROCEDURE 的用户 与我的一致当 sp 由 root 定义时(完全省略 SQL SECURITY DEFINER 和 DEFINER 子句),之前的评论观察 insert 只允许用户执行权限
    • 埃加德,你是对的。我一定有别的想法。我会马上纠正自己。
    猜你喜欢
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 2011-02-01
    • 1970-01-01
    • 2017-01-04
    相关资源
    最近更新 更多