TRUSTWORTHY 数据库属性

适用于SQL Server Azure SQL 托管实例

TRUSTWORTHY 数据库属性用于指明 SQL Server 实例是否信任该数据库以及其中的内容。 默认情况下,此设置为 OFF,但是可以使用 ALTER DATABASE 语句将其设置为 ON。 例如:ALTER DATABASE AdventureWorks2022 SET TRUSTWORTHY ON;

注意

必须是 sysadmin 固定服务器角色的成员才能设置此选项。

建议将 TRUSTWORTHY 数据库属性设置为 OFF,以缓解当附加包含以下对象之一的数据库时可能存在的某些威胁:

这两种情况均要求具有特定程度的权限,当它们在已附加到 SQL Server 实例的数据库的上下文中使用时,会受到相应机制的保护。 但是,如果数据库脱机,则对数据库文件具有访问权限的用户可能会将其附加到其选择的 SQL Server 实例,并将恶意内容添加到数据库中。 在 SQL Server 中分离和附加数据库时,将对限制访问数据库文件的数据和日志文件设置某些权限。

因为无法立即信任附加到 SQL Server 实例的数据库,所以不允许数据库访问超出数据库范围的资源,直至数据库已显式标记为可信。 因此,如果备份或分离 TRUSTWORTHY 选项设置为 ON 的数据库,并将该数据库附加或还原到同一个或另一个 SQL Server 实例,则附加/还原完成后,TRUSTWORTHY 属性将设置为 OFF。 此外,旨在访问数据库以外资源的模块和具有 EXTERNAL_ACCESS 和 UNSAFE 权限设置的程序集还需要额外条件才能成功运行。

注意

默认情况下,对于 msdb 数据库,TRUSTWORTHY 设置将设置为 ON。 如果更改此设置的默认值,则可能会导致使用 msdb 数据库的 SQL Server 组件发生意外行为。

如果 TRUSTWORTHY 设置被设置为 ON,并且数据库的所有者是具有管理凭据的组的成员(例如 sysadmin 组),则数据库所有者可以创建并运行可能损害 SQL Server 实例的不安全程序集。

详细信息

在 Internet 服务提供商 (ISP) 环境中(例如,在 Web 托管服务中),允许每个客户管理自己的数据库,禁止访问系统数据库和其他用户数据库。 例如,两家竞争公司的数据库可以由同一家 ISP 托管,并存在于 SQL Server 的同一实例中。 当数据库附加到原始实例时,可将危险代码添加到用户数据库,并在部署数据库时在 ISP 实例上启用该代码。 这种情况使得控制跨数据库访问变得至关重要。

如果同一个常规实体拥有和管理每个数据库,则除非需要特定于应用程序的功能(例如跨数据库 Service Broker 通信),否则与数据库建立信任关系仍然不是很好的做法。 可以通过启用跨数据库所有权链接,或将数据库标记为受到使用 TRUSTWORTHY 属性的实例的信任,来建立数据库之间的信任关系。 sys.databases 目录视图的 is_trustworthy_on 列指示数据库是否设置了 TRUSTWORTHY 属性集。

数据库所有权和信任的最佳做法包括:

  • 具有数据库的不同所有者。 并非所有数据库都应该由系统管理员拥有。
  • 限制每个数据库的所有者数量。
  • 有选择地授予信任。
  • 将跨数据库所有权链设置保留为 OFF,除非在单个单元中部署多个数据库。
  • 将使用权迁移到选择性信任,而不是使用 TRUSTWORTHY 属性。

以下代码示例可用于获取 TRUSTWORTHY 属性设置为 ON 且其数据库所有者属于 sysadmin 服务器角色的数据库的列表。

SELECT SUSER_SNAME(owner_sid) AS DBOWNER,
    d.name AS DATABASENAME
FROM sys.server_principals r
INNER JOIN sys.server_role_members m ON r.principal_id = m.role_principal_id
INNER JOIN sys.server_principals p ON p.principal_id = m.member_principal_id
INNER JOIN sys.databases d ON suser_sname(d.owner_sid) = p.name
WHERE is_trustworthy_on = 1
    AND d.name NOT IN ('msdb')
    AND r.type = 'R'
    AND r.name = N'sysadmin';
GO

可以运行以下查询来确定 TRUSTWORTHY 数据库的 msdb 属性 :

SELECT name,
    trustworthy_setting = CASE is_trustworthy_on
        WHEN 1 THEN 'Trustworthy setting is ON for msdb'
        ELSE 'Trustworthy setting is OFF for msdb'
        END
FROM sys.databases
WHERE database_id = 4;
GO

如果此查询显示该 TRUSTWORTHY 属性设置为 OFF,则可运行以下查询,将 TRUSTWORTHY 属性设置为 ON。

ALTER DATABASE msdb SET TRUSTWORTHY ON;
GO

警告

可通过多种方式提升具有 db_owner 角色的用户,在将 TRUSTWORTHY 设置为 ON 时,让该用户成为 sysadmin。 使用属性 TRUSTWORTHY 时应小心谨慎。 以下 SQL 代码可用于获取在数据库中授予 db_owner 角色的数据库用户列表。

SELECT    roles.principal_id    AS RolePrincipalID
   ,    roles.name       AS RolePrincipalName
   ,    database_role_members.member_principal_id  AS MemberPrincipalID
   ,    members.name      AS MemberPrincipalName
FROM sys.database_role_members AS database_role_members  
JOIN sys.database_principals AS roles  
   ON database_role_members.role_principal_id = roles.principal_id  
JOIN sys.database_principals AS members  
   ON database_role_members.member_principal_id = members.principal_id where  roles.name='db_owner' and members.name <>'dbo'
GO

后续步骤