Skip to content

AutoSerializer bakes a false compressed flag into the AES-GCM AAD #166

@27Bslash6

Description

@27Bslash6

Summary

AutoSerializer's msgpack/dataframe/series paths never set compressed= on their metadata, so it defaults False even though Rust ByteStorage LZ4 ran. EncryptionWrapper binds str(metadata.compressed) into the AES-GCM AAD, so an EncryptionWrapper(serializer=AutoSerializer()) write authenticates "False" while StandardSerializer (the canonical path) authenticates "True" for the identical wire format.

Evidence

  • src/cachekit/serializers/auto_serializer.py:451 (compressed unset) + base.py:201 (default False) + :785 (LZ4 ran)
  • src/cachekit/serializers/encryption_wrapper.py:231,395 (binds str(compressed) into AAD v0x03)
  • Canonical: standard_serializer.py:296 sets compressed=True; protocol protocol/spec/encryption.md:285,303 uses true; tests/critical/test_aad_v03_security.py:66 asserts "True"

Impact

Intra-process round-trips fine (decrypt rebuilds the same wrong AAD). The hazard is cross-SDK / corrected-impl reads: a conformant reader computes a different AAD and AES-GCM auth fails on a legitimately stored entry. Gated behind the non-default direct EncryptionWrapper(serializer=AutoSerializer()) API (the decorator forces StandardSerializer). See cachekit-io/protocol#12 for the spec-side gap.

Fix

Set compressed consistently in AutoSerializer metadata (reflect the ByteStorage codec actually applied).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingencryptionEncryption/cryptography related

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions