From 670115b0b4f33f302a99f775c54007b68b761f5d Mon Sep 17 00:00:00 2001 From: Snowmanzx <105658828+Snowmanzx@users.noreply.github.com> Date: Wed, 10 Jun 2026 17:25:09 +0300 Subject: [PATCH] fix: reject malformed amount strings in validateStringAmount validateStringAmount used parseFloat, which reads a leading numeric prefix so values like "1abc", "1.2.3" and "1e6" passed validation and only failed later in parseUnits. Replaced it with a strict decimal check. Negative and zero amounts still report must be greater than 0 as before, so existing tests keep passing. --- .../src/interface/payment/utils/validation.test.ts | 8 ++++++++ .../src/interface/payment/utils/validation.ts | 9 +++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/account-sdk/src/interface/payment/utils/validation.test.ts b/packages/account-sdk/src/interface/payment/utils/validation.test.ts index 6f5bb576..c79707ae 100644 --- a/packages/account-sdk/src/interface/payment/utils/validation.test.ts +++ b/packages/account-sdk/src/interface/payment/utils/validation.test.ts @@ -20,6 +20,14 @@ describe('validateStringAmount', () => { ); }); + it('rejects malformed numeric strings that parseFloat would accept', () => { + const message = 'Invalid amount: must be a valid number'; + const malformed = ['1abc', '1.2.3', '1foo', '1e6', '1.', '.', '']; + for (const value of malformed) { + expect(() => validateStringAmount(value, 6)).toThrow(message); + } + }); + it('should reject non-string amounts', () => { expect(() => validateStringAmount(10 as any, 6)).toThrow('Invalid amount: must be a string'); }); diff --git a/packages/account-sdk/src/interface/payment/utils/validation.ts b/packages/account-sdk/src/interface/payment/utils/validation.ts index c6e2ad7f..018da0fe 100644 --- a/packages/account-sdk/src/interface/payment/utils/validation.ts +++ b/packages/account-sdk/src/interface/payment/utils/validation.ts @@ -11,13 +11,14 @@ export function validateStringAmount(amount: string, maxDecimals: number): void throw new Error('Invalid amount: must be a string'); } - const numAmount = parseFloat(amount); - - if (isNaN(numAmount)) { + // parseFloat is too lenient: it reads a leading numeric prefix and accepts values + // like "1abc", "1.2.3" or "1e6", which then fail later in parseUnits. Require a + // plain decimal string instead. + if (!/^-?\d+(\.\d+)?$/.test(amount)) { throw new Error('Invalid amount: must be a valid number'); } - if (numAmount <= 0) { + if (Number(amount) <= 0) { throw new Error('Invalid amount: must be greater than 0'); }