Skip to content

[Security] NativeMethods.ValidateCredentials — silently passes for non-gMSA accounts when password is null/empty (function name promises validation) #1016

@Christophe-Rogiers

Description

@Christophe-Rogiers

Severity: Warning

File: src/Servy.Core/Native/NativeMethods.cs lines 664–757

Finding

public static void ValidateCredentials(string username, string? password)
{
    // ... regex/identity checks ...

    if (string.IsNullOrEmpty(password) || isGMSA)
    {
        return;   // <-- silent success
    }

    // LogonUser is only attempted past this point
    ...
}

A non-gMSA user account with a null or empty password slips past validation without any logon attempt being made. The function name ValidateCredentials and its XML summary ("Validates Windows credentials by resolving the identity and attempting a network logon") imply that a logon was attempted; the early return makes that promise false.

Real-world consequence: when a user fills in UserAccount = "DOMAIN\bob" but leaves Password blank in the install form, ValidateCredentials returns success, the install path proceeds, and CreateService registers the service with a blank password. The service then fails to start at the SCM layer with a confusing 1069 ("Logon failure: the user has not been granted the requested logon type"), leaving the operator chasing a phantom permission/policy issue when the actual root cause is "we accepted an empty password and pretended to validate it".

The early return is correct for gMSA (which intentionally has no password), but conflating "isGMSA" with "password is empty" hides the user error.

Suggested fix

Reject empty passwords for non-gMSA accounts up front:

if (isGMSA)
    return;   // gMSA has no password — by design

if (string.IsNullOrEmpty(password))
    throw new ArgumentException(
        "A password is required for non-gMSA service accounts. " +
        "If this is a Group Managed Service Account, ensure the username ends with '$'.");

…and align the XML summary to make the gMSA-only exemption explicit:

/// <summary>
/// Validates Windows credentials by resolving the identity and (for non-gMSA accounts)
/// attempting a network logon. gMSA accounts are validated by identity translation only.
/// </summary>

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions