【问题标题】:Provide only GRANT EXECUTE 'procedure' to a user (No select or insert permissions)仅向用户提供 GRANT EXECUTE 'procedure'(无选择或插入权限)
【发布时间】:2017-05-30 15:45:00
【问题描述】:

我想知道是否可以向用户授予EXECUTE 权限而不授予对运行过程的表的SELECTINSERT 等权限?

将它用于 web 应用程序的登录表。 MySQL 在 Docker 容器中运行。用于创建过程的 SQL 作为 docker build 过程的一部分被复制(运行时,sql 在 entrypoint.sh 中使用)。运行容器时会创建 Login_db(-e 标志)。

我想从下面删除 GRANT SELECT 行,所以无论发生什么,webapp 服务器都无法运行 SELECT 查询 - 例如执行 SELECT * FROM logins

CREATE USER 'logins'@'172.24.0.7' IDENTIFIED BY 'some-password';
GRANT SELECT, INSERT, UPDATE on logins_db.login TO 'logins'@'172.24.0.7';
GRANT EXECUTE ON PROCEDURE logins_db.sp_login16 TO 'logins'@'172.24.0.7';
FLUSH PRIVILEGES;

这并不能解决问题 - 因为作为表所有者会暴露相同的权限:

Execute stored proc fails with GRANT EXECUTE because of table permissions

这可以解释为什么我不能,但是表名对我来说有点奇怪(MySQL 新手 - 我的印象是 mysql.proc 是一个系统表,所以不确定它是否适用):

How to grant execute on specific stored procedure to user

是否可能是 root 在创建过程时没有 SELECT 权限,因此登录用户无法运行它? (因为 Docker MySQL 运行 entrypoint.sh 然后是环境变量)?

程序代码在这里(我知道,不是最优雅的)-考虑到DEFINER 是root,我可以GRANT 然后REVOKE 在其中为logins 用户提供特权吗?

CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_login16`(
IN p_email VARCHAR(120),
IN p_password VARCHAR(120))
BEGIN
SELECT user_id,user_password FROM login WHERE user_email = p_email;

【问题讨论】:

    标签: mysql security stored-procedures docker grant


    【解决方案1】:

    是的,您可以通过在声明 stored procedure 时使用 sql security definer 来做到这一点:

    SQL SECURITY 特性可以用 DEFINER 或 INVOKER 来指定 安全上下文;也就是说,例程是否使用 例程 DEFINER 子句中指定的帐户的权限或 调用它的用户。此帐户必须有权访问 例程关联的数据库。默认值为 定义者。调用例程的用户必须拥有 EXECUTE 它的特权,如果例程执行,DEFINER 帐户也必须如此 在定义者安全上下文中。

    DEFINER 子句指定了在什么情况下要使用的 MySQL 帐户 在例程执行时检查例程的访问权限 具有 SQL SECURITY DEFINER 特性。

    如果给 DEFINER 子句一个用户值,它应该是一个 MySQL 指定为 'user_name'@'host_name'、CURRENT_USER 或 当前用户()。默认的 DEFINER 值是执行 CREATE PROCEDURE 或 CREATE FUNCTION 语句。这与 明确指定 DEFINER = CURRENT_USER。

    总结一下:在这种情况下,definer 子句中的用户必须具有对底层表的选择/插入权限,而执行存储过程的用户必须对存储过程具有执行权限。

    【讨论】:

    • 感谢您的回答。如果我错了,请纠正我,但是 > 因此,该过程是否成功取决于调用者是否具有它的 EXECUTE 权限和 mysql.user 表的 SELECT 权限。会建议登录用户需要在登录表上拥有SELECT 权限?
    • 对不起,我不太理解你的总结。不过可以肯定的是,非管理员用户不应该对 mysql 数据库(名为 mysql 的数据库)中的任何表有任何访问权限。甚至没有选择。
    • 所以在您链接到的页面的更下方,有两个示例。我引用的东西(因此........ MySQL.user 表)来自第二个示例之后。似乎表明具有执行权限的用户必须对将运行存储过程的表具有选择权限?
    • 不,示例后的文档明确说明“过程成功或失败取决于调用者是否具有 EXECUTE 权限并且 'admin'@'localhost' 具有 mysql.user 的 SELECT 权限桌子。”管理员帐户是示例中的定义者。
    • 啊!所以两者的第一个例子是相关的。明白了!谢谢!
    【解决方案2】:

    添加了具有SELECTINSERTUPDATE 权限的新用户ADMIN@localhostADMIN 然后成为所有过程的DEFINER'logins'@'172.24.0.7' 仅被授予EXECUTE 权限。现在完美运行!

    显然你不能像我尝试的那样使用 root。感谢@Shadow 为我指明了正确的方向。

    设置管理员用户:

    CREATE USER 'admin'@'localhost' IDENTIFIED BY '<password>';
    GRANT SELECT, INSERT, UPDATE, DELETE ON db.table_name TO 'admin'@'localhost';
    GRANT ALTER ROUTINE, CREATE ROUTINE, EXECUTE ON *.* TO 'admin'@'localhost'; 
    FLUSH PRIVILEGES;
    

    定义使用受限管理员用户创建条目的存储过程

    DELIMITER $$
    CREATE DEFINER=`admin`@`localhost` PROCEDURE `sp_createTableEntry`(
    
        IN value_one VARCHAR(120),
        IN value_two VARCHAR(200)
    )
    BEGIN
        IF ( select exists (select 1 from table_name where column_one = value_one) ) THEN
         
            select 'Column One Exists !!';
         
        ELSE
         
            insert into table_name
            (  
                column_one,
                column_two
            )
            values
            (
                value_one,
                value_two
            );
        END IF ;
    END $$
    DELIMITER ;
    

    【讨论】:

    • 你的链接失效了。
    • @Fusion 将链接替换为实际的 sql。抱歉,请稍后将 repo 设置为私有。
    猜你喜欢
    • 2013-07-30
    • 2020-08-08
    • 2017-07-06
    • 1970-01-01
    • 2012-10-20
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    相关资源
    最近更新 更多