Rust State Invariant Bypass: ClosePipeline Silently Skips Safety Checks in Release Builds
A multi-stage security audit has uncovered a defense-in-depth parity gap in the `ClosePipeline` component of the `app` crate. The `start_close` and `start_persist` methods enforce a critical single-flight invariant—ensuring that close and persist operations never execute simultaneously—using `debug_assert!` statements that vanish entirely when compiled in release mode. The finding, catalogued as H-017, flags the use of debug assertions for state validation where upstream Stellar-core implements equivalent checks via `releaseAssert`, which aborts unconditionally across all build configurations.
The vulnerable code paths reside in `crates/app/src/app/close_pipeline.rs` at lines 70 and beyond, where `debug_assert!(self.is_idle(), ...)` guards against concurrent state transitions. In debug builds, a violation would trigger a panic; in release builds, the check is eliminated entirely, leaving the invariant unenforced. While the audit team characterizes the risk as low and notes no current exploit path, the divergence from upstream safety guarantees represents a meaningful reduction in defense-in-depth posture. If a code path ever allows the idle state assumption to be violated, the resulting behavior would differ silently between development and production environments.
The finding carries a status of VIABLE, indicating it is technically sound but not presently exploitable given known code paths. The audit recommends aligning the `ClosePipeline` implementation with Stellar-core's releaseAssert pattern to ensure invariant enforcement regardless of build mode. The crate maintainers now face pressure to patch the invariant checks before any future refactoring introduces paths that could trigger the unchecked state transitions.