diff --git a/packages/rest-api/src/controllers/bridgeTxStatusController.ts b/packages/rest-api/src/controllers/bridgeTxStatusController.ts index a0074a954e..a8eadc173e 100644 --- a/packages/rest-api/src/controllers/bridgeTxStatusController.ts +++ b/packages/rest-api/src/controllers/bridgeTxStatusController.ts @@ -15,10 +15,14 @@ export const bridgeTxStatusController = async (req, res) => { try { const { destChainId, bridgeModule, synapseTxId } = req.query + const txIdWith0x = !synapseTxId.startsWith('0x') + ? `0x${synapseTxId}` + : synapseTxId + const status = await Synapse.getBridgeTxStatus( Number(destChainId), bridgeModule, - synapseTxId + txIdWith0x ) if (status) { diff --git a/packages/rest-api/src/routes/bridgeTxStatusRoute.ts b/packages/rest-api/src/routes/bridgeTxStatusRoute.ts index 85227c760f..a9a22e65b1 100644 --- a/packages/rest-api/src/routes/bridgeTxStatusRoute.ts +++ b/packages/rest-api/src/routes/bridgeTxStatusRoute.ts @@ -5,6 +5,7 @@ import { showFirstValidationError } from '../middleware/showFirstValidationError import { bridgeTxStatusController } from '../controllers/bridgeTxStatusController' import { CHAINS_ARRAY } from '../constants/chains' import { VALID_BRIDGE_MODULES } from '../constants' +import { validateKappa } from '../validations/validateKappa' const router = express.Router() @@ -134,7 +135,10 @@ router.get( check('synapseTxId') .exists() .withMessage('synapseTxId is required') - .isString(), + .isString() + .withMessage('synapseTxId must be a string') + .custom((value) => validateKappa(value)) + .withMessage('synapseTxId must be valid hex string'), ], showFirstValidationError, bridgeTxStatusController diff --git a/packages/rest-api/src/tests/bridgeTxStatusRoute.test.ts b/packages/rest-api/src/tests/bridgeTxStatusRoute.test.ts index b806ef282b..2a1fa71ed9 100644 --- a/packages/rest-api/src/tests/bridgeTxStatusRoute.test.ts +++ b/packages/rest-api/src/tests/bridgeTxStatusRoute.test.ts @@ -64,6 +64,20 @@ describe('Get Bridge TX Status Route', () => { expect(response.body.error).toHaveProperty('field', 'synapseTxId') }, 10000) + it('should return 400 for invalid synapseTxId', async () => { + const response = await request(app).get('/bridgeTxStatus').query({ + destChainId: '1', + bridgeModule: 'SynapseRFQ', + synapseTxId: "'0x1234' OR '1'='1'", + }) + + expect(response.status).toBe(400) + expect(response.body.error).toHaveProperty( + 'message', + 'synapseTxId must be valid hex string' + ) + }, 10000) + it('should return 400 for missing destChainId', async () => { const response = await request(app).get('/bridgeTxStatus').query({ bridgeModule: 'bridge', diff --git a/packages/rest-api/src/validations/validateKappa.ts b/packages/rest-api/src/validations/validateKappa.ts new file mode 100644 index 0000000000..22ee8023c9 --- /dev/null +++ b/packages/rest-api/src/validations/validateKappa.ts @@ -0,0 +1,11 @@ +export const validateKappa = (synapseTxId: string) => { + let hexRegex + + if (synapseTxId.startsWith('0x')) { + hexRegex = /^0x[0-9a-fA-F]{64}$/ + } else { + hexRegex = /^[0-9a-fA-F]{64}$/ + } + + return hexRegex.test(synapseTxId) +}