From 69f7d268305893be6ef12d72a5825814aface989 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 06:11:28 +0000 Subject: [PATCH] fix: securely extract client IP from x-forwarded-for header Co-authored-by: Shreyassp002 <96625037+Shreyassp002@users.noreply.github.com> --- .jules/flash.md | 6 ++++++ src/app/api/v1/payment-links/route.ts | 2 +- src/lib/api/verify-api-key.ts | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .jules/flash.md diff --git a/.jules/flash.md b/.jules/flash.md new file mode 100644 index 0000000..6f6987d --- /dev/null +++ b/.jules/flash.md @@ -0,0 +1,6 @@ + +## 2024-05-18 - [Fix IP Extraction from x-forwarded-for] +**Category:** Security | Bug +**Finding:** The `x-forwarded-for` header can contain multiple comma-separated IP addresses when a request goes through proxies. Previously, the raw string or untrimmed string was being directly assigned to `ip_address` in database logs, which has a length limit of 45 (`varchar(45)`). +**Learning:** For Next.js/Supabase architectures, processing headers containing proxy chains must always handle string extraction properly. Passing a raw comma-separated list of IPs can crash database inserts, and ignoring whitespace can cause malformed data. +**Action:** Always extract the actual client IP by splitting the `x-forwarded-for` header by commas and explicitly trimming whitespace: `ip.split(',')[0].trim()`. diff --git a/src/app/api/v1/payment-links/route.ts b/src/app/api/v1/payment-links/route.ts index 679f324..288c743 100644 --- a/src/app/api/v1/payment-links/route.ts +++ b/src/app/api/v1/payment-links/route.ts @@ -147,7 +147,7 @@ export async function POST(req: NextRequest) { method: 'POST', status_code: 201, request_body: body, - ip_address: clientIp.split(',')[0], + ip_address: clientIp.split(',')[0].trim(), // eslint-disable-next-line @typescript-eslint/no-explicit-any }).then(({ error }: any) => { if (error) console.error('Failed to log API call', error) diff --git a/src/lib/api/verify-api-key.ts b/src/lib/api/verify-api-key.ts index 9b858a8..fc504ef 100644 --- a/src/lib/api/verify-api-key.ts +++ b/src/lib/api/verify-api-key.ts @@ -57,7 +57,7 @@ export async function verifyApiKey(req: NextRequest) { endpoint: req.nextUrl.pathname, method: req.method, status_code: 200, // Assumed success if we get here - ip_address: req.headers.get('x-forwarded-for') || 'unknown', + ip_address: (req.headers.get('x-forwarded-for') || 'unknown').split(',')[0].trim(), user_agent: req.headers.get('user-agent') || 'unknown' // eslint-disable-next-line @typescript-eslint/no-explicit-any }).then(({ error }: any) => {