Repository navigation
fix(directory): verify events before forwarding and persistence - #2918
Merged
Merged
Conversation
Independently verify live directory notifications and raw directory ingestion before either storage tier changes. Cover forged producer notifications, unsigned and tampered DTOs, retained SDK verification state after seen-state loss, and real relay-to-app persistence with reopening. Preserve existing projection and recency assertions using signed fixtures. Fixes #2521.
…ases Keep the original ID and its valid signature while altering signed fields, and assert signature-only verification succeeds while ID verification fails. This isolates content binding from bad-signature rejection in the raw ingress and app persistence tests.
Contributor
|
Warning Review limit reachedEnable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. Next included review available in 45 seconds. View limit details
CodeRabbit Verify
|
28 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
MDK's live directory forwarder relied on SDK authentication, and raw directory ingestion accepted unsigned records. The SDK cache fix in #2912 repaired that dependency, but MDK still needed its own protection against forged profiles, follow lists, and relay lists arriving through another producer or a future regression.
Fix
Authenticate each event's content, ID, and signature before live forwarding, and independently authenticate raw records at directory ingestion before either store changes. Invalid records are ignored; valid updates retain existing projection and freshness behavior. Existing ingestion fixtures now carry real signatures while retaining their assertions.
Verification
cargo fmt --allcargo nextest run -p transport-nostr --all-features --locked— 145 passed.cargo nextest run -p nostr-directory --locked— 80 passed.cargo nextest run -p marmot-app --lib --features test-policy-overrides,otlp-export --locked -E 'test(/directory/) | test(/^(tests::relay_plane_runtime|relay_telemetry_export)::/) | test(/ingesting_|stale_live_relay_list_|zero_timestamp_relay_list_|same_second_multiline_|onboarding/)'— 195 passed.cargo clippy -p transport-nostr -p nostr-directory -p marmot-app --all-targets --all-features --locked -- -D warningsjust binding-docs-gatecargo nextest run -p cgka-conformance-simulator --locked --test app_runtime_journeys --test process_orchestrator -E 'test(=public_app_03_late_join_and_messaging) | test(=engine_app_runtime_and_process_adapters_reach_equivalent_public_state)'— 2 passed.cargo nextest run -p wn-cli --locked --test cli --features test-policy-overrides -E 'test(=local_group_message_workflow_runs_through_the_dm_contract) | test(=daemon_start_status_execute_and_stop_are_user_facing_commands)'— 2 passed.8772b465c; read-only checkouts stayed clean.The wire tests cover retained verification state after the default SDK seen tracker is cleared, and actual relay → SDK → directory forwarder → sync worker → app persistence, including exact unchanged cache/shared rows and reopening. The owner regressions isolate MDK's guards; the wire tests also traverse the already-fixed SDK. Four tests are added to existing binaries, with no new production seam. No API signatures, dependency versions, workspace versions, or schemas change.
Fixes #2521.
Test audit: wall times for new tests and signed-fixture updates
directory_forwarder_verifies_each_notification_independentlydirectory_wire_rejects_forgery_when_verified_ids_outlive_seen_statedirectory_ingress_authenticates_before_writing_either_storelive_directory_forgery_cannot_change_persisted_metadataingesting_all_read_nip65_list_replaces_cached_write_targetsstale_live_relay_list_events_do_not_replace_newer_cached_listszero_timestamp_relay_list_event_populates_legacy_empty_statesame_second_multiline_bio_does_not_replace_cached_single_line_biodirectory_entry_reconciles_nostr_components_independentlyingesting_remote_contact_list_does_not_promote_follows_and_caps_stored_followsingesting_kind0_profile_persists_only_bounded_unknown_fieldsingesting_kind0_profile_preserves_multiline_about_and_single_line_fieldsThe eight fixture updates preserve their existing assertions. The two direct guard tests provide red/green evidence; the two wire tests cover transport and persistence risks.