避免使用 SET TRUSTWORTHY ON

发布于 2024-09-14 09:25:31 字数 1571 浏览 2 评论 0原文

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

我下面的代码给出了我正在尝试做的事情的简化演示。如果取消注释 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

I'm working with a system which had to create objects in one database based on objects being created in another database. The objects are not duplicates, so I can't simply replicate the objects.

I have code below which gives a simplified demonstration of what I'm trying to do. If you uncomment the ALTER DATABASE statements then it will run without any errors. That has the potential of creating a security hole though, so I'd like to avoid it if possible.

I've tried using certificates and impersonation, but nothing seems to work. I think that the DDL trigger is ignoring a lot of the security when it comes to users vs. logins. I've also tried creating a stored procedure in Test_DB_2 which calls the SP in Test_DB_1 and having the trigger call that stored procedure instead, but that didn't help either.

So, your challenge, if you're willing to accept it, is to get the code below to work without setting TRUSTWORTHY ON (or turning on db chaining if that has any effect).

Thanks for any help that you can give!

/************************
   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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

诠释孤独 2024-09-21 09:25:31

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

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

这是防弹的。请参阅调用过程在另一个数据库中,从激活的过程中获取完整的示例。

Too easy. Use Code Signing:

  • create self signed certificate in db1
  • sign the trigger with a certificate
  • drop private key to prevent abuse
  • export certificate into db2 (backup/create from file)
  • create credential from certificate in db2
  • grant AUTHENTICATE and any other necessary permission to certificate derived credential
  • ?
  • profit

This is bullet proof. See Call a procedure in another database from an activated procedure for a fully fledged example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文