未经ALTER许可的更新权限

时间:2019-08-16 15:42:13

标签: sql-server stored-procedures permissions sql-injection

我有一个存储过程,该过程将一些数据插入表中。最后,我要在该表上更新STATISTICS。执行该过程的用户没有足够的权限来运行UPDATE STATITICS。现在,我的想法是创建一个存储过程,该存储过程作为所有者(具有足够的权限)执行,并向用户授予对此存储过程的执行权限。 到目前为止,它仍然有效,但是如果我使用

EXEC dwh.sp_UpdateStatistics @schemaName = 'dwh', @tableName = 'dim_Assets;SELECT 123;'

它返回123。

我已经阅读了有关SQL注入的信息,但是我不知道如何解决此问题。

这是步骤:

CREATE PROCEDURE dwh.sp_UpdateStatistics @schemaName VARCHAR(10) = NULL, @tableName VARCHAR(50) = NULL
WITH EXECUTE AS owner
AS

DECLARE @updateStatistics NVARCHAR(MAX);

SET @updateStatistics = N'UPDATE STATISTICS ' + @schemaName + '.' + @tableName;

EXEC sp_executesql @updateStatistics;

能否请我帮忙找到一种方法来更新统计信息,而又不授予任何其他权限并且也没有SQL注入的风险。 (这并不是他们所期望的,它完全是内部的,但这仅仅是为了有一个良好的睡眠和“以正确的方式做”的感觉。) 谢谢! (我有SQLServer2017,但无法使用此标签创建帖子。)

1 个答案:

答案 0 :(得分:1)

使用backup retention period。我还建议为动态对象使用适当的数据类型:

QUOTENAME

我还从参数中删除了CREATE PROCEDURE dwh.sp_UpdateStatistics @schemaName sysname, @tableName sysname WITH EXECUTE AS owner AS BEGIN DECLARE @updateStatistics NVARCHAR(MAX); SET @updateStatistics = N'UPDATE STATISTICS ' + QUOTENAME(@schemaName) + N'.' + QUOTENAME(@tableName) + N';'; EXEC sp_executesql @updateStatistics; END; ,因为将它们设为可选是没有意义的(因为= NULL的值为@updateStatistics)。

如果要创建该对象,以便在对象不存在时不运行代码,请使用类似NULL的内容进行检查:

INFORMATION_SCHEMA

如果对象不存在,这将导致CREATE PROCEDURE dwh.sp_UpdateStatistics @schemaName sysname, @tableName sysname WITH EXECUTE AS owner AS BEGIN DECLARE @updateStatistics NVARCHAR(MAX); SELECT @updateStatistics = N'UPDATE STATISTICS ' + QUOTENAME(T.TABLE_SCHEMA) + N'.' + QUOTENAME(T.TABLE_NAME) + N';' FROM INFORMATION_SCHEMA.TABLES T WHERE T.TABLE_SCHEMA = @schemaName AND T.TABLE_NAME = @tableName; EXEC sp_executesql @updateStatistics; END; 的值为@updateStatistics,然后将不运行(动态)SQL。