避免使用SET TRUSTWORTHY ON

Tom*_*m H 3 sql security cross-database sql-server-2008

我正在使用一个系统,该系统必须根据在另一个数据库中创建的对象在一个数据库中创建对象.对象不是重复的,所以我不能简单地复制对象.

我有下面的代码,简化了我正在尝试做的事情.如果取消注释ALTER DATABASE语句,它将运行而没有任何错误.这有可能创造一个安全漏洞,所以我想尽可能避免它.

我尝试过使用证书和假冒,但似乎没有任何效果.我认为DDL触发器在用户与登录时忽略了很多安全性.我也试着创造Test_DB_2存储过程中它调用了Test_DB_1 SP和具有存储过程,而不是由触发器调用,但这并没有帮助.

所以,你的挑战,如果你愿意接受它,是让下面的代码,而无需设置TRUSTWORTHY ON(或数据库链接转向如果有任何影响)工作.

感谢您提供的任何帮助!

/************************
   SET-UP THE TEST
************************/
USE master
GO
CREATE LOGIN Test_Security_Login WITH PASSWORD = 'p@ssw0rd1!'
CREATE DATABASE Test_DB_1
CREATE DATABASE Test_DB_2
GO
USE Test_DB_1
GO
CREATE PROCEDURE dbo.Create_View
AS
BEGIN
 EXEC('CREATE VIEW Test_View AS SELECT 1 AS one')
END
GO
CREATE USER Test_Security_User FOR LOGIN Test_Security_Login
GRANT EXECUTE ON dbo.Create_View TO Test_Security_User
GO
USE Test_DB_2
GO
CREATE TRIGGER DDL_TRIGGER ON DATABASE WITH EXECUTE AS 'dbo' FOR DDL_VIEW_EVENTS
AS
BEGIN
 EXEC Test_DB_1.dbo.Create_View
END
GO
CREATE USER Test_Security_User FOR LOGIN Test_Security_Login
EXEC sp_addrolemember 'db_ddladmin', 'Test_Security_User'

/************************
   RUN THE TEST
************************/
USE Test_DB_2
GO
--ALTER DATABASE Test_DB_1 SET TRUSTWORTHY ON
--ALTER DATABASE Test_DB_2 SET TRUSTWORTHY ON
EXECUTE AS USER = 'Test_Security_User'
GO
CREATE VIEW dbo.Test_View_2 AS SELECT 2 AS two
GO
REVERT
GO

/************************
   CLEAN-UP
************************/
USE master
GO
DROP DATABASE Test_DB_1
DROP DATABASE Test_DB_2
DROP LOGIN Test_Security_Login
GO
Run Code Online (Sandbox Code Playgroud)

Rem*_*anu 7

太容易了.使用代码签名:

  • 在db1中创建自签名证书
  • 用证书签名触发器
  • 删除私钥以防止滥用
  • 将证书导出到db2(从文件备份/创建)
  • 从db2中的证书创建凭证
  • 授予AUTHENTICATE和证书派生凭证的任何其他必要权限
  • 利润

这是防弹的.有关完全成熟的示例,请参阅从激活过程调用另一个数据库中的过程.

  • 我实际上能够通过使用由DDL触发器调用的存根过程与使用EXECUTE AS的存根SP以及使用GRANT AUTHENTICATE实现的证书来使其工作.我之前尝试过使用存根SP而且我尝试过使用证书,但我认为缺少的部分是AUTHENTICATE权限.一旦我将其减少到最低要求的权限,我将用完整的代码发布答案,但是既然你指出了我正确的方向,我将接受你的答案.谢谢! (4认同)