Skip to content

Conversation

tnull
Copy link
Contributor

@tnull tnull commented Aug 22, 2025

Previously, we omitted setting ChaCha20Poly1305RFC's aad field, which had the tag not commit to any particular key. This would allow a malicious VSS provider to substitute blobs stored under a different key without the client noticing.

Here, we allow to set the aad (which usually should be the full key under which we expect the Storable to get stored). This change is backwards compatible if users provide a static aad: &[] argument. Otherwise, users will need to find an upgrade path client-side.

Previously, we omitted setting `ChaCha20Poly1305RFC`'s `aad` field,
which had the `tag` not commit to any particular key. This would allow a
malicious VSS provider to substitute blobs stored under a different key
without the client noticing.

Here, we allow to set the `aad` (which usually should be the full key
under which we expect the `Storable` to get stored). This change is
backwards compatible if users provide a static `aad: &[]` argument.
Otherwise, users will need to find an upgrade path client-side.
@ldk-reviews-bot
Copy link

ldk-reviews-bot commented Aug 22, 2025

👋 I see @jkczyz was un-assigned.
If you'd like another reviewer assignment, please click here.

tnull added 2 commits August 22, 2025 11:23
Previously, this `unwrap` could have us panic if the service wouldn't
provide a message including the `EncryptionMetadata`. Here we fix this
by simply erroring out if the expected metadata is not present.
There is now reason `StorableBuilder` needs to permanently own the
`data_encryption_key`, which just risks that the key will linger around
in memory after `StorableBuilder` has been dropped. Here, we switch the
API to simply take `data_encryption_key` by reference for the
`build`/`deconstruct` operations.
@tnull tnull force-pushed the 2025-08-include-key-aad branch from e7bdd0a to 3c62a9f Compare August 22, 2025 09:44
.. to make sure the values don't linger in memory.
@tnull tnull force-pushed the 2025-08-include-key-aad branch from 3c62a9f to 03ca9d9 Compare August 22, 2025 09:48
@jurvis
Copy link

jurvis commented Aug 22, 2025

the core of the issue of not having the AAD is that we can no longer authenticate the storage context of the encrypted blob.

another attack that is still possible is that the VSS provider can claim thing that an encrypted blob came from a different store_id, despite the underlying blob being the same. Works something like this:

  • Since one DEK is reused across tenants and stores (i.e. S1, S2)
  • A client can write value to S2 with a valid triple (nonce, ciphertext, tag)
  • But a malicious VSS can return the S2 blob, but label it as coming from S1
  • Client verifies AEAD tag successfully and accepts whatever S2

Not really sure how this becomes bad in practice, but also something worth keeping in mind.

@jurvis
Copy link

jurvis commented Aug 22, 2025

something that just came to mind while thinking about backwards-compatibility.

A server could also:

  1. Return an older triple for the same key OR pick any version it wants for PlaintextBlob
  2. And since AAD is now empty, we don't know if it's actually the latest version and the client cannot verify and could get stale state

I'm not sure adding something to AAD alone would help here at all. The App would need to store some state, which runs counter to VSS' use-case as a backup store (how do you verify something you don't have information about?)

///
/// Refer to docs on [`Storable`] for more information.
///
/// [`PutObjectRequest`]: crate::types::PutObjectRequest
pub fn build(&self, input: Vec<u8>, version: i64) -> Storable {
pub fn build(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if we could be opinionated here for future writes and have the AAD commit to:

  1. The key-value key (lol) [fixes the issue mentioned in pr]
  2. store_id [fixes potential multi-tenancy issues]

@ldk-reviews-bot
Copy link

🔔 1st Reminder

Hey @jkczyz! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@tankyleo tankyleo requested review from tankyleo and removed request for jkczyz August 25, 2025 06:08
@ldk-reviews-bot
Copy link

🔔 1st Reminder

Hey @tankyleo! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants