应用程序用户是否应该成为数据库用户?

28

我的以前的工作涉及维护和编程一个非常大的数据库,其中包含大量数据。 用户主要通过内部网络界面查看此数据。每个用户帐户都是RDBMS中的真正一流帐户,而不是具有用户帐户表格,这使得他们能够连接自己的查询工具等,同时允许我们通过RDBMS本身来控制访问,而不是使用我们自己的应用逻辑。

如果您不在公共Intranet上处理可能有数百万个(可能是恶意)用户之类的情况,那么这是一个好的设置吗?还是总是更好地定义自己的处理用户帐户的方式、自己的权限、自己的应用安全逻辑,并只向需要特殊需求的高级用户分发RDBMS帐户?


“恶意用户”不仅存在于互联网上 - 他们中的大多数在公司里有工作,你可能现在正在与其中一些人共事 - 当你解雇某人时,切断所有用户帐户和物理访问权限是首要任务,这是有原因的。 - kloucks
没错,kloucks。我在那份工作中总是很难说服人们相信恶意行为(以及看起来像恶意的无能)可能发生在我们“安全”的内部网络中。但在这种情况下,你只需给人们只读访问权限或适当的权限即可。 - skiphoppy
需要最关注直接授予数据库权限的是那些高级用户。他们拥有足够的知识,可以通过绕过应用程序的内部控制来实施欺诈行为。 - HLGEM
12个回答

20
我不同意将数据库用于用户访问控制与其他人所说的那样危险。我来自Oracle Forms开发领域,这种用户访问控制是常态。就像任何设计决策一样,它有其优点和缺点。
其中一个优点是我可以从数据库的单个设置中控制每个表的选择/插入/更新/删除权限。在一个系统中,我们有4个不同的应用程序(由不同的团队管理,并使用不同的语言)访问相同的数据库表。我们能够声明仅具有经理角色的用户才能在特定表中插入/更新/删除数据。如果我们没有通过数据库进行管理,那么每个应用程序团队都必须正确地在其应用程序中实现(复制)该逻辑。如果有一个应用程序搞错了,那么其他应用程序也会受到影响。此外,如果您想更改单个资源的权限,则需要管理重复代码。
另一个优点是我们不需要担心将用户密码存储在数据库表中(以及随之而来的所有限制)。
我不同意“数据库用户帐户本质上比应用程序定义的任何内容更危险”的说法。更改数据库特定权限所需的权限通常要比更新/删除“PERSONS”表中的单行所需的权限严格得多。
而且,“扩展”并不是问题,因为我们将权限分配给Oracle角色,然后将角色分配给用户。通过一个单独的Oracle语句,我们可以更改数百万用户的权限(尽管我们没有那么多用户)。
应用程序授权不是一个简单的问题。许多定制解决方案存在漏洞,黑客可以轻松利用。像Oracle这样的大公司已经花费了很多精力和代码来提供强大的应用程序授权系统。我同意使用Oracle安全性并不能适用于每个应用程序。但我不会那么快地摒弃它,转而使用自定义解决方案。

1
一些好的观点。我认为在这些情况下,你需要像Oracle这样“严肃”的关系型数据库才能站起来,但在某些环境下,这可能是合适的。 - Draemon
最重要的是不要交叉使用。要么在数据库权限中表达所有访问控制逻辑,要么在代码中实现。混合使用它们意味着您失去了以数据库为中心设计的好处,同时保留了许多负面影响。 - daotoad

19

编辑:我应该澄清一下,尽管在原帖中有任何内容,但即使没有代码存在,你正在逻辑上定义一个应用程序。否则,它只是一个具有所有相关危险的公共数据库。

也许我会因为这篇文章而被攻击到死,但我认为这是安全和设计术语方面一个极其危险的反模式

用户对象应该由运行它的系统定义。如果您实际上是在另一个应用程序中(数据库)定义这些对象,那么您就失去了控制。

从设计角度来看,这毫无意义,因为如果您想要扩展这些账户的任何数据(电子邮件地址、员工编号、MyTheme...),您将无法扩展数据库用户,并且您将需要构建那个用户表。

与您的应用程序定义的账户相比,数据库用户帐户本质上更加危险,因为它们可能被数据库以及任何通过DBA连接到数据库的其他东西提升、删除、访问或以其他方式操纵。您将关键的系统元素公开。

无法扩展。想象一下一个抽象的地方,您将拥有成千上万的用户。作为 DB 帐户,这是不可管理的,但作为表中的记录,则只是数据。老生常谈的论点“只会有 X 个用户”对我来说没有任何意义,因为我看到非常有限的内部应用程序在业务感觉可以为客户增加价值或公司刚被一个巨大的合作伙伴收购,现在需要访问时变得公开。您必须计划合理的可扩展性。

您将无法共享连接池,您不会比只创建几个角色帐户更安全,并且当您需要进行大规模更改或备份时,可能无法有效地影响。

总而言之,这对我来说似乎存在许多严重的问题,我想其他更有经验的 SOer 可能还可以列出更多。


1
不要忘记欺诈的危险,如果用户可以从应用程序以外的来源访问数据。想要窃取的用户可以绕过应用程序中设置的所有内部控制。 - HLGEM

3
每个用户帐户都是RDBMS中的真正一流帐户,这使他们能够连接自己的查询工具等等。
如果RDBMS包含以下任何信息,则不是一个好主意:
- HIPAA或Sarbanes-Oxley或The Official Secrets Act(英国)覆盖的任何信息 - 信用卡信息或其他客户信用信息(采购订单、授信额度等) - 个人信息(社会安全号码、出生日期等) - 竞争、专有或知识产权信息
因为当用户可以使用自己的非托管查询工具时,公司无法知道或审计查询了什么信息以及查询结果被发送到哪里。
还有@annakata所说的。

1
数据库有审计工具,就像操作系统一样。此外,您应该拥有分层防御,并且不要假设应用程序没有漏洞,这些漏洞可能允许用户规避“黄金查询”。 - florin
1
这实际上是不正确的。拥有多个用户使用自己的账号连接到数据库,并不意味着所有用户都拥有相同的权限...如果数据库用户没有查询表的权限,他将无法执行此操作,无论其中包含的数据有多么重要... - Thomas Carlton

3
我认为,在传统的数据库应用程序中,它们不应该存在。原因已经很明显了。在传统的数据库应用程序中,有一个业务层处理所有安全问题,这是因为与应用程序交互的人和与数据库交互的人之间有非常强烈的界限。
在这种情况下,最好自己管理这些用户和角色。您可以决定需要存储关于他们的哪些信息,以及记录和审计哪些信息。最重要的是,您可以基于纯粹的业务规则定义访问权限,而不是基于数据库规则。然而,这些不是技术问题,而是设计问题。如果您需要控制这一点,那么自己管理用户就是有意义的。
您描述了一个允许用户直接查询数据库的系统。在这种情况下,为什么不使用DB帐户呢?如果您尝试分析用户编写的查询并根据您设计的一些规则对其进行审核,那么DB帐户将比您做得更好。对我来说,这听起来像是一个需要编写和维护的噩梦系统。
不要因为您可以而锁定东西。向负责人解释安全性的影响,但不要试图阻止人们做事情,因为您可以。特别是当他们习惯直接访问数据时。
作为开发人员,我们的工作是使人们能够做他们需要做的事情。在您描述的情况下,特别是连接到数据库并使用自己的工具查询它。那么我认为,除了数据库帐户以外的任何东西都可能不安全或限制过多。

1

我会避免给任何用户数据库访问权限。稍后,当这开始引起问题时,收回他们的访问权限将变得非常困难。

至少,给他们访问只读副本的权限,这样他们就不能用错误的查询摧毁你整个公司。


1
现在许多数据库查询工具非常先进,但重新实现整个世界只是为了添加限制可能会感到非常遗憾。只要数据库用户权限被正确锁定,这可能是可以的。然而,在许多情况下,您不能这样做,应该向数据库公开高级别API以正确地在许多表中插入对象,而无需用户需要特定培训,即“只需将地址添加到那张表中,为什么不起作用?”。
如果他们只想使用数据在Excel等软件中生成报告,那么您可以使用像BIRT这样的报告前端。
因此,基本上,如果用户对数据库有一定的了解,并且资源来实施适当的前端较少,则继续执行此操作。但是,如果资源出现,就可能是时候考虑为他们创建更简单、面向任务的前端,以满足人们的需求了。

1

这在某种程度上类似于:SQL Server/AD 有什么用处

我认为将安全模型(至少是基本的)放入数据库本身并不是一个坏主意。您可以在应用程序层面添加限制以进行美化,但无论用户使用基于应用程序还是用户的帐户访问数据库,最好将该帐户限制为仅允许用户允许的操作。

我并不代表所有应用程序,但我见过很多应用程序,其中捕获密码就像在记事本中打开代码、使用包含的dll解密配置文件或查找备份文件(例如asp.net中的web.config.bak)一样简单,可以从浏览器中访问。


1

*如果关系型数据库包含以下任何信息: * HIPAA或Sarbanes-Oxley或英国官方保密法(The Official Secrets Act) * 信用卡信息或其他客户信用信息(采购订单,信贷额度等) * 个人信息(社会安全号码,出生日期等) * 竞争性,专有或知识产权信息*

这不是一个好主意,但可以完美地管理数据库用户可以查看和修改哪些数据。数据库(至少Oracle)还可以审计所有活动,包括选择操作。拥有成千上万的数据库用户也是完全正常的。

构建良好安全的应用程序更加困难,因为您必须编写此安全性,而数据库提供此安全性,并且可以以声明性方式进行配置,无需编写代码。


如果我理解你的意思正确,开发人员/设计师/架构师不应该费心在应用程序中构建任何数据安全性,因为这应该由数据库管理员完成? - kloucks
设计师、架构师和数据库管理员可以共同设计数据安全策略。不要在太晚和数据库管理员沟通。为了使应用程序更加用户友好,应当禁止在表单中修改用户无权更改的数据库数据。 - Theo

1
我知道,我在回复一个很久以前的帖子,但最近在我的当前项目中遇到了同样的情况。我也在思考类似的想法,即“应用程序用户是否可以成为数据库用户?”。 这是我的分析:
  1. 如果您的应用程序将由许多用户使用,则在数据库上创建如此大量的应用程序用户毫无意义。
  2. 假设您在数据库上创建了X(巨大的数量)个用户。您正在打开通向数据库的明确网关。

让我们为解决方案考虑一个场景:

有两种类型的应用程序用户(管理者和助手)。两者都需要访问数据库进行一些交易。

显然,您会在数据库中创建两个角色,一个用于每种类型(管理者和助手)。但是,如何从应用程序连接数据库用户?如果您为每个用户创建一个帐户,那么您将线性地在数据库上创建帐户。

我的建议:

  1. 为每个角色创建一个数据库账户。(比如说Manager_Role_Account
  2. 让你的应用程序具有业务逻辑,将应用程序用户映射到相应的角色。(用户Tom拥有经理角色,对应Manager_Role_Account
  3. 使用在#2中确定的角色对应的数据库用户(Manager_Role_Account)连接到数据库并执行查询。

希望这样说得清楚明白!

更新:正如我所说,在我的项目中遇到了类似的情况(后端使用Postgresql数据库,前端使用Java Web应用程序),我发现了一个非常有用的东西,叫做代理认证

这意味着您可以作为一个用户登录到数据库,但根据代理用户限制或扩展您的权限。 我找到了一些很好的链接来解释这个问题。

  1. 对于Postgresql版本低于Choice of authentication approach for financial app on PostgreSQL

    1. 对于Oracle 代理认证

希望这可以帮助到您!


0

这取决于情况(像大多数事情一样)。

拥有多个数据库用户会使连接池失效,因为大多数库基于连接字符串和用户帐户来处理池化。

另一方面,这可能比我们从头开始做任何事情都更安全。它将安全性留给操作系统和数据库服务器,我比自己更信任它们。但是,只有在您努力配置数据库权限的情况下才是如此。如果您使用具有相同权限的许多OS/数据库用户,则帮助不大。您仍然会获得审计跟踪,但也只是如此。

话虽如此,我不知道是否愿意让普通用户使用自己的工具直接连接到数据库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接