【问题标题】:Best practice on users/roles on SQL Server for a web application用于 Web 应用程序的 SQL Server 上的用户/角色的最佳实践
【发布时间】:2010-11-26 14:05:26
【问题描述】:

我在网上搜索了一下,但找不到任何能真正抓住问题或涵盖如何在数据库上设置用户/角色的基础的东西。

基本上,会有一个用户用于从应用程序(在本例中为 Web 应用程序)访问数据库,该用户需要访问数据库以执行常规数据库操作(选择、插入、更新、删除)和执行存储过程(使用 exec 在其他存储过程/UDF 中运行存储过程)。

然后,我们还会有一个主管理员用户(这很简单)。

我目前有一个开发环境,在我看来,我们并没有真正很好地管理安全性(应用程序使用具有 db_owner 角色的用户,尽管它是一个 Intranet 应用程序)。尽管它是一个 Intranet 应用程序,但我们仍然牢记安全性,并希望了解开发人员为此类环境设置用户/角色的一些方式。

编辑:Web 应用程序和 SQL Server 位于不同的机器上。

编辑:忘了提到使用了需要直接读/写访问的 ORM。

问题: 设置用户访问应用程序的“最佳实践”是什么?将适用哪些角色?有哪些注意事项?

【问题讨论】:

  • 网络应用是否在冒充呼叫者?
  • 不是为了访问 SQL Server(我们将它单独用于 Reporting Services)。忘了说我们的 Web 应用程序在它自己的专用盒子上,而数据库也在一个单独的专用盒子上。
  • 坦率地说,如果您的 ORM 需要直接读/写,是时候切换到理解存储过程的 ORM。
  • @blowdart: 或者完全拒绝 ORM :)
  • 好吧,如果我要在存储过程中编写所有读/写代码并让我的 ORM 调用这些代码,那将扼杀 ORM 的目的,即不必编写所有代码。

标签: sql sql-server security


【解决方案1】:

首先,我倾向于将权限封装在数据库角色中,而不是将它们附加到单个用户主体。这里最大的胜利是角色是您的数据库的一部分,因此您可以完全编写安全脚本,然后告诉部署类型“添加用户并将他添加到该角色中”,并且他们不会与 SQL 权限笨蛋作斗争。此外,这可以让事情变得足够干净,您可以避免在 db_owner 模式下进行开发,并且对自己感觉更好——以及像玩游戏一样练习,通常可以避免任何问题。

就为该角色应用权限而言,这些天我倾向于将网络撒得更广,尤其是当有人使用 ORM 并通过应用程序处理安全性时。在 T-SQL 术语中,它看起来像这样:

GRANT SELECT, UPDATE, INSERT, DELETE, EXECUTE on SCHEMA::DBO to [My DB Role]

一开始这可能看起来有点吓人,但实际上并非如此——该角色除了操作数据之外不能做任何事情。无法访问扩展过程或系统过程或授予用户访问权限等。另一个很大的优势是更改架构(例如添加表或过程)不需要进一步的安全工作,只要您留在该架构内。

SQL 2005+ 需要考虑的另一件事是使用数据库模式来保护对象组。现在,这里的大技巧是许多 ORM 和迁移工具不喜欢它们,但是如果您将默认模式 [dbo] 呈现给应用程序,则可以将替代模式用于特殊安全的东西。例如——为应该由管理员手动运行的特殊、残酷的数据库清理程序创建一个 ADMIN 模式。甚至为应用程序中需要更精细的数据库权限的特殊、高度安全的部分提供单独的架构。

只要在有单独框的用户中进行接线,即使没有域,您也可以使用 Windows 身份验证(在 Sql Server 术语中是集成身份验证)。只需在两个盒子上创建一个具有相同凭据(用户/密码组合)的用户。设置一个应用程序域以在 Web 框上以该用户身份运行,并在 sql 框和利润上设置一个由该主体支持的 Sql Server 用户。也就是说,使用数据库角色几乎可以让您脱离这个决定,因为部署类型应该能够根据需要处理创建 sql 用户和修改连接字符串。

【讨论】:

  • 我倾向于这种方法,因为设置这些权限所需的表数量会更干净。我只是想知道妥协是否值得(它在 Intranet 中,所以我们的风险比 Web 环境低一点)。
  • 我真的不会称其为妥协——ORM 角度应该可以防止 SQL 注入攻击,因为没有任何真正“松散”的字符串会攻击数据库。实际上,这里最大的攻击向量是任何调用 sp_execute_sql 的存储过程。此外,应用层的安全性更容易构建和测试,依赖专门的数据库权限是对过去时代的延续,在那个时代,保护堆栈的上层部分更加困难。
  • 我将采用这种方法,因为它适用于正在进行的开发(Remus' 是一种非常相似的方法,但使用单独的模式需要将所有对象移动到新模式。. .伟大的新发展,不过)。
【解决方案2】:

长期以来,SQL Server 应用程序访问数据库的指导方针是将数据访问隔离到存储过程中,将过程分组到架构中,并将架构上的执行权限授予应用程序使用的主体。所有权链接将保证对过程调用者的数据访问。可以通过检查存储过程来查看访问。这是一个简单的模型,易于理解、设计、部署和管理。使用存储过程可以利用代码签名,这是最精细和最强大的访问控制方法,也是唯一一种防篡改(如果过程被更改,签名会丢失)。

问题在于,Visual Studio 设计人员提出的每一项技术都与此建议背道而驰。开发人员看到的模型很难专门用于存储过程。开发人员喜欢先设计他们的类模型,然后从逻辑模型生成表结构。基于过程的指南要求过程首先存在,在编写应用程序的第一行之前,这实际上是由于现代开发的迭代方式而在开发中存在的问题。这不是无法解决的,只要团队领导意识到这个问题并解决它(即,在开发周期开始时,让程序准备好,即使是模拟程序)。

【讨论】:

  • +1:很好的答案。突出设计数据库安全性时的一些非常相关的问题/注意事项。
  • 我忘记了一些关于我们使用 ORM 的信息,这基本上需要对数据库进行直接读/写访问。对于这样的事情,添加读写角色是否合适?
  • 从安全的角度来看:没有。您希望保护数据不被受感染的 Web 服务器任意更新(纵深防御)。实际上,没有可行的替代方案。至少访问所需的表,不要将 Web 服务器主体添加到 db_datareader/db_datawriter 角色。
  • 我非常喜欢这种方法,但我们的数据库中可能有 100 多个表,其中大部分是由 ORM 对象访问的。保持这一点会引起很多麻烦。
  • 您可以将所有对象(表)分组到一个模式中,并在该模式上授予必要的权限(SELECT、INSERT、UPDATE、DELETE)。见msdn.microsoft.com/en-us/library/ms187940.aspx。 Web 应用程序对架构中的对象具有的读/写权限。您甚至可以使用两个模式将对象(表)分为只读和读写。
【解决方案3】:

创建 Web 应用程序使用的用户“webuser”。

只向该用户授予存储过程执行权限。不允许直接表读/写。如果您需要从表中读取某些内容,请编写一个 proc。如果需要写数据,再写一个proc。

这样一来,一切都变得简单而美好。一位应用程序用户,仅具有相关权限。如果安全受到威胁,那么入侵者所能做的就是运行 procs。

【讨论】:

  • 这有一个问题(忘记了原始问题中的一些相关信息)。我们使用为我们生成类的 ORM,因此不能仅限于存储过程来读取/写入数据。
  • @Manuel: 好的,这会改变一些事情——但如果你曾经删除过 ORM 限制(确实如此),那么我仍然会推荐用户方法而不是角色/模式权限。
  • @Wyatt:那是美好的一年!关于如何实施安全性的古老战争/讨论永远不会消失,我看到你喜欢一种不同的方法。没关系 - 每个人都有自己的!
猜你喜欢
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 2012-03-22
  • 2016-11-16
  • 2016-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多