Skip to content

[audit][medium] Merk::verify can panic on corrupted aggregate data #706

Description

@QuantumExplorer

Created from a Codex audit of grovedb. No code changes were made as part of the audit.

Summary

Merk::verify unwraps hash and aggregate-data calculations during recursive verification.

Impact / failure scenario

Malformed or corrupt aggregate trees can panic verification or Restorer::finalize instead of returning a bad-link error.

References

  • merk/src/merk/mod.rs:789
  • merk/src/merk/mod.rs:796
  • merk/src/merk/restore.rs:677

Suggested fix

Propagate these errors through verify_link rather than unwrapping.

Suggested tests

Construct or restore a counted/summed tree with corrupt aggregate data and assert finalize/verify returns an error.


September 2026 audit addendum — S04

Audit group: S04. Classification: security. Provisional severity: medium.

Audit addendum for #706, based on provisional static review of snapshot 2fa0f133. The existing aggregate-verification concern has a retained peer-fed restoration path in this snapshot. This addendum strengthens its boundary evidence and qualifications; it does not establish that current develop or any deployed service remains affected.

The expected contract is that restoration admits only metadata compatible with the trusted host tree and that invalid aggregate state returns an error. The saved trace follows admission of transported feature metadata, persistence into nodes and links, and final verification. The restore path does not establish compatibility between the incoming feature schema and its trusted host tree. Subsequent consumers can encounter a schema expectation or a checked aggregate error that is converted into a panic.

Two related subcases are preserved: ordinary nonprovable metadata in a normal host tree, and distinct provable count schemas reaching a type-specific hash consumer. They share the missing host-feature admission rule. Commitment equality is a real control, but it does not establish every feature relationship used by these consumers. Ordinary writers maintain homogeneous features; restoration is the relevant additional ingress.

Many nearby unwrap calls merely extract a cost wrapper and are not panic evidence. The report concerns actual fallible aggregate results and internal schema expectations. Likewise, the documented rejection of query feature forgery applies where decoded metadata is discarded; the retained restoration path persists it. Honest aggregate reconstruction in #671 remains related but independently requires correct own-value reconstruction.

Issue #706 covers the panic sink; this addendum adds the restoration ingress and host-type admission requirement. Error propagation alone addresses the panic symptom and is not claimed to complete the metadata-validation fix. Validate incoming feature schema against trusted host type before persistence and derive nonprovable metadata from authenticated element and child semantics. Propagate aggregate and hash-verification failures instead of assuming success. Retain successful round trips across supported tree families. No runtime reproduction or application execution was performed. Medium severity is scoped to library availability; whether a panic affects one task or an entire process depends on caller policy.

Validation to complete

  • Verify supported host/feature combinations are validated before persistence.
  • Require typed errors from failed aggregate computation and schema mismatch during verification.
  • Preserve ordinary and provable aggregate round trips without counting cost-wrapper extraction as a panic site.

Limits and existing work

Related tracking: issue #706 (open), issue #671 (open), PR #556 (merged), PR #481 (merged), PR #769 (merged), PR #840 (open).

Scope: saved GroveDB worktree with revision context 2fa0f133877420a0d9c91ba7bc51b1775ab8c783. This report does not establish that current develop or any deployed application is affected. Focused runtime validation remains outstanding.

Audit source and canonical finding identifiers

Source status: snapshot-backed (git_worktree); plain source locations are used because this is not a sealed commit-only scan.

Audited revision context: 2fa0f133877420a0d9c91ba7bc51b1775ab8c783.

The findings were manually reconciled from a preserved scan bundle. The native scan ended before final completion; these are provisional source-review findings, not a completed native scan certification.

Canonical finding ID: csf_d88ff59763ba133dd0ff75c4

Primary fingerprint: codex-security/v1:sha256:709c968d8a8b831b7f945a52c18c3f3f63b52df4e97e9fa8b8e705e2b7e49cc1

Canonical finding ID: csf_cc9f8960f566b2805239d92b

Primary fingerprint: codex-security/v1:sha256:128377f2f7475a0e855055d271f93adea4c170e8e679e3ffd37ebd740edfcfe9

Source locations:

  • Location (root_control): merk/src/proofs/tree.rs:171-188
  • Location (implementation): merk/src/merk/restore.rs:317-336
  • Location (implementation): merk/src/tree/mod.rs:704-724
  • Location (implementation): merk/src/merk/mod.rs:788-799
  • Location (implementation): merk/src/merk/restore.rs:691-702
  • Location (entrypoint): merk/src/merk/restore.rs:242-259
  • Location (propagation): merk/src/merk/restore.rs:317-337
  • Location (propagation): merk/src/merk/restore.rs:691-695
  • Location (root_control): merk/src/merk/mod.rs:789-797
  • Location (sink): merk/src/tree/mod.rs:836-849
  • Location (supporting): merk/src/proofs/tree.rs:169-204
  • Location (supporting): merk/src/tree/mod.rs:837-849
  • Location (root_control): merk/src/merk/restore.rs:242-262
  • Location (propagation): merk/src/merk/restore.rs:317-336
  • Location (root_control): merk/src/proofs/tree.rs:171-203
  • Location (propagation): merk/src/proofs/tree.rs:54-68
  • Location (entrypoint): merk/src/merk/restore.rs:691-699
  • Location (outcome): merk/src/merk/mod.rs:788-799
  • Location (propagation): merk/src/tree/mod.rs:837-862

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:state-syncS groups: state restoration, synchronization and append-client transactions.audit:2026-09Reconciled September 2026 GroveDB audit; audited worktree at 2fa0f133.audit:needs-validationSaved source evidence reviewed; focused runtime and deployment validation outstanding.bugSomething isn't workingseverity:medium-provisionalMedium impact in the audited scenario; provisional static assessment.type:securityAudit reports a security property failure; deployment impact needs validation.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions