TRUSTWORTHY 数据库属性

适用于:SQL ServerAzure SQL 托管实例

TRUSTWORTHY数据库属性表示SQL Server实例是否信任数据库及其内容。 默认情况下,这个设置是 OFF,但你可以通过 语ALTER DATABASE句将其设置为 ON

例如:

ALTER DATABASE AdventureWorks2025 SET TRUSTWORTHY ON;

注意

若要设置此选项,必须具有 CONTROL SERVER 权限,或者是 sysadmin 固定服务器角色的成员。

为了减轻某些威胁,将数据库属性设置为 TRUSTWORTHYOFF。 这些威胁可能源于附加包含以下对象之一的数据库:

  • 带有 EXTERNAL_ACCESS OR UNSAFE 权限设置的恶意组装。 欲了解更多信息,请参见 CLR集成安全性

  • 被定义为高权限用户运行的恶意模块。 更多信息请参见 EXECUTE AS 条款

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

由于连接到SQL Server实例的数据库不能立即被信任,数据库在明确标记为可信之前,不允许访问超出数据库范围的资源。 因此,如果你备份或分离一个有该TRUSTWORTHY选项ON的数据库,并将数据库附加或恢复到同一或另一个 SQL Server 实例,TRUSTWORTHY属性会被设置为 OFF 连接或恢复完成时。 此外,设计用于访问数据库外部资源的模块,以及带有 EXTERNAL_ACCESS 或 权限 UNSAFE 设置的装配,成功运行时有额外的要求。

注意

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

如果你将设置设置为 TRUSTWORTHYON,且数据库所有者是拥有管理员凭证的组成员,比如系统管理员组,数据库所有者就可以创建并运行不安全的装配,从而威胁 SQL Server 实例。

备注

在互联网服务提供商(ISP)环境中,例如网络托管服务,每个客户管理自己的数据库,无法访问系统数据库或其他用户数据库。 例如,ISP可以在同一SQL Server实例中托管两家竞争公司的数据库。 如果你把用户数据库附加到原实例上,可能会给用户数据库添加危险代码。 当你将数据库部署到ISP实例时,代码会变得活跃。 这种情况使得跨数据库访问的控制变得至关重要。

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

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

  • 为数据库指定不同的所有者。 并非所有数据库都应该由系统管理员拥有。

  • 限制每个数据库的所有者数量。

  • 有选择地授予信任。

  • 除非你将多个数据库作为一个单元部署,否则将跨数据库所有权链设置设置为OFF

  • 将使用权迁移到选择性信任,而不是使用 TRUSTWORTHY 属性。

以下 Transact-SQL 示例返回一个数据库 TRUSTWORTHY 列表,这些数据库的属性设置为 ON ,且其数据库所有者属于 系统管理员 固定服务器角色。

SELECT SUSER_SNAME(owner_sid) AS DBOWNER,
       d.name AS DATABASENAME
FROM sys.server_principals AS r
     INNER JOIN sys.server_role_members AS m
         ON r.principal_id = m.role_principal_id
     INNER JOIN sys.server_principals AS p
         ON p.principal_id = m.member_principal_id
     INNER JOIN sys.databases AS 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

以下示例确定数据库的TRUSTWORTHYmsdb属性。

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

如果查询显示TRUSTWORTHY属性设置为 OFFmsdb你可以运行以下查询,将其恢复为默认值。ON

ALTER DATABASE msdb SET TRUSTWORTHY ON;
GO

安全警告

TRUSTWORTHY属性是ON且数据库所有者是系统管理员固定服务器角色的成员时,db_owner固定数据库角色的成员可以将其权限提升为系统管理员。 这两种条件都是必备条件。 对房产要小心 TRUSTWORTHY

以下 Transact-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
     INNER JOIN sys.database_principals AS roles
         ON database_role_members.role_principal_id = roles.principal_id
     INNER 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