我需要设置一个系统,该系统允许开发人员为数据库请求紧急ID。他们将被分配到一个名为“分析师”的角色,他将为他们提供一个下拉框,以及他们可以访问的数据库。他们将提交请求并生成临时SQL登录并显示在屏幕上。登录将有一些特权。登录将在12小时后被删除。请求临时登录的安全性
我已经把自己作为一个在ASP.net上的SA工作了,但现在我正在修改程序在应用程序连接字符串中使用SQL登录工作。
我试过几件东西让它工作,但碰到了路障。
这是我做的真正的工作。
USE [SQLEmergencyLoginRequest]
GO
/****** Object: StoredProcedure [dbo].[SQLELR_Login_CREATE] Script Date: 12/08/2009 14:48:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SQLELR_Login_CREATE]
@SERVER VARCHAR(50),
@DATABASE VARCHAR(50),
@NTLOGIN VARCHAR(50),
@IR INT,
@LOGIN VARCHAR(50) OUTPUT,
@PWD VARCHAR(20) OUTPUT,
@NotifyDBA INT
WITH EXECUTE AS OWNER
AS
/*
Emergency_Access_Login_CREATE: Create Login/PWD, Create User, Create Role, Add User to Role, return Login/PWD.
*/
DECLARE @Random_Login_Extension VARCHAR(20)
DECLARE @sql VARCHAR(1000)
SET @Database = QUOTENAME(@Database);
BEGIN TRANSACTION
--CREATE LOGIN/PWD
EXEC dbo.random_password @Random_Login_Extension OUTPUT;
EXEC dbo.random_password @PWD OUTPUT;
SET @LOGIN = 'Emergency_Login_' + @Random_Login_Extension;
SET @sql= 'CREATE LOGIN [' + @LOGIN + ']' +
'WITH PASSWORD= ''' + @PWD + ''', DEFAULT_DATABASE=[master], ' +
'CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF';
EXEC(@sql);
--CREATE USER
DECLARE @User_Cmd VARCHAR(1000);
SET @User_Cmd = 'USE ' + @DATABASE + ';' +
'CREATE USER [' + @LOGIN + '] FOR LOGIN [' + @LOGIN + '];' +
'EXEC sp_addrolemember N''db_datareader'',''' + @LOGIN + ''';' +
'EXEC sp_addrolemember N''db_datawriter'',''' + @LOGIN + ''';' +
'EXEC sp_addrolemember N''db_ddladmin'',''' + @LOGIN + ''';';
EXEC (@User_Cmd);
INSERT INTO dbo.SQLELR_Emergency_Logins
([CreationTime]
,[NTLogin]
,[IR]
,[SERVER]
,[DATABASE]
,SQLLoginCreated)
VALUES
(GETDATE()
,@NTLOGIN
,@IR
,@SERVER
,@DATABASE
,@LOGIN)
DECLARE @MYBODY VARCHAR(500)
SET @MYBODY = @NTLOGIN + ' has created a temporary login in the ' + @Database + ' Database. The login name is ' + @LOGIN;
DECLARE @MYSUBJECT VARCHAR(500)
SET @MYSUBJECT = 'Emergency Login Creation ON server ' + @@SERVERNAME;
IF @NotifyDBA = 1
BEGIN
EXEC msdb.dbo.sp_notify_operator
@profile_name = 'SQLDBA',
@name = 'SQLDBA',
@subject = @MYSUBJECT,
@body = @MYBODY;
END
COMMIT TRANSACTION
我不想申请帐户在每一个DB高度特权,所以我创建了另一个帐户,这将进入每一个数据库,并有db_owner
。很明显,使用固定数据库角色的sp_addrolemember
需要db_owner才能工作,这就是为什么acct是db_owner
。我更喜欢安全管理员,但似乎这是不可能的。
回到问题 - 使用EXECUTE AS和动态代码不起作用。
通过在创建用户的每个数据库中创建存储过程来完成此操作的唯一方法是?
我们这样做是因为我们想要降低服务器上的安全性,并从开发人员那里拿走db_owner,这已经成为多年来的常态。创建这种机制将满足他们关于无法访问的唯一剩余投诉。他们担心我们不会回答一个页面,他们将无法解决问题,所以这会照顾到这一点。
当然,任何有关安全漏洞的建议也会受到赞赏。
来吧,使用QUOTENAME。你不想要任何'exec SQLELR_Login_CREATE ...,@DATABASE ='master; exec IAmInUrDatabsePwningUrTables;',...' – 2009-12-08 22:37:33
如果所有参数都是通过.net与SqlParameter提交的,这仍然是一个漏洞?也许有人可以尝试从另一个SQL模块调用? – Sam 2009-12-08 23:47:45
是的,它仍然是一个漏洞。作为一般规则,绝不要依赖客户端在服务器上安全(即SqlParameter),因为攻击者不会使用客户端。特别是,任何低权限的用户都可以使用此过程来挂载特权升级攻击,通过Sql Injection向量利用EXECUTE AS特权。换句话说,任何客人都可以成为系统管理员。 – 2009-12-09 00:29:08