MySQL 5.7 存储程序和视图的访问控制

存储程序和视图的访问控制
存储程序和视图是在使用之前定义的,当被引用时,会在一个安全上下文中执行,这个安全上下文中决定了它们的权限。这些权限由它们的 DEFINER属性控制,如果有,则由它们的SQL SECURITY控制。

所有存储程序(过程、函数、触发器和事件)和视图都可以有一个DEFINER属性来命名MySQL帐户。如果在存储程序或视图定义中省略了DEFINER 属性,则默认帐户是创建对象的用户。

触发器和事件没有SQL SECURITY特性,总是在定义器上下文中执行。服务器根据需要自动调用这些对象,因此不存在调用用户。

定义器和调用程序安全上下文的区别如下:
.在definer安全上下文中执行的存储程序或视图使用由其definer属性命名的帐户的特权执行。这些权限可能与调用用户的权限完全不同。调用 者必须具有适当的权限来引用对象(例如,EXECUTE以调用存储过程,或SELECT以从视图中选择),但是当对象执行时,调用者的权限被忽略, 只有定义者帐户权限重要。如果该帐户的权限很少,则对象可以执行的操作就会相应地受到限制。如果定义者帐户具有高度特权(例如root帐户 ),那么无论谁调用它,对象都可以执行强大的操作。

.在调用者安全上下文中执行的存储例程或视图只能执行调用者具有权限的操作。可以指定DEFINER属性,但对在调用者上下文中执行的对象无效 。
考虑下面的存储过程:

CREATE DEFINER = 'admin'@'localhost' PROCEDURE p1()
SQL SECURITY DEFINER
BEGIN
UPDATE t1 SET counter = counter + 1;
END;

任何拥有p1的EXECUTE权限的用户都可以用CALL语句调用它。然而,当p1执行时,它是在definer安全上下文中执行的,因此以` admin ` @ ` localhost `的特权执行,该帐户在definer属性中命名。该帐户必须具有p1的EXECUTE权限以及表t1的UPDATE权限。否则,该过程将失败。

现在考虑这个存储过程,它与p1相同,只是它的SQL SECURITY是INVOKER:

CREATE DEFINER = 'admin'@'localhost' PROCEDURE p2()
SQL SECURITY INVOKER
BEGIN
UPDATE t1 SET counter = counter + 1;
END;

与p1不同,P2在invoker安全上下文中执行。DEFINER属性是不相关的,p2以调用用户的权限执行。如果调用者缺少p2的EXECUTE特权或表t1的 UPDATE特权,p2就会失败。

MySQL使用以下规则来控制用户可以在对象DEFINER属性中指定哪些帐户:
.只有当您具有SUPER权限时,才能指定除您自己的帐户之外的DEFINER值。

.如果您没有SUPER权限,那么唯一合法的用户值就是您自己的帐户,可以直接功或使用CURRENT_USER指定,您不能将定义器设置为其他帐户。

为了尽量减少存储程序和视图创建和使用的潜在风险,请遵循以下指导方针
.对于存储例程或视图,尽可能在对象定义中使用SQL SECURITY INVOKER,以便仅由具有该对象执行的操作的适当权限的用户使用。

.如果在使用具有SUPER权限的帐户时创建定义上下文存储的程序或视图,请指定一个显式的DEFINER属性,该属性指定仅拥有该对象执行的操作 所需权限的帐户。只有在绝对必要时才指定具有高度特权的DEFINER帐户。

.管理员可以通过不授予用户SUPER权限来阻止用户指定高权限的DEFINER帐户。

.在编写定义器-上下文对象时,应牢记它们可能能够访问调用用户没有特权的数据。在某些情况下,可以通过不授予未授权用户特定权限来阻止 对这些对象的引用:
.没有EXECUTE权限的用户不能引用存储过程或函数。

.视图不能被没有相应权限的用户引用(SELECT用于从中选择,INSERT用于向其中插入,等等)。

但是,触发器不存在这种控制,因为用户不直接引用它们。触发器总是在definer上下文中执行,通过访问与其关联的表来激活,即使是没有特 权的用户访问普通表也可以。如果定义帐户是高度特权,触发器可以执行敏感或危险的操作。如果从创建触发器的用户的帐户中撤销了创建触发 器所需的SUPER和TRIGGER权限,则仍然如此。管理员在授予用户这种特权组合时应该特别小心。

发表评论

电子邮件地址不会被公开。