【问题标题】:SQL Server stored procedure that grants itself EXECUTE permission授予自身 EXECUTE 权限的 SQL Server 存储过程
【发布时间】:2020-06-04 23:07:52
【问题描述】:

尝试搜索此内容,但找不到任何内容。我在生产数据库中有一些存储过程,开发人员最后添加了一个

GRANT EXECUTE ON [ProcName] to [USER1] AS [dbo]

我的敏锐感觉告诉我不应该这样做,因为所有用户访问都应该(并且是)在 SSMS 中以适当的级别进行管理。如果数据库开始真的很忙并且每次都不断地授予此访问权限,这也可能会引入死锁。

除了确保用户在开发过程中获得许可之外,我一生都想不出为什么需要这样做的正当理由。我打算删除它,但我只是想知道我是否遗漏了什么?

【问题讨论】:

  • 很可能,部署脚本在 proc 和后续 GRANT 之间缺少一个 GO 批处理终止符,因此该语句成为存储过程的一部分。

标签: sql-server stored-procedures access-control sql-grant


【解决方案1】:

99.999% 的可能性这是一个错误。存储过程在批处理结束时结束。开发人员可能使用这样的 DDL 批处理创建了该过程:

create procedure foo
as
begin
  print 'foo'
end

grant execute on foo to User1 as dbo  --this is still part of the procedure!
go

默认情况下,存储过程作为调用者执行,调用者在没有管理员身份的情况下无法运行该 GRANT。

在您的 DDL 脚本中包含 GRANT 是一种很好的做法,但是对于每个对象使用单独的 GRANT 是一种可以追溯到好的工具(如 SSDT)之前和用户模式分离之前的做法。

今天,在架构级别进行 GRANT 是一种更好的做法,因此无需为每个对象设置权限。虽然 GRANT 应该是模式设计的一部分,并且在不同环境中是相同的,但这些授权通常应该是对 SCHEMA 上的角色的 GRANT。然后在不同的环境中,ROLE 可能有不同的成员,但 GRANT 永远不会改变。

所以生产 DBA 可能会运行

ALTER ROLE APP_FRONT_END ADD MEMBER [MyDomain\AppPoolIdentity]

但不是

GRANT EXECUTE ON FOO TO [MyDomain\AppPoolIdentity]

【讨论】:

  • 谢谢大卫...同意这可能更多的是一个错误而不是目的。正如对 Jeff 的回答所评论的那样,这是从过去的开发人员那里继承的代码,有些缺少 GO,因此 GRANT 成为了过程的一部分。我是 SO 新手,我看到我只能将一个解决方案评为最佳答案,但我认为两者都是有效的。对于这个问题,我认为正如您所指出的,在开发人员方面(以及其他让其进入生产阶段的人)更多的是一个错误,但我也同意 Jeff 的观点,即让人们承担责任。
  • 为了弥补只能标记一个正确答案,我投票赞成@DavidBrowne 的帖子和您在上面的评论。也感谢您提供上述反馈。
  • SSDT 默认执行此操作,如果您向下滚动到存储过程的末尾,您将看到包含 GRANT 语句。
【解决方案2】:

不...你没有错过任何东西。对于很多“开发人员”来说,这实际上是一件很常见的事情,开发人员需要为此被拉到地毯上。 CTO、开发经理和 DBA 应该加入他们,如果其中之一能够通过并且是主要原因之一...

  1. 绝不应允许开发人员将代码部署到 staging、UAT 或 Prod
  2. 为什么应该有一个 100% 的代码审查流程
  3. 为什么要对此类事情制定书面规则,而绝对不能容忍此类事情。恕我直言,“一劳永逸,你在这里”。

如果没有他们支付的人做这种愚蠢的事情,公司的安全问题就已经够多了。对这种事情应该零容忍。

如果这一切让我在这个主题上听起来很残酷,那么我已经成功地说出了关于这个主题需要说的话,但是你(读者)可能是问题的一部分。

{编辑} 让我再定义一下……

这作为部署脚本的一部分可能是合法的,但它绝不应该是实际存储过程的一部分,因为没有理由不断地向给定的存储过程授予相同的权限。这对我来说仍然是“违规”,因为开发人员不应该通过代码或任何其他方式分配权限。只有 DBA 应该分配这样的 priv,并且需要有票证或其他一些可追溯性来说明为什么需要这些 priv 才能通过安全审计。

也没有理由将 DBO 级别的执行权限授予给定用户。您应该只向用户授予 EXECUTE privs 权限,并且存储过程中应该有正确的 WITH EXECUTE AS xxxxx 语句才能完成存储过程需要做的事情。

如果授权代码中的“user1”是开发人员,那么是时候让开发人员了解他们为什么要这样做了。但是,就像我说的,这段代码实际上不应该存在。应该由 DBA 授予此类权限。

如果它是一个现有的存储过程,合法用户需要它以“dbo”级别的权限执行,则可能需要使用 WITH EXECUTE AS xxxxx 修复该存储过程,而不是授予个人此类权限。

与 SQL Server 中的所有其他内容一样,“IT DEPENDS”和我所说的可能有一个非常罕见的例外,但我会找到一种不同的方法来使它工作,特别是如果引用的“user1”是公众面孔应用程序。

【讨论】:

  • 感谢 Jeff...这是从过去的开发人员那里继承的代码,在检查更多代码时,我发现有些缺少 GO,因此 GRANT 成为 proc 的一部分,但有些没有。同意这是草率的,不应该通过代码审查。 (如果它曾经碰巧开始)
  • 同意,它永远不应该成为实际过程的一部分,并且很可能是开发人员错过了在开发后将其完全删除或在其之前添加 GO 以使其不会被编译。在我作为开发人员的过去生活中,即使在开发过程中,我也从未在我的过程中这样做过;从来没有必要,而且我从来没有遇到过它作为 DBA 在生产中的合法需求,所以看到它感到很惊讶,因此想知道我是否“没有得到关于这种方法的备忘录”。澄清一下,“user1”实际上是一个 db 角色,但是,如上所述,privs 不应在每次运行时都在 proc 中完成。
  • 感谢他对 Karl 的反馈。了解有关此类问题背景的更多详细信息总是很好。
猜你喜欢
  • 2014-12-23
  • 2015-12-01
  • 1970-01-01
  • 2010-09-30
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多