存储过程与无存储过程 - 安全观点
Posted
技术标签:
【中文标题】存储过程与无存储过程 - 安全观点【英文标题】:Stored Procedures vs No Stored Procedures - Security Viewpoint 【发布时间】:2010-11-15 01:17:06 【问题描述】:对于 Web 应用程序数据库,从安全的角度仅,与仅 sp 解决方案相反的论点是什么,其中 app db 帐户无权访问表和视图,只能执行sps?
如果有人拦截了 app db 帐户,那么受到攻击的表面区域会比不暴露表和视图时要小得多。非 sp 解决方案提供(或不提供)哪些安全优势?我看到了使用非 sp 解决方案的许多优点,但是公开所有表让我有点担心。
这个问题是针对主要数据库供应商的产品,但特别是 sql server 2008。
【问题讨论】:
【参考方案1】:好吧,我想您自己确实抓住了问题的核心:如果您不对所有 CRUD 操作使用存储过程,则您必须至少授予一个特定于应用程序的数据库用户帐户至少对所有表的 SELECT 权限.
如果您想允许 db 帐户执行更多工作,该帐户可能还需要其他权限,例如能够对某些表进行 UPDATE 和 DELETE。
我看不出非存储 proc 方法如何带来任何安全优势 - 它确实打开了更多的大门,真正的问题是:你能负担得起吗?您能否充分保护特定于应用的数据库帐户,使其不会损害您系统的整体安全性?
一种可能的折衷方案是使用视图或表访问权限来允许 SELECT,但使用存储过程处理其他所有内容(更新、删除、插入) - 一半安全,一半方便...
通常情况下 - 这是便利性(非 sp 方法;可能使用 ORM)和安全性(所有 SProc 方法;可能更麻烦,但更安全)之间的经典权衡。
马克
【讨论】:
谢谢。我已经考虑过您的部分解决方案 - 选择表格,更新 sps。你试过这种方法吗?有什么意外导致问题吗? @Steve:不,我从来没有做过这种混合方法。我以前的工作是全 SProc - 安全,但工作起来很痛苦。我目前的一个是直接访问表 - 方便但不是非常安全....【参考方案2】:这是传统智慧正确的领域之一:仅公开存储过程可以让您更好地控制安全性。直接访问表和视图更容易,有时您需要这样做,但安全性会降低。
【讨论】:
【参考方案3】:仅从安全的角度来看,我看不出非 SP 方法比 SP 方法有任何优势,因为:
您必须直接向基础表等授予权限 使用 sproc,可以封装/隐藏所有真正的底层架构信息(SP 也可以加密)【讨论】:
【参考方案4】:不使用存储过程的最大安全优势是清晰。通过查看帐户对表的访问权限,您可以确切地知道帐户可以做什么。对于存储过程,情况不一定如此。如果一个帐户有能力执行过程 X,那确实会限制该帐户执行该过程并且不会访问基础表,但 X 可以做任何事情。它可以删除表、更改数据、删除数据等。
要了解帐户可以使用存储过程做什么,您必须查看存储过程。每次更新存储过程时,都必须有人查看它的作用,以确保不会“意外”将某些东西放入其中。存储过程中安全性的真正问题来自组织内部,而不是流氓攻击者。
这是一个例子:
假设您试图限制对员工表的访问。如果没有存储过程,您只会拒绝对表的访问。要获得访问权限,几乎有人必须公然要求您授予权限。当然,他们可以让您运行一个脚本来授予访问权限,但大多数人至少会尝试查看一个更改数据库模式的脚本(假设该脚本不更新存储过程,我将在下面讨论)。
一个应用程序可能有数百个存储过程。根据我的经验,它们会经常更新,在这里添加一个字段,在那里删除一个。让某人一直查看更新过程脚本的数量变得令人生畏,并且在大多数组织中,数据库团队开始只快速查看过程(或不查看全部),然后继续进行。这就是真正的问题所在。现在,在此示例中,如果 IT 人员中的某个人想要允许访问某个表,则该人只需要插入一行代码来授予访问权限或执行其他操作。在一个完美的世界里,这会被抓住。我们中的大多数人都没有在一个完美的世界中工作。
存储过程的真正问题在于它们给系统添加了一定程度的混淆。混淆带来了复杂性,而复杂性最终带来了更多的工作来理解管理底层系统。 IT 部门的大多数人都过度劳累,事情就这样过去了。在这种情况下,您不会尝试攻击系统以获得访问权限,而是使用系统负责人来获取您想要的东西。米特尼克是对的,在安全方面,人是问题。
对组织的大多数攻击来自内部。每当您将复杂性引入任何系统时,就会出现漏洞,事情可能会被忽略。不信,想想你在哪里工作。完成有关您将要求谁访问系统的步骤。很快你就会意识到你可以让人们在适当的时候忽略一些事情。成功渗透涉及人员的系统的关键是做一些看似无害但真正具有颠覆性的事情。
记住,如果我试图攻击一个系统:我不是你的朋友;我对你的孩子或爱好没有兴趣;我会以任何必要的方式使用你来得到我想要的;我不在乎我是否背叛了你。 “但他是我的朋友,这就是为什么我相信他相信他所做的事情是正确的”的想法在事后并不令人安慰。
【讨论】:
为谁澄清?如果数据库团队负责数据库访问,那么开发人员甚至不应该知道数据库对象(表)的名称。不知道为什么让开发人员看到数据库代码是一种安全优势。 混淆不是安全性。这就像说强盗找不到珠宝,因为我把它藏在壁橱里。如果我真的想闯入不知道架构的东西是一个小烦恼,而不是一个障碍。我的观点是,不使用 sprocs 可以保持简单的安全性,这是确保系统安全的最大因素。从这个角度来看,对 db 系统的更改越少,系统就越安全,因为被忽视的可能性就越小。每次发布都更改存储过程的功能会增加丢失某些内容的机会。 如果你有内联 SQL,你更容易受到 SQL 注入的影响,但使用 Sproc,它只是存储在一个变量中,不会影响调用的结构 没错,但这是调用应用程序的弱点,而不是数据库本身。如果你在 sprocs 中使用动态 sql,你可能同样容易受到 sproc 的 sql 注入。 @Kevin:仍然不明白不使用 Sprocs 如何使其“更”安全或“更”简单。如果唯一允许的访问是 SP 执行,那么我可以在一个地方审核我的所有 SQL 代码,并确定哪些 proc 访问哪些对象 - 如果我允许用户对表的选择权限我不能这样做 - 谁知道他们在写什么查询。【参考方案5】:除了与存储过程的传统安全分离(过程的 EXEC 权限,依赖所有权链接进行数据访问)之外,存储过程可以是 code signed,从而对链接服务器等任何服务器功能进行非常精细和特定的访问控制,server scoped management views,在用户普通访问之外对stored procedures and even data in other databases 的受控访问。
T-SQL 批量发出的普通请求,无论多么花哨,背后有多少层代码生成和 ORM,根本无法签名,因此无法使用最特定 和强大的访问控制机制可用。
【讨论】:
【参考方案6】:让我们以一个需要真正安全的系统为例,比如贵公司的会计系统。如果您使用 procs 并仅授予对 procs 的访问权限,那么用户除了 proc 所做的事情外,永远不能做任何事情。这是一种内部控制,旨在确保系统的任何用户都无法绕过系统的业务规则。这就是阻止人们购买公司然后自己批准资金的原因,从而为欺诈打开了大门。这也可以防止组织中的许多人删除帐户表中的所有记录,因为他们没有删除权限,除了从 proc 授予的权限,一次只允许删除一个。
现在开发人员必须拥有更多权限才能进行开发,但如果您要考虑安全性,他们不应该在生产机器上拥有更多权限。确实,开发人员可以编写一个恶意的 sp,它在投入生产时会做坏事。同一位开发人员虽然可以将相同的代码放入应用程序版本中,但很可能会被抓到或不会被抓到,就好像他们恶意更改了一个过程一样。就我个人而言,我认为 proc 可能更容易捕获,因为它可能会被 dbas 与代码分开审查,这可能意味着经理或配置管理人员和 dbas 有机会仅查看经理或配置管理人员。我们都知道现实是,没有人将代码推送到 prod 有时间亲自审查它的每一部分,因此聘请值得信赖的开发人员至关重要。进行代码审查和源代码控制可以帮助发现恶意更改或将其回滚到以前的版本,但无论如何,使用 sps 副应用程序代码都面临着开发人员的风险。
系统管理员也是如此。为了完成他们的工作,他们必须拥有系统的全部权限。他们可能会在不被抓住的情况下造成很大的伤害。在这种情况下,您能做的最好的事情就是将这种访问权限限制在尽可能少的人身上,并尽您所能雇用值得信赖的人。至少,如果您拥有此访问权限的人很少,那么如果发生问题,就更容易找到问题的根源。您可以通过异地备份来最大程度地降低风险(因此,至少可以在一定程度上修复管理员损坏的情况),但您永远无法完全摆脱这种风险。同样,无论您允许应用程序以何种方式访问数据,这都是正确的。
因此,sps 的真正用途并不是消除所有可能的风险,而是让更少的人能够伤害系统。使用应用程序代码影响数据库信息本质上是不安全的,在我看来,不应允许在任何存储财务信息或个人信息的系统中使用。
【讨论】:
【参考方案7】:这是一个不完美的类比,但我喜欢将 DB 的“dbo”模式中的表与 OO 术语中的“私有”数据进行比较,并将 Views 和 Stored Procs 与“public”进行比较。甚至可以将“公共”模式与 dbo 模式分开,以明确区分。如果您遵循这个想法,您将获得安全优势和可扩展性优势。
一个帐户(不是网络应用程序的帐户)具有 dbo 访问权限并拥有数据库,网络应用程序使用仅限于面向公众的结构的另一个帐户进行连接。
【讨论】:
【参考方案8】:唯一可能反对的论点是,我遇到了某些语句无法在 SP 中有效参数化(并且需要动态 sql)的情况,这为您提供了 in-SP SQL 注入的可能性。然而,这确实是一个非常狭隘的考虑,而且很少见。至少在 PostgreSQL 中,我偶尔会看到一些需要额外审查的案例。
总的来说,即使在这些情况下,我认为 SP 类型的方法在安全方面给您带来了好处,因为它们意味着应用程序可以使用通用的反 SQL 注入机制,否则可能无法使用,并且您的 SP可以被许多应用程序使用。此外,如果所有活动都必须通过 SP,那么您可以减少暴露于 sql-injection 并集中审计问题。
一般来说,用户可以做的越少,通常存在的安全风险就越少。这意味着用户可以使用 sql 注入攻击做的事情越少。
存储过程通常提供比没有的更好、更细粒度的安全性。
【讨论】:
【参考方案9】:这里的大多数答案都指定了使用存储过程的安全优势。在不考虑这些优点的情况下,还有一些没有提到的大缺点:
数据访问模式有时比正在执行的特定过程重要得多。我们想要记录/监控/分析/发出警报/阻止谁访问数据、何时以及如何访问数据。使用存储过程时,我们不能总是得到这些信息。
某些组织可能拥有大量存储过程。不可能对所有这些都进行审查,而关注表可能更有意义(尤其是考虑到存储过程可能非常复杂、存在错误并引入其他安全问题时)。
某些组织可能需要分离关注点。数据库管理员(或任何编写存储过程的人)并不总是安全人员的一部分。有时安全人员有必要只关注数据,因为他们不负责业务逻辑,而编写业务逻辑的人并不完全受信任。
【讨论】:
以上是关于存储过程与无存储过程 - 安全观点的主要内容,如果未能解决你的问题,请参考以下文章