{"record":{"id":"6e851f5646450cf4","repo":"JuliusBrussee/caveman","slug":"sqlite-parent-q-grants-broad-windows-write-access","errorCode":null,"errorMessage":"sqlite parent %q grants broad Windows write access","messagePattern":"sqlite parent %q grants broad Windows write access","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/ccr/sqlite_parent_security_windows.go","lineNumber":34,"sourceCode":"\t\twindows.SE_FILE_OBJECT,\n\t\twindows.DACL_SECURITY_INFORMATION,\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"inspect sqlite parent ACL %q: %w\", path, err)\n\t}\n\tif descriptor == nil {\n\t\treturn fmt.Errorf(\"sqlite parent %q has no security descriptor\", path)\n\t}\n\tdacl, _, err := descriptor.DACL()\n\tif err != nil || dacl == nil {\n\t\treturn fmt.Errorf(\"sqlite parent %q has no restrictive DACL\", path)\n\t}\n\tbroad, err := windowsACLGrantsBroadWrite(dacl)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"inspect sqlite parent ACL %q: %w\", path, err)\n\t}\n\tif broad {\n\t\treturn fmt.Errorf(\"sqlite parent %q grants broad Windows write access\", path)\n\t}\n\treturn nil\n}\n\nfunc windowsACLGrantsBroadWrite(dacl *windows.ACL) (bool, error) {\n\tbroadSIDs := make([]*windows.SID, 0, 4)\n\tfor _, sidType := range []windows.WELL_KNOWN_SID_TYPE{\n\t\twindows.WinWorldSid,\n\t\twindows.WinAuthenticatedUserSid,\n\t\twindows.WinBuiltinUsersSid,\n\t\twindows.WinBuiltinGuestsSid,\n\t} {\n\t\tsid, err := windows.CreateWellKnownSid(sidType)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tbroadSIDs = append(broadSIDs, sid)\n\t}","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/engine/ccr/sqlite_parent_security_windows.go#L16-L52","documentation":"The library validates that the parent directory of its SQLite recovery database is not writable by broad groups (Everyone, Authenticated Users, Builtin Users, Builtin Guests). If any allow ACE granting write/append/delete/DELETE_CHILD/WRITE_DAC/WRITE_OWNER or generic write access to one of those SIDs is found on the directory's DACL, it refuses to proceed rather than risk tampering with the recovery store. This is a deliberate fail-closed security check for the CCR store on Windows.","triggerScenarios":"Any CCR store operation (PutObject/putObject path) on Windows where the DB parent directory's DACL contains an inherit-only-excluded, allow-type ACE for WinWorldSid, WinAuthenticatedUserSid, WinBuiltinUsersSid, or WinBuiltinGuestsSid with a broad write mask — e.g. a home directory or temp folder with default Users-write ACLs.","commonSituations":"Running the engine under a profile or directory whose defaults include BUILTIN\\Users write ACEs (e.g. C:\\Users\\Public, shared temp folders); manually loosened ACLs via icacls; cloned/rolled-back VMs or restored directories whose ACL inheritance was widened; relocating the CCR db to a shared folder.","solutions":["Restrict the parent directory ACL so no broad SID holds write access (e.g. icacls <dir> /inheritance:r /grant:r \"%USERNAME%\":F) and retry","Point the CCR database path at a user-private directory (e.g. %USERPROFILE%\\.caveman) whose ACLs only grant your account access","Inspect the offending ACEs with icacls <dir> or Get-Acl to identify which broad SID is granted write and remove that specific ACE","Verify after fixing that the directory is not on a volume applying broad default inheritance from a shared parent"],"exampleFix":"# before: broad ACEs on the store directory\nicacls C:\\Users\\me\\.caveman  # shows BUILTIN\\Users:(W)\n# after: strip inheritance, keep only current user\nicacls C:\\Users\\me\\.caveman /inheritance:r /grant:r \"%USERNAME%\":F","handlingStrategy":"validation","validationCode":"// Pre-check the parent directory ACL with PowerShell before starting the engine\n// icacls <parentDir> — fail if output shows Everyone, Authenticated Users,\n// BUILTIN\\Users, or BUILTIN\\Guests with (W)/(M)/(F)/(DE) rights\n// Harden with:\n//   icacls <parentDir> /inheritance:r /grant:r \"%USERNAME%\":F","typeGuard":null,"tryCatchPattern":"if err := store.Put(ctx, obj); err != nil {\n  if strings.Contains(err.Error(), \"grants broad Windows write access\") {\n    return fmt.Errorf(\"refusing to use CCR store %s: %w (harden the directory ACL first)\", ccrPath, err)\n  }\n  return err\n}","preventionTips":["Provision the store directory with an explicit restrictive ACL before first use: icacls <dir> /inheritance:r /grant:r <user>:F","Never place the CCR db in shared locations like C:\\Users\\Public or a group-writable temp dir","Audit ACLs after volume restores or VM clones, which can widen inheritance","Re-run the icacls audit as part of deployment health checks"],"tags":["windows","acl","security","filesystem"],"backgroundTag":"insufficient-permissions","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}