Skip to content

fix: Validate the validation_create secret parameter - #7934

Draft
SoubeDev wants to merge 2 commits into
XRPLF:developfrom
SoubeDev:fix-6763-validation-create-secret-validation
Draft

fix: Validate the validation_create secret parameter#7934
SoubeDev wants to merge 2 commits into
XRPLF:developfrom
SoubeDev:fix-6763-validation-create-secret-validation

Conversation

@SoubeDev

@SoubeDev SoubeDev commented Aug 3, 2026

Copy link
Copy Markdown

doValidationCreate read the optional secret with an unguarded asString(), which throws for arrays and objects and silently stringifies every scalar. The throw was swallowed by callMethod's catch-all, so a malformed value produced a generic internal error rather than invalidParams, and the request was recorded as a server fault in the perf log.

The coercion case is worse than a bad error code: parseGenericSeed accepts any non-empty string as a passphrase, so {"secret": 12345} did not fail at all. It hashed "12345" and returned a real validator key derived from the printed form of a number the caller never meant as a passphrase. Booleans behaved the same way; null coerced to "" and happened to be rejected already.

Guard the conversion with an isString() check and return invalidParams when it fails. The check has to sit in the handler rather than in validationSeed, whose only failure channel is nullopt and is already mapped to badSeed, which must stay that way for a string secret that is not a seed.

This makes the handler stricter: a secret given as a number or a bool was previously coerced and is now rejected. The command is admin only, and the commandline builds the field from argv via asString(), so it is always a string there and the parser is unaffected. An absent secret still picks a random seed, and a string secret behaves exactly as before.

Add a ValidationCreate test suite, which did not exist; the two cases in ValidatorRPC go through env.rpc(), which stringifies like the commandline does and so cannot reach the handler with a non-string.

Fixes #6763

High Level Overview of Change

Context of Change

API Impact

  • Public API: New feature (new methods and/or new fields)
  • Public API: Breaking change (in general, breaking changes should only impact the next api_version)
  • libxrpl change (any change that may affect libxrpl or dependents of libxrpl)
  • Peer protocol change (must be backward compatible or bump the peer protocol version)

SoubeDev and others added 2 commits August 3, 2026 11:07
doValidationCreate read the optional secret with an unguarded asString(),
which throws for arrays and objects and silently stringifies every scalar.
The throw was swallowed by callMethod's catch-all, so a malformed value
produced a generic internal error rather than invalidParams, and the request
was recorded as a server fault in the perf log.

The coercion case is worse than a bad error code: parseGenericSeed accepts
any non-empty string as a passphrase, so {"secret": 12345} did not fail at
all. It hashed "12345" and returned a real validator key derived from the
printed form of a number the caller never meant as a passphrase. Booleans
behaved the same way; null coerced to "" and happened to be rejected already.

Guard the conversion with an isString() check and return invalidParams when
it fails. The check has to sit in the handler rather than in validationSeed,
whose only failure channel is nullopt and is already mapped to badSeed, which
must stay that way for a string secret that is not a seed.

This makes the handler stricter: a secret given as a number or a bool was
previously coerced and is now rejected. The command is admin only, and the
commandline builds the field from argv via asString(), so it is always a
string there and the parser is unaffected. An absent secret still picks a
random seed, and a string secret behaves exactly as before.

Add a ValidationCreate test suite, which did not exist; the two cases in
ValidatorRPC go through env.rpc(), which stringifies like the commandline
does and so cannot reach the handler with a non-string.

Fixes XRPLF#6763

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The entry was added with a placeholder because the pull request did not
exist when the fix was committed. Point it at XRPLF#7934.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

Missing type validation for secret in validation_create

1 participant