我正在开发一个运行SQL服务器的产品,该服务器允许某些应用程序登录,并且他们的登录被授予运行存储过程的权限 - 并且没有ELSE。存储过程由管理员拥有;存储过程接受查询并执行它,然后将结果返回给应用程序。
不幸的是我无法弄清楚为什么应用程序可以调用它被授予访问权限的存储过程,但是存储过程不能执行传递给它的SQL语句。
当我以管理员身份登录时,存储过程执行传入的查询,但是当我以受限用户身份登录时,它会在execute语句中抛出异常。
例如:
EXEC [Admin].[STORED_PROC] @SQL_STATEMENT = 'SELECT * FROM table_x'
STORED_PROC看起来像这样:
BEGIN TRY
EXEC (@SQL_STATEMENT)
END TRY
BEGIN CATCH
-- some logging when an exception is caught, and the exception is caught here!!!
END CATCH
try catch语句中没有任何内容,除了EXEC ...并且当我以Admin身份登录时SQL_STATEMENT有效,但是当我以用户身份登录时却没有。
有人可以帮我弄清楚我需要设置哪些权限才能让用户只通过存储过程运行查询?
所以有一些关于允许通过存储过程执行原始SQL语句的注释违背了使用存储过程的目的...但实际上我们实际上正在做的是我们将加密的SQL语句传递给存储过程和存储过程获取语句解密,然后执行它。
所以是的,实际上原始SQL语句不安全并且它们无法实现存储过程的目的,但我不知道如何加密通过ODBC传递并针对2005之前的SQL Server运行的SQL查询。 / p>
无论如何,我试图提出一些最小的保护措施,至少要有一些基本的安全措施。
答案 0 :(得分:6)
由于您使用的是动态sql,SQL服务器无法分辨您正在使用哪些表,因此您必须同时向所有表授予SELECT权限
答案 1 :(得分:4)
用户还需要在表格上使用SELECT授权
答案 2 :(得分:4)
允许将原始SQL传递到存储过程然后执行是数据不安全的本质。
SQL Server安全性的结构使得SQL的任意位在其自己的安全上下文中执行。如果您没有临时运行查询的权限,则您也没有权限通过存储过程运行它。在这方面,SQL Server正在为您节省开支。
答案 3 :(得分:0)
由于您的系统允许访问存储过程并且没有其他内容(这有利于安全目的且不应更改),因此您在任何情况下都不能使用动态SQL,因为权限不在表级别,而您的dbas是不太可能改变这一点。这不仅是为了防止SQL注入攻击,而且是为了防止可能的内部欺诈,因此任何考虑过这一重要事项的工作场所都不愿意妥协,以使您的生活更轻松。您只需重新设计即可动态执行任何操作。你别无选择。如果您首先编写了procs来执行您想要的操作,则无需发送encypted sql。
答案 4 :(得分:0)
在SP中通过EXEC
或sp_executesql
使用动态SQL时,SP上的EXEC
权限不允许您在动态sql中运行任意代码。您需要授予SELECT
(yuck),或者您可以使用EXECUTE AS
或SETUSER
冒充其他用户。
使用普通SQL时,EXEC
权限可以正常工作,覆盖未经授权的SELECT
个持久性。但是,如果你有DENY
,我相信它胜过它。
话虽如此,当SQL的源<在之外的SP(或数据库之外)时,我仍然不确定是否应该使用EXECUTE AS
。对于不受外界影响的代码生成或动态sql,EXECUTE AS
可以是一个有用的工具
答案 5 :(得分:0)
这很可能是因为不同的模式,即登录的用户不是Admin模式的一部分,或者至少我不希望这样。
允许您希望实现的访问类型的安全技术,即允许访问由同一模式拥有的对象,称为Ownership Chaining。
这个原则并没有在帖子中得到最好的解释。
以下是Microsoft的链接,解释了这一概念。
http://msdn.microsoft.com/en-us/library/ms188676(SQL.90).aspx
这是一篇关于安全性的优秀文章,提供了示例和演练,所有权链以及其他技术。
http://www.sommarskog.se/grantperm.html
我希望这很清楚并且可以帮助你,但请随时提出进一步的问题。
干杯,约翰