Skip to content

SoulCache v1.1.1

Latest

Choose a tag to compare

@kasihagustinusT kasihagustinusT released this 07 Aug 04:49
· 1 commit to main since this release

SoulCache v1.1.1

High-performance data fetching and caching runtime for TypeScript. Zero runtime dependencies. Framework-agnostic.

This is a security patch release following an independent security review. All four
packages (@soulcache/core, @soulcache/react, @soulcache/devtools,
@soulcache/devtools-core) are bumped to 1.1.1. The public API is fully compatible
with v1.1.0 / v1.0.0.

Highlights

  • Honest checksum algorithmschecksum: 'sha-256' now writes a real FIPS 180-4
    SHA-256 digest (64-hex) instead of silently reusing the non-cryptographic 32-bit
    djb2 hash that every label produced before. Deprecated labels that were never
    implemented (sha-384, sha-512, md5) are rejected on write; payloads persisted
    by earlier versions under any label remain readable.
  • No error.stack in dehydrated state by default — internal file paths no longer
    leak to clients in SSR flows. Opt back in with includeStack: true for
    server-side debugging.
  • Hardened hydrate() — malformed entries (non-array queryKey, non-object
    query) are rejected before they can corrupt the cache.
  • CSPRNG-generated idsgenerateId() uses crypto.randomUUID() when available.

What's Changed

Security

  • Checksum integrity (SLC-INTEGRITY-001). JsonSerializer/JsonDeserializer
    now honor the configured ChecksumAlgorithm:
    • sha-256 computes a real, synchronous, zero-dependency SHA-256 digest (FIPS
      180-4) — previously the label silently produced the same 32-bit djb2 value as
      every other label.
    • Writes under sha-384, sha-512, or md5 throw SerializationError (these
      labels were never implemented and are deprecated; migrate to sha-256 or the
      default fast-32).
    • Reads under sha-256 verify against both the real digest and the legacy djb2
      value, so 1.0.0/1.1.0 payloads keep validating; legacy labels remain readable.
  • Stack disclosure (SLC-HYDRATE-003). dehydrate() no longer includes
    error.stack by default; pass includeStack: true to preserve it for server-side
    debugging.
  • Hydrate tampering (SLC-HYDRATE-001). hydrate() structurally validates every
    entry before writing; malformed entries are skipped. The default overwrite
    merge strategy is unchanged.
  • Weak ids (SLC-RNG-001). generateId() prefers crypto.randomUUID(), with the
    legacy scheme retained as a fallback.

Documentation

  • SECURITY.md adds secure-usage guidance (query-key scoping, trusted hydrate
    sources, checksum = corruption detection not tamper-proofing, stack opt-in).
  • New consumer security page docs/content/docs/security.mdx.
  • Release notes and migration guide updated for v1.1.1.

Testing

  • New SHA-256 test suite with FIPS 180-4 vectors (empty, "abc", two-block, padding
    boundary) plus serializer/deserializer dual-mode, hydration validation, and
    CSPRNG id tests.
  • Root suite green on the release commit; public API verified compatible with the
    v1.0.0 baseline.

Breaking Changes

None. No public API signature changed. Two opt-in/opt-out behavior changes to
review (see Upgrade Notes).

Upgrade Notes

  • Dehydrated error entries no longer include error.stack by default. If you used
    stacks from dehydrated state (e.g. SSR debugging), pass
    dehydrate(engine, { includeStack: true }) — and keep stacks server-side.
  • If you configured checksum: 'sha-384' | 'sha-512' | 'md5', serialization now
    throws. Switch to sha-256 (real) or drop the option (default fast-32).
    Persisted payloads never need migration; they restore correctly.

Known Limitations

  • Checksums are unkeyed: both fast-32 and sha-256 detect accidental corruption,
    not an attacker who can rewrite both payload and checksum. Use authenticated
    storage (HMAC/encryption) where adversarial persistence is in scope.
  • Retry engine and the plugin system remain internal modules.

Credits

Maintained by Kasih Agustinus and the SoulCache contributors.

Full Changelog