包含的数据库面临着一些独有的威胁, SQL Server 数据库引擎 管理员应该了解并缓解这些威胁。 大多数威胁都与 USER WITH PASSWORD
身份验证过程相关,这会将身份验证边界从数据库引擎级别移动到数据库级别。
与用户相关的威胁
具有 ALTER ANY USER
权限的包含数据库中的用户(如 db_owner 成员和 db_securityadmin 固定数据库角色)可以在 SQL Server 管理员没有知识或权限的情况下授予对数据库的访问权限。 向用户授予对封闭数据库的访问权限会增加整个 SQL Server 实例的潜在攻击面。 管理员应了解此访问控制委派,并非常小心地将 ALTER ANY USER
权限授予包含数据库中的用户。 所有数据库所有者都具有 ALTER ANY USER
权限。 SQL Server 管理员应定期审核包含数据库中的用户。
使用来宾帐户访问其他数据库
具有 ALTER ANY USER
权限的数据库所有者和数据库用户可以创建包含的数据库用户。 连接到 SQL Server 实例上的包含数据库后,如果其他数据库启用了 来宾 帐户,则包含的数据库用户可以访问数据库引擎上的其他数据库。
在另一个数据库中创建重复用户
某些应用程序可能要求用户有权访问多个数据库。 这可以通过在每个数据库中创建相同的包含的数据库用户来完成。 使用密码创建第二个用户时使用 SID 选项。 以下示例在两个数据库中创建两个相同的用户。
USE DB1;
GO
CREATE USER Carlo WITH PASSWORD = '<strong password>';
-- Return the SID of the user
SELECT SID FROM sys.database_principals WHERE name = 'Carlo';
-- Change to the second database
USE DB2;
GO
CREATE USER Carlo WITH PASSWORD = '<same password>', SID = <SID from DB1>;
GO
若要执行跨数据库查询,必须在调用数据库上设置 TRUSTWORTHY
该选项。 例如,如果在上面定义的用户 Carlo 位于 DB1 中,要执行 SELECT * FROM db2.dbo.Table1;
,则必须为数据库 DB1 启用 TRUSTWORTHY
设置。 执行以下代码以启用 TRUSTWORHTY
设置。
ALTER DATABASE DB1 SET TRUSTWORTHY ON;
创建复制登录名的用户
如果创建了具有密码的受限制数据库用户,并使用与 SQL Server 登录名相同的名称,而且该 SQL Server 登录名尝试连接时指定受限制数据库为初始目录,那么该 SQL Server 登录名将无法成功连接。 连接将作为包含在数据库中的用户进行评估,其中的密码权限设定在包含的数据库上,而不是基于 SQL Server 登录的用户。 这可能会导致 SQL Server 登录被有意或意外地拒绝服务攻击。
最佳做法是, sysadmin 固定服务器角色的成员应考虑始终连接而不使用初始目录选项。 这会连接登录到 master 数据库,并防止数据库所有者尝试滥用登录过程。 然后,管理员可以使用
USE
<数据库> 语句切换到包含的数据库。 您还可以将登录的默认数据库设置为包含的数据库,这样完成对 master 的登录后,会再切换到包含的数据库。最佳做法是不要使用与 SQL Server 登录名同名的密码创建包含的数据库用户。
如果存在重复登录名,则无需指定初始目录即可连接到 master 数据库,然后执行
USE
命令以更改为包含的数据库。当存在包含数据库时,非包含数据库的用户应在不指定初始目录的情况下连接到数据库引擎,或者将非包含数据库的名称指定为初始目录。 这可以避免连接到数据库引擎管理员无法直接控制的包含数据库。
通过更改数据库的包含状态来增加访问权限
具有 ALTER ANY DATABASE
权限的登录名(例如 dbcreator 固定服务器角色的成员)和具有 CONTROL DATABASE
权限的非包含数据库中的用户(如 db_owner 固定数据库角色的成员)可以更改数据库的包含设置。 如果数据库的包含设置从NONE
更改为PARTIAL
或FULL
,则可以通过创建具有密码的包含数据库用户来授予用户访问权限。 如果没有 SQL Server 管理员的知识或同意,这可以提供访问权限。 若要防止包含任何数据库,请将数据库引擎contained database authentication
选项设置为 0。 若要防止具有密码的包含数据库用户尝试连接到所选的包含数据库,请使用登录触发器取消这些登录尝试。
附加包含的数据库
通过附加包含的数据库,管理员可以为不需要的用户授予对数据库引擎实例的访问权限。 对此风险感到担心的管理员可以将数据库以 RESTRICTED_USER
模式上线,从而阻止包含的数据库用户使用密码进行身份验证。 只有通过登录名授权的主体才能访问数据库引擎。
用户在创建时使用当时生效的密码要求创建,而在数据库被附加时不会重新检查密码。 通过将允许弱密码的数据库附加到具有更严格密码策略的系统,管理员可以允许不符合附加数据库引擎上的当前密码策略的密码。 管理员可以要求为附加数据库重置所有密码,从而避免保留弱密码。
密码策略
数据库中的密码可以要求是强密码,但不能依靠强有力的密码策略来保护。 尽可能使用 Windows 身份验证,以利用 Windows 提供的更广泛的密码策略。
Kerberos 身份验证
具有密码的包含的数据库用户无法使用 Kerberos 身份验证。 如果可能,请使用 Windows 身份验证来利用 Windows 功能,例如 Kerberos。
脱机字典攻击
带有密码的数据库用户的密码哈希,是存储在已包含的数据库中的。 任何有权访问数据库文件的人都可以对数据库用户进行字典攻击,因为这些用户的密码存在于未经审核的系统中。 若要缓解此威胁,请限制对数据库文件的访问,或者仅允许使用 Windows 身份验证连接到包含的数据库。
逃离受限的数据库
如果数据库是部分包含的,则 SQL Server 管理员应定期审核包含数据库中用户和模块的权限。
通过AUTO_CLOSE拒绝服务
不要将包含的数据库配置为自动关闭。 如果关闭,则打开数据库以对用户进行身份验证会占用其他资源,并可能导致拒绝服务攻击。