Repository navigation
On Windows the log-hash key is held to an allowlist, so a key anyone beyond SYSTEM, Administrators and the service can read is refused (#4028) - #4044
Merged
Conversation
…ond SYSTEM, Administrators and the service account can read is refused (#4028) The credential check the key shares refuses only a file Users, Authenticated Users or Everyone can read. INTERACTIVE, Domain Users or one named user holding ReadData passed it, and whoever reads the key can test guesses at every literal the keyed hashes hide. DarlingFileSecurity.ReadersBeyondTrusted is an allowlist over the trusted-owner set; the key's load refuses on it and its creation verifies against it. The credential files keep the denylist their existing DACLs were built against, so this cannot newly refuse an install's credentials. Red-watched: without the load check, a key with an INTERACTIVE read grant loads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv
This was referenced Sep 23, 2026
…s, and is judged and read through one held handle (#4028 review) Round-1 security review of #4044: - Medium: the allowlist asked only who could READ the key. WriteData let an account plant a key of its own (LocalMachine DPAPI, entropy in the source), and ChangePermissions or TakeOwnership let it grant itself the read. Any Allow entry beyond SYSTEM, Administrators and the service account now refuses the key. - Low: the key was checked by path and read by path, so whoever could write the directory could swap the file in between. It is now opened once, sharing read alone, and its links, hard links, owner and DACL are judged through that handle, which the read then uses, bounded to 1 KB. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv
… review) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv
erikdarlingdata
marked this pull request as ready for review
September 23, 2026 15:15
erikdarlingdata
enabled auto-merge (squash)
September 23, 2026 15:15
erikdarlingdata
added a commit
that referenced
this pull request
Sep 23, 2026
…ntries in their sections (#4080) Adds 42 entries and 42 link refs (#3992, #3995, #3996, #3998, #4001, #4002, #4003, #4007, #4010, #4011, #4013, #4015, #4020, #4022, #4025, #4029, #4030, #4031, #4036, #4038, #4039, #4040, #4044, #4047, #4048, #4049, #4050, #4051, #4055, #4061, #4063, #4064, #4065, #4066, #4067, #4068, #4069, #4070, #4071, #4073, #4074, #4078). Each PR's entry was buffered, and this lands every entry whose PR was merged on origin/dev when it ran. #3989 left 26 entries under bare 'Changed' and 'Fixed' lines above '### Added'. They move into '### Changed' and '### Fixed', below the new entries, and one blank line stays under [Unreleased]. Claude-Session: https://claude.ai/code/session_01Ua31ugERL5DmhFVRtf6keQ Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #4028.
Why
#4020's review (Low 3): on Windows the log-hash key was trusted through the credential check it shares with the role credential files. That check refuses only a file Users, Authenticated Users or Everyone can read, so INTERACTIVE, Domain Users or one named user holding ReadData passed it. Whoever can read the key can test guesses at every literal the keyed hashes hide.
What changes
DarlingFileSecurity.AccessBeyondTrusted(path): an allowlist over the trusted-owner set (SYSTEM, Administrators, the service account). It names every other account holding ANY Allow entry, or reports a DACL it can't read.DarlingLogHashKeyFile.Loadrefuses a key with any such reader, after the shared check. Creating a key verifies against the same allowlist, so a key is never written that the next start would refuse.darling.jsonis read by INTERACTIVE by design, so this can't newly refuse an install's credentials.Round-1 review fixes (cd02713)
Medium: the check asked only who could READ. An account with WriteData could plant a key of its own. Any local user can make a valid one, because the DPAPI is LocalMachine and the entropy is in the source. An account with ChangePermissions or TakeOwnership could grant itself the read. Now any Allow entry for anyone beyond the three trusted accounts refuses the key, whatever it grants. The service writes only those three entries.
Low: the key was checked by path, then read by path. Whoever controls a pre-existing
darling-keyscould swap the file in between.DarlingFileSecurity.OpenForServiceOnlyReadopens the key once, without following a link at its name and sharing read alone, so nobody can rename, delete, replace or write it while it is held. Through that handle it checks:The read then uses the same handle, bounded to 1 KB. A key this service writes is about 350 bytes. This closes the swap without the directory allowlist, which stays out of scope below.
Low: the Unix half of Log-hash key trust: check who owns the key directory and file on Unix, and allowlist the directory's DACL on Windows (#4020 review, Low) #4028. This stays out of scope by the ruling; see below. The reviewer's FIFO point is the same case.
Not done, and closed with this
Test plan
AKeyAnyoneBeyondTheServiceCanRead_IsRefused_OnWindows. A real key, with an INTERACTIVE read grant added, is refused with INTERACTIVE named; the file is untouched; and the shared denylist alone would have loaded it.AKeyAnyoneBeyondTheServiceHoldsAnyRightTo_IsRefused_OnWindows: WriteData, AppendData, ChangePermissions, TakeOwnership and Delete. All 5 fail with the ReadData-only filter restored.AHeldKey_CannotBeRenamedDeletedOrWritten_UntilItIsReleased_OnWindows: fails when the handle shares write and delete.AHardLinkedKey_IsRefused_OnWindows: fails without the link-count check.AnOversizedKey_IsRefused_OnWindows: fails without the 1 KB bound.PgLogHashKey*26,DarlingFileSecurity*17,*HardenFiles*19,DocCommentHygiene77,DarlingManagedRoles*27.PgLogHashKey*,DarlingFileSecurityTests,DarlingHardenFilesVerbTests,DarlingStoreLoginsTests,ComposeStoreRolesLiveTests: 114 green, plus the new test. Build: 0 warnings.🤖 Generated with Claude Code
https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv