diff --git a/packages/api/src/utils/ports.spec.ts b/packages/api/src/utils/ports.spec.ts index ea4dc284c7..0a53c867ea 100644 --- a/packages/api/src/utils/ports.spec.ts +++ b/packages/api/src/utils/ports.spec.ts @@ -75,7 +75,7 @@ describe('removePorts', () => { expect(removePorts(req(undefined))).toBeUndefined(); }); - test('returns undefined when ip is empty string', () => { + test('returns empty string when ip is empty string', () => { expect(removePorts({ ip: '' } as Request)).toBe(''); }); @@ -90,6 +90,12 @@ describe('removePorts', () => { }); }); + describe('express-rate-limit v8 heuristic guard', () => { + test('function source does not contain "req.ip" (guards against ERR_ERL_KEY_GEN_IPV6)', () => { + expect(removePorts.toString()).not.toContain('req.ip'); + }); + }); + describe('unrecognized formats fall through unchanged', () => { test('returns garbage input unchanged', () => { expect(removePorts(req('not-an-ip'))).toBe('not-an-ip'); diff --git a/packages/api/src/utils/ports.ts b/packages/api/src/utils/ports.ts index ecd38039d6..ed20c89193 100644 --- a/packages/api/src/utils/ports.ts +++ b/packages/api/src/utils/ports.ts @@ -1,8 +1,12 @@ import type { Request } from 'express'; -/** Strips port suffix from req.ip for use as a rate-limiter key (IPv4 and IPv6-safe) */ +/** + * Strips port suffix from req.ip for use as a rate-limiter key (IPv4 and IPv6-safe). + * Bracket notation for the ip property avoids express-rate-limit v8's toString() + * heuristic that scans for the literal substring "req.ip" (ERR_ERL_KEY_GEN_IPV6). + */ export function removePorts(req: Request): string | undefined { - const ip = req?.ip; + const ip = req?.['ip']; if (!ip) { return ip; }