From c4eea0b7718e80e44edb3c207d7d5e77778d3b09 Mon Sep 17 00:00:00 2001 From: Annakaee Date: Mon, 29 Jun 2026 04:33:07 +0100 Subject: [PATCH 1/2] fix: enforce 100kb payload limit on express.json and handle 413s --- backend/src/__tests__/errorHandling.test.ts | 19 +++++++++++++++++++ backend/src/app.ts | 3 ++- backend/src/middleware/errorHandler.ts | 13 +++++++++++++ pr_body_1184.md | 10 ++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 pr_body_1184.md diff --git a/backend/src/__tests__/errorHandling.test.ts b/backend/src/__tests__/errorHandling.test.ts index 991fde07..4b56868d 100644 --- a/backend/src/__tests__/errorHandling.test.ts +++ b/backend/src/__tests__/errorHandling.test.ts @@ -75,6 +75,25 @@ describe('Centralized Error Handling', () => { }); }); + describe("Request Payload Size Limit", () => { + it("should return 413 when payload exceeds the configured limit", async () => { + // Create a payload larger than 100kb + const largePayload = { + data: "x".repeat(1024 * 150) // 150kb string + }; + + const response = await request(app) + .post("/api/simulate") + .set("Authorization", authHeader) + .send(largePayload); + + expect(response.status).toBe(413); + expect(response.body.success).toBe(false); + expect(response.body.error.code).toBe('VALIDATION_ERROR'); + expect(response.body.error.message).toMatch(/payload too large/i); + }); + }); + /* ── Consistent JSON structure ────────────────────────────── */ describe('Response structure consistency', () => { diff --git a/backend/src/app.ts b/backend/src/app.ts index 141faa31..e8259f85 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -110,7 +110,8 @@ const corsOptions: cors.CorsOptions = { app.use(cors(corsOptions)); app.use(compression()); -app.use(express.json()); +// Explicit request body size limit set to 100kb to mitigate payload-based DoS and unbounded audit log writes. +app.use(express.json({ limit: '100kb' })); app.use(globalRateLimiter); app.use(requestIdMiddleware); app.use(requestLogger); diff --git a/backend/src/middleware/errorHandler.ts b/backend/src/middleware/errorHandler.ts index 496c2ee2..a5532db1 100644 --- a/backend/src/middleware/errorHandler.ts +++ b/backend/src/middleware/errorHandler.ts @@ -94,6 +94,19 @@ export const errorHandler = ( return; } + // ── Payload Too Large (body-parser) ──────────────────────── + if ('type' in err && (err as any).type === 'entity.too.large') { + res.status(413).json({ + success: false, + message: 'Request payload too large', + error: { + code: ErrorCode.VALIDATION_ERROR, // Or a dedicated code if defined + message: 'Request payload too large', + }, + }); + return; + } + // ── Unexpected / Programming Errors ────────────────────────── logger.error('Unhandled error', { requestId: req.requestId, diff --git a/pr_body_1184.md b/pr_body_1184.md new file mode 100644 index 00000000..75e714df --- /dev/null +++ b/pr_body_1184.md @@ -0,0 +1,10 @@ +Closes #1184 + +### What does this PR do? +This PR enforces an explicit 100kb payload size limit on `express.json()` and correctly handles resulting `entity.too.large` errors so they return a structured 413 response rather than defaulting to an unhandled 500 error. + +### Description +- **Explicit Size Limit:** Added an explicit `{ limit: '100kb' }` configuration to `express.json()` in `app.ts`. This protects the application and audit logs from unbounded payload sizes, while remaining more than generous enough to accommodate legitimate signed transaction payloads. +- **Centralized Error Handling:** Updated `errorHandler.ts` to natively catch `entity.too.large` errors emitted by `body-parser` and translate them into standard `413 Payload Too Large` responses with the `VALIDATION_ERROR` code. +- **Test Coverage:** Added an integration test in `errorHandling.test.ts` to assert that a 150kb payload correctly trips the limit and returns the structured `413` error. +- **Documentation:** Added inline comments describing the rationale behind the payload limit in `app.ts`. From cf94fac72681e69f015e6f642d1364d622a71529 Mon Sep 17 00:00:00 2001 From: Annakaee Date: Wed, 1 Jul 2026 14:08:53 +0100 Subject: [PATCH 2/2] chore: remove stray pr_body_1184.md --- backend/src/__tests__/errorHandling.test.ts | 10 +++++----- backend/src/middleware/errorHandler.ts | 2 +- pr_body_1184.md | 10 ---------- 3 files changed, 6 insertions(+), 16 deletions(-) delete mode 100644 pr_body_1184.md diff --git a/backend/src/__tests__/errorHandling.test.ts b/backend/src/__tests__/errorHandling.test.ts index 4b56868d..ca0dffb7 100644 --- a/backend/src/__tests__/errorHandling.test.ts +++ b/backend/src/__tests__/errorHandling.test.ts @@ -75,16 +75,16 @@ describe('Centralized Error Handling', () => { }); }); - describe("Request Payload Size Limit", () => { - it("should return 413 when payload exceeds the configured limit", async () => { + describe('Request Payload Size Limit', () => { + it('should return 413 when payload exceeds the configured limit', async () => { // Create a payload larger than 100kb const largePayload = { - data: "x".repeat(1024 * 150) // 150kb string + data: 'x'.repeat(1024 * 150), // 150kb string }; const response = await request(app) - .post("/api/simulate") - .set("Authorization", authHeader) + .post('/api/simulate') + .set('Authorization', authHeader) .send(largePayload); expect(response.status).toBe(413); diff --git a/backend/src/middleware/errorHandler.ts b/backend/src/middleware/errorHandler.ts index a5532db1..f15f85fe 100644 --- a/backend/src/middleware/errorHandler.ts +++ b/backend/src/middleware/errorHandler.ts @@ -95,7 +95,7 @@ export const errorHandler = ( } // ── Payload Too Large (body-parser) ──────────────────────── - if ('type' in err && (err as any).type === 'entity.too.large') { + if ('type' in err && (err as { type?: string }).type === 'entity.too.large') { res.status(413).json({ success: false, message: 'Request payload too large', diff --git a/pr_body_1184.md b/pr_body_1184.md deleted file mode 100644 index 75e714df..00000000 --- a/pr_body_1184.md +++ /dev/null @@ -1,10 +0,0 @@ -Closes #1184 - -### What does this PR do? -This PR enforces an explicit 100kb payload size limit on `express.json()` and correctly handles resulting `entity.too.large` errors so they return a structured 413 response rather than defaulting to an unhandled 500 error. - -### Description -- **Explicit Size Limit:** Added an explicit `{ limit: '100kb' }` configuration to `express.json()` in `app.ts`. This protects the application and audit logs from unbounded payload sizes, while remaining more than generous enough to accommodate legitimate signed transaction payloads. -- **Centralized Error Handling:** Updated `errorHandler.ts` to natively catch `entity.too.large` errors emitted by `body-parser` and translate them into standard `413 Payload Too Large` responses with the `VALIDATION_ERROR` code. -- **Test Coverage:** Added an integration test in `errorHandling.test.ts` to assert that a 150kb payload correctly trips the limit and returns the structured `413` error. -- **Documentation:** Added inline comments describing the rationale behind the payload limit in `app.ts`.