Skip to content

harden: collection count validation in persistence deserialization - #124

Merged
kacy merged 1 commit into
mainfrom
security/ember-persistence
Feb 14, 2026
Merged

harden: collection count validation in persistence deserialization#124
kacy merged 1 commit into
mainfrom
security/ember-persistence

Conversation

@kacy

@kacy kacy commented Feb 14, 2026

Copy link
Copy Markdown
Owner

summary

adds MAX_COLLECTION_COUNT (100M) and validate_collection_count() to the
persistence format module. all deserialization loops that iterate 0..count
now validate the count before entering the loop.

previously, capped_capacity only limited Vec::with_capacity pre-allocation
— the loop itself would still iterate up to u32::MAX (~4.3 billion) times
from a crafted or corrupt file. a corrupt count field could cause the server to
spin for hours during AOF replay or snapshot loading.

the validation covers:

  • read_string_list() (used by SADD, SREM, HDEL, ZREM)
  • AOF from_bytes() inline loops (LPUSH/RPUSH, ZADD, HSET)
  • AOF rewriter read_payload_for_tag() (all collection tags)
  • snapshot reader for all collection types (list, set, hash, sorted set)

the 100M cap is generous enough that no realistic workload would hit it, while
catching obviously corrupt values that would otherwise cause unbounded iteration.

what was tested

all 95 existing persistence tests pass (cargo test -p ember-persistence --features encryption,vector).

design considerations

follows the same pattern established for vectors (MAX_PERSISTED_VECTOR_COUNT).
the constant lives in format.rs alongside capped_capacity since both are
deserialization safety guards.

adds MAX_COLLECTION_COUNT (100M) and validate_collection_count() to
reject corrupt count fields before entering iteration loops. previously
capped_capacity only limited pre-allocation but the loop itself would
iterate up to u32::MAX times from a crafted file.

covers aof record deserialization, aof rewriter, and snapshot reader
for all collection types (list, set, hash, sorted set).
@kacy
kacy merged commit 2e15f88 into main Feb 14, 2026
7 checks passed
@kacy
kacy deleted the security/ember-persistence branch February 14, 2026 21:49
kacy added a commit that referenced this pull request Feb 19, 2026
adds MAX_COLLECTION_COUNT (100M) and validate_collection_count() to
reject corrupt count fields before entering iteration loops. previously
capped_capacity only limited pre-allocation but the loop itself would
iterate up to u32::MAX times from a crafted file.

covers aof record deserialization, aof rewriter, and snapshot reader
for all collection types (list, set, hash, sorted set).
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.

1 participant