The published Win32 contract should be read conservatively as requiring enabled SeDebugPrivilege for the documented cross-account case; it does not state that an existing process handle and an allowing token DACL waive that requirement.^1^
Documented stages
These are separate authorization elements:
- Process-handle requirement
ProcessHandlemust be a valid process handle whose granted access includesPROCESS_QUERY_LIMITED_INFORMATION. This requirement concerns the handle already supplied toOpenProcessToken; the function does not reopen the process by PID.^1^ When the handle is initially obtained throughOpenProcess, its requested rights are checked against the process object's security descriptor. EnabledSeDebugPrivilegecausesOpenProcessto grant the requested access regardless of that descriptor.^2^ - Token-object access check
OpenProcessToken(hProcess, TOKEN_QUERY, ...)checksTOKEN_QUERYagainst the DACL in the primary token object's security descriptor.^3^SeDebugPrivilegeis documented as ignoring the process DACL, not the token DACL.^4^ Thus, enabling it does not replace the separateTOKEN_QUERYauthorization check. - Cross-account remark Independently of those parameter descriptions, the
OpenProcessTokenRemarks say:- A non-elevated process can obtain a handle to an elevated process when both processes were started by the same account.
- If the checked process was started by another account, the checking process needs
SE_DEBUG_NAMEenabled.^1^
The page does not limit that statement to obtaining the original process handle, nor does it provide an exception for a process handle acquired previously, inherited, or duplicated. Consequently, the requested interpretation—“the privilege is needed only to obtain the handle or overcome its DACL”—is plausible as an implementation model but is not presently stated as the supported Win32 contract.
For the exact base case, the documented prerequisites therefore are cumulative:
HANDLE token = nullptr;
if (!OpenProcessToken(process, TOKEN_QUERY, &token)) {
DWORD error = GetLastError();
// Cross-account use is not documented as exempt from SeDebugPrivilege.
} else {
// Query token information as needed.
CloseHandle(token);
}
Lower-level documentation does not establish an exemption
The kernel-facing NtOpenProcessToken page documents a process-handle access requirement and a token-DACL check. Its listed errors include an insufficient process-handle right and STATUS_PRIVILEGE_NOT_HELD for access requiring SeSecurityPrivilege; it does not list a distinct cross-account SeDebugPrivilege condition.^5^
That omission does not override the explicit Win32 remark or prove that a supplied handle bypasses it. The lower-level page also specifies PROCESS_QUERY_INFORMATION, whereas the current Win32 page specifies PROCESS_QUERY_LIMITED_INFORMATION, so it is not a complete substitute for the Win32 contract.
Version and security-context qualifications
- The
OpenProcessTokenpage gives no client/server build on which the cross-account rule changes.^1^ -
PROCESS_QUERY_LIMITED_INFORMATIONis not supported on Windows XP or Windows Server 2003; it was introduced with the newer process-access model.^6^ - MIC/UAC: Mandatory Integrity Control is evaluated in addition to, and before, discretionary DACL access. An allowing DACL therefore does not negate a mandatory integrity restriction.^7^
- Restricted caller token: Access must pass using both enabled SIDs and restricting SIDs. A normal DACL allow ACE is insufficient unless both checks permit access.^8^
- AppContainer: User/group authorization and AppContainer package or capability authorization are intersected, and AppContainers have additional process isolation.^9^
- Protected processes/PPL: The public process-security page documents additional restrictions for protected processes, including denial of several process rights. It does not document the precise supplied-handle/PPL token-opening case, so no broader conclusion should be inferred from the ordinary-process contract.^6^
Obtaining authoritative clarification
No public source here records an owning Windows API team's clarification for this exact supplied-handle scenario. Submit documentation feedback on the OpenProcessToken page asking the owner to state explicitly whether the cross-account sentence:
- applies during
OpenProcessTokeneven when the supplied handle already has the required granted access; or - describes only acquiring sufficient process access.
Microsoft Learn supports page-specific feedback and documentation questions through its feedback experience.^10^ If a binding answer is required before that documentation is corrected, use a Microsoft support case; community Q&A cannot create a Windows API compatibility contract.
References
- OpenProcessToken function (processthreadsapi.h)
- OpenProcess function (processthreadsapi.h)
- Access Rights for Access-Token Objects
- Privilege Constants (Authorization)
- NtOpenProcessToken function (ntifs.h)
- Process Security and Access Rights
- Mandatory Integrity Control mechanism
- Restricted Tokens
- Launch an AppContainer
- Provide feedback for Microsoft Learn content