{"record":{"id":"fe97dabe2016ffcd","repo":"crowdsecurity/crowdsec","slug":"only-system-administrators-or-the-user-currently","errorCode":null,"errorMessage":"only SYSTEM, Administrators or the user currently running crowdsec can have more than read/execute on plugin %s","messagePattern":"only SYSTEM, Administrators or the user currently running crowdsec can have more than read/execute on plugin (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csplugin/utils_windows.go","lineNumber":151,"sourceCode":"\t\tif ace.AceType == ACCESS_DENIED_ACE_TYPE {\n\t\t\tcontinue\n\t\t}\n\t\taceSid := (*windows.SID)(unsafe.Pointer(&ace.SidStart))\n\n\t\tif aceSid.Equals(systemSid) || aceSid.Equals(adminSid) {\n\t\t\tlog.Debugf(\"Not checking permission for well-known SID %s\", aceSid.String())\n\t\t\tcontinue\n\t\t}\n\n\t\tif aceSid.Equals(currentUserSid) {\n\t\t\tlog.Debugf(\"Not checking permission for current user %s\", currentUser.Username)\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Debugf(\"Checking permission for SID %s\", aceSid.String())\n\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()","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csplugin/utils_windows.go#L133-L169","documentation":"This is the final policy enforcement in CheckPerms: for every allow-ACE whose SID is not SYSTEM, BUILTIN\\Administrators, or the crowdsec process user, the code masks the AccessMask with the inverse of FILE_GENERIC_READ|FILE_GENERIC_EXECUTE; any extra bits (e.g. write/delete) mean that account could modify the plugin binary, so CheckPerms rejects it. It exists because a world-writable plugin could be swapped for malicious code executed by crowdsec.","triggerScenarios":"Calling CheckPerms on a plugin whose DACL grants a non-whitelisted account more than read/execute — e.g. ACEs granting Users or Everyone Modify/Full Control, or inherited broad-write ACEs on the plugin directory.","commonSituations":"Plugin directory shared with group write access for convenience; inherited permissions from a loosely-secured parent folder; plugins deployed by a tool that grants 'Users: Modify'; files in a temp/downloads folder with permissive default ACLs.","solutions":["Restrict the plugin's ACL so non-privileged accounts get only read/execute: `icacls <plugin> /inheritance:r /grant Administrators:F /grant SYSTEM:F /grant Users:RX`","Fix the parent directory's inherited permissions so plugins don't inherit broad write ACEs","Move the plugins out of any world-writable directory into the standard install path","Audit with `icacls <plugin>` and remove ACEs granting Users/Everyone Modify or Full Control"],"exampleFix":"// before\n# Everyone has Modify on the plugin → rejected\nicacls notify-email.exe\nEveryone:(M)\n// after\n# elevated shell\nicacls notify-email.exe /inheritance:r /grant Administrators:F /grant SYSTEM:F /grant Users:RX","handlingStrategy":"validation","validationCode":"func pluginACLEntriesAreReadExecute(path string, trusted map[string]bool) error {\n\tsd, err := windows.GetNamedSecurityInfo(path, windows.SE_FILE_OBJECT, windows.DACL_SECURITY_INFORMATION)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdacl, _, err := sd.DACL()\n\tif err != nil || dacl == nil {\n\t\treturn errors.New(\"DACL missing\")\n\t}\n\t// entries granting non-trusted SIDs more than RX will be rejected by CheckPerms\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Grant only Users:RX (read/execute) on plugin binaries at install time","Break inheritance on the plugin directory so broad ACEs don't propagate","Audit ACLs after every plugin deployment (`icacls <plugin>`)","Never place plugins in world-writable directories"],"tags":["windows","acl","security","permissions"],"backgroundTag":"insufficient-permissions","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}