代码之家  ›  专栏  ›  技术社区  ›  Tom H zenazn

避免使用设置值得信赖的

  •  3
  • Tom H zenazn  · 技术社区  · 14 年前

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

    下面的代码对我要做的事情进行了简单的演示。如果您取消对 ALTER DATABASE 语句,然后它将运行而不出现任何错误。不过,这有可能造成安全漏洞,所以如果可能的话,我想避免出现这种情况。

    我试过使用证书和冒充,但似乎没什么效果。我认为当涉及到用户和登录时,DDL触发器忽略了很多安全性。我还尝试在test_db_2中创建一个存储过程,它调用test_db_1中的sp,并让触发器调用该存储过程,但这也没有帮助。

    因此,如果您愿意接受它,您的挑战是让下面的代码在不设置值得信赖的情况下工作(或者如果有任何影响,则打开DB链接)。

    谢谢你的帮助!

    /************************
       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
    
    1 回复  |  直到 14 年前
        1
  •  7
  •   Remus Rusanu    14 年前

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

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

    这是防弹的。见 Call a procedure in another database from an activated procedure 作为一个成熟的例子。