fix(auditing): mask sensitive entity-diff values and add IAuditExempt opt-out - #1392
Merged
Merged
Conversation
… opt-out EntityDiffBuilder flagged password/secret/token properties as IsSensitive but stored their old and new values verbatim, so every Identity write copied PasswordHash and token columns into AuditRecords. Sensitive values are now masked to "****" (null kept as null) before the payload leaves the interceptor; keyword list aligned with JsonMaskingService. Adds IAuditExempt (Contracts): entities implementing it are skipped by the entity-change interceptor entirely, for data that must live in one table only. [NoAudit] only covers HTTP activity auditing and never did this. Fixes #1389. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Fixes #1389 (proposal by @marcelo-maciel), plus a second leak found while verifying it.
1. Sensitive values were stored in plain text
EntityDiffBuildersetIsSensitivefor property names containing password/secret/token, but still wrote the real old/new values into the payload.PropertyChange's comment ("value already masked/hashed") was false, andJsonMaskingServiceonly runs in the HTTP middleware. Identity's DbContext is audited, soPasswordHashand token columns landed inauditing."AuditRecords".Now: sensitive values →
"****"(null stays null, so set/cleared is still visible). Keywords: password, secret, token, apikey, connectionstring, securitystamp.2. Per-entity opt-out:
IAuditExemptThe marker interface from the issue, in
Modules.Auditing.Contracts. The interceptor skips any entry whose entity implements it. Opt-in, so nothing changes by default.[NoAudit]is unrelated (HTTP activity only); the XML doc and.agents/rules/modules/auditing.mdsay so.Behaviour change
Audit rows for sensitive properties now show
****instead of the value. Anyone who relied on seeing those values in the trail loses them. That's intended.Tests
AuditingSaveChangesInterceptorTests(EF InMemory + capturing publisher): insert masking, update masking of old and new values, and exempt vs non-exempt entities in one save (with a positive control). All three fail before the fix. Auditing.Tests 66/66, auditing integration tests 48/48, build 0 warnings.🤖 Generated with Claude Code