编写器的安全注意事项
VSS 基础结构要求编写器进程能够同时充当 COM 客户端和服务器。
当充当服务器时,VSS 编写器会公开 COM 接口(例如,VSS 事件处理程序(例如,CVssWriter::OnIdentify)并从 VSS 进程(如请求者和 VSS 服务)接收传入 COM 调用,或者从 VSS 外部的进程进行 RPC 调用(例如,当这些进程生成 VSS 事件时(例如, 当请求者调用 IVssBackupComponents::GatherWriterMetadata时。 因此,VSS 编写器需要安全地管理哪些 COM 客户端能够对其进程进行传入 COM 调用。
同样,VSS 编写器也可以充当 COM 客户端,对 VSS 基础结构提供的回调进行传出 COM 调用,或对 VSS 外部的进程进行 RPC 调用。 由备份应用程序或 VSS 服务提供的这些回调允许编写器执行诸如通过 IVssComponent 接口更新备份组件文档等任务。 因此,VSS 安全设置必须允许编写器向其他 VSS 进程发出传出 COM 调用。
管理编写器安全问题的最简单机制涉及正确选择运行它的用户帐户。 编写器通常需要在管理员组或备份作员组成员的用户下运行,或者需要作为本地系统帐户运行。
默认情况下,当编写器充当 COM 客户端时,如果未在这些帐户下运行,则会使用 E_ACCESSDENIED 自动拒绝它进行的任何 COM 调用,甚至无法访问 COM 方法实现。
禁用 COM 异常处理
开发编写器时,将 COM COMGLB_EXCEPTION_DONOT_HANDLE全局选项标志设置为禁用 COM 异常处理。 请务必执行此作,因为 COM 异常处理可以屏蔽 VSS 应用程序中的严重错误。 屏蔽的错误会使进程处于不稳定且不可预知的状态,这可能会导致损坏和挂起。 有关此标志的详细信息,请参阅 IGlobalOptions。
设置编写器默认 COM 访问检查权限
编写器需要注意,当他们的进程充当服务器(例如处理 VSS 事件)时,他们必须允许来自其他 VSS 参与者(例如请求者或 VSS 服务)的传入调用。
但是,默认情况下,进程将只允许在同一登录会话(SELF SID)下运行的 COM 客户端,或在本地系统帐户下运行。 这是一个潜在的问题,因为这些默认值不足以支持 VSS 基础结构。 例如,请求者可以作为“备份作员”用户帐户运行,该用户帐户既不在编写器进程所在的同一登录会话中,也不是本地系统帐户。
为了处理此类问题,每个 COM 服务器进程都可以进一步控制是否允许 RPC 或 COM 客户端执行服务器(在本例中编写器)实现的 COM 方法,方法是使用 CoInitializeSecurity 设置进程范围内的默认 COM 访问检查权限。
编写器可以显式执行以下作:
允许所有进程访问以调用写入器进程。
此选项可能足以用于许多编写器,并且由其他 COM 服务器使用,例如,所有基于 SVCHOST 的 Windows 服务都已使用此选项,默认情况下所有 COM+ 服务也是如此。
允许所有进程执行传入 COM 调用不一定是安全漏洞。 充当 COM 服务器的编写器(与其他所有 COM 服务器一样)始终保留在其进程中实现的每个 COM 方法上对其客户端授权的选项。
若要允许所有进程 COM 访问编写器,可以将 NULL 安全描述符作为 CoInitializeSecurity的第一个参数传递。 (请注意,CoInitializeSecurity 必须在整个过程中最多调用一次。有关 CoInitializeSecurity的更多详细信息,请参阅 COM 文档。
下面是一个代码示例,其中包括调用 CoInitializeSecurity:
// Initialize COM security. hr = CoInitializeSecurity( NULL, // PSECURITY_DESCRIPTOR pSecDesc, -1, // LONG cAuthSvc, NULL, // SOLE_AUTHENTICATION_SERVICE *asAuthSvc, NULL, // void *pReserved1, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // DWORD dwAuthnLevel, RPC_C_IMP_LEVEL_IDENTIFY, // DWORD dwImpLevel, NULL, // void *pAuthList, EOAC_NONE, // DWORD dwCapabilities, NULL // void *pReserved3 );
使用 CoInitializeSecurity显式设置编写器的 COM 级别安全性时,应执行以下作:
将身份验证级别设置为至少 RPC_C_AUTHN_LEVEL_CONNECT。
为了提高安全性,请考虑使用 RPC_C_AUTHN_LEVEL_PKT_PRIVACY。
将模拟级别设置为 RPC_C_IMP_LEVEL_IDENTIFY,除非编写器进程需要允许模拟与 VSS 无关的特定 RPC 或 COM 调用。
仅允许指定进程访问以调用写入器进程。
调用 CoInitializeSecurity 且具有非NULL 安全描述符的 COM 服务器(例如编写器)可以使用描述符来配置自身以仅接受属于特定帐户集的用户的传入调用。
编写器必须确保在有效用户下运行的 COM 客户端有权调用其进程。 在第一个参数中指定安全描述符的编写器必须允许以下用户对请求程序进程执行传入调用:
- 本地系统
- 本地管理员组的成员
- 本地备份作员组的成员
- 编写器正在运行的帐户
显式控制对编写器的用户帐户访问权限
在某些情况下,限制对作为本地系统运行的进程的编写器的访问权限,或者在本地管理员或本地备份作员本地组下,可能过于限制。
例如,编写器进程(可能是第三方非系统编写器)通常不需要在管理员或备份作员帐户下运行。 出于安全原因,最好不要人为地提升进程的特权来支持 VSS。
在这些情况下,必须修改 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VSS\VssAccessControl 注册表项,以指示 VSS 指定用户安全地运行 VSS 编写器。
在此密钥下,必须创建与要授予或拒绝访问权限的帐户同名的子项。 此子项必须设置为下表中的值之一。
价值 | 意义 |
---|---|
0 | 拒绝用户访问你的编写者和请求者。 |
1 | 向用户授予对编写器的访问权限。 |
2 | 向用户授予对请求者的访问权限。 |
3 | 向用户授予对编写者和请求者的访问权限。 |
以下示例授予对“MyDomain\MyUser”帐户的访问权限:
HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
Services
VSS
VssAccessControl
MyDomain\MyUser = 1<dl>
<dt>
Data type
</dt>
<dd> REG_DWORD</dd>
</dl>
此机制还可用于显式限制其他允许的用户运行 VSS 编写器。 以下示例将限制来自“ThatDomain\Administrator”帐户的访问:
HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
Services
VSS
VssAccessControl
ThatDomain\Administrator = 0<dl>
<dt>
Data type
</dt>
<dd> REG_DWORD</dd>
</dl>
用户 ThatDomain\Administrator 将无法运行 VSS 编写器。