Skip to content

[audit][S01] State restoration can accept item contents without authenticating them #876

Description

@QuantumExplorer

Audit group: S01. Classification: security. Provisional severity: high.

Static review of audited snapshot 2fa0f133 identifies an integrity gap in state restoration: successfully restored ordinary item contents are not necessarily authenticated by the expected root. This finding concerns the library's peer-fed restoration contract. It does not establish that current develop or a deployed service exposes the affected workflow.

The expected contract is that accepting a snapshot authenticates both its structure and the element contents subsequently returned by the database. The retained evidence follows chunk admission, stored-node construction, finalization and session commit. Some accepted restoration representations carry value contents separately from their supplied commitment. Restoration preserves both without enforcing the element-specific relationship. Link checks and final root equality reuse stored commitments, so they do not independently establish ordinary-value integrity.

Legitimate reference and subtree elements require combined commitments; this report does not recommend removing those formats or applying a plain value hash to every element. Its narrow supported case is ordinary items. A separate complete integrity traversal can detect simple-value disagreement, but ordinary restoration completion does not invoke that additional check. Normal value-binding representations also remain effective controls.

Validate the canonical relationship between element type, transported representation and commitment before persistence. Recompute simple-value commitments and retain the appropriate semantic checks for composite elements. Successful completion should establish stored-content integrity as well as expected-root equality, with ordinary round trips preserved across supported families.

Closed issue #682 concerns trusted local metadata and is a different boundary. PR #558's final root check is present in the reasoning but does not supply the missing content relationship; PR #840's proposed restoration changes require separate assessment. This is a provisional static finding without an executed reproduction, runtime storage test or demonstrated downstream impact. Independent records differed between high and medium severity; the high rating here is scoped to successful acceptance of unauthenticated persistent contents.

Validation to complete

  • Use existing valid snapshot round trips to compare restored ordinary values with independently computed commitments.
  • Verify all admitted restoration representations enforce element-specific authenticity before persistence.
  • Preserve honest reference/subtree combined-commitment behavior and check rejected restoration leaves no accepted inconsistent state.

Limits and existing work

Related tracking: issue #682 (closed), PR #450 (merged), PR #558 (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_a3a3dae52be7a50e888d9145

Primary fingerprint: codex-security/v1:sha256:716b6a3176bca42c56bd2a41c60f6e7f066b92f1c75e62f7bab13ef5e89ded11

Canonical finding ID: csf_e24e8ad11ac3538fe94e0011

Primary fingerprint: codex-security/v1:sha256:62d7fd4062f98edb49edf292f37a5361d6b24ad994024e812b3cf0a1574f5c3b

Canonical finding ID: csf_b34ca15a1fdc612a6f49c5a5

Primary fingerprint: codex-security/v1:sha256:1a05a0eef9e50a54cdcf4c96f756bf9bc5f075fc30a6ce76192e5c3d7ca99955

Canonical finding ID: csf_7b9c78e8ac6e4af1a13ab8b1

Primary fingerprint: codex-security/v1:sha256:ca0285ab6989d145297c518bd5f769144f047e26f79884bc0e8ffc16f306b184

Canonical finding ID: csf_eb34b57554a929890ca676d4

Primary fingerprint: codex-security/v1:sha256:7b853344d079bec6cad4621a4bd8744dd7431831fe5dd028a2c70ba8d6f6001c

Canonical finding ID: csf_1ef181e2dbaf17fecd12a7a7

Primary fingerprint: codex-security/v1:sha256:bb76f32d11bc14fe1673e3e37b3c1c922f31666c5e49d5c5e85fbe5955f920e7

Canonical finding ID: csf_5ede9ab67c20c0722ef08b84

Primary fingerprint: codex-security/v1:sha256:b2beaf9e25da353723bd07f4170b2085d92b7543059af62b505c0fa0172dc8f0

Source locations:

  • Location (root_control): merk/src/merk/restore.rs:242
  • Location (sink): merk/src/merk/restore.rs:317
  • Location (sink): merk/src/merk/restore.rs:356
  • Location (propagation): merk/src/proofs/tree.rs:153
  • Location (entrypoint): grovedb/src/replication/state_sync_session.rs:512
  • Location (outcome): merk/src/element/get.rs:175
  • Location (entrypoint): merk/src/merk/restore.rs:242-251
  • Location (root_control): merk/src/merk/restore.rs:317-336
  • Location (root_control): merk/src/merk/restore.rs:356-372
  • Location (sink): merk/src/merk/restore.rs:691-699
  • Location (propagation): merk/src/merk/mod.rs:688-724
  • Location (propagation): merk/src/merk/mod.rs:788-799
  • Location (outcome): grovedb/src/replication/state_sync_session.rs:257-276
  • Location (expected_control): grovedb/src/lib.rs:2120-2126
  • Location (entrypoint): merk/src/merk/restore.rs:242-259
  • Location (root_control): merk/src/merk/restore.rs:317-337
  • Location (alternate_route): merk/src/merk/restore.rs:356-372
  • Location (propagation): merk/src/tree/kv.rs:89-106
  • Location (control_boundary): grovedb/src/replication/state_sync_session.rs:679-702
  • Location (counterevidence): grovedb/src/replication/state_sync_session.rs:705-724
  • Location (sink): merk/src/tree/mod.rs:671-677
  • Location (sink): grovedb/src/replication/state_sync_session.rs:257-276
  • Location (supporting): grovedb/src/replication/state_sync_session.rs:109-112
  • Location (supporting): merk/src/proofs/tree.rs:154-169
  • Location (outcome): grovedb/src/lib.rs:634-639
  • Location (entrypoint): merk/src/merk/restore.rs:242-253
  • Location (propagation): merk/src/proofs/tree.rs:153-165
  • Location (sink): merk/src/merk/restore.rs:356-372
  • Location (propagation): merk/src/tree/kv.rs:89-103
  • Location (expected_control): merk/src/merk/mod.rs:788-799
  • Location (outcome): merk/src/merk/restore.rs:691-702
  • Location (entrypoint): grovedb/src/replication/state_sync_session.rs:104-114
  • Location (root_control): merk/src/merk/restore.rs:241-256
  • Location (propagation): merk/src/proofs/tree.rs:153-158
  • Location (sink): merk/src/merk/restore.rs:355-373
  • Location (propagation): merk/src/tree/kv.rs:86-104
  • Location (expected_control): merk/src/merk/restore.rs:691-704
  • Location (outcome): merk/src/merk/mod.rs:697-723
  • Location (root_control): merk/src/merk/restore.rs:318-338
  • Location (propagation): merk/src/proofs/tree.rs:159-168
  • Location (expected_control): merk/src/merk/mod.rs:697-734
  • Location (outcome): merk/src/element/get.rs:165-190
  • Location (root_control): merk/src/merk/restore.rs:242-256
  • Location (sink): merk/src/merk/restore.rs:356-374
  • Location (propagation): merk/src/tree/kv.rs:89-104
  • Location (outcome): merk/src/merk/mod.rs:688-724
  • Location (expected_control): merk/src/merk/restore.rs:268-282
  • Location (sink): merk/src/merk/restore.rs:317-336
  • Location (entrypoint): grovedb/src/replication/state_sync_session.rs:433-441
  • Location (root_control): merk/src/merk/restore.rs:242-263
  • Location (supporting): merk/src/merk/mod.rs:688-724
  • Location (supporting): grovedb/src/replication/state_sync_session.rs:678-700
  • Location (entrypoint): grovedb/src/replication/state_sync_session.rs:106-119
  • Location (root_control): merk/src/merk/restore.rs:242-259
  • Location (propagation): merk/src/merk/restore.rs:273-290
  • Location (sink): merk/src/merk/restore.rs:356-373
  • Location (sink): merk/src/merk/restore.rs:317-335
  • Location (propagation): merk/src/tree/kv.rs:88-107
  • Location (expected_control): merk/src/merk/restore.rs:692-705
  • Location (outcome): grovedb/src/lib.rs:625-640

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:high-provisionalHigh 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