From 2177256a2c537cdf9ab114efa74ccdc5c21320ed Mon Sep 17 00:00:00 2001 From: Nick Maynard Date: Mon, 8 Sep 2025 23:05:22 +0100 Subject: [PATCH] Fix ordering to allow X-Forwarded-For to be correctly managed by Cloudflare --- src/lib/__tests__/detect.test.ts | 7 +++++++ src/lib/constants.ts | 14 ++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/lib/__tests__/detect.test.ts b/src/lib/__tests__/detect.test.ts index 1cb558ad..0ee34572 100644 --- a/src/lib/__tests__/detect.test.ts +++ b/src/lib/__tests__/detect.test.ts @@ -2,6 +2,7 @@ import * as detect from '../detect'; import { expect } from '@jest/globals'; const IP = '127.0.0.1'; +const BAD_IP = '127.127.127.127'; test('getIpAddress: Custom header', () => { process.env.CLIENT_IP_HEADER = 'x-custom-ip-header'; @@ -17,6 +18,12 @@ test('getIpAddress: Standard header', () => { expect(detect.getIpAddress(new Headers({ 'x-forwarded-for': IP }))).toEqual(IP); }); +test('getIpAddress: CloudFlare header is lower priority than standard header', () => { + expect( + detect.getIpAddress(new Headers({ 'cf-connecting-ip': BAD_IP, 'x-forwarded-for': IP })), + ).toEqual(IP); +}); + test('getIpAddress: No header', () => { expect(detect.getIpAddress(new Headers())).toEqual(null); }); diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 2718c135..9c9ecd96 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -333,18 +333,20 @@ export const BROWSERS = { yandexbrowser: 'Yandex', }; +// The order here is important and influences how IPs are detected by lib/detect.ts +// Please do not change the order unless you know exactly what you're doing - read https://developers.cloudflare.com/fundamentals/reference/http-headers/ export const IP_ADDRESS_HEADERS = [ - 'cf-connecting-ip', + 'x-client-ip', + 'x-forwarded-for', + 'cf-connecting-ip', // This should be *after* x-forwarded-for, so that x-forwarded-for is respected if present 'do-connecting-ip', 'fastly-client-ip', - 'forwarded', 'true-client-ip', - 'x-appengine-user-ip', - 'x-client-ip', + 'x-real-ip', 'x-cluster-client-ip', 'x-forwarded', - 'x-forwarded-for', - 'x-real-ip', + 'forwarded', + 'x-appengine-user-ip', ]; export const SOCIAL_DOMAINS = [