crowdsecurity/crowdsec · error

while adjusting token privileges: %w

Error message

while adjusting token privileges: %w

What it means

This error wraps a failure from windows.AdjustTokenPrivileges, which is called with DisableAllPrivileges=true to strip every privilege from the duplicated token so the plugin runs with minimal rights. It is thrown when the Win32 call returns an error (as opposed to returning success with GetLastWin32Error=ERROR_NOT_ALL_ASSIGNED, which is not treated as failure here since all privileges are being disabled).

Source

Thrown at pkg/csplugin/utils_windows.go:182

	err := windows.OpenProcessToken(proc, windows.TOKEN_DUPLICATE|windows.TOKEN_ADJUST_DEFAULT|
		windows.TOKEN_QUERY|windows.TOKEN_ASSIGN_PRIMARY|windows.TOKEN_ADJUST_GROUPS|windows.TOKEN_ADJUST_PRIVILEGES, &procToken)
	if err != nil {
		return nil, fmt.Errorf("while opening process token: %w", err)
	}
	defer procToken.Close()

	err = windows.DuplicateTokenEx(procToken, 0, nil, windows.SecurityImpersonation,
		windows.TokenPrimary, &token)
	if err != nil {
		return nil, fmt.Errorf("while duplicating token: %w", err)
	}

	//Remove all privileges from the token

	err = windows.AdjustTokenPrivileges(token, true, nil, 0, nil, nil)

	if err != nil {
		return nil, fmt.Errorf("while adjusting token privileges: %w", err)
	}

	//Run the plugin as a medium integrity level process
	//For some reasons, low level integrity don't work, the plugin and crowdsec cannot communicate over the TCP socket
	sid, err := windows.CreateWellKnownSid(windows.WELL_KNOWN_SID_TYPE(windows.WinMediumLabelSid))
	if err != nil {
		return nil, err
	}

	tml := &windows.Tokenmandatorylabel{}
	tml.Label.Attributes = windows.SE_GROUP_INTEGRITY
	tml.Label.Sid = sid

	err = windows.SetTokenInformation(token, windows.TokenIntegrityLevel,
		(*byte)(unsafe.Pointer(tml)), tml.Size())
	if err != nil {
		token.Close()
		return nil, fmt.Errorf("while setting token information: %w", err)

View on GitHub (pinned to 909b515798)

Solutions

  1. Fix the root cause reported by earlier steps: ensure OpenProcessToken and DuplicateTokenEx succeeded so the token handle is valid.
  2. Verify the caller has the rights needed to adjust the token (the token was created by the same process, so this usually indicates EDR interference).
  3. Capture the wrapped syscall.Errno in logs to identify ERROR_INVALID_HANDLE vs ERROR_ACCESS_DENIED.
  4. Reboot/restart the service to clear a corrupted token state if the same code works in a clean environment.
Defensive patterns

Strategy: try-catch

Validate before calling

// Token validity can be probed before adjusting privileges
if token == 0 {
    return fmt.Errorf("token handle invalid before AdjustTokenPrivileges")
}

Try / catch

cmd, err := broker.CreateCmd(ctx, binaryPath)
if err != nil {
    var errno syscall.Errno
    if errors.As(err, &errno) && errno == windows.ERROR_INVALID_HANDLE {
        log.Error("privilege adjustment failed on invalid token; check earlier token steps")
    }
    return err
}

Prevention

When it happens

Trigger: getProcessAttr, called from PluginBroker.CreateCmd during plugin startup on Windows, fails at AdjustTokenPrivileges(token, true, nil, 0, nil, nil) — e.g. the token handle is invalid or the caller lacks rights to modify the token's privileges.

Common situations: Token handle already closed/invalid after a failed earlier step; security software tampering with token modification calls; corrupt token state from a failed DuplicateTokenEx; running in a hardened service context that forbids AdjustTokenPrivileges.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/4b64f1c19a4abd8f. Report an issue: GitHub.