编写器的安全注意事项

VSS 基础结构要求编写器进程能够同时充当 COM 客户端和服务器。

充当服务器时,VSS 编写器 (公开 COM 接口,例如,VSS 事件处理程序(如 CVssWriter::OnIdentify )) ,并从 VSS 进程 ((如请求方和 VSS 服务)接收来自 VSS 外部进程的传入 COM 调用) 或 RPC 调用,例如,当这些进程生成 VSS 事件 (, 当请求者调用 IVssBackupComponents::GatherWriterMetadata) 时。 因此,VSS 编写器需要安全地管理哪些 COM 客户端能够对其进程进行传入的 COM 调用。

同样,VSS 编写器还可以充当 COM 客户端,对 VSS 基础结构提供的回调发出传出 COM 调用,或对 VSS 外部的进程进行 RPC 调用。 备份应用程序或 VSS 服务提供的这些回调允许编写器执行任务,例如通过 IVssComponent 接口更新备份组件文档。 因此,VSS 安全设置必须允许编写器向其他 VSS 进程发出传出 COM 调用。

管理编写器安全问题的最简单机制涉及正确选择运行它的用户帐户。 编写器通常需要在管理员组或备份操作员组成员的用户下运行,或者需要作为本地系统帐户运行。

默认情况下,当编写器充当 COM 客户端时,如果它不在这些帐户下运行,则它进行的任何 COM 调用都会自动被拒绝 并E_ACCESSDENIED ,甚至无需访问 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 调用。

  • 仅允许指定进程访问以调用写入器进程。

    使用非 NULL 安全描述符调用 CoInitializeSecurity 的 COM 服务器) (,例如调用 CoInitializeSecurity 的编写器,可以使用描述符将自身配置为仅接受来自属于一组特定帐户的用户的传入调用。

    编写器必须确保在有效用户下运行的 COM 客户端有权调用其进程。 在第一个参数中指定安全描述符的编写器必须允许以下用户对请求者进程执行传入调用:

    • Local System
    • 本地管理员组的成员
    • 本地备份操作员组的成员
    • 运行编写器的帐户

显式控制用户帐户对编写器的访问权限

在某些情况下,将编写器的访问权限限制为作为本地系统运行或在本地管理员或本地备份操作员本地组下运行的进程可能过于严格。

例如,编写器进程 (第三方非系统编写器) 通常不需要在管理员或备份操作员帐户下运行。 出于安全原因,最好不要人为地提升进程的权限以支持 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 编写器。