Skip to content

Commit 20e334d

Browse files
authored
fix: validate block cursor pagination parameter format (#2317)
1 parent 39e384f commit 20e334d

File tree

4 files changed

+20
-10
lines changed

4 files changed

+20
-10
lines changed

src/api/routes/v2/block-tenures.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { handleBlockCache } from '../../../api/controllers/cache-controller';
55
import { getPagingQueryLimit, ResourceType } from '../../../api/pagination';
66
import { CursorOffsetParam, LimitParam } from '../../../api/schemas/params';
77
import { BlockListV2ResponseSchema } from '../../../api/schemas/responses/responses';
8-
import { BlockTenureParamsSchema } from './schemas';
8+
import { BlockTenureParamsSchema, BlockCursorParamSchema } from './schemas';
99
import { NotFoundError } from '../../../errors';
1010
import { NakamotoBlock } from '../../../api/schemas/entities/block';
1111
import { parseDbNakamotoBlock } from './helpers';
@@ -28,7 +28,7 @@ export const BlockTenureRoutes: FastifyPluginAsync<
2828
querystring: Type.Object({
2929
limit: LimitParam(ResourceType.Block),
3030
offset: CursorOffsetParam({ resource: ResourceType.Block }),
31-
cursor: Type.Optional(Type.String({ description: 'Cursor for pagination' })),
31+
cursor: Type.Optional(BlockCursorParamSchema),
3232
}),
3333
response: {
3434
200: BlockListV2ResponseSchema,

src/api/routes/v2/blocks.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
import { handleBlockCache, handleChainTipCache } from '../../../api/controllers/cache-controller';
2-
import { BlockParamsSchema, cleanBlockHeightOrHashParam, parseBlockParam } from './schemas';
2+
import {
3+
BlockParamsSchema,
4+
cleanBlockHeightOrHashParam,
5+
BlockCursorParamSchema,
6+
parseBlockParam,
7+
} from './schemas';
38
import { parseDbNakamotoBlock } from './helpers';
49
import { InvalidRequestError, NotFoundError } from '../../../errors';
510
import { parseDbTx } from '../../../api/controllers/db-controller';
611
import { FastifyPluginAsync } from 'fastify';
712
import { Type, TypeBoxTypeProvider } from '@fastify/type-provider-typebox';
813
import { Server } from 'node:http';
914
import { CursorOffsetParam, LimitParam, OffsetParam } from '../../schemas/params';
10-
import { getPagingQueryLimit, pagingQueryLimits, ResourceType } from '../../pagination';
15+
import { getPagingQueryLimit, ResourceType } from '../../pagination';
1116
import { PaginatedResponse } from '../../schemas/util';
12-
import {
13-
NakamotoBlock,
14-
NakamotoBlockSchema,
15-
SignerSignatureSchema,
16-
} from '../../schemas/entities/block';
17+
import { NakamotoBlock, NakamotoBlockSchema } from '../../schemas/entities/block';
1718
import { TransactionSchema } from '../../schemas/entities/transactions';
1819
import {
1920
BlockListV2ResponseSchema,
@@ -37,7 +38,7 @@ export const BlockRoutesV2: FastifyPluginAsync<
3738
querystring: Type.Object({
3839
limit: LimitParam(ResourceType.Block),
3940
offset: CursorOffsetParam({ resource: ResourceType.Block }),
40-
cursor: Type.Optional(Type.String({ description: 'Cursor for pagination' })),
41+
cursor: Type.Optional(BlockCursorParamSchema),
4142
}),
4243
response: {
4344
200: BlockListV2ResponseSchema,

src/api/routes/v2/schemas.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ export const PoxSignerLimitParamSchema = Type.Integer({
7171
description: 'PoX signers per page',
7272
});
7373

74+
export const BlockCursorParamSchema = Type.String({
75+
pattern: '^0x[a-fA-F0-9]{64}$',
76+
description: 'Cursor for block pagination',
77+
});
78+
7479
export type BlockIdParam =
7580
| { type: 'height'; height: number }
7681
| { type: 'hash'; hash: string }

tests/api/block.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,10 @@ describe('block tests', () => {
834834
const latestPageCursor = body.cursor;
835835
const latestBlock = body.results[0];
836836

837+
// Cursor fetch is rejected if it's not a valid block hash
838+
const req2 = await supertest(api.server).get(`/extended/v2/blocks?limit=3&cursor=testvalue`);
839+
expect(req2.statusCode).toBe(400);
840+
837841
// Can fetch same page using cursor
838842
({ body } = await supertest(api.server).get(
839843
`/extended/v2/blocks?limit=3&cursor=${body.cursor}`

0 commit comments

Comments
 (0)