Conversation
On an encrypted account, every stash push carried each device's local plaintext copy of an attachment's name, size and type. The server had just started ignoring those on a push - see the matching cloud fix - but the app was the other half: this is what stops it sending them at all, and what stops the equivalent leak on delete. seal_stash_payload and seal_context_payload now blank a tombstone's text outright rather than merely skip sealing it - the local row still holds it after a delete, and skipping meant it went to the server readable. And every attachment in a pushed stash is reduced to its id and deleted flag: the name, type and size already travel sealed in the descriptor seal_attachment writes at upload time, and sending the local copy again is exactly what let the server's bug overwrite that descriptor's key. Separately, an encrypted account's upload no longer tells cloud storage the file's real type - it declared it in the Content-Type header even when the bytes were sealed, which the bucket keeps as metadata and returns on every read. And a new sync pass, convert_attachments_to_encrypted, re-encrypts the attachments an account still stores in plaintext because they were uploaded before encryption was turned on - a gap nothing closed until now. A few per cycle: read the plaintext (this device's own copy if it has one, the server's otherwise), seal it, and drive the cloud's new propose/confirm rekey endpoints. Marks the account done once the server agrees nothing plaintext is left, so a settled account costs nothing on later syncs. 153 Rust tests, 218 frontend tests and a clean tsc pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KkYvnuq8Y4nYD1jSCi9GCR
Co-Authored-By: Claude Opus 5 (1M context) <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.
On an encrypted account, every stash push carried each device's local plaintext copy of an attachment's name, size and type. The server had just started ignoring those on a push - see the matching cloud fix - but the app was the other half: this is what stops it sending them at all, and what stops the equivalent leak on delete.
seal_stash_payload and seal_context_payload now blank a tombstone's text outright rather than merely skip sealing it - the local row still holds it after a delete, and skipping meant it went to the server readable. And every attachment in a pushed stash is reduced to its id and deleted flag: the name, type and size already travel sealed in the descriptor seal_attachment writes at upload time, and sending the local copy again is exactly what let the server's bug overwrite that descriptor's key.
Separately, an encrypted account's upload no longer tells cloud storage the file's real type - it declared it in the Content-Type header even when the bytes were sealed, which the bucket keeps as metadata and returns on every read.
And a new sync pass, convert_attachments_to_encrypted, re-encrypts the attachments an account still stores in plaintext because they were uploaded before encryption was turned on - a gap nothing closed until now. A few per cycle: read the plaintext (this device's own copy if it has one, the server's otherwise), seal it, and drive the cloud's new propose/confirm rekey endpoints. Marks the account done once the server agrees nothing plaintext is left, so a settled account costs nothing on later syncs.
153 Rust tests, 218 frontend tests and a clean tsc pass.
Claude-Session: https://claude.ai/code/session_01KkYvnuq8Y4nYD1jSCi9GCR