Skip to content

[Robustness] Servy.psm1 Assert-Administrator — WindowsIdentity from GetCurrent() never disposed (handle leak per call) #864

@Christophe-Rogiers

Description

@Christophe-Rogiers

Severity: Info

File: src/Servy.CLI/Servy.psm1, lines 479-485

Assert-Administrator calls WindowsIdentity.GetCurrent() and abandons the resulting object — no Dispose(), no try/finally. WindowsIdentity owns a native impersonation token handle and implements IDisposable:

function Assert-Administrator {
    $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($identity)

    if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
        throw \"This operation requires Administrator privileges. Run PowerShell as Administrator.\"
    }
}

The function is called by every privileged module command (Invoke-ServyServiceCommand, install/uninstall, start/stop, etc.). For a long-running PowerShell session that drives many service operations, every call leaks a token handle until GC's finalizer runs.

PowerShell 2.0 has no using statement (added in PS 5.0), but a manual try/finally still works:

function Assert-Administrator {
    $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
    try {
        $principal = New-Object Security.Principal.WindowsPrincipal($identity)
        if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
            throw \"This operation requires Administrator privileges. Run PowerShell as Administrator.\"
        }
    }
    finally {
        $identity.Dispose()
    }
}

(Same pattern as the C# fix in #861 for ProtectedKeyProvider.SaveProtected — module and main-product code should treat WindowsIdentity consistently.)

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions