TRUSTWORTHY 数据库属性
TRUSTWORTHY
数据库属性用于指明 SQL Server 实例是否信任该数据库以及其中的内容。 默认情况下,此设置为 OFF,但是可以使用 ALTER DATABASE
语句将其设置为 ON。 例如:ALTER DATABASE AdventureWorks2022 SET TRUSTWORTHY ON;
。
注意
必须是 sysadmin 固定服务器角色的成员才能设置此选项。
建议将 TRUSTWORTHY
数据库属性设置为 OFF,以缓解当附加包含以下对象之一的数据库时可能存在的某些威胁:
带有 EXTERNAL_ACCESS 或 UNSAFE 权限设置的有害程序集。 有关详细信息,请参阅 CLR Integration Security。
所定义的、作为高特权用户执行的有害模块。 有关详细信息,请参阅 EXECUTE AS 子句 (Transact-SQL)。
这两种情况均要求具有特定程度的权限,当它们在已附加到 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