You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Windows Save leaves the serialized plaintext credential unscrubbed when it exceeds the 2560-byte blob limit #165
WindowsCredentialStore.Save (CredentialCache/Storage/WindowsCredentialStore.cs, ~lines 75–108) serializes the credential into byte[] blob and then checks its size before entering the try { … } finally { CredentialSerialization.Zero(blob); } block:
byte[]blob=CredentialSerialization.Serialize(credential);if(blob.Length>NativeMethods.CRED_MAX_CREDENTIAL_BLOB_SIZE){thrownewCredentialStoreException(...);// blob is never zeroed on this path}try{
...}finally{CredentialSerialization.Zero(blob);}
When the size check throws, the full plaintext JSON (username/password or token) stays on the managed heap until the GC reclaims it, and it is never zeroed.
Why it matters
The recent scrubbing work (e.g. 97a49ab, "scrub Linux Secret Service plaintext like Windows and macOS") commits the library to zeroing every managed plaintext copy on every path, including when an exception is thrown. The macOS Save and the Linux path both honour this. The Windows over-limit path is the only one that doesn't.
Concrete scenario: someone stores a CredentialWithToken holding a long JWT or PAT whose serialized form is over 2560 bytes. Save throws CredentialStoreException as it should, but the serialized secret is left in memory unscrubbed. It is then exposed to memory dumps, crash dumps and swap, which is exactly what the scrubbing is meant to prevent.
Suggested fix
Move the size check inside the try, so the finally covers it:
blob is zeroed on every exit path of WindowsCredentialStore.Save, including the over-limit throw.
If the shared-layer tests can observe it, add a test that saves an oversize credential and asserts the buffer was scrubbed. At minimum, add a test asserting the throw still happens.
Priority: Medium. The plaintext credential is left unscrubbed on the heap, but only on the error path for credentials whose serialized form exceeds 2560 bytes (for example a long JWT or PAT). The fix is trivial.
Area / suggested owner: Windows store (WindowsCredentialStore.Save).
Activity
matt-edmondson commentedon Sep 26, 2026
Triage
WindowsCredentialStore.Save).tryso thefinallyzeroesblob, and add at least a test that asserts the throw.Generated by Claude Code