{"record":{"id":"83bf4c423eb4a1cd","repo":"crowdsecurity/crowdsec","slug":"while-opening-process-token-w","errorCode":null,"errorMessage":"while opening process token: %w","messagePattern":"while opening process token: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csplugin/utils_windows.go","lineNumber":167,"sourceCode":"\t\tdenyMask := ^(windows.FILE_GENERIC_READ | windows.FILE_GENERIC_EXECUTE)\n\t\tif ace.AccessMask&uint32(denyMask) != 0 {\n\t\t\treturn fmt.Errorf(\"only SYSTEM, Administrators or the user currently running crowdsec can have more than read/execute on plugin %s\", path)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc getProcessAttr() (*windows.SysProcAttr, error) {\n\tvar procToken, token windows.Token\n\n\tproc := windows.CurrentProcess()\n\tdefer windows.CloseHandle(proc)\n\n\terr := windows.OpenProcessToken(proc, windows.TOKEN_DUPLICATE|windows.TOKEN_ADJUST_DEFAULT|\n\t\twindows.TOKEN_QUERY|windows.TOKEN_ASSIGN_PRIMARY|windows.TOKEN_ADJUST_GROUPS|windows.TOKEN_ADJUST_PRIVILEGES, &procToken)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"while opening process token: %w\", err)\n\t}\n\tdefer procToken.Close()\n\n\terr = windows.DuplicateTokenEx(procToken, 0, nil, windows.SecurityImpersonation,\n\t\twindows.TokenPrimary, &token)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"while duplicating token: %w\", err)\n\t}\n\n\t//Remove all privileges from the token\n\n\terr = windows.AdjustTokenPrivileges(token, true, nil, 0, nil, nil)\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"while adjusting token privileges: %w\", err)\n\t}\n\n\t//Run the plugin as a medium integrity level process","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csplugin/utils_windows.go#L149-L185","documentation":"This error wraps a failure from windows.OpenProcessToken, which opens the access token of the current crowdsec process so it can be duplicated and handed to the plugin subprocess. It is thrown when the OS refuses to open the process token with the requested access rights (TOKEN_DUPLICATE, TOKEN_QUERY, TOKEN_ASSIGN_PRIMARY, etc.), typically due to insufficient privileges on the process or a token/security-descriptor problem.","triggerScenarios":"getProcessAttr, called from PluginBroker.CreateCmd when spawning a notification plugin on Windows, fails at OpenProcessToken — e.g. the process runs under an account whose token cannot be opened with the requested access mask, or a Win32 error such as ERROR_ACCESS_DENIED is returned by the syscall.","commonSituations":"Running crowdsec as a restricted service account or inside a sandboxed environment that strips token access rights; corrupted or restricted process token; third-party security software (AV/EDR) blocking token manipulation; running on a Windows variant where the calling process's DACL denies TOKEN_DUPLICATE.","solutions":["Run crowdsec as a sufficiently privileged account (e.g. LocalSystem or a service account with SeAssignPrimaryTokenPrivilege / admin rights).","Check whether antivirus/EDR or AppLocker policy is blocking token operations and add an exclusion for the crowdsec binary.","Verify the process token is intact: log the underlying Win32 error from the wrapped %w to identify ERROR_ACCESS_DENIED vs other codes.","Upgrade/repair Windows if the process token is corrupted (rare); test with a minimal Go program calling OpenProcessToken with the same mask."],"exampleFix":"// before\nprocTokenAccess := windows.TOKEN_DUPLICATE | windows.TOKEN_ADJUST_DEFAULT | windows.TOKEN_QUERY | windows.TOKEN_ASSIGN_PRIMARY | windows.TOKEN_ADJUST_GROUPS | windows.TOKEN_ADJUST_PRIVILEGES\nerr := windows.OpenProcessToken(proc, procTokenAccess, &procToken)\n// after (narrow the mask and surface the underlying error for diagnosis)\nprocTokenAccess := windows.TOKEN_DUPLICATE | windows.TOKEN_QUERY | windows.TOKEN_ASSIGN_PRIMARY\nif err := windows.OpenProcessToken(proc, procTokenAccess, &procToken); err != nil {\n    return nil, fmt.Errorf(\"while opening process token: %w\", err) // inspect wrapped syscall.Errno\n}","handlingStrategy":"try-catch","validationCode":"if runtime.GOOS != \"windows\" {\n    // token APIs not needed; skip\n}\n// Probe ability to open the process token before starting plugins\nvar tok windows.Token\nif err := windows.OpenProcessToken(windows.CurrentProcess(), windows.TOKEN_QUERY, &tok); err != nil {\n    log.Warnf(\"process token not openable, plugins may fail to start: %v\", err)\n}\n","typeGuard":null,"tryCatchPattern":"cmd, err := broker.CreateCmd(ctx, binaryPath)\nif err != nil {\n    var errno syscall.Errno\n    if errors.As(err, &errno) {\n        switch errno {\n        case windows.ERROR_ACCESS_DENIED:\n            log.Error(\"insufficient privileges to open process token; run crowdsec as LocalSystem/admin\")\n        default:\n            log.Errorf(\"token open failed: %v\", err)\n        }\n    }\n    return err\n}","preventionTips":["Run the crowdsec service under LocalSystem or an admin-equivalent account on Windows.","Keep AV/EDR exclusions current for the crowdsec binary and plugin paths.","Log the full error chain (%w) so the underlying syscall.Errno is visible.","Smoke-test plugin startup after Windows updates or security-policy changes."],"tags":["windows","process-token","privilege"],"backgroundTag":"insufficient-permissions","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}