如何只允许通过存储过程插入?

时间:2016-05-31 03:22:10

标签: mysql sql security stored-procedures insert

我有this question for SQL-Server

的MySQL版本

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

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

input {
  jdbc {
    jdbc_driver_library => "C:\Users\Administrator\Downloads\Microsoft JDBC Driver 4.2 for SQL Server\sqljdbc_4.2\enu\sqljdbc42.jar"
    jdbc_driver_class => "com.microsoft.sqlserver.jdbc.SQLServerDriver"
    jdbc_connection_string => "jdbc:sqlserver://localhost:1433/WIN-07LLQEN2SJB\SQLEXPRESS;user=sa;password=*****"
    jdbc_user => "sa"
    jdbc_password => "*****"
    schedule => "* * * * *"
    statement => "SELECT database_id, name, data_used_size, log_used_size FROM DISK.dbo.disk_activity"
    jdbc_paging_enabled => "true"
    jdbc_page_size => "50000"
  }
}
filter {
}
output {
  stdout {
    codec => rubydebug
  }
  elasticsearch_http {
    host => "localhost"
    index => "sql"
  }
}

我已在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 ; 时,我得到:

  

第1行的错误1142(42000):INSERT命令被拒绝用户'用户名'@'localhost'用于表'dbtable'

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

1 个答案:

答案 0 :(得分: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子句中指定的用户的权限执行该过程。在这两种情况下,只要 definer 具有数据对象的权限, invoker 只需要对过程本身拥有特权。

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

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

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

指定SECURITY INVOKER会导致MySQL使用使用存储过程的权限执行。这意味着调用者必须对过程访问的所有数据对象上的过程具有特权。例如,可以使用管理例程来完成此操作,以便不允许在系统表中进行清理的用户也无法使用在系统表中粘贴的过程,即使意外地授予了访问该程序的权限。