Respect #[SensitiveParameter] when reporting mapping failures - #130
Draft
janedbal wants to merge 1 commit into
Draft
Respect #[SensitiveParameter] when reporting mapping failures#130janedbal wants to merge 1 commit into
janedbal wants to merge 1 commit into
Conversation
Mapping failures embed the offending value in the exception message, which typically ends up in logs and in API error responses. PHP applies #[SensitiveParameter] only to stack-trace arguments, so credentials mapped through an input DTO leaked verbatim. Constructor parameters marked with #[SensitiveParameter] (or wrapped in the new #[MapSensitive]) are now compiled with a try/catch that replaces the offending value with its type, keeping path, keys and expectation intact. The wrapper sits below Optional/default-value handling and above validators, so validator messages are redacted too. Co-Authored-By: Claude Code
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.
Mapping failures embed the offending value in the exception message (
Expected non-empty string, got "hunter2"), and those messages typically end up in logs and in API error responses. PHP applies#[SensitiveParameter]only to stack-trace arguments, so credentials mapped through an input DTO leaked verbatim./passwordnow fails withExpected non-empty string, got string (redacted), while/loginkeeps reporting its value as before. Path, keys and the expectation itself are preserved — only the value is dropped.How
MappingFailedExceptionbuilds a second, value-free reason alongside the current one;MappingFailedException::redact($e)returns an equivalent exception built from it.missingKey/extraKeysare unchanged, as keys are structural rather than data. The source exception is deliberately not kept asprevious(its message holds the value); apreviousthat is itself aMappingFailedExceptionis redacted recursively.SensitiveInputMapperCompilerwraps the whole subtree intry { … } catch (MappingFailedException $e) { throw MappingFailedException::redact($e); }. This covers nested mappers and any third-partyAssert*validator without touching the ~36MappingFailedException::incorrect*call sites. Required one newPhpCodeBuilder::tryCatch()helper.DefaultMapperCompilerFactorywraps the parameter's provider after validators but beforeOptional/MapDefaultValue, so an optional sensitive parameter keeps itsUndefinedAwareMapperCompilerbehaviour — wrapping it on the outside would have silently made the key required.addValidatorProvider()also pushes validators insideMapSensitive, so the explicit attribute behaves identically to the native one.Notes
redact()is a static factory rather than an instance method:$e->redacted()tripsshipmonk.missingPreviousExceptionin every generated mapper, whereas passing the caught exception as an argument satisfies that rule honestly and matches the existing static-factory style of the class.#[SensitiveParameter]is PHP 8.2+, and this package supports 8.1. Detection is by attribute name, so nothing breaks on 8.1 — the attribute just cannot be written there, hence the#[MapSensitive(new MapString())]fallback documented in the README.ObjectInputMapperCompilerdumps the whole payload when the input is not an array, before any per-parameter mapper runs.Co-Authored-By: Claude Code