Skip to content

Keep rejected identifier values out of validation messages [patch] - #425

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/333-redact-rejected-value
Oct 14, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/333-redact-rejected-value

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #333

What changed

SemanticString.PerformValidation threw Cannot convert "<canonical value>" to T. That put a rejected card number (PAN), JWT or IBAN into logs in full, and it dropped the reason the validation attribute gave.

  • protected internal virtual bool IncludeValueInErrors => true on SemanticString<T>. CreditCardNumber, JwtToken and Iban override it to false, so their message reads Cannot convert the value to CreditCardNumber: ….
  • Reasons in the message. A new AttributeValidation.GetValidationErrors collects the errors of every attribute that rejects the value: the failing attributes under [ValidateAll], and the union of all of them under [ValidateAny]. A native attribute contributes its ValidationResult.Errors. An attribute that reports no reason is named instead. Example: Cannot convert the value to CreditCardNumber: The value must be a valid credit card number (Luhn check failed).
  • Types that don't opt out still quote the value, so existing messages only gain the reason suffix. The existing ErrorMessages_ContainTypeInformation test still passes.

Tests

Semantics.Test/Identifiers/ValidationMessageTests.cs:

  • CreditCardNumber, JwtToken, Iban: the message omits the canonical input and contains the reason (Luhn, JWT header, mod-97)
  • Uuid (not sensitive): the message keeps the value and adds the reason

With the library change stashed, all four tests fail. With it applied, they pass. The full Semantics.Test suite passes on net10.0 (1645 passed, 0 failed). Semantics.Strings builds for every target framework, netstandard2.0 included.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QbGcYckSzgr6jPyoNYhWvA


Generated by Claude Code

A failed SemanticString creation quoted the whole canonical value in its
ArgumentException, so a mistyped card number, a tampered JWT or an IBAN
went straight into logs. The message also dropped the reason each
validation attribute gives.

Add a protected internal IncludeValueInErrors hook, set to false on
CreditCardNumber, JwtToken and Iban, and append the errors of every
rejecting attribute to the message.

Fixes #333

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QbGcYckSzgr6jPyoNYhWvA
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 3fbcfe3 into main Oct 14, 2026
15 checks passed
@matt-edmondson
matt-edmondson deleted the fix/333-redact-rejected-value branch October 14, 2026 04:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A rejected CreditCardNumber, JwtToken or Iban puts the full value in the exception message, and the message never says which rule failed

2 participants