CLIENTS: ClientV2 - V2 Security Review Hardening Fixes - #724
Merged
cjdutoit merged 42 commits intoJul 18, 2026
Merged
Conversation
…IsInvalidAndLogItAsync -> FAIL
…IsInvalidAndLogItAsync -> PASS
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.
Pre-release security review of ClientV2 and its V2 dependencies. Fixes 17 of the 24 review findings (V2 paths only; V1 out of scope). Each behavioural change was developed test-first (red/green). All suites green: Core unit 3023, Portal unit 130, EventHandlers unit 11, Core acceptance 63, EventHandlers acceptance 1. BasicApp, Portal, and SubstrateApi smoke-tested end-to-end.
High
faultedEventV2Idsguard as the dead-event path, so an unarchivable row can no longer loop forever.TryClaimScheduledEventV2Asyncuses a conditionalExecuteUpdate(WHERE Type == Scheduled SET Type = Immediate); the losing racer gets 0 rows and skips. No schema change/migration. Proven under real concurrency by a new acceptance test (two parallel sweeps → exactly one dispatch).Medium
ConcurrentDictionary<Guid, IEventHandler>(idempotent register, snapshotGetAll()) — duplicate ids no longer poison dispatch.DispatchConfiguration.HandlerTimeout, default infinite) so a hung handler can't wedge the sweeps.EventListnerHowTo Documentation #8 ListenerFilterCriterialength-capped at registration.EventParticipantV2Id.IClientV2isIAsyncDisposableand handler registration resolves a fresh scope per call.Low
RetentionDays < 1(prevents immediate deletion of all archives).UpdatedDate(was overwritten withCreatedDate).BatchSizeForBulkProcessingwith an attempted-id guard.ContactEmail/ContactPhonefrom the health participant report (PII).IArchivingEventV2OrchestrationServiceandIListenerEventV2OrchestrationServicerestored tointernal.Also included
ParticipantSecretin appsettings with the seeded 36+ char value (a pre-existing mismatch, unrelated to the review, that broke submits on a fresh DB).Not in this PR
#3 (secret hashing), #12 (V1 SSRF/retry — out of scope), #13/#14/#15 (secret-exposure cluster), #16/#17 (config/limits), #24 (info bundle).
closes #723