Skip to content

fix: prevent field label leak through rule parameters in validation messages - #10579

Closed
gr8man wants to merge 3 commits into
codeigniter4:developfrom
gr8man:fix/validation-param-label-leak
Closed

gr8man wants to merge 3 commits into
codeigniter4:developfrom
gr8man:fix/validation-param-label-leak

Conversation

@gr8man

@gr8man gr8man commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Description

Validation::getErrorMessage() used the rule parameter as a key into the
defined field rules to substitute the referenced field's label in the error
message. When a parameter that was not a field reference (e.g. a numeric
limit like min_length[secret]) coincidentally matched a defined field
name, that field's label leaked into the error message (information
disclosure of internal field labels plus a wrong message).

Label substitution now only applies to rules whose parameter is a field
reference: matches, differs, required_with, required_without. Other
rules render the parameter verbatim.

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value (without duplication)
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@carson-codeigniter4 carson-codeigniter4 Bot added the bug Verified issues on the current code behavior or pull requests that will fix them label Sep 21, 2026
Comment on lines +40 to +45
private const FIELD_REFERENCE_RULES = [
'matches',
'differs',
'required_with',
'required_without',
];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also add uploaded and is_image here.

@carson-codeigniter4 carson-codeigniter4 Bot added the stale Pull requests with conflicts label Sep 27, 2026
@carson-codeigniter4

This comment has been minimized.

…essages

getErrorMessage() resolved a rule parameter as a key into the field rules
to substitute the referenced field's label. A parameter that was not a
field reference (e.g. min_length[secret]) could coincidentally match a
defined field name and leak its label into the error message.

Label substitution now only applies to field-referencing rules
(matches, differs, required_with, required_without).
@gr8man
gr8man force-pushed the fix/validation-param-label-leak branch from 8a179ac to 3eec126 Compare September 27, 2026 16:28
@carson-codeigniter4 carson-codeigniter4 Bot removed the stale Pull requests with conflicts label Sep 27, 2026

@michalsn michalsn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly, I now see that this introduces a compatibility issue with custom rules.
For example, an application could define a rule that references another field:

example_rule[password]

If password has the label Your Password, a custom error message such as:

'example_rule' => 'The {field} field must match {param}.'

would now return:

The Confirmation field must match password.

instead of:

The Confirmation field must match Your Password.

The validation result would remain unchanged, but existing error messages would change because custom rules cannot appear in the hardcoded list.

The underlying issue is that we cannot reliably determine whether a parameter is a literal value or a field reference without knowing the rule semantics. Given this compatibility tradeoff, I think we should leave the current behavior unchanged for now.

@gr8man gr8man closed this Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Verified issues on the current code behavior or pull requests that will fix them

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants