{"record":{"id":"bb2785e26afe3c39","repo":"crowdsecurity/crowdsec","slug":"no-dacl-found-on-plugin-meaning-fully-permissive","errorCode":null,"errorMessage":"no DACL found on plugin, meaning fully permissive access on plugin %s","messagePattern":"no DACL found on plugin, meaning fully permissive access on plugin (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csplugin/utils_windows.go","lineNumber":107,"sourceCode":"\towner, _, err := sd.Owner()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"while getting owner: %w\", err)\n\t}\n\tif !owner.IsValid() {\n\t\treturn errors.New(\"owner is invalid\")\n\t}\n\n\tif !owner.Equals(systemSid) && !owner.Equals(currentUserSid) && !owner.Equals(adminSid) {\n\t\treturn fmt.Errorf(\"plugin at %s is not owned by SYSTEM, Administrators or by current user, but by %s\", path, owner.String())\n\t}\n\n\tdacl, _, err := sd.DACL()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"while getting DACL: %w\", err)\n\t}\n\n\tif dacl == nil {\n\t\treturn fmt.Errorf(\"no DACL found on plugin, meaning fully permissive access on plugin %s\", path)\n\t}\n\n\trs := reflect.ValueOf(dacl).Elem()\n\n\t/*\n\t\t\tFor reference, the structure of the ACL type is:\n\t\t\ttype ACL struct {\n\t\t\taclRevision byte\n\t\t\tsbz1        byte\n\t\t\taclSize     uint16\n\t\t\taceCount    uint16\n\t\t\tsbz2        uint16\n\t\t}\n\t\tAs the field are not exported, we have to use reflection to access them, this should not be an issue as the structure won't (probably) change any time soon.\n\t*/\n\taceCount := rs.Field(3).Uint()\n\n\tfor i := range aceCount {","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csplugin/utils_windows.go#L89-L125","documentation":"This is an explicit security check: if the plugin file has no DACL, Windows grants everyone full access, meaning any local user could modify or replace the plugin binary that crowdsec executes. CheckPerms refuses such a file. Note this can also trigger on filesystems that don't support ACLs at all.","triggerScenarios":"Calling CheckPerms on a plugin whose security descriptor has a NULL DACL — the file has no ACL entries, or the file sits on a filesystem without NT ACL support (FAT32/exFAT, some network shares) so GetNamedSecurityInfo returns no DACL.","commonSituations":"Plugins copied to/from FAT32 USB media or non-NTFS mounts; files shared over network filesystems without ACL propagation; manually stripped ACLs (`icacls /remove` all entries); container bind-mounts that drop ACL information.","solutions":["Move the plugins to an NTFS volume and apply a restrictive ACL: `icacls <plugin> /inheritance:r /grant Administrators:F /grant SYSTEM:F`","Ensure a DACL exists at all — a freshly reset or explicitly granted ACL (`icacls <plugin> /grant ...`) removes the NULL-DACL state","Avoid storing plugins on FAT32/exFAT/network shares; use the default install path on NTFS","Verify with `icacls <plugin>` that explicit ACEs are listed"],"exampleFix":"// before\n# plugin on FAT32 mount → no DACL\n// after\n# move to NTFS and grant explicit ACEs (elevated)\nmove C:\\mnt\\usb\\notify-email.exe C:\\ProgramData\\crowdsec\\plugins\\\nicacls \"C:\\ProgramData\\crowdsec\\plugins\\notify-email.exe\" /inheritance:r /grant Administrators:F /grant SYSTEM:F /grant \"NT AUTHORITY\\SYSTEM\":RX","handlingStrategy":"validation","validationCode":"func hasDACL(path string) (bool, error) {\n\tsd, err := windows.GetNamedSecurityInfo(path, windows.SE_FILE_OBJECT, windows.DACL_SECURITY_INFORMATION)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tdacl, _, err := sd.DACL()\n\treturn dacl != nil, err\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always store plugins on NTFS, never FAT32/exFAT or ACL-less network shares","Explicitly grant a restrictive ACL at install time instead of relying on inheritance","Verify `icacls <plugin>` lists ACEs after deployment"],"tags":["windows","acl","security","filesystem"],"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"}